diff options
Diffstat (limited to 'src/bun.js/bindings/webcore')
302 files changed, 43040 insertions, 0 deletions
diff --git a/src/bun.js/bindings/webcore/AbortAlgorithm.h b/src/bun.js/bindings/webcore/AbortAlgorithm.h new file mode 100644 index 000000000..26dd666b4 --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortAlgorithm.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 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 "ActiveDOMCallback.h" +#include "CallbackResult.h" +#include <wtf/ThreadSafeRefCounted.h> + +namespace WebCore { + +class AbortAlgorithm : public ThreadSafeRefCounted<AbortAlgorithm>, public ActiveDOMCallback { +public: + using ActiveDOMCallback::ActiveDOMCallback; + + virtual CallbackResult<void> handleEvent() = 0; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/AbortAlgorithm.idl b/src/bun.js/bindings/webcore/AbortAlgorithm.idl new file mode 100644 index 000000000..a28c77856 --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortAlgorithm.idl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2020 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. + */ + +callback AbortAlgorithm = undefined (); diff --git a/src/bun.js/bindings/webcore/AbortController.cpp b/src/bun.js/bindings/webcore/AbortController.cpp new file mode 100644 index 000000000..8e419971a --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortController.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config.h" +#include "AbortController.h" + +#include "AbortSignal.h" +#include "DOMException.h" +#include "JSDOMException.h" +// #include <wtf/IsoMallocInlines.h> + +namespace WebCore { + +WTF_MAKE_ISO_ALLOCATED_IMPL(AbortController); + +Ref<AbortController> AbortController::create(ScriptExecutionContext& context) +{ + return adoptRef(*new AbortController(context)); +} + +AbortController::AbortController(ScriptExecutionContext& context) + : m_signal(AbortSignal::create(&context)) +{ +} + +AbortController::~AbortController() = default; + +AbortSignal& AbortController::signal() +{ + return m_signal.get(); +} + +void AbortController::abort(JSDOMGlobalObject& globalObject, JSC::JSValue reason) +{ + ASSERT(reason); + if (reason.isUndefined()) + reason = toJS(&globalObject, &globalObject, DOMException::create(AbortError)); + + m_signal->signalAbort(reason); +} + +} diff --git a/src/bun.js/bindings/webcore/AbortController.h b/src/bun.js/bindings/webcore/AbortController.h new file mode 100644 index 000000000..f7bf96f25 --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortController.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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 "root.h" + +#include "ZigGlobalObject.h" + +#include "ScriptWrappable.h" +#include <wtf/Ref.h> +#include <wtf/RefCounted.h> + +namespace JSC { +class JSValue; +} + +namespace Zig { +class GlobalObject; +} + +namespace WebCore { + +class AbortSignal; + +class ScriptExecutionContext; + +class AbortController final : public ScriptWrappable, public RefCounted<AbortController> { + WTF_MAKE_ISO_ALLOCATED(AbortController); + +public: + static Ref<AbortController> create(ScriptExecutionContext&); + ~AbortController(); + + AbortSignal& signal(); + void abort(Zig::GlobalObject&, JSC::JSValue reason); + +private: + explicit AbortController(ScriptExecutionContext&); + + Ref<AbortSignal> m_signal; +}; + +} diff --git a/src/bun.js/bindings/webcore/AbortController.idl b/src/bun.js/bindings/webcore/AbortController.idl new file mode 100644 index 000000000..0d011e205 --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortController.idl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2017 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. + */ + +[ + Exposed=*, + GenerateAddOpaqueRoot=signal +] interface AbortController { + [CallWith=CurrentScriptExecutionContext] constructor(); + + [SameObject] readonly attribute AbortSignal signal; + + [CallWith=CurrentGlobalObject] undefined abort(optional any reason); +}; diff --git a/src/bun.js/bindings/webcore/AbortSignal.cpp b/src/bun.js/bindings/webcore/AbortSignal.cpp new file mode 100644 index 000000000..8554b3b83 --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortSignal.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2017-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 + * 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. + */ + +#include "config.h" +#include "AbortSignal.h" + +#include "AbortAlgorithm.h" +#include "DOMException.h" +// #include "DOMTimer.h" +#include "Event.h" +#include "EventNames.h" +#include "JSDOMException.h" +#include "ScriptExecutionContext.h" +#include <JavaScriptCore/Exception.h> +#include <JavaScriptCore/JSCast.h> +// #include <wtf/IsoMallocInlines.h> + +namespace WebCore { + +WTF_MAKE_ISO_ALLOCATED_IMPL(AbortSignal); + +Ref<AbortSignal> AbortSignal::create(ScriptExecutionContext* context) +{ + return adoptRef(*new AbortSignal(context)); +} + +// https://dom.spec.whatwg.org/#dom-abortsignal-abort +Ref<AbortSignal> AbortSignal::abort(JSDOMGlobalObject& globalObject, ScriptExecutionContext& context, JSC::JSValue reason) +{ + ASSERT(reason); + if (reason.isUndefined()) + reason = toJS(&globalObject, &globalObject, DOMException::create(AbortError)); + return adoptRef(*new AbortSignal(&context, Aborted::Yes, reason)); +} + +// https://dom.spec.whatwg.org/#dom-abortsignal-timeout +Ref<AbortSignal> AbortSignal::timeout(ScriptExecutionContext& context, uint64_t milliseconds) +{ + auto signal = adoptRef(*new AbortSignal(&context)); + // signal->setHasActiveTimeoutTimer(true); + // auto action = [signal](ScriptExecutionContext& context) mutable { + // signal->setHasActiveTimeoutTimer(false); + + // auto* globalObject = JSC::jsCast<JSDOMGlobalObject*>(context.globalObject()); + // if (!globalObject) + // return; + + // auto& vm = globalObject->vm(); + // Locker locker { vm.apiLock() }; + // signal->signalAbort(toJS(globalObject, globalObject, DOMException::create(TimeoutError))); + // }; + // DOMTimer::install(context, WTFMove(action), Seconds::fromMilliseconds(milliseconds), true); + return signal; +} + +AbortSignal::AbortSignal(ScriptExecutionContext* context, Aborted aborted, JSC::JSValue reason) + : ContextDestructionObserver(context) + , m_aborted(aborted == Aborted::Yes) + , m_reason(reason) +{ + ASSERT(reason); +} + +AbortSignal::~AbortSignal() = default; + +// https://dom.spec.whatwg.org/#abortsignal-signal-abort +void AbortSignal::signalAbort(JSC::JSValue reason) +{ + // 1. If signal's aborted flag is set, then return. + if (m_aborted) + return; + + // 2. Set signal’s aborted flag. + m_aborted = true; + + // 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); + m_reason.setWeakly(reason); + + Ref protectedThis { *this }; + auto algorithms = std::exchange(m_algorithms, {}); + for (auto& algorithm : algorithms) + algorithm(); + + // 5. Fire an event named abort at signal. + dispatchEvent(Event::create(eventNames().abortEvent, Event::CanBubble::No, Event::IsCancelable::No)); +} + +// https://dom.spec.whatwg.org/#abortsignal-follow +void AbortSignal::signalFollow(AbortSignal& signal) +{ + if (aborted()) + return; + + if (signal.aborted()) { + signalAbort(signal.reason().getValue()); + return; + } + + ASSERT(!m_followingSignal); + m_followingSignal = signal; + signal.addAlgorithm([weakThis = WeakPtr { this }] { + if (weakThis) + weakThis->signalAbort(weakThis->m_followingSignal ? weakThis->m_followingSignal->reason().getValue() : JSC::jsUndefined()); + }); +} + +void AbortSignal::eventListenersDidChange() +{ + m_hasAbortEventListener = hasEventListeners(eventNames().abortEvent); +} + +bool AbortSignal::whenSignalAborted(AbortSignal& signal, Ref<AbortAlgorithm>&& algorithm) +{ + if (signal.aborted()) { + algorithm->handleEvent(); + return true; + } + signal.addAlgorithm([algorithm = WTFMove(algorithm)]() mutable { + algorithm->handleEvent(); + }); + return false; +} + +void AbortSignal::throwIfAborted(JSC::JSGlobalObject& lexicalGlobalObject) +{ + if (!aborted()) + return; + + auto& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + throwException(&lexicalGlobalObject, scope, m_reason.getValue()); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/AbortSignal.h b/src/bun.js/bindings/webcore/AbortSignal.h new file mode 100644 index 000000000..24f893f22 --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortSignal.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017-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 + * 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 "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/WeakPtr.h> + +namespace WebCore { + +class AbortAlgorithm; +class ScriptExecutionContext; + +class AbortSignal final : public RefCounted<AbortSignal>, public EventTargetWithInlineData, private ContextDestructionObserver { + WTF_MAKE_ISO_ALLOCATED_EXPORT(AbortSignal, WEBCORE_EXPORT); + +public: + static Ref<AbortSignal> create(ScriptExecutionContext*); + WEBCORE_EXPORT ~AbortSignal(); + + static Ref<AbortSignal> abort(JSDOMGlobalObject&, ScriptExecutionContext&, JSC::JSValue reason); + static Ref<AbortSignal> timeout(ScriptExecutionContext&, uint64_t milliseconds); + + static bool whenSignalAborted(AbortSignal&, Ref<AbortAlgorithm>&&); + + void signalAbort(JSC::JSValue reason); + void signalFollow(AbortSignal&); + + bool aborted() const { return m_aborted; } + const JSValueInWrappedObject& reason() const { return m_reason; } + + bool hasActiveTimeoutTimer() const { return m_hasActiveTimeoutTimer; } + bool hasAbortEventListener() const { return m_hasAbortEventListener; } + + using RefCounted::deref; + using RefCounted::ref; + + using Algorithm = Function<void()>; + void addAlgorithm(Algorithm&& algorithm) { m_algorithms.append(WTFMove(algorithm)); } + + bool isFollowingSignal() const { return !!m_followingSignal; } + + void throwIfAborted(JSC::JSGlobalObject&); + +private: + enum class Aborted : bool { No, + Yes }; + explicit AbortSignal(ScriptExecutionContext*, Aborted = Aborted::No, JSC::JSValue reason = JSC::jsUndefined()); + + void setHasActiveTimeoutTimer(bool hasActiveTimeoutTimer) { m_hasActiveTimeoutTimer = hasActiveTimeoutTimer; } + + // EventTarget. + EventTargetInterface eventTargetInterface() const final { return AbortSignalEventTargetInterfaceType; } + ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } + void refEventTarget() final { ref(); } + void derefEventTarget() final { deref(); } + void eventListenersDidChange() final; + + bool m_aborted { false }; + Vector<Algorithm> m_algorithms; + WeakPtr<AbortSignal> m_followingSignal; + JSValueInWrappedObject m_reason; + bool m_hasActiveTimeoutTimer { false }; + bool m_hasAbortEventListener { false }; +}; + +} diff --git a/src/bun.js/bindings/webcore/AbortSignal.idl b/src/bun.js/bindings/webcore/AbortSignal.idl new file mode 100644 index 000000000..f81c5b0a2 --- /dev/null +++ b/src/bun.js/bindings/webcore/AbortSignal.idl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017-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 + * 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. + */ + +[ + CustomIsReachable, + Exposed=*, + JSCustomMarkFunction, + PrivateIdentifier, + PublicIdentifier +] interface AbortSignal : EventTarget { + [PrivateIdentifier] static boolean whenSignalAborted(AbortSignal object, AbortAlgorithm algorithm); + + [NewObject, CallWith=CurrentScriptExecutionContext&CurrentGlobalObject] static AbortSignal abort(optional any reason); + [Exposed=(Window, Worker), NewObject, CallWith=CurrentScriptExecutionContext] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds); + + readonly attribute boolean aborted; + readonly attribute any reason; + [CallWith=CurrentGlobalObject] undefined throwIfAborted(); + + attribute EventHandler onabort; +}; diff --git a/src/bun.js/bindings/webcore/ActiveDOMObject.cpp b/src/bun.js/bindings/webcore/ActiveDOMObject.cpp new file mode 100644 index 000000000..d2662f8e9 --- /dev/null +++ b/src/bun.js/bindings/webcore/ActiveDOMObject.cpp @@ -0,0 +1,195 @@ +// /* +// * 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 "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 diff --git a/src/bun.js/bindings/webcore/ActiveDOMObject.h b/src/bun.js/bindings/webcore/ActiveDOMObject.h new file mode 100644 index 000000000..e483a46b7 --- /dev/null +++ b/src/bun.js/bindings/webcore/ActiveDOMObject.h @@ -0,0 +1,170 @@ +// /* +// * 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. +// * +// */ + +// #pragma once + +// #include "ContextDestructionObserver.h" +// #include "TaskSource.h" +// #include <wtf/Assertions.h> +// #include <wtf/CancellableTask.h> +// #include <wtf/Forward.h> +// #include <wtf/Function.h> +// #include <wtf/RefCounted.h> +// #include <wtf/Threading.h> + +// namespace WebCore { + +// class Document; +// class Event; +// class EventLoopTaskGroup; +// class EventTarget; + +// enum class ReasonForSuspension { +// JavaScriptDebuggerPaused, +// WillDeferLoading, +// BackForwardCache, +// PageWillBeSuspended, +// }; + +// class WEBCORE_EXPORT ActiveDOMObject : public ContextDestructionObserver { +// public: +// // The suspendIfNeeded must be called exactly once after object construction to update +// // the suspended state to match that of the ScriptExecutionContext. +// void suspendIfNeeded(); +// void assertSuspendIfNeededWasCalled() const; + +// // This function is used by JS bindings to determine if the JS wrapper should be kept alive or not. +// bool hasPendingActivity() const { return m_pendingActivityInstanceCount || virtualHasPendingActivity(); } + +// // However, the suspend function will sometimes be called even if canSuspendForDocumentSuspension() returns false. +// // That happens in step-by-step JS debugging for example - in this case it would be incorrect +// // to stop the object. Exact semantics of suspend is up to the object in cases like that. + +// virtual const char* activeDOMObjectName() const = 0; + +// // These functions must not have a side effect of creating or destroying +// // any ActiveDOMObject. That means they must not result in calls to arbitrary JavaScript. +// virtual void suspend(ReasonForSuspension); +// virtual void resume(); + +// // This function must not have a side effect of creating an ActiveDOMObject. +// // That means it must not result in calls to arbitrary JavaScript. +// // It can, however, have a side effect of deleting an ActiveDOMObject. +// virtual void stop(); + +// template<class T> +// class PendingActivity : public RefCounted<PendingActivity<T>> { +// public: +// explicit PendingActivity(T& thisObject) +// : m_thisObject(thisObject) +// { +// ++(m_thisObject->m_pendingActivityInstanceCount); +// } + +// ~PendingActivity() +// { +// ASSERT(m_thisObject->m_pendingActivityInstanceCount > 0); +// --(m_thisObject->m_pendingActivityInstanceCount); +// } + +// private: +// Ref<T> m_thisObject; +// }; + +// template<class T> Ref<PendingActivity<T>> makePendingActivity(T& thisObject) +// { +// ASSERT(&thisObject == this); +// return adoptRef(*new PendingActivity<T>(thisObject)); +// } + +// bool isContextStopped() const; +// bool isAllowedToRunScript() const; + +// template<typename T> +// static void queueTaskKeepingObjectAlive(T& object, TaskSource source, Function<void ()>&& task) +// { +// object.queueTaskInEventLoop(source, [protectedObject = Ref { object }, activity = object.ActiveDOMObject::makePendingActivity(object), task = WTFMove(task)] () { +// task(); +// }); +// } + +// template<typename T> +// static void queueCancellableTaskKeepingObjectAlive(T& object, TaskSource source, TaskCancellationGroup& cancellationGroup, Function<void()>&& task) +// { +// CancellableTask cancellableTask(cancellationGroup, WTFMove(task)); +// object.queueTaskInEventLoop(source, [protectedObject = Ref { object }, activity = object.ActiveDOMObject::makePendingActivity(object), cancellableTask = WTFMove(cancellableTask)]() mutable { +// cancellableTask(); +// }); +// } + +// template<typename EventTargetType> +// static void queueTaskToDispatchEvent(EventTargetType& target, TaskSource source, Ref<Event>&& event) +// { +// target.queueTaskToDispatchEventInternal(target, source, WTFMove(event)); +// } + +// template<typename EventTargetType> +// static void queueCancellableTaskToDispatchEvent(EventTargetType& target, TaskSource source, TaskCancellationGroup& cancellationGroup, Ref<Event>&& event) +// { +// target.queueCancellableTaskToDispatchEventInternal(target, source, cancellationGroup, WTFMove(event)); +// } + +// protected: +// explicit ActiveDOMObject(ScriptExecutionContext*); +// explicit ActiveDOMObject(Document*); +// explicit ActiveDOMObject(Document&); +// virtual ~ActiveDOMObject(); + +// private: +// enum CheckedScriptExecutionContextType { CheckedScriptExecutionContext }; +// ActiveDOMObject(ScriptExecutionContext*, CheckedScriptExecutionContextType); + +// // This is used by subclasses to indicate that they have pending activity, meaning that they would +// // like the JS wrapper to stay alive (because they may still fire JS events). +// virtual bool virtualHasPendingActivity() const { return false; } + +// void queueTaskInEventLoop(TaskSource, Function<void ()>&&); +// void queueTaskToDispatchEventInternal(EventTarget&, TaskSource, Ref<Event>&&); +// void queueCancellableTaskToDispatchEventInternal(EventTarget&, TaskSource, TaskCancellationGroup&, Ref<Event>&&); + +// uint64_t m_pendingActivityInstanceCount { 0 }; +// #if ASSERT_ENABLED +// bool m_suspendIfNeededWasCalled { false }; +// Ref<Thread> m_creationThread { Thread::current() }; +// #endif + +// friend class ActiveDOMObjectEventDispatchTask; +// }; + +// #if !ASSERT_ENABLED + +// inline void ActiveDOMObject::assertSuspendIfNeededWasCalled() const +// { +// } + +// #endif + +// } // namespace WebCore diff --git a/src/bun.js/bindings/webcore/AddEventListenerOptions.h b/src/bun.js/bindings/webcore/AddEventListenerOptions.h new file mode 100644 index 000000000..79128ee15 --- /dev/null +++ b/src/bun.js/bindings/webcore/AddEventListenerOptions.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016-2020 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. + */ + +#pragma once + +#include "AbortSignal.h" +#include "EventListenerOptions.h" +#include <optional> + +namespace WebCore { + +struct AddEventListenerOptions : EventListenerOptions { + AddEventListenerOptions(bool capture = false, std::optional<bool> passive = std::nullopt, bool once = false, RefPtr<AbortSignal>&& signal = nullptr) + : EventListenerOptions(capture) + , passive(passive) + , once(once) + , signal(WTFMove(signal)) + { + } + + std::optional<bool> passive; + bool once { false }; + RefPtr<AbortSignal> signal; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/BufferSource.h b/src/bun.js/bindings/webcore/BufferSource.h new file mode 100644 index 000000000..ee78e38d1 --- /dev/null +++ b/src/bun.js/bindings/webcore/BufferSource.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * Copyright (C) 2021 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 "JavaScriptCore/ArrayBuffer.h" +#include "JavaScriptCore/ArrayBufferView.h" +#include "wtf/RefPtr.h" +#include <variant> + +namespace WebCore { + +class BufferSource { +public: + using VariantType = std::variant<RefPtr<JSC::ArrayBufferView>, RefPtr<JSC::ArrayBuffer>>; + + BufferSource() {} + BufferSource(VariantType&& variant) + : m_variant(WTFMove(variant)) + { + } + + const VariantType& variant() const { return m_variant; } + + const uint8_t* data() const + { + return std::visit([](auto& buffer) -> const uint8_t* { + return buffer ? static_cast<const uint8_t*>(buffer->data()) : nullptr; + }, + m_variant); + } + + void* mutableData() const + { + return std::visit([](auto& buffer) -> void* { + return buffer->data(); + }, + m_variant); + } + + size_t length() const + { + return std::visit([](auto& buffer) -> size_t { + return buffer ? buffer->byteLength() : 0; + }, + m_variant); + } + + template<class Encoder> void encode(Encoder&) const; + template<class Decoder> static std::optional<BufferSource> decode(Decoder&); + +private: + VariantType m_variant; +}; + +template<class Encoder> +void BufferSource::encode(Encoder& encoder) const +{ + encoder << static_cast<uint64_t>(length()); + if (!length()) + return; + + encoder.encodeFixedLengthData(data(), length() * sizeof(uint8_t), alignof(uint8_t)); +} + +template<class Decoder> +std::optional<BufferSource> BufferSource::decode(Decoder& decoder) +{ + std::optional<uint64_t> size; + decoder >> size; + if (!size) + return std::nullopt; + if (!*size) + return BufferSource(); + + auto dataSize = CheckedSize { *size }; + if (UNLIKELY(dataSize.hasOverflowed())) + return std::nullopt; + + const uint8_t* data = decoder.decodeFixedLengthReference(dataSize, alignof(uint8_t)); + if (!data) + return std::nullopt; + return BufferSource(JSC::ArrayBuffer::tryCreate(static_cast<const void*>(data), dataSize.value())); +} + +inline BufferSource toBufferSource(const uint8_t* data, size_t length) +{ + return BufferSource(JSC::ArrayBuffer::tryCreate(data, length)); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/CallbackResult.h b/src/bun.js/bindings/webcore/CallbackResult.h new file mode 100644 index 000000000..878fe4221 --- /dev/null +++ b/src/bun.js/bindings/webcore/CallbackResult.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2017 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 <wtf/Expected.h> + +namespace WebCore { + +enum class CallbackResultType { + Success, + ExceptionThrown, + UnableToExecute +}; + +template<typename ReturnType> class CallbackResult { +public: + CallbackResult(CallbackResultType); + CallbackResult(ReturnType&&); + + CallbackResultType type() const; + ReturnType&& releaseReturnValue(); + +private: + Expected<ReturnType, CallbackResultType> m_value; +}; + +template<> class CallbackResult<void> { +public: + CallbackResult() = default; + CallbackResult(CallbackResultType); + + CallbackResultType type() const; + +private: + CallbackResultType m_type = CallbackResultType::Success; +}; + + +template<typename ReturnType> inline CallbackResult<ReturnType>::CallbackResult(CallbackResultType type) + : m_value(makeUnexpected(type)) +{ +} + +template<typename ReturnType> inline CallbackResult<ReturnType>::CallbackResult(ReturnType&& returnValue) + : m_value(WTFMove(returnValue)) +{ +} + +template<typename ReturnType> inline CallbackResultType CallbackResult<ReturnType>::type() const +{ + return m_value.has_value() ? CallbackResultType::Success : m_value.error(); +} + +template<typename ReturnType> inline auto CallbackResult<ReturnType>::releaseReturnValue() -> ReturnType&& +{ + ASSERT(m_value.has_value()); + return WTFMove(m_value.value()); +} + + +// Void specialization + +inline CallbackResult<void>::CallbackResult(CallbackResultType type) + : m_type(type) +{ +} + +inline CallbackResultType CallbackResult<void>::type() const +{ + return m_type; +} + +} diff --git a/src/bun.js/bindings/webcore/CloseEvent.cpp b/src/bun.js/bindings/webcore/CloseEvent.cpp new file mode 100644 index 000000000..7d0522adb --- /dev/null +++ b/src/bun.js/bindings/webcore/CloseEvent.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2019 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 "root.h" +#include "CloseEvent.h" + +// #include <wtf/IsoMallocInlines.h> + +namespace WebCore { + +WTF_MAKE_ISO_ALLOCATED_IMPL(CloseEvent); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/CloseEvent.h b/src/bun.js/bindings/webcore/CloseEvent.h new file mode 100644 index 000000000..6681727f6 --- /dev/null +++ b/src/bun.js/bindings/webcore/CloseEvent.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2011 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +#pragma once + +#include "root.h" +#include "Event.h" +#include "EventNames.h" + +namespace WebCore { + +class CloseEvent final : public Event { + WTF_MAKE_ISO_ALLOCATED(CloseEvent); + +public: + static Ref<CloseEvent> create(bool wasClean, unsigned short code, const String& reason) + { + return adoptRef(*new CloseEvent(wasClean, code, reason)); + } + + struct Init : EventInit { + bool wasClean { false }; + unsigned short code { 0 }; + String reason; + }; + + static Ref<CloseEvent> create(const AtomString& type, const Init& initializer, IsTrusted isTrusted = IsTrusted::No) + { + return adoptRef(*new CloseEvent(type, initializer, isTrusted)); + } + + bool wasClean() const { return m_wasClean; } + unsigned short code() const { return m_code; } + String reason() const { return m_reason; } + + // Event function. + EventInterface eventInterface() const override { return CloseEventInterfaceType; } + +private: + CloseEvent(bool wasClean, int code, const String& reason) + : Event(eventNames().closeEvent, CanBubble::No, IsCancelable::No) + , m_wasClean(wasClean) + , m_code(code) + , m_reason(reason) + { + } + + CloseEvent(const AtomString& type, const Init& initializer, IsTrusted isTrusted) + : Event(type, initializer, isTrusted) + , m_wasClean(initializer.wasClean) + , m_code(initializer.code) + , m_reason(initializer.reason) + { + } + + bool m_wasClean; + unsigned short m_code; + String m_reason; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/CloseEvent.idl b/src/bun.js/bindings/webcore/CloseEvent.idl new file mode 100644 index 000000000..acb852e46 --- /dev/null +++ b/src/bun.js/bindings/webcore/CloseEvent.idl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2011 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +[ + Exposed=(Window,Worker), +] interface CloseEvent : Event { + constructor([AtomString] DOMString type, optional CloseEventInit eventInitDict); + + readonly attribute boolean wasClean; + readonly attribute unsigned short code; + readonly attribute USVString reason; +}; + +dictionary CloseEventInit : EventInit { + boolean wasClean = false; + unsigned short code = 0; + USVString reason = ""; +}; diff --git a/src/bun.js/bindings/webcore/CommonAtomStrings.cpp b/src/bun.js/bindings/webcore/CommonAtomStrings.cpp new file mode 100644 index 000000000..57cdc3d24 --- /dev/null +++ b/src/bun.js/bindings/webcore/CommonAtomStrings.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 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 + * 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. + */ + +#include "config.h" +#include "CommonAtomStrings.h" + +namespace WebCore { + +#define DEFINE_COMMON_ATOM(atomName, atomValue) \ + MainThreadLazyNeverDestroyed<const AtomString> atomName ## AtomData; +#define INITIALIZE_COMMON_ATOM(atomName, atomValue) \ + atomName ## AtomData.constructWithoutAccessCheck(atomValue ## _s); + +WEBCORE_COMMON_ATOM_STRINGS_FOR_EACH_KEYWORD(DEFINE_COMMON_ATOM) + +void initializeCommonAtomStrings() +{ + // Initialization is not thread safe, so this function must be called from the main thread first. + ASSERT(isUIThread()); + + static std::once_flag initializeKey; + std::call_once(initializeKey, [] { + WEBCORE_COMMON_ATOM_STRINGS_FOR_EACH_KEYWORD(INITIALIZE_COMMON_ATOM) + }); +} + +#undef DEFINE_COMMON_ATOM +#undef INITIALIZE_COMMON_ATOM + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/CommonAtomStrings.h b/src/bun.js/bindings/webcore/CommonAtomStrings.h new file mode 100644 index 000000000..0385f8222 --- /dev/null +++ b/src/bun.js/bindings/webcore/CommonAtomStrings.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 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 + * 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 <wtf/NeverDestroyed.h> +#include <wtf/text/AtomString.h> + +namespace WebCore { + +#define WEBCORE_COMMON_ATOM_STRINGS_FOR_EACH_KEYWORD(macro) \ + macro(alternative, "alternative") \ + macro(auto, "auto") \ + macro(captions, "captions") \ + macro(commentary, "commentary") \ + macro(cssContentType, "text/css") \ + macro(eager, "eager") \ + macro(email, "email") \ + macro(false, "false") \ + macro(lazy, "lazy") \ + macro(main, "main") \ + macro(none, "none") \ + macro(off, "off") \ + macro(on, "on") \ + macro(plaintextOnly, "plaintext-only") \ + macro(reset, "reset") \ + macro(search, "search") \ + macro(star, "*") \ + macro(submit, "submit") \ + macro(subtitles, "subtitles") \ + macro(tel, "tel") \ + macro(text, "text") \ + macro(textPlainContentType, "text/plain") \ + macro(true, "true") \ + macro(url, "url") \ + macro(xml, "xml") \ + macro(xmlns, "xmlns") + + +#define DECLARE_COMMON_ATOM(atomName, atomValue) \ + extern MainThreadLazyNeverDestroyed<const AtomString> atomName ## AtomData; \ + inline const AtomString& atomName ## Atom() { return atomName ## AtomData.get(); } + +WEBCORE_COMMON_ATOM_STRINGS_FOR_EACH_KEYWORD(DECLARE_COMMON_ATOM) + +#undef DECLARE_COMMON_ATOM + +WEBCORE_EXPORT void initializeCommonAtomStrings(); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ContextDestructionObserver.h b/src/bun.js/bindings/webcore/ContextDestructionObserver.h new file mode 100644 index 000000000..ccf20f301 --- /dev/null +++ b/src/bun.js/bindings/webcore/ContextDestructionObserver.h @@ -0,0 +1,33 @@ + + +#pragma once + +#include "root.h" + +#include "ScriptExecutionContext.h" + +namespace WebCore { + +// TODO: +class ContextDestructionObserver { + +public: + WEBCORE_EXPORT void contextDestroyed() {} + + ScriptExecutionContext* scriptExecutionContext() const { return m_context; } + + ContextDestructionObserver(ScriptExecutionContext* context) + : m_context(context) + { + } + ContextDestructionObserver(ContextDestructionObserver& context) + : m_context(context.m_context) + { + } + +private: + int m_junk = 0; + ScriptExecutionContext* m_context; +}; + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/CustomEvent.cpp b/src/bun.js/bindings/webcore/CustomEvent.cpp new file mode 100644 index 000000000..2f17f794b --- /dev/null +++ b/src/bun.js/bindings/webcore/CustomEvent.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2011-2017 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 "CustomEvent.h" + +#include <JavaScriptCore/JSCInlines.h> +// #include <wtf/IsoMallocInlines.h> + +namespace WebCore { + +WTF_MAKE_ISO_ALLOCATED_IMPL(CustomEvent); + +inline CustomEvent::CustomEvent(IsTrusted isTrusted) + : Event(isTrusted) +{ +} + +inline CustomEvent::CustomEvent(const AtomString& type, const Init& initializer, IsTrusted isTrusted) + : Event(type, initializer, isTrusted) + , m_detail(initializer.detail) +{ +} + +CustomEvent::~CustomEvent() = default; + +Ref<CustomEvent> CustomEvent::create(IsTrusted isTrusted) +{ + return adoptRef(*new CustomEvent(isTrusted)); +} + +Ref<CustomEvent> CustomEvent::create(const AtomString& type, const Init& initializer, IsTrusted isTrusted) +{ + return adoptRef(*new CustomEvent(type, initializer, isTrusted)); +} + +void CustomEvent::initCustomEvent(const AtomString& type, bool canBubble, bool cancelable, JSC::JSValue detail) +{ + if (isBeingDispatched()) + return; + + initEvent(type, canBubble, cancelable); + + // 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 + m_detail.setWeakly(detail); + m_cachedDetail.clear(); +} + +EventInterface CustomEvent::eventInterface() const +{ + return CustomEventInterfaceType; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/CustomEvent.h b/src/bun.js/bindings/webcore/CustomEvent.h new file mode 100644 index 000000000..53df6d985 --- /dev/null +++ b/src/bun.js/bindings/webcore/CustomEvent.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2011-2018 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. + */ + +#pragma once + +#include "root.h" +#include "Event.h" +#include "JSValueInWrappedObject.h" +// #include "SerializedScriptValue.h" + +namespace WebCore { + +class CustomEvent final : public Event { + WTF_MAKE_ISO_ALLOCATED(CustomEvent); + +public: + virtual ~CustomEvent(); + + static Ref<CustomEvent> create(IsTrusted = IsTrusted::No); + + struct Init : EventInit { + JSC::JSValue detail; + }; + + static Ref<CustomEvent> create(const AtomString& type, const Init&, IsTrusted = IsTrusted::No); + + void initCustomEvent(const AtomString& type, bool canBubble, bool cancelable, JSC::JSValue detail = JSC::JSValue::JSUndefined); + + const JSValueInWrappedObject& detail() const { return m_detail; } + JSValueInWrappedObject& cachedDetail() { return m_cachedDetail; } + +private: + CustomEvent(IsTrusted); + CustomEvent(const AtomString& type, const Init& initializer, IsTrusted); + + EventInterface eventInterface() const final; + + JSValueInWrappedObject m_detail; + JSValueInWrappedObject m_cachedDetail; +}; + +} // namespace WebCore
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/CustomEvent.idl b/src/bun.js/bindings/webcore/CustomEvent.idl new file mode 100644 index 000000000..4b48b4335 --- /dev/null +++ b/src/bun.js/bindings/webcore/CustomEvent.idl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2011-2018 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. + */ + +[ + Exposed=*, + JSCustomMarkFunction, +] interface CustomEvent : Event { + constructor(DOMString type, optional CustomEventInit eventInitDict); + + [CustomGetter] readonly attribute any detail; + + undefined initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null); +}; + +dictionary CustomEventInit : EventInit { + any detail = null; +}; diff --git a/src/bun.js/bindings/webcore/CustomEventCustom.cpp b/src/bun.js/bindings/webcore/CustomEventCustom.cpp new file mode 100644 index 000000000..a5da060e3 --- /dev/null +++ b/src/bun.js/bindings/webcore/CustomEventCustom.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015-2021 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 "JSCustomEvent.h" + +#include "CustomEvent.h" +#include "DOMWrapperWorld.h" +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSCJSValue.h> +#include <JavaScriptCore/Structure.h> + +namespace WebCore { + +JSC::JSValue JSCustomEvent::detail(JSC::JSGlobalObject& lexicalGlobalObject) const +{ + return cachedPropertyValue(lexicalGlobalObject, *this, wrapped().cachedDetail(), [this] { + return wrapped().detail().getValue(JSC::jsNull()); + }); +} + +template<typename Visitor> +void JSCustomEvent::visitAdditionalChildren(Visitor& visitor) +{ + wrapped().detail().visit(visitor); + wrapped().cachedDetail().visit(visitor); +} + +DEFINE_VISIT_ADDITIONAL_CHILDREN(JSCustomEvent); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h new file mode 100644 index 000000000..b437e5879 --- /dev/null +++ b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h @@ -0,0 +1,884 @@ +#pragma once + +#include "root.h" + +#include "wtf/FastMalloc.h" +#include "wtf/Noncopyable.h" + +namespace WebCore { +using namespace JSC; + +class DOMClientIsoSubspaces { + WTF_MAKE_NONCOPYABLE(DOMClientIsoSubspaces); + WTF_MAKE_FAST_ALLOCATED(DOMClientIsoSubspaces); + +public: + DOMClientIsoSubspaces() = default; + + /* --- bun --- */ + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBuffer; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFFIFunction; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNapiClass; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNapiPrototype; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSSQLStatement; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSSQLStatementConstructor; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSSinkConstructor; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSSinkController; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSSink; + /* --- bun --- */ + + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMException; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMFormData; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMFormDataIterator; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMURL; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForURLSearchParams; + + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForURLSearchParamsIterator; + + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExposedToWorkerAndWindow; + + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTouch; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTouchEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTouchList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInternalSettingsGenerated; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPU; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUAdapter; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUBindGroup; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUBindGroupLayout; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUBuffer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUBufferUsage; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUCanvasContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUColorWrite; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUCommandBuffer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUCommandEncoder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUCompilationInfo; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUCompilationMessage; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUComputePassEncoder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUComputePipeline; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUDevice; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUDeviceLostInfo; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUExternalTexture; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUMapMode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUOutOfMemoryError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUPipelineLayout; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUQuerySet; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUQueue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPURenderBundle; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPURenderBundleEncoder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPURenderPassEncoder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPURenderPipeline; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUSampler; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUShaderModule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUShaderStage; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUSupportedFeatures; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUSupportedLimits; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUTexture; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUTextureUsage; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUTextureView; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUUncapturedErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGPUValidationError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitPlaybackTargetAvailabilityEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayCancelEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayCouponCodeChangedEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayPaymentAuthorizedEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayPaymentMethodSelectedEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePaySession; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePaySetup; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePaySetupFeature; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayShippingContactSelectedEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayShippingMethodSelectedEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForApplePayValidateMerchantEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForClipboard; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForClipboardItem; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMCache; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMCacheStorage; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForContactsManager; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBasicCredential; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCredentialsContainer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaKeyMessageEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaKeySession; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaKeyStatusMap; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaKeyStatusMapIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaKeySystemAccess; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaKeys; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitMediaKeyMessageEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitMediaKeyNeededEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitMediaKeySession; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitMediaKeys; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMFileSystem; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemDirectoryEntry; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemDirectoryReader; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemEntry; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemFileEntry; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFetchHeaders; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFetchHeadersIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFetchRequest; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFetchResponse; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemDirectoryHandle; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemFileHandle; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemHandle; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemSyncAccessHandle; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGamepad; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGamepadButton; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGamepadEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGeolocation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGeolocationCoordinates; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGeolocationPosition; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGeolocationPositionError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHighlight; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHighlightRegister; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBCursor; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBCursorWithValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBDatabase; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBFactory; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBIndex; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBKeyRange; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBObjectStore; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBOpenDBRequest; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBRequest; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBTransaction; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIDBVersionChangeEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaCapabilities; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaControlsHost; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBlobEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaRecorder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaRecorderErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaMetadata; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaSession; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaSessionCoordinator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaSource; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSourceBuffer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSourceBufferList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVideoPlaybackQuality; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCanvasCaptureMediaStreamTrack; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaDeviceInfo; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaDevices; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaStream; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaStreamTrack; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaStreamTrackEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOverconstrainedError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOverconstrainedErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCCertificate; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCDTMFSender; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCDTMFToneChangeEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCDataChannel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCDataChannelEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCDtlsTransport; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCEncodedAudioFrame; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCEncodedVideoFrame; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCIceCandidate; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCIceTransport; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCPeerConnection; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCPeerConnectionIceErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCPeerConnectionIceEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCRtpReceiver; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCRtpSFrameTransform; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCRtpSFrameTransformErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCRtpScriptTransform; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCRtpScriptTransformer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCRtpSender; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCRtpTransceiver; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCSctpTransport; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCSessionDescription; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCStatsReport; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCTrackEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRTCTransformEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLModelElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNotification; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNotificationEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMerchantValidationEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPaymentAddress; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPaymentMethodChangeEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPaymentRequest; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPaymentRequestUpdateEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPaymentResponse; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPermissionStatus; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPermissions; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPictureInPictureEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPictureInPictureWindow; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPushEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPushManager; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPushMessageData; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPushSubscription; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPushSubscriptionChangeEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPushSubscriptionOptions; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRemotePlayback; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechRecognition; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechRecognitionAlternative; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechRecognitionErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechRecognitionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechRecognitionResult; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechRecognitionResultList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechSynthesis; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechSynthesisErrorEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechSynthesisEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechSynthesisUtterance; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSpeechSynthesisVoice; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStorageManager; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForByteLengthQueuingStrategy; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCountQueuingStrategy; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableByteStreamController; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableStream; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableStreamBYOBReader; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableStreamBYOBRequest; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableStreamDefaultController; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableStreamDefaultReader; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableStreamSink; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForReadableStreamSource; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTransformStream; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTransformStreamDefaultController; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWritableStream; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWritableStreamDefaultController; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWritableStreamDefaultWriter; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWritableStreamSink; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebLock; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebLockManager; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAnalyserNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioBuffer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioBufferSourceNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioDestinationNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioListener; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioParam; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioParamMap; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioProcessingEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioScheduledSourceNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioWorklet; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioWorkletGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioWorkletNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioWorkletProcessor; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBaseAudioContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBiquadFilterNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForChannelMergerNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForChannelSplitterNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForConstantSourceNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForConvolverNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDelayNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDynamicsCompressorNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGainNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIIRFilterNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaElementAudioSourceNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaStreamAudioDestinationNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaStreamAudioSourceNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOfflineAudioCompletionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOfflineAudioContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOscillatorNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPannerNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPeriodicWave; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForScriptProcessorNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStereoPannerNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWaveShaperNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAuthenticatorAssertionResponse; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAuthenticatorAttestationResponse; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAuthenticatorResponse; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPublicKeyCredential; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVideoColorSpace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDatabase; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSQLError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSQLResultSet; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSQLResultSetRowList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSQLTransaction; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCloseEvent; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebSocket; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRBoundedReferenceSpace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRFrame; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRHand; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRHandIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRInputSource; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRInputSourceArray; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRInputSourceArrayIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRJointPose; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRJointSpace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRLayer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRPose; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRReferenceSpace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRRenderState; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRRigidTransform; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRSession; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRSpace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRSystem; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRView; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRViewerPose; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRViewport; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRWebGLLayer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXRInputSourceEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXRInputSourcesChangeEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXRReferenceSpaceEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXRSessionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAnimationEffect; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAnimationPlaybackEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAnimationTimeline; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSAnimation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSTransition; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCustomEffect; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDocumentTimeline; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForKeyframeEffect; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebAnimation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCryptoKey; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSubtleCrypto; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSConditionRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSCounterStyleRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSFontFaceRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSFontPaletteValuesRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSGroupingRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSImportRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSKeyframeRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSKeyframesRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSLayerBlockRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSLayerStatementRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMediaRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSNamespaceRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSPageRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSPaintSize; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSRuleList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSStyleDeclaration; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSStyleRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSStyleSheet; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSSupportsRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSUnknownRule; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMCSSNamespace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMMatrix; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMMatrixReadOnly; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeprecatedCSSOMCounter; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeprecatedCSSOMPrimitiveValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeprecatedCSSOMRGBColor; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeprecatedCSSOMRect; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeprecatedCSSOMValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeprecatedCSSOMValueList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFontFace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFontFaceSet; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFontFaceSetIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaQueryList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaQueryListEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStyleMedia; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStyleSheet; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStyleSheetList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSKeywordValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSNumericValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSOMVariableReferenceValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSStyleImageValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSStyleValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSUnitValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSUnparsedValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSUnparsedValueIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStylePropertyMap; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStylePropertyMapReadOnly; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMathInvert; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMathMax; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMathMin; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMathNegate; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMathProduct; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMathSum; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMathValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSNumericArray; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSNumericArrayIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSMatrixComponent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSPerspective; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSRotate; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSScale; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSSkew; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSSkewX; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSSkewY; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSTransformComponent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSTransformValue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSTransformValueIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCSSTranslate; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAbstractRange; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAnimationEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAttr; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBeforeUnloadEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBroadcastChannel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCDATASection; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCharacterData; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForClipboardEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForComment; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCompositionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCustomElementRegistry; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCustomEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMImplementation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMPoint; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMPointReadOnly; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMQuad; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMRect; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMRectList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMRectReadOnly; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMStringList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMStringMap; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDataTransfer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDataTransferItem; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDataTransferItemList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeviceMotionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDeviceOrientationEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDocument; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDocumentFragment; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDocumentType; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDragEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFocusEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFormDataEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHashChangeEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIdleDeadline; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInputEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForKeyboardEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessageChannel; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessageEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMessagePort; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMouseEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMutationEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMutationObserver; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMutationRecord; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNamedNodeMap; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNode; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNodeIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNodeList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNodeListIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOverflowEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPageTransitionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPointerEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPopStateEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForProcessingInstruction; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForProgressEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPromiseRejectionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRange; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSecurityPolicyViolationEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForShadowRoot; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStaticRange; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForText; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextDecoder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextDecoderStream; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextDecoderStreamDecoder; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEncoder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEncoderStream; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEncoderStreamEncoder; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTransitionEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTreeWalker; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForUIEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWheelEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXMLDocument; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBlob; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFile; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileReader; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileReaderSync; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMFormData; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMFormDataIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMTokenList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMTokenListIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMURL; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLAllCollection; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLAnchorElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLAreaElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLAttachmentElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLAudioElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLBRElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLBaseElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLBodyElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLButtonElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLCanvasElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLCollection; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDListElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDataElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDataListElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDetailsElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDialogElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDirectoryElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDivElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLDocument; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLEmbedElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLFieldSetElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLFontElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLFormControlsCollection; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLFormElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLFrameElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLFrameSetElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLHRElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLHeadElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLHeadingElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLHtmlElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLIFrameElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLImageElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLInputElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLLIElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLLabelElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLLegendElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLLinkElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLMapElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLMarqueeElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLMediaElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLMenuElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLMenuItemElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLMetaElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLMeterElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLModElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLOListElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLObjectElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLOptGroupElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLOptionElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLOptionsCollection; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLOutputElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLParagraphElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLParamElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLPictureElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLPreElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLProgressElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLQuoteElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLScriptElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLSelectElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLSlotElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLSourceElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLSpanElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLStyleElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTableCaptionElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTableCellElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTableColElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTableElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTableRowElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTableSectionElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTemplateElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTextAreaElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTimeElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTitleElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLTrackElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLUListElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLUnknownElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHTMLVideoElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForImageBitmap; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForImageData; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaController; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaEncryptedEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMediaError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOffscreenCanvas; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRadioNodeList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSubmitEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextMetrics; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTimeRanges; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForURLSearchParams; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForURLSearchParamsIterator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForValidityState; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitMediaKeyError; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForANGLEInstancedArrays; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCanvasGradient; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCanvasPattern; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCanvasRenderingContext2D; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTBlendMinMax; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTColorBufferFloat; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTColorBufferHalfFloat; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTFloatBlend; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTFragDepth; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTShaderTextureLOD; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTTextureCompressionRGTC; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTTextureFilterAnisotropic; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEXTsRGB; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForImageBitmapRenderingContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForKHRParallelShaderCompile; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESElementIndexUint; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESFBORenderMipmap; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESStandardDerivatives; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESTextureFloat; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESTextureFloatLinear; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESTextureHalfFloat; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESTextureHalfFloatLinear; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOESVertexArrayObject; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForOffscreenCanvasRenderingContext2D; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPaintRenderingContext2D; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPath2D; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGL2RenderingContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLActiveInfo; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLBuffer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLColorBufferFloat; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLCompressedTextureASTC; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLCompressedTextureATC; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLCompressedTextureETC; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLCompressedTextureETC1; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLCompressedTexturePVRTC; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLCompressedTextureS3TC; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLCompressedTextureS3TCsRGB; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLContextEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLDebugRendererInfo; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLDebugShaders; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLDepthTexture; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLDrawBuffers; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLFramebuffer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLLoseContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLMultiDraw; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLProgram; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLQuery; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLRenderbuffer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLRenderingContext; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLSampler; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLShader; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLShaderPrecisionFormat; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLSync; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLTexture; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLTransformFeedback; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLUniformLocation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLVertexArrayObject; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebGLVertexArrayObjectOES; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioTrack; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioTrackConfiguration; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAudioTrackList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDataCue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextTrack; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextTrackCue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextTrackCueGeneric; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextTrackCueList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextTrackList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTrackEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVTTCue; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVTTRegion; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVTTRegionList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVideoTrack; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVideoTrackConfiguration; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVideoTrackList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCommandLineAPIHost; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInspectorAuditAccessibilityObject; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInspectorAuditDOMObject; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInspectorAuditResourcesObject; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInspectorFrontendHost; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMApplicationCache; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMathMLElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMathMLMathElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBarProp; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCrypto; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMSelection; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMWindow; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEventSource; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHistory; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIntersectionObserver; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForIntersectionObserverEntry; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForLocation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNavigator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformance; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceEntry; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceMark; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceMeasure; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceNavigation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceNavigationTiming; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceObserver; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceObserverEntryList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformancePaintTiming; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceResourceTiming; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceServerTiming; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPerformanceTiming; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRemoteDOMWindow; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForResizeObserver; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForResizeObserverEntry; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForResizeObserverSize; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForScreen; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForShadowRealmGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForUndoItem; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForUndoManager; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForUserMessageHandler; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForUserMessageHandlersNamespace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForVisualViewport; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitNamespace; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebKitPoint; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerNavigator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMMimeType; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMMimeTypeArray; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMPlugin; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMPluginArray; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStorage; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForStorageEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAltGlyphDefElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAltGlyphElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAltGlyphItemElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAngle; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimateColorElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimateElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimateMotionElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimateTransformElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedAngle; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedBoolean; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedEnumeration; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedInteger; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedLength; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedLengthList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedNumber; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedNumberList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedPreserveAspectRatio; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedRect; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedString; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimatedTransformList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGAnimationElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGCircleElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGClipPathElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGComponentTransferFunctionElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGCursorElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGDefsElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGDescElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGEllipseElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEBlendElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEColorMatrixElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEComponentTransferElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFECompositeElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEConvolveMatrixElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEDiffuseLightingElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEDisplacementMapElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEDistantLightElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEDropShadowElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEFloodElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEFuncAElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEFuncBElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEFuncGElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEFuncRElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEGaussianBlurElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEImageElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEMergeElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEMergeNodeElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEMorphologyElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEOffsetElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFEPointLightElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFESpecularLightingElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFESpotLightElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFETileElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFETurbulenceElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFilterElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFontElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFontFaceElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFontFaceFormatElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFontFaceNameElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFontFaceSrcElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGFontFaceUriElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGForeignObjectElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGGElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGGeometryElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGGlyphElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGGlyphRefElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGGradientElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGGraphicsElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGHKernElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGImageElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGLength; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGLengthList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGLineElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGLinearGradientElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGMPathElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGMarkerElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGMaskElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGMatrix; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGMetadataElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGMissingGlyphElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGNumber; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGNumberList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSeg; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegArcAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegArcRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegClosePath; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoCubicAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoCubicRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoCubicSmoothAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoCubicSmoothRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoQuadraticAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoQuadraticRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoQuadraticSmoothAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegCurvetoQuadraticSmoothRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegLinetoAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegLinetoHorizontalAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegLinetoHorizontalRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegLinetoRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegLinetoVerticalAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegLinetoVerticalRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegMovetoAbs; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPathSegMovetoRel; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPatternElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPoint; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPointList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPolygonElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPolylineElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGPreserveAspectRatio; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGRadialGradientElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGRect; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGRectElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGRenderingIntent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGSVGElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGScriptElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGSetElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGStopElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGStringList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGStyleElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGSwitchElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGSymbolElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTRefElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTSpanElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTextContentElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTextElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTextPathElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTextPositioningElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTitleElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTransform; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGTransformList; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGUnitTypes; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGUseElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGVKernElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGViewElement; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGViewSpec; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSVGZoomEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForGCObservation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInternalSettings; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInternals; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInternalsMapLike; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForInternalsSetLike; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMallocStatistics; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMemoryInfo; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMockCDMFactory; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMockContentFilterSettings; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMockPageOverlay; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMockPaymentCoordinator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorkerInternals; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTypeConversions; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebFakeXRDevice; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebFakeXRInputController; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWebXRTest; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDedicatedWorkerGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorker; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkerLocation; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExtendableEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExtendableMessageEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFetchEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNavigationPreloadManager; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorker; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorkerClient; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorkerClients; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorkerContainer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorkerGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorkerRegistration; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServiceWorkerWindowClient; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSharedWorker; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSharedWorkerGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPaintWorkletGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorklet; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForWorkletGlobalScope; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMParser; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXMLHttpRequest; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXMLHttpRequestEventTarget; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXMLHttpRequestProgressEvent; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXMLHttpRequestUpload; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXMLSerializer; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXPathEvaluator; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXPathExpression; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXPathNSResolver; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXPathResult; + // std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForXSLTProcessor; + + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAbortController; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForAbortSignal; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForErrorEvent; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEvent; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEventListener; + std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForEventTarget; +}; +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/DOMConstructors.h b/src/bun.js/bindings/webcore/DOMConstructors.h new file mode 100644 index 000000000..b0219fffc --- /dev/null +++ b/src/bun.js/bindings/webcore/DOMConstructors.h @@ -0,0 +1,881 @@ + +#include "wtf/FastMalloc.h" +#include "wtf/Noncopyable.h" + +#pragma once + +namespace WebCore { + +enum class DOMConstructorID : uint16_t { + Touch, + TouchEvent, + TouchList, + InternalSettingsGenerated, + GPU, + GPUAdapter, + GPUBindGroup, + GPUBindGroupLayout, + GPUBuffer, + GPUBufferUsage, + GPUCanvasContext, + GPUColorWrite, + GPUCommandBuffer, + GPUCommandEncoder, + GPUCompilationInfo, + GPUCompilationMessage, + GPUComputePassEncoder, + GPUComputePipeline, + GPUDevice, + GPUDeviceLostInfo, + GPUExternalTexture, + GPUMapMode, + GPUOutOfMemoryError, + GPUPipelineLayout, + GPUQuerySet, + GPUQueue, + GPURenderBundle, + GPURenderBundleEncoder, + GPURenderPassEncoder, + GPURenderPipeline, + GPUSampler, + GPUShaderModule, + GPUShaderStage, + GPUSupportedFeatures, + GPUSupportedLimits, + GPUTexture, + GPUTextureUsage, + GPUTextureView, + GPUUncapturedErrorEvent, + GPUValidationError, + WebKitPlaybackTargetAvailabilityEvent, + ApplePayCancelEvent, + ApplePayCouponCodeChangedEvent, + ApplePayError, + ApplePayPaymentAuthorizedEvent, + ApplePayPaymentMethodSelectedEvent, + ApplePaySession, + ApplePaySetup, + ApplePaySetupFeature, + ApplePayShippingContactSelectedEvent, + ApplePayShippingMethodSelectedEvent, + ApplePayValidateMerchantEvent, + Clipboard, + ClipboardItem, + DOMCache, + DOMCacheStorage, + ContactsManager, + BasicCredential, + CredentialsContainer, + MediaKeyMessageEvent, + MediaKeySession, + MediaKeyStatusMap, + MediaKeySystemAccess, + MediaKeys, + WebKitMediaKeyMessageEvent, + WebKitMediaKeyNeededEvent, + WebKitMediaKeySession, + WebKitMediaKeys, + DOMFileSystem, + FileSystemDirectoryEntry, + FileSystemDirectoryReader, + FileSystemEntry, + FileSystemFileEntry, + FetchHeaders, + FetchRequest, + FetchResponse, + FileSystemDirectoryHandle, + FileSystemFileHandle, + FileSystemHandle, + FileSystemSyncAccessHandle, + Gamepad, + GamepadButton, + GamepadEvent, + Geolocation, + GeolocationCoordinates, + GeolocationPosition, + GeolocationPositionError, + Highlight, + HighlightRegister, + IDBCursor, + IDBCursorWithValue, + IDBDatabase, + IDBFactory, + IDBIndex, + IDBKeyRange, + IDBObjectStore, + IDBOpenDBRequest, + IDBRequest, + IDBTransaction, + IDBVersionChangeEvent, + MediaCapabilities, + MediaControlsHost, + BlobEvent, + MediaRecorder, + MediaRecorderErrorEvent, + MediaMetadata, + MediaSession, + MediaSessionCoordinator, + MediaSource, + SourceBuffer, + SourceBufferList, + VideoPlaybackQuality, + CanvasCaptureMediaStreamTrack, + MediaDeviceInfo, + MediaDevices, + MediaStream, + MediaStreamTrack, + MediaStreamTrackEvent, + OverconstrainedError, + OverconstrainedErrorEvent, + RTCCertificate, + RTCDTMFSender, + RTCDTMFToneChangeEvent, + RTCDataChannel, + RTCDataChannelEvent, + RTCDtlsTransport, + RTCEncodedAudioFrame, + RTCEncodedVideoFrame, + RTCError, + RTCErrorEvent, + RTCIceCandidate, + RTCIceTransport, + RTCPeerConnection, + RTCPeerConnectionIceErrorEvent, + RTCPeerConnectionIceEvent, + RTCRtpReceiver, + RTCRtpSFrameTransform, + RTCRtpSFrameTransformErrorEvent, + RTCRtpScriptTransform, + RTCRtpScriptTransformer, + RTCRtpSender, + RTCRtpTransceiver, + RTCSctpTransport, + RTCSessionDescription, + RTCStatsReport, + RTCTrackEvent, + RTCTransformEvent, + HTMLModelElement, + Notification, + NotificationEvent, + MerchantValidationEvent, + PaymentAddress, + PaymentMethodChangeEvent, + PaymentRequest, + PaymentRequestUpdateEvent, + PaymentResponse, + PermissionStatus, + Permissions, + PictureInPictureEvent, + PictureInPictureWindow, + PushEvent, + PushManager, + PushMessageData, + PushSubscription, + PushSubscriptionChangeEvent, + PushSubscriptionOptions, + RemotePlayback, + SpeechRecognition, + SpeechRecognitionAlternative, + SpeechRecognitionErrorEvent, + SpeechRecognitionEvent, + SpeechRecognitionResult, + SpeechRecognitionResultList, + SpeechSynthesis, + SpeechSynthesisErrorEvent, + SpeechSynthesisEvent, + SpeechSynthesisUtterance, + SpeechSynthesisVoice, + StorageManager, + ByteLengthQueuingStrategy, + CountQueuingStrategy, + ReadableByteStreamController, + ReadableStream, + ReadableStreamBYOBReader, + ReadableStreamBYOBRequest, + ReadableStreamDefaultController, + ReadableStreamDefaultReader, + ReadableStreamSink, + ReadableStreamSource, + TransformStream, + TransformStreamDefaultController, + WritableStream, + WritableStreamDefaultController, + WritableStreamDefaultWriter, + WritableStreamSink, + WebLock, + WebLockManager, + AnalyserNode, + AudioBuffer, + AudioBufferSourceNode, + AudioContext, + AudioDestinationNode, + AudioListener, + AudioNode, + AudioParam, + AudioParamMap, + AudioProcessingEvent, + AudioScheduledSourceNode, + AudioWorklet, + AudioWorkletGlobalScope, + AudioWorkletNode, + AudioWorkletProcessor, + BaseAudioContext, + BiquadFilterNode, + ChannelMergerNode, + ChannelSplitterNode, + ConstantSourceNode, + ConvolverNode, + DelayNode, + DynamicsCompressorNode, + GainNode, + IIRFilterNode, + MediaElementAudioSourceNode, + MediaStreamAudioDestinationNode, + MediaStreamAudioSourceNode, + OfflineAudioCompletionEvent, + OfflineAudioContext, + OscillatorNode, + PannerNode, + PeriodicWave, + ScriptProcessorNode, + StereoPannerNode, + WaveShaperNode, + AuthenticatorAssertionResponse, + AuthenticatorAttestationResponse, + AuthenticatorResponse, + PublicKeyCredential, + VideoColorSpace, + Database, + SQLError, + SQLResultSet, + SQLResultSetRowList, + SQLTransaction, + CloseEvent, + WebSocket, + WebXRBoundedReferenceSpace, + WebXRFrame, + WebXRHand, + WebXRInputSource, + WebXRInputSourceArray, + WebXRJointPose, + WebXRJointSpace, + WebXRLayer, + WebXRPose, + WebXRReferenceSpace, + WebXRRenderState, + WebXRRigidTransform, + WebXRSession, + WebXRSpace, + WebXRSystem, + WebXRView, + WebXRViewerPose, + WebXRViewport, + WebXRWebGLLayer, + XRInputSourceEvent, + XRInputSourcesChangeEvent, + XRReferenceSpaceEvent, + XRSessionEvent, + AnimationEffect, + AnimationPlaybackEvent, + AnimationTimeline, + CSSAnimation, + CSSTransition, + CustomEffect, + DocumentTimeline, + KeyframeEffect, + WebAnimation, + CryptoKey, + SubtleCrypto, + CSSConditionRule, + CSSContainerRule, + CSSCounterStyleRule, + CSSFontFaceRule, + CSSFontPaletteValuesRule, + CSSGroupingRule, + CSSImportRule, + CSSKeyframeRule, + CSSKeyframesRule, + CSSLayerBlockRule, + CSSLayerStatementRule, + CSSMediaRule, + CSSNamespaceRule, + CSSPageRule, + CSSPaintSize, + CSSRule, + CSSRuleList, + CSSStyleDeclaration, + CSSStyleRule, + CSSStyleSheet, + CSSSupportsRule, + CSSUnknownRule, + DOMCSSNamespace, + DOMMatrix, + DOMMatrixReadOnly, + DeprecatedCSSOMCounter, + DeprecatedCSSOMPrimitiveValue, + DeprecatedCSSOMRGBColor, + DeprecatedCSSOMRect, + DeprecatedCSSOMValue, + DeprecatedCSSOMValueList, + FontFace, + FontFaceSet, + MediaList, + MediaQueryList, + MediaQueryListEvent, + StyleMedia, + StyleSheet, + StyleSheetList, + CSSKeywordValue, + CSSNumericValue, + CSSOMVariableReferenceValue, + CSSStyleImageValue, + CSSStyleValue, + CSSUnitValue, + CSSUnparsedValue, + StylePropertyMap, + StylePropertyMapReadOnly, + CSSColor, + CSSColorValue, + CSSHSL, + CSSHWB, + CSSLCH, + CSSLab, + CSSOKLCH, + CSSOKLab, + CSSRGB, + CSSMathInvert, + CSSMathMax, + CSSMathMin, + CSSMathNegate, + CSSMathProduct, + CSSMathSum, + CSSMathValue, + CSSNumericArray, + CSSMatrixComponent, + CSSPerspective, + CSSRotate, + CSSScale, + CSSSkew, + CSSSkewX, + CSSSkewY, + CSSTransformComponent, + CSSTransformValue, + CSSTranslate, + AbortController, + AbortSignal, + AbstractRange, + AnimationEvent, + Attr, + BeforeUnloadEvent, + BroadcastChannel, + CDATASection, + CharacterData, + ClipboardEvent, + Comment, + CompositionEvent, + CustomElementRegistry, + CustomEvent, + DOMException, + DOMImplementation, + DOMPoint, + DOMPointReadOnly, + DOMQuad, + DOMRect, + DOMRectList, + DOMRectReadOnly, + DOMStringList, + DOMStringMap, + DataTransfer, + DataTransferItem, + DataTransferItemList, + DeviceMotionEvent, + DeviceOrientationEvent, + Document, + DocumentFragment, + DocumentType, + DragEvent, + Element, + ErrorEvent, + Event, + EventListener, + EventTarget, + FocusEvent, + FormDataEvent, + HashChangeEvent, + IdleDeadline, + InputEvent, + KeyboardEvent, + MessageChannel, + MessageEvent, + MessagePort, + MouseEvent, + MutationEvent, + MutationObserver, + MutationRecord, + NamedNodeMap, + Node, + NodeFilter, + NodeIterator, + NodeList, + OverflowEvent, + PageTransitionEvent, + PointerEvent, + PopStateEvent, + ProcessingInstruction, + ProgressEvent, + PromiseRejectionEvent, + Range, + SecurityPolicyViolationEvent, + ShadowRoot, + StaticRange, + Text, + TextDecoder, + TextDecoderStream, + TextDecoderStreamDecoder, + TextEncoder, + TextEncoderStream, + TextEncoderStreamEncoder, + TextEvent, + TransitionEvent, + TreeWalker, + UIEvent, + WheelEvent, + XMLDocument, + Blob, + File, + FileList, + FileReader, + FileReaderSync, + DOMFormData, + DOMTokenList, + DOMURL, + HTMLAllCollection, + HTMLAnchorElement, + HTMLAreaElement, + HTMLAttachmentElement, + HTMLAudioElement, + HTMLAudioElementLegacyFactory, + HTMLBRElement, + HTMLBaseElement, + HTMLBodyElement, + HTMLButtonElement, + HTMLCanvasElement, + HTMLCollection, + HTMLDListElement, + HTMLDataElement, + HTMLDataListElement, + HTMLDetailsElement, + HTMLDialogElement, + HTMLDirectoryElement, + HTMLDivElement, + HTMLDocument, + HTMLElement, + HTMLEmbedElement, + HTMLFieldSetElement, + HTMLFontElement, + HTMLFormControlsCollection, + HTMLFormElement, + HTMLFrameElement, + HTMLFrameSetElement, + HTMLHRElement, + HTMLHeadElement, + HTMLHeadingElement, + HTMLHtmlElement, + HTMLIFrameElement, + HTMLImageElement, + HTMLImageElementLegacyFactory, + HTMLInputElement, + HTMLLIElement, + HTMLLabelElement, + HTMLLegendElement, + HTMLLinkElement, + HTMLMapElement, + HTMLMarqueeElement, + HTMLMediaElement, + HTMLMenuElement, + HTMLMenuItemElement, + HTMLMetaElement, + HTMLMeterElement, + HTMLModElement, + HTMLOListElement, + HTMLObjectElement, + HTMLOptGroupElement, + HTMLOptionElement, + HTMLOptionElementLegacyFactory, + HTMLOptionsCollection, + HTMLOutputElement, + HTMLParagraphElement, + HTMLParamElement, + HTMLPictureElement, + HTMLPreElement, + HTMLProgressElement, + HTMLQuoteElement, + HTMLScriptElement, + HTMLSelectElement, + HTMLSlotElement, + HTMLSourceElement, + HTMLSpanElement, + HTMLStyleElement, + HTMLTableCaptionElement, + HTMLTableCellElement, + HTMLTableColElement, + HTMLTableElement, + HTMLTableRowElement, + HTMLTableSectionElement, + HTMLTemplateElement, + HTMLTextAreaElement, + HTMLTimeElement, + HTMLTitleElement, + HTMLTrackElement, + HTMLUListElement, + HTMLUnknownElement, + HTMLVideoElement, + ImageBitmap, + ImageData, + MediaController, + MediaEncryptedEvent, + MediaError, + OffscreenCanvas, + RadioNodeList, + SubmitEvent, + TextMetrics, + TimeRanges, + URLSearchParams, + ValidityState, + WebKitMediaKeyError, + ANGLEInstancedArrays, + CanvasGradient, + CanvasPattern, + CanvasRenderingContext2D, + EXTBlendMinMax, + EXTColorBufferFloat, + EXTColorBufferHalfFloat, + EXTFloatBlend, + EXTFragDepth, + EXTShaderTextureLOD, + EXTTextureCompressionRGTC, + EXTTextureFilterAnisotropic, + EXTsRGB, + ImageBitmapRenderingContext, + KHRParallelShaderCompile, + OESElementIndexUint, + OESFBORenderMipmap, + OESStandardDerivatives, + OESTextureFloat, + OESTextureFloatLinear, + OESTextureHalfFloat, + OESTextureHalfFloatLinear, + OESVertexArrayObject, + OffscreenCanvasRenderingContext2D, + PaintRenderingContext2D, + Path2D, + WebGL2RenderingContext, + WebGLActiveInfo, + WebGLBuffer, + WebGLColorBufferFloat, + WebGLCompressedTextureASTC, + WebGLCompressedTextureATC, + WebGLCompressedTextureETC, + WebGLCompressedTextureETC1, + WebGLCompressedTexturePVRTC, + WebGLCompressedTextureS3TC, + WebGLCompressedTextureS3TCsRGB, + WebGLContextEvent, + WebGLDebugRendererInfo, + WebGLDebugShaders, + WebGLDepthTexture, + WebGLDrawBuffers, + WebGLFramebuffer, + WebGLLoseContext, + WebGLMultiDraw, + WebGLProgram, + WebGLQuery, + WebGLRenderbuffer, + WebGLRenderingContext, + WebGLSampler, + WebGLShader, + WebGLShaderPrecisionFormat, + WebGLSync, + WebGLTexture, + WebGLTransformFeedback, + WebGLUniformLocation, + WebGLVertexArrayObject, + WebGLVertexArrayObjectOES, + AudioTrack, + AudioTrackConfiguration, + AudioTrackList, + DataCue, + TextTrack, + TextTrackCue, + TextTrackCueGeneric, + TextTrackCueList, + TextTrackList, + TrackEvent, + VTTCue, + VTTRegion, + VTTRegionList, + VideoTrack, + VideoTrackConfiguration, + VideoTrackList, + CommandLineAPIHost, + InspectorAuditAccessibilityObject, + InspectorAuditDOMObject, + InspectorAuditResourcesObject, + InspectorFrontendHost, + DOMApplicationCache, + MathMLElement, + MathMLMathElement, + BarProp, + Crypto, + DOMSelection, + DOMWindow, + EventSource, + History, + IntersectionObserver, + IntersectionObserverEntry, + Location, + Navigator, + Performance, + PerformanceEntry, + PerformanceMark, + PerformanceMeasure, + PerformanceNavigation, + PerformanceNavigationTiming, + PerformanceObserver, + PerformanceObserverEntryList, + PerformancePaintTiming, + PerformanceResourceTiming, + PerformanceServerTiming, + PerformanceTiming, + RemoteDOMWindow, + ResizeObserver, + ResizeObserverEntry, + ResizeObserverSize, + Screen, + ShadowRealmGlobalScope, + UndoItem, + UndoManager, + UserMessageHandler, + UserMessageHandlersNamespace, + VisualViewport, + WebKitNamespace, + WebKitPoint, + WorkerNavigator, + DOMMimeType, + DOMMimeTypeArray, + DOMPlugin, + DOMPluginArray, + Storage, + StorageEvent, + SVGAElement, + SVGAltGlyphDefElement, + SVGAltGlyphElement, + SVGAltGlyphItemElement, + SVGAngle, + SVGAnimateColorElement, + SVGAnimateElement, + SVGAnimateMotionElement, + SVGAnimateTransformElement, + SVGAnimatedAngle, + SVGAnimatedBoolean, + SVGAnimatedEnumeration, + SVGAnimatedInteger, + SVGAnimatedLength, + SVGAnimatedLengthList, + SVGAnimatedNumber, + SVGAnimatedNumberList, + SVGAnimatedPreserveAspectRatio, + SVGAnimatedRect, + SVGAnimatedString, + SVGAnimatedTransformList, + SVGAnimationElement, + SVGCircleElement, + SVGClipPathElement, + SVGComponentTransferFunctionElement, + SVGCursorElement, + SVGDefsElement, + SVGDescElement, + SVGElement, + SVGEllipseElement, + SVGFEBlendElement, + SVGFEColorMatrixElement, + SVGFEComponentTransferElement, + SVGFECompositeElement, + SVGFEConvolveMatrixElement, + SVGFEDiffuseLightingElement, + SVGFEDisplacementMapElement, + SVGFEDistantLightElement, + SVGFEDropShadowElement, + SVGFEFloodElement, + SVGFEFuncAElement, + SVGFEFuncBElement, + SVGFEFuncGElement, + SVGFEFuncRElement, + SVGFEGaussianBlurElement, + SVGFEImageElement, + SVGFEMergeElement, + SVGFEMergeNodeElement, + SVGFEMorphologyElement, + SVGFEOffsetElement, + SVGFEPointLightElement, + SVGFESpecularLightingElement, + SVGFESpotLightElement, + SVGFETileElement, + SVGFETurbulenceElement, + SVGFilterElement, + SVGFontElement, + SVGFontFaceElement, + SVGFontFaceFormatElement, + SVGFontFaceNameElement, + SVGFontFaceSrcElement, + SVGFontFaceUriElement, + SVGForeignObjectElement, + SVGGElement, + SVGGeometryElement, + SVGGlyphElement, + SVGGlyphRefElement, + SVGGradientElement, + SVGGraphicsElement, + SVGHKernElement, + SVGImageElement, + SVGLength, + SVGLengthList, + SVGLineElement, + SVGLinearGradientElement, + SVGMPathElement, + SVGMarkerElement, + SVGMaskElement, + SVGMatrix, + SVGMetadataElement, + SVGMissingGlyphElement, + SVGNumber, + SVGNumberList, + SVGPathElement, + SVGPathSeg, + SVGPathSegArcAbs, + SVGPathSegArcRel, + SVGPathSegClosePath, + SVGPathSegCurvetoCubicAbs, + SVGPathSegCurvetoCubicRel, + SVGPathSegCurvetoCubicSmoothAbs, + SVGPathSegCurvetoCubicSmoothRel, + SVGPathSegCurvetoQuadraticAbs, + SVGPathSegCurvetoQuadraticRel, + SVGPathSegCurvetoQuadraticSmoothAbs, + SVGPathSegCurvetoQuadraticSmoothRel, + SVGPathSegLinetoAbs, + SVGPathSegLinetoHorizontalAbs, + SVGPathSegLinetoHorizontalRel, + SVGPathSegLinetoRel, + SVGPathSegLinetoVerticalAbs, + SVGPathSegLinetoVerticalRel, + SVGPathSegList, + SVGPathSegMovetoAbs, + SVGPathSegMovetoRel, + SVGPatternElement, + SVGPoint, + SVGPointList, + SVGPolygonElement, + SVGPolylineElement, + SVGPreserveAspectRatio, + SVGRadialGradientElement, + SVGRect, + SVGRectElement, + SVGRenderingIntent, + SVGSVGElement, + SVGScriptElement, + SVGSetElement, + SVGStopElement, + SVGStringList, + SVGStyleElement, + SVGSwitchElement, + SVGSymbolElement, + SVGTRefElement, + SVGTSpanElement, + SVGTextContentElement, + SVGTextElement, + SVGTextPathElement, + SVGTextPositioningElement, + SVGTitleElement, + SVGTransform, + SVGTransformList, + SVGUnitTypes, + SVGUseElement, + SVGVKernElement, + SVGViewElement, + SVGViewSpec, + SVGZoomEvent, + GCObservation, + InternalSettings, + Internals, + InternalsMapLike, + InternalsSetLike, + MallocStatistics, + MemoryInfo, + MockCDMFactory, + MockContentFilterSettings, + MockPageOverlay, + MockPaymentCoordinator, + ServiceWorkerInternals, + TypeConversions, + WebFakeXRDevice, + WebFakeXRInputController, + WebXRTest, + DedicatedWorkerGlobalScope, + Worker, + WorkerGlobalScope, + WorkerLocation, + ExtendableEvent, + ExtendableMessageEvent, + FetchEvent, + NavigationPreloadManager, + ServiceWorker, + ServiceWorkerClient, + ServiceWorkerClients, + ServiceWorkerContainer, + ServiceWorkerGlobalScope, + ServiceWorkerRegistration, + ServiceWorkerWindowClient, + SharedWorker, + SharedWorkerGlobalScope, + PaintWorkletGlobalScope, + Worklet, + WorkletGlobalScope, + CustomXPathNSResolver, + DOMParser, + XMLHttpRequest, + XMLHttpRequestEventTarget, + XMLHttpRequestProgressEvent, + XMLHttpRequestUpload, + XMLSerializer, + XPathEvaluator, + XPathExpression, + XPathNSResolver, + XPathResult, + XSLTProcessor, + + // --bun-- + Buffer, +}; + +static constexpr unsigned numberOfDOMConstructorsBase = 846; + +static constexpr unsigned bunExtraConstructors = 1; + +static constexpr unsigned numberOfDOMConstructors = numberOfDOMConstructorsBase + bunExtraConstructors; + +class DOMConstructors { + WTF_MAKE_NONCOPYABLE(DOMConstructors); + WTF_MAKE_FAST_ALLOCATED(DOMConstructors); + +public: + using ConstructorArray = std::array<JSC::WriteBarrier<JSC::JSObject>, numberOfDOMConstructors>; + DOMConstructors() = default; + ConstructorArray& array() { return m_array; } + const ConstructorArray& array() const { return m_array; } + +private: + ConstructorArray m_array {}; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/DOMHighResTimeStamp.h b/src/bun.js/bindings/webcore/DOMHighResTimeStamp.h new file mode 100644 index 000000000..11b678600 --- /dev/null +++ b/src/bun.js/bindings/webcore/DOMHighResTimeStamp.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 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 + +namespace WebCore { + +using DOMHighResTimeStamp = double; + +} diff --git a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h new file mode 100644 index 000000000..66b94e359 --- /dev/null +++ b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h @@ -0,0 +1,892 @@ + +#pragma once + +#include "root.h" + +#include "wtf/FastMalloc.h" +#include "wtf/Noncopyable.h" + +namespace WebCore { +using namespace JSC; + +class DOMIsoSubspaces { + WTF_MAKE_NONCOPYABLE(DOMIsoSubspaces); + WTF_MAKE_FAST_ALLOCATED(DOMIsoSubspaces); + +public: + DOMIsoSubspaces() = default; + /*-- BUN --*/ + std::unique_ptr<IsoSubspace> m_subspaceForBuffer; + std::unique_ptr<IsoSubspace> m_subspaceForFFIFunction; + std::unique_ptr<IsoSubspace> m_subspaceForNapiClass; + std::unique_ptr<IsoSubspace> m_subspaceForNapiPrototype; + std::unique_ptr<IsoSubspace> m_subspaceForJSSQLStatement; + std::unique_ptr<IsoSubspace> m_subspaceForJSSQLStatementConstructor; + std::unique_ptr<IsoSubspace> m_subspaceForJSSinkConstructor; + std::unique_ptr<IsoSubspace> m_subspaceForJSSinkController; + std::unique_ptr<IsoSubspace> m_subspaceForJSSink; + /*-- BUN --*/ + + // std::unique_ptr<IsoSubspace> m_subspaceForTouch; + // std::unique_ptr<IsoSubspace> m_subspaceForTouchEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForTouchList; + // std::unique_ptr<IsoSubspace> m_subspaceForInternalSettingsGenerated; + // std::unique_ptr<IsoSubspace> m_subspaceForGPU; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUAdapter; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUBindGroup; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUBindGroupLayout; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUBuffer; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUBufferUsage; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUCanvasContext; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUColorWrite; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUCommandBuffer; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUCommandEncoder; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUCompilationInfo; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUCompilationMessage; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUComputePassEncoder; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUComputePipeline; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUDevice; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUDeviceLostInfo; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUExternalTexture; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUMapMode; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUOutOfMemoryError; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUPipelineLayout; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUQuerySet; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUQueue; + // std::unique_ptr<IsoSubspace> m_subspaceForGPURenderBundle; + // std::unique_ptr<IsoSubspace> m_subspaceForGPURenderBundleEncoder; + // std::unique_ptr<IsoSubspace> m_subspaceForGPURenderPassEncoder; + // std::unique_ptr<IsoSubspace> m_subspaceForGPURenderPipeline; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUSampler; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUShaderModule; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUShaderStage; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUSupportedFeatures; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUSupportedLimits; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUTexture; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUTextureUsage; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUTextureView; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUUncapturedErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForGPUValidationError; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitPlaybackTargetAvailabilityEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayCancelEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayCouponCodeChangedEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayError; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayPaymentAuthorizedEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayPaymentMethodSelectedEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePaySession; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePaySetup; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePaySetupFeature; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayShippingContactSelectedEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayShippingMethodSelectedEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForApplePayValidateMerchantEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForClipboard; + // std::unique_ptr<IsoSubspace> m_subspaceForClipboardItem; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMCache; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMCacheStorage; + // std::unique_ptr<IsoSubspace> m_subspaceForContactsManager; + // std::unique_ptr<IsoSubspace> m_subspaceForBasicCredential; + // std::unique_ptr<IsoSubspace> m_subspaceForCredentialsContainer; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaKeyMessageEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaKeySession; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaKeyStatusMap; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaKeyStatusMapIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaKeySystemAccess; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaKeys; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitMediaKeyMessageEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitMediaKeyNeededEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitMediaKeySession; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitMediaKeys; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMFileSystem; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemDirectoryEntry; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemDirectoryReader; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemEntry; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemFileEntry; + std::unique_ptr<IsoSubspace> m_subspaceForFetchHeaders; + std::unique_ptr<IsoSubspace> m_subspaceForFetchHeadersIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForFetchRequest; + // std::unique_ptr<IsoSubspace> m_subspaceForFetchResponse; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemDirectoryHandle; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemFileHandle; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemHandle; + // std::unique_ptr<IsoSubspace> m_subspaceForFileSystemSyncAccessHandle; + // std::unique_ptr<IsoSubspace> m_subspaceForGamepad; + // std::unique_ptr<IsoSubspace> m_subspaceForGamepadButton; + // std::unique_ptr<IsoSubspace> m_subspaceForGamepadEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForGeolocation; + // std::unique_ptr<IsoSubspace> m_subspaceForGeolocationCoordinates; + // std::unique_ptr<IsoSubspace> m_subspaceForGeolocationPosition; + // std::unique_ptr<IsoSubspace> m_subspaceForGeolocationPositionError; + // std::unique_ptr<IsoSubspace> m_subspaceForHighlight; + // std::unique_ptr<IsoSubspace> m_subspaceForHighlightRegister; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBCursor; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBCursorWithValue; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBDatabase; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBFactory; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBIndex; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBKeyRange; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBObjectStore; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBOpenDBRequest; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBRequest; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBTransaction; + // std::unique_ptr<IsoSubspace> m_subspaceForIDBVersionChangeEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaCapabilities; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaControlsHost; + // std::unique_ptr<IsoSubspace> m_subspaceForBlobEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaRecorder; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaRecorderErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaMetadata; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaSession; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaSessionCoordinator; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaSource; + // std::unique_ptr<IsoSubspace> m_subspaceForSourceBuffer; + // std::unique_ptr<IsoSubspace> m_subspaceForSourceBufferList; + // std::unique_ptr<IsoSubspace> m_subspaceForVideoPlaybackQuality; + // std::unique_ptr<IsoSubspace> m_subspaceForCanvasCaptureMediaStreamTrack; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaDeviceInfo; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaDevices; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaStream; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaStreamTrack; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaStreamTrackEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForOverconstrainedError; + // std::unique_ptr<IsoSubspace> m_subspaceForOverconstrainedErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCCertificate; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCDTMFSender; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCDTMFToneChangeEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCDataChannel; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCDataChannelEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCDtlsTransport; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCEncodedAudioFrame; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCEncodedVideoFrame; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCError; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCIceCandidate; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCIceTransport; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCPeerConnection; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCPeerConnectionIceErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCPeerConnectionIceEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCRtpReceiver; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCRtpSFrameTransform; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCRtpSFrameTransformErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCRtpScriptTransform; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCRtpScriptTransformer; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCRtpSender; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCRtpTransceiver; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCSctpTransport; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCSessionDescription; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCStatsReport; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCTrackEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRTCTransformEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLModelElement; + // std::unique_ptr<IsoSubspace> m_subspaceForNotification; + // std::unique_ptr<IsoSubspace> m_subspaceForNotificationEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMerchantValidationEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPaymentAddress; + // std::unique_ptr<IsoSubspace> m_subspaceForPaymentMethodChangeEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPaymentRequest; + // std::unique_ptr<IsoSubspace> m_subspaceForPaymentRequestUpdateEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPaymentResponse; + // std::unique_ptr<IsoSubspace> m_subspaceForPermissionStatus; + // std::unique_ptr<IsoSubspace> m_subspaceForPermissions; + // std::unique_ptr<IsoSubspace> m_subspaceForPictureInPictureEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPictureInPictureWindow; + // std::unique_ptr<IsoSubspace> m_subspaceForPushEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPushManager; + // std::unique_ptr<IsoSubspace> m_subspaceForPushMessageData; + // std::unique_ptr<IsoSubspace> m_subspaceForPushSubscription; + // std::unique_ptr<IsoSubspace> m_subspaceForPushSubscriptionChangeEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPushSubscriptionOptions; + // std::unique_ptr<IsoSubspace> m_subspaceForRemotePlayback; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechRecognition; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechRecognitionAlternative; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechRecognitionErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechRecognitionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechRecognitionResult; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechRecognitionResultList; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechSynthesis; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechSynthesisErrorEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechSynthesisEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechSynthesisUtterance; + // std::unique_ptr<IsoSubspace> m_subspaceForSpeechSynthesisVoice; + // std::unique_ptr<IsoSubspace> m_subspaceForStorageManager; + std::unique_ptr<IsoSubspace> m_subspaceForByteLengthQueuingStrategy; + std::unique_ptr<IsoSubspace> m_subspaceForCountQueuingStrategy; + std::unique_ptr<IsoSubspace> m_subspaceForReadableByteStreamController; + std::unique_ptr<IsoSubspace> m_subspaceForReadableStream; + std::unique_ptr<IsoSubspace> m_subspaceForReadableStreamBYOBReader; + std::unique_ptr<IsoSubspace> m_subspaceForReadableStreamBYOBRequest; + std::unique_ptr<IsoSubspace> m_subspaceForReadableStreamDefaultController; + std::unique_ptr<IsoSubspace> m_subspaceForReadableStreamDefaultReader; + std::unique_ptr<IsoSubspace> m_subspaceForReadableStreamSink; + std::unique_ptr<IsoSubspace> m_subspaceForReadableStreamSource; + std::unique_ptr<IsoSubspace> m_subspaceForTransformStream; + std::unique_ptr<IsoSubspace> m_subspaceForTransformStreamDefaultController; + std::unique_ptr<IsoSubspace> m_subspaceForWritableStream; + std::unique_ptr<IsoSubspace> m_subspaceForWritableStreamDefaultController; + std::unique_ptr<IsoSubspace> m_subspaceForWritableStreamDefaultWriter; + std::unique_ptr<IsoSubspace> m_subspaceForWritableStreamSink; + // std::unique_ptr<IsoSubspace> m_subspaceForWebLock; + // std::unique_ptr<IsoSubspace> m_subspaceForWebLockManager; + // std::unique_ptr<IsoSubspace> m_subspaceForAnalyserNode; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioBuffer; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioBufferSourceNode; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioContext; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioDestinationNode; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioListener; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioNode; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioParam; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioParamMap; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioProcessingEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioScheduledSourceNode; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioWorklet; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioWorkletGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioWorkletNode; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioWorkletProcessor; + // std::unique_ptr<IsoSubspace> m_subspaceForBaseAudioContext; + // std::unique_ptr<IsoSubspace> m_subspaceForBiquadFilterNode; + // std::unique_ptr<IsoSubspace> m_subspaceForChannelMergerNode; + // std::unique_ptr<IsoSubspace> m_subspaceForChannelSplitterNode; + // std::unique_ptr<IsoSubspace> m_subspaceForConstantSourceNode; + // std::unique_ptr<IsoSubspace> m_subspaceForConvolverNode; + // std::unique_ptr<IsoSubspace> m_subspaceForDelayNode; + // std::unique_ptr<IsoSubspace> m_subspaceForDynamicsCompressorNode; + // std::unique_ptr<IsoSubspace> m_subspaceForGainNode; + // std::unique_ptr<IsoSubspace> m_subspaceForIIRFilterNode; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaElementAudioSourceNode; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaStreamAudioDestinationNode; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaStreamAudioSourceNode; + // std::unique_ptr<IsoSubspace> m_subspaceForOfflineAudioCompletionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForOfflineAudioContext; + // std::unique_ptr<IsoSubspace> m_subspaceForOscillatorNode; + // std::unique_ptr<IsoSubspace> m_subspaceForPannerNode; + // std::unique_ptr<IsoSubspace> m_subspaceForPeriodicWave; + // std::unique_ptr<IsoSubspace> m_subspaceForScriptProcessorNode; + // std::unique_ptr<IsoSubspace> m_subspaceForStereoPannerNode; + // std::unique_ptr<IsoSubspace> m_subspaceForWaveShaperNode; + // std::unique_ptr<IsoSubspace> m_subspaceForAuthenticatorAssertionResponse; + // std::unique_ptr<IsoSubspace> m_subspaceForAuthenticatorAttestationResponse; + // std::unique_ptr<IsoSubspace> m_subspaceForAuthenticatorResponse; + // std::unique_ptr<IsoSubspace> m_subspaceForPublicKeyCredential; + // std::unique_ptr<IsoSubspace> m_subspaceForVideoColorSpace; + // std::unique_ptr<IsoSubspace> m_subspaceForDatabase; + // std::unique_ptr<IsoSubspace> m_subspaceForSQLError; + // std::unique_ptr<IsoSubspace> m_subspaceForSQLResultSet; + // std::unique_ptr<IsoSubspace> m_subspaceForSQLResultSetRowList; + // std::unique_ptr<IsoSubspace> m_subspaceForSQLTransaction; + std::unique_ptr<IsoSubspace> m_subspaceForCloseEvent; + std::unique_ptr<IsoSubspace> m_subspaceForWebSocket; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRBoundedReferenceSpace; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRFrame; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRHand; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRHandIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRInputSource; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRInputSourceArray; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRInputSourceArrayIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRJointPose; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRJointSpace; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRLayer; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRPose; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRReferenceSpace; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRRenderState; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRRigidTransform; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRSession; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRSpace; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRSystem; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRView; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRViewerPose; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRViewport; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRWebGLLayer; + // std::unique_ptr<IsoSubspace> m_subspaceForXRInputSourceEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForXRInputSourcesChangeEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForXRReferenceSpaceEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForXRSessionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForAnimationEffect; + // std::unique_ptr<IsoSubspace> m_subspaceForAnimationPlaybackEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForAnimationTimeline; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSAnimation; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSTransition; + // std::unique_ptr<IsoSubspace> m_subspaceForCustomEffect; + // std::unique_ptr<IsoSubspace> m_subspaceForDocumentTimeline; + // std::unique_ptr<IsoSubspace> m_subspaceForKeyframeEffect; + // std::unique_ptr<IsoSubspace> m_subspaceForWebAnimation; + // std::unique_ptr<IsoSubspace> m_subspaceForCryptoKey; + // std::unique_ptr<IsoSubspace> m_subspaceForSubtleCrypto; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSConditionRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSCounterStyleRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSFontFaceRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSFontPaletteValuesRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSGroupingRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSImportRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSKeyframeRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSKeyframesRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSLayerBlockRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSLayerStatementRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMediaRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSNamespaceRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSPageRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSPaintSize; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSRuleList; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSStyleDeclaration; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSStyleRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSStyleSheet; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSSupportsRule; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSUnknownRule; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMCSSNamespace; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMMatrix; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMMatrixReadOnly; + // std::unique_ptr<IsoSubspace> m_subspaceForDeprecatedCSSOMCounter; + // std::unique_ptr<IsoSubspace> m_subspaceForDeprecatedCSSOMPrimitiveValue; + // std::unique_ptr<IsoSubspace> m_subspaceForDeprecatedCSSOMRGBColor; + // std::unique_ptr<IsoSubspace> m_subspaceForDeprecatedCSSOMRect; + // std::unique_ptr<IsoSubspace> m_subspaceForDeprecatedCSSOMValue; + // std::unique_ptr<IsoSubspace> m_subspaceForDeprecatedCSSOMValueList; + // std::unique_ptr<IsoSubspace> m_subspaceForFontFace; + // std::unique_ptr<IsoSubspace> m_subspaceForFontFaceSet; + // std::unique_ptr<IsoSubspace> m_subspaceForFontFaceSetIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaList; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaQueryList; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaQueryListEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForStyleMedia; + // std::unique_ptr<IsoSubspace> m_subspaceForStyleSheet; + // std::unique_ptr<IsoSubspace> m_subspaceForStyleSheetList; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSKeywordValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSNumericValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSOMVariableReferenceValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSStyleImageValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSStyleValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSUnitValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSUnparsedValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSUnparsedValueIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForStylePropertyMap; + // std::unique_ptr<IsoSubspace> m_subspaceForStylePropertyMapReadOnly; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMathInvert; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMathMax; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMathMin; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMathNegate; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMathProduct; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMathSum; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMathValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSNumericArray; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSNumericArrayIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSMatrixComponent; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSPerspective; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSRotate; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSScale; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSSkew; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSSkewX; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSSkewY; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSTransformComponent; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSTransformValue; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSTransformValueIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForCSSTranslate; + + // std::unique_ptr<IsoSubspace> m_subspaceForAbstractRange; + // std::unique_ptr<IsoSubspace> m_subspaceForAnimationEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForAttr; + // std::unique_ptr<IsoSubspace> m_subspaceForBeforeUnloadEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForBroadcastChannel; + // std::unique_ptr<IsoSubspace> m_subspaceForCDATASection; + // std::unique_ptr<IsoSubspace> m_subspaceForCharacterData; + // std::unique_ptr<IsoSubspace> m_subspaceForClipboardEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForComment; + // std::unique_ptr<IsoSubspace> m_subspaceForCompositionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForCustomElementRegistry; + std::unique_ptr<IsoSubspace> m_subspaceForCustomEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMException; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMImplementation; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMPoint; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMPointReadOnly; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMQuad; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMRect; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMRectList; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMRectReadOnly; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMStringList; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMStringMap; + // std::unique_ptr<IsoSubspace> m_subspaceForDataTransfer; + // std::unique_ptr<IsoSubspace> m_subspaceForDataTransferItem; + // std::unique_ptr<IsoSubspace> m_subspaceForDataTransferItemList; + // std::unique_ptr<IsoSubspace> m_subspaceForDeviceMotionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForDeviceOrientationEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForDocument; + // std::unique_ptr<IsoSubspace> m_subspaceForDocumentFragment; + // std::unique_ptr<IsoSubspace> m_subspaceForDocumentType; + // std::unique_ptr<IsoSubspace> m_subspaceForDragEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForElement; + + // std::unique_ptr<IsoSubspace> m_subspaceForFocusEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForFormDataEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForHashChangeEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForIdleDeadline; + // std::unique_ptr<IsoSubspace> m_subspaceForInputEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForKeyboardEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMessageChannel; + std::unique_ptr<IsoSubspace> m_subspaceForMessageEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMessagePort; + // std::unique_ptr<IsoSubspace> m_subspaceForMouseEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMutationEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMutationObserver; + // std::unique_ptr<IsoSubspace> m_subspaceForMutationRecord; + // std::unique_ptr<IsoSubspace> m_subspaceForNamedNodeMap; + // std::unique_ptr<IsoSubspace> m_subspaceForNode; + // std::unique_ptr<IsoSubspace> m_subspaceForNodeIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForNodeList; + // std::unique_ptr<IsoSubspace> m_subspaceForNodeListIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForOverflowEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPageTransitionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPointerEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPopStateEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForProcessingInstruction; + // std::unique_ptr<IsoSubspace> m_subspaceForProgressEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForPromiseRejectionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForRange; + // std::unique_ptr<IsoSubspace> m_subspaceForSecurityPolicyViolationEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForShadowRoot; + // std::unique_ptr<IsoSubspace> m_subspaceForStaticRange; + // std::unique_ptr<IsoSubspace> m_subspaceForText; + // std::unique_ptr<IsoSubspace> m_subspaceForTextDecoder; + // std::unique_ptr<IsoSubspace> m_subspaceForTextDecoderStream; + // std::unique_ptr<IsoSubspace> m_subspaceForTextDecoderStreamDecoder; + std::unique_ptr<IsoSubspace> m_subspaceForTextEncoder; + // std::unique_ptr<IsoSubspace> m_subspaceForTextEncoderStream; + // std::unique_ptr<IsoSubspace> m_subspaceForTextEncoderStreamEncoder; + // std::unique_ptr<IsoSubspace> m_subspaceForTextEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForTransitionEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForTreeWalker; + // std::unique_ptr<IsoSubspace> m_subspaceForUIEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForWheelEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForXMLDocument; + // std::unique_ptr<IsoSubspace> m_subspaceForBlob; + // std::unique_ptr<IsoSubspace> m_subspaceForFile; + // std::unique_ptr<IsoSubspace> m_subspaceForFileList; + // std::unique_ptr<IsoSubspace> m_subspaceForFileReader; + // std::unique_ptr<IsoSubspace> m_subspaceForFileReaderSync; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMFormData; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMFormDataIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMTokenList; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMTokenListIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMURL; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLAllCollection; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLAnchorElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLAreaElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLAttachmentElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLAudioElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLBRElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLBaseElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLBodyElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLButtonElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLCanvasElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLCollection; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDListElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDataElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDataListElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDetailsElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDialogElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDirectoryElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDivElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLDocument; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLEmbedElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLFieldSetElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLFontElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLFormControlsCollection; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLFormElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLFrameElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLFrameSetElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLHRElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLHeadElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLHeadingElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLHtmlElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLIFrameElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLImageElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLInputElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLLIElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLLabelElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLLegendElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLLinkElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLMapElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLMarqueeElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLMediaElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLMenuElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLMenuItemElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLMetaElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLMeterElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLModElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLOListElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLObjectElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLOptGroupElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLOptionElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLOptionsCollection; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLOutputElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLParagraphElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLParamElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLPictureElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLPreElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLProgressElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLQuoteElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLScriptElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLSelectElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLSlotElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLSourceElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLSpanElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLStyleElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTableCaptionElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTableCellElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTableColElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTableElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTableRowElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTableSectionElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTemplateElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTextAreaElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTimeElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTitleElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLTrackElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLUListElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLUnknownElement; + // std::unique_ptr<IsoSubspace> m_subspaceForHTMLVideoElement; + // std::unique_ptr<IsoSubspace> m_subspaceForImageBitmap; + // std::unique_ptr<IsoSubspace> m_subspaceForImageData; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaController; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaEncryptedEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForMediaError; + // std::unique_ptr<IsoSubspace> m_subspaceForOffscreenCanvas; + // std::unique_ptr<IsoSubspace> m_subspaceForRadioNodeList; + // std::unique_ptr<IsoSubspace> m_subspaceForSubmitEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForTextMetrics; + // std::unique_ptr<IsoSubspace> m_subspaceForTimeRanges; + // std::unique_ptr<IsoSubspace> m_subspaceForURLSearchParams; + // std::unique_ptr<IsoSubspace> m_subspaceForURLSearchParamsIterator; + // std::unique_ptr<IsoSubspace> m_subspaceForValidityState; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitMediaKeyError; + // std::unique_ptr<IsoSubspace> m_subspaceForANGLEInstancedArrays; + // std::unique_ptr<IsoSubspace> m_subspaceForCanvasGradient; + // std::unique_ptr<IsoSubspace> m_subspaceForCanvasPattern; + // std::unique_ptr<IsoSubspace> m_subspaceForCanvasRenderingContext2D; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTBlendMinMax; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTColorBufferFloat; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTColorBufferHalfFloat; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTFloatBlend; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTFragDepth; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTShaderTextureLOD; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTTextureCompressionRGTC; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTTextureFilterAnisotropic; + // std::unique_ptr<IsoSubspace> m_subspaceForEXTsRGB; + // std::unique_ptr<IsoSubspace> m_subspaceForImageBitmapRenderingContext; + // std::unique_ptr<IsoSubspace> m_subspaceForKHRParallelShaderCompile; + // std::unique_ptr<IsoSubspace> m_subspaceForOESElementIndexUint; + // std::unique_ptr<IsoSubspace> m_subspaceForOESFBORenderMipmap; + // std::unique_ptr<IsoSubspace> m_subspaceForOESStandardDerivatives; + // std::unique_ptr<IsoSubspace> m_subspaceForOESTextureFloat; + // std::unique_ptr<IsoSubspace> m_subspaceForOESTextureFloatLinear; + // std::unique_ptr<IsoSubspace> m_subspaceForOESTextureHalfFloat; + // std::unique_ptr<IsoSubspace> m_subspaceForOESTextureHalfFloatLinear; + // std::unique_ptr<IsoSubspace> m_subspaceForOESVertexArrayObject; + // std::unique_ptr<IsoSubspace> m_subspaceForOffscreenCanvasRenderingContext2D; + // std::unique_ptr<IsoSubspace> m_subspaceForPaintRenderingContext2D; + // std::unique_ptr<IsoSubspace> m_subspaceForPath2D; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGL2RenderingContext; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLActiveInfo; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLBuffer; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLColorBufferFloat; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLCompressedTextureASTC; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLCompressedTextureATC; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLCompressedTextureETC; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLCompressedTextureETC1; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLCompressedTexturePVRTC; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLCompressedTextureS3TC; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLCompressedTextureS3TCsRGB; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLContextEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLDebugRendererInfo; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLDebugShaders; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLDepthTexture; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLDrawBuffers; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLFramebuffer; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLLoseContext; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLMultiDraw; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLProgram; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLQuery; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLRenderbuffer; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLRenderingContext; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLSampler; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLShader; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLShaderPrecisionFormat; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLSync; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLTexture; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLTransformFeedback; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLUniformLocation; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLVertexArrayObject; + // std::unique_ptr<IsoSubspace> m_subspaceForWebGLVertexArrayObjectOES; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioTrack; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioTrackConfiguration; + // std::unique_ptr<IsoSubspace> m_subspaceForAudioTrackList; + // std::unique_ptr<IsoSubspace> m_subspaceForDataCue; + // std::unique_ptr<IsoSubspace> m_subspaceForTextTrack; + // std::unique_ptr<IsoSubspace> m_subspaceForTextTrackCue; + // std::unique_ptr<IsoSubspace> m_subspaceForTextTrackCueGeneric; + // std::unique_ptr<IsoSubspace> m_subspaceForTextTrackCueList; + // std::unique_ptr<IsoSubspace> m_subspaceForTextTrackList; + // std::unique_ptr<IsoSubspace> m_subspaceForTrackEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForVTTCue; + // std::unique_ptr<IsoSubspace> m_subspaceForVTTRegion; + // std::unique_ptr<IsoSubspace> m_subspaceForVTTRegionList; + // std::unique_ptr<IsoSubspace> m_subspaceForVideoTrack; + // std::unique_ptr<IsoSubspace> m_subspaceForVideoTrackConfiguration; + // std::unique_ptr<IsoSubspace> m_subspaceForVideoTrackList; + // std::unique_ptr<IsoSubspace> m_subspaceForCommandLineAPIHost; + // std::unique_ptr<IsoSubspace> m_subspaceForInspectorAuditAccessibilityObject; + // std::unique_ptr<IsoSubspace> m_subspaceForInspectorAuditDOMObject; + // std::unique_ptr<IsoSubspace> m_subspaceForInspectorAuditResourcesObject; + // std::unique_ptr<IsoSubspace> m_subspaceForInspectorFrontendHost; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMApplicationCache; + // std::unique_ptr<IsoSubspace> m_subspaceForMathMLElement; + // std::unique_ptr<IsoSubspace> m_subspaceForMathMLMathElement; + // std::unique_ptr<IsoSubspace> m_subspaceForBarProp; + // std::unique_ptr<IsoSubspace> m_subspaceForCrypto; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMSelection; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMWindow; + // std::unique_ptr<IsoSubspace> m_subspaceForEventSource; + // std::unique_ptr<IsoSubspace> m_subspaceForHistory; + // std::unique_ptr<IsoSubspace> m_subspaceForIntersectionObserver; + // std::unique_ptr<IsoSubspace> m_subspaceForIntersectionObserverEntry; + // std::unique_ptr<IsoSubspace> m_subspaceForLocation; + // std::unique_ptr<IsoSubspace> m_subspaceForNavigator; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformance; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceEntry; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceMark; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceMeasure; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceNavigation; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceNavigationTiming; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceObserver; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceObserverEntryList; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformancePaintTiming; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceResourceTiming; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceServerTiming; + // std::unique_ptr<IsoSubspace> m_subspaceForPerformanceTiming; + // std::unique_ptr<IsoSubspace> m_subspaceForRemoteDOMWindow; + // std::unique_ptr<IsoSubspace> m_subspaceForResizeObserver; + // std::unique_ptr<IsoSubspace> m_subspaceForResizeObserverEntry; + // std::unique_ptr<IsoSubspace> m_subspaceForResizeObserverSize; + // std::unique_ptr<IsoSubspace> m_subspaceForScreen; + // std::unique_ptr<IsoSubspace> m_subspaceForShadowRealmGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForUndoItem; + // std::unique_ptr<IsoSubspace> m_subspaceForUndoManager; + // std::unique_ptr<IsoSubspace> m_subspaceForUserMessageHandler; + // std::unique_ptr<IsoSubspace> m_subspaceForUserMessageHandlersNamespace; + // std::unique_ptr<IsoSubspace> m_subspaceForVisualViewport; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitNamespace; + // std::unique_ptr<IsoSubspace> m_subspaceForWebKitPoint; + // std::unique_ptr<IsoSubspace> m_subspaceForWorkerNavigator; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMMimeType; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMMimeTypeArray; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMPlugin; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMPluginArray; + // std::unique_ptr<IsoSubspace> m_subspaceForStorage; + // std::unique_ptr<IsoSubspace> m_subspaceForStorageEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAltGlyphDefElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAltGlyphElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAltGlyphItemElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAngle; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimateColorElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimateElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimateMotionElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimateTransformElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedAngle; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedBoolean; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedEnumeration; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedInteger; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedLength; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedLengthList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedNumber; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedNumberList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedPreserveAspectRatio; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedRect; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedString; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimatedTransformList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGAnimationElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGCircleElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGClipPathElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGComponentTransferFunctionElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGCursorElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGDefsElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGDescElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGEllipseElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEBlendElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEColorMatrixElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEComponentTransferElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFECompositeElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEConvolveMatrixElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEDiffuseLightingElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEDisplacementMapElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEDistantLightElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEDropShadowElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEFloodElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEFuncAElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEFuncBElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEFuncGElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEFuncRElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEGaussianBlurElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEImageElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEMergeElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEMergeNodeElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEMorphologyElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEOffsetElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFEPointLightElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFESpecularLightingElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFESpotLightElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFETileElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFETurbulenceElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFilterElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFontElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFontFaceElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFontFaceFormatElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFontFaceNameElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFontFaceSrcElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGFontFaceUriElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGForeignObjectElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGGElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGGeometryElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGGlyphElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGGlyphRefElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGGradientElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGGraphicsElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGHKernElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGImageElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGLength; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGLengthList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGLineElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGLinearGradientElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGMPathElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGMarkerElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGMaskElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGMatrix; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGMetadataElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGMissingGlyphElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGNumber; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGNumberList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSeg; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegArcAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegArcRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegClosePath; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoCubicAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoCubicRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoCubicSmoothAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoCubicSmoothRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoQuadraticAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoQuadraticRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoQuadraticSmoothAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegCurvetoQuadraticSmoothRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegLinetoAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegLinetoHorizontalAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegLinetoHorizontalRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegLinetoRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegLinetoVerticalAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegLinetoVerticalRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegMovetoAbs; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPathSegMovetoRel; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPatternElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPoint; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPointList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPolygonElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPolylineElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGPreserveAspectRatio; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGRadialGradientElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGRect; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGRectElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGRenderingIntent; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGSVGElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGScriptElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGSetElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGStopElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGStringList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGStyleElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGSwitchElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGSymbolElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTRefElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTSpanElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTextContentElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTextElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTextPathElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTextPositioningElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTitleElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTransform; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGTransformList; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGUnitTypes; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGUseElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGVKernElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGViewElement; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGViewSpec; + // std::unique_ptr<IsoSubspace> m_subspaceForSVGZoomEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForGCObservation; + // std::unique_ptr<IsoSubspace> m_subspaceForInternalSettings; + // std::unique_ptr<IsoSubspace> m_subspaceForInternals; + // std::unique_ptr<IsoSubspace> m_subspaceForInternalsMapLike; + // std::unique_ptr<IsoSubspace> m_subspaceForInternalsSetLike; + // std::unique_ptr<IsoSubspace> m_subspaceForMallocStatistics; + // std::unique_ptr<IsoSubspace> m_subspaceForMemoryInfo; + // std::unique_ptr<IsoSubspace> m_subspaceForMockCDMFactory; + // std::unique_ptr<IsoSubspace> m_subspaceForMockContentFilterSettings; + // std::unique_ptr<IsoSubspace> m_subspaceForMockPageOverlay; + // std::unique_ptr<IsoSubspace> m_subspaceForMockPaymentCoordinator; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorkerInternals; + // std::unique_ptr<IsoSubspace> m_subspaceForTypeConversions; + // std::unique_ptr<IsoSubspace> m_subspaceForWebFakeXRDevice; + // std::unique_ptr<IsoSubspace> m_subspaceForWebFakeXRInputController; + // std::unique_ptr<IsoSubspace> m_subspaceForWebXRTest; + // std::unique_ptr<IsoSubspace> m_subspaceForDedicatedWorkerGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForWorker; + std::unique_ptr<IsoSubspace> m_subspaceForWorkerGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForWorkerLocation; + // std::unique_ptr<IsoSubspace> m_subspaceForExtendableEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForExtendableMessageEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForFetchEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForNavigationPreloadManager; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorker; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorkerClient; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorkerClients; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorkerContainer; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorkerGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorkerRegistration; + // std::unique_ptr<IsoSubspace> m_subspaceForServiceWorkerWindowClient; + // std::unique_ptr<IsoSubspace> m_subspaceForSharedWorker; + // std::unique_ptr<IsoSubspace> m_subspaceForSharedWorkerGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForPaintWorkletGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForWorklet; + // std::unique_ptr<IsoSubspace> m_subspaceForWorkletGlobalScope; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMParser; + // std::unique_ptr<IsoSubspace> m_subspaceForXMLHttpRequest; + // std::unique_ptr<IsoSubspace> m_subspaceForXMLHttpRequestEventTarget; + // std::unique_ptr<IsoSubspace> m_subspaceForXMLHttpRequestProgressEvent; + // std::unique_ptr<IsoSubspace> m_subspaceForXMLHttpRequestUpload; + // std::unique_ptr<IsoSubspace> m_subspaceForXMLSerializer; + // std::unique_ptr<IsoSubspace> m_subspaceForXPathEvaluator; + // std::unique_ptr<IsoSubspace> m_subspaceForXPathExpression; + // std::unique_ptr<IsoSubspace> m_subspaceForXPathNSResolver; + // std::unique_ptr<IsoSubspace> m_subspaceForXPathResult; + // std::unique_ptr<IsoSubspace> m_subspaceForXSLTProcessor; + + std::unique_ptr<IsoSubspace> m_subspaceForAbortController; + std::unique_ptr<IsoSubspace> m_subspaceForAbortSignal; + std::unique_ptr<IsoSubspace> m_subspaceForErrorEvent; + std::unique_ptr<IsoSubspace> m_subspaceForEvent; + std::unique_ptr<IsoSubspace> m_subspaceForEventListener; + std::unique_ptr<IsoSubspace> m_subspaceForEventTarget; + + std::unique_ptr<IsoSubspace> m_subspaceForZigGlobalObject; + + std::unique_ptr<IsoSubspace> m_subspaceForExposedToWorkerAndWindow; + std::unique_ptr<IsoSubspace> m_subspaceForURLSearchParams; + std::unique_ptr<IsoSubspace> m_subspaceForURLSearchParamsIterator; + + std::unique_ptr<IsoSubspace> m_subspaceForDOMException; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMFormData; + // std::unique_ptr<IsoSubspace> m_subspaceForDOMFormDataIterator; + std::unique_ptr<IsoSubspace> m_subspaceForDOMURL; +}; +} // namespace WebCore + +namespace WebCore { +using DOMIsoSubspaces = WebCore::DOMIsoSubspaces; +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/DOMPromiseProxy.h b/src/bun.js/bindings/webcore/DOMPromiseProxy.h new file mode 100644 index 000000000..2b8706e76 --- /dev/null +++ b/src/bun.js/bindings/webcore/DOMPromiseProxy.h @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2017-2021 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 "ExceptionOr.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMPromiseDeferred.h" +#include <wtf/Function.h> +#include <wtf/Vector.h> + +namespace WebCore { + +template<typename IDLType> +class DOMPromiseProxy { + WTF_MAKE_FAST_ALLOCATED; +public: + using Value = typename IDLType::StorageType; + + DOMPromiseProxy() = default; + ~DOMPromiseProxy() = default; + + JSC::JSValue promise(JSC::JSGlobalObject&, JSDOMGlobalObject&); + + void clear(); + + bool isFulfilled() const; + + void resolve(typename IDLType::StorageType); + void resolveWithNewlyCreated(typename IDLType::StorageType); + void reject(Exception, RejectAsHandled = RejectAsHandled::No); + +private: + JSC::JSValue resolvePromise(JSC::JSGlobalObject&, JSDOMGlobalObject&, const Function<void(DeferredPromise&)>&); + + std::optional<ExceptionOr<Value>> m_valueOrException; + Vector<Ref<DeferredPromise>, 1> m_deferredPromises; +}; + +template<> +class DOMPromiseProxy<IDLUndefined> { + WTF_MAKE_FAST_ALLOCATED; +public: + DOMPromiseProxy() = default; + ~DOMPromiseProxy() = default; + + JSC::JSValue promise(JSC::JSGlobalObject&, JSDOMGlobalObject&); + + void clear(); + + bool isFulfilled() const; + + void resolve(); + void reject(Exception, RejectAsHandled = RejectAsHandled::No); + +private: + std::optional<ExceptionOr<void>> m_valueOrException; + Vector<Ref<DeferredPromise>, 1> m_deferredPromises; +}; + +// Instead of storing the value of the resolution directly, DOMPromiseProxyWithResolveCallback +// allows the owner to specify callback to be called when the resolved value is needed. This is +// needed to avoid reference cycles when the resolved value is the owner, such as is the case with +// FontFace and FontFaceSet. +template<typename IDLType> +class DOMPromiseProxyWithResolveCallback { + WTF_MAKE_FAST_ALLOCATED; +public: + using ResolveCallback = Function<typename IDLType::ParameterType()>; + + template <typename Class, typename BaseClass> + DOMPromiseProxyWithResolveCallback(Class&, typename IDLType::ParameterType (BaseClass::*)()); + DOMPromiseProxyWithResolveCallback(ResolveCallback&&); + ~DOMPromiseProxyWithResolveCallback() = default; + + JSC::JSValue promise(JSC::JSGlobalObject&, JSDOMGlobalObject&); + + void clear(); + + bool isFulfilled() const; + + void resolve(typename IDLType::ParameterType); + void resolveWithNewlyCreated(typename IDLType::ParameterType); + void reject(Exception, RejectAsHandled = RejectAsHandled::No); + +private: + ResolveCallback m_resolveCallback; + std::optional<ExceptionOr<void>> m_valueOrException; + Vector<Ref<DeferredPromise>, 1> m_deferredPromises; +}; + +// MARK: - DOMPromiseProxy<IDLType> generic implementation + +template<typename IDLType> +inline JSC::JSValue DOMPromiseProxy<IDLType>::resolvePromise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const Function<void(DeferredPromise&)>& resolvePromiseCallback) +{ + UNUSED_PARAM(lexicalGlobalObject); + for (auto& deferredPromise : m_deferredPromises) { + if (deferredPromise->globalObject() == &globalObject) + return deferredPromise->promise(); + } + + // DeferredPromise can fail construction during worker abrupt termination. + auto deferredPromise = DeferredPromise::create(globalObject, DeferredPromise::Mode::RetainPromiseOnResolve); + if (!deferredPromise) + return JSC::jsUndefined(); + + if (m_valueOrException) { + if (m_valueOrException->hasException()) + deferredPromise->reject(m_valueOrException->exception()); + else + resolvePromiseCallback(*deferredPromise); + } + + auto result = deferredPromise->promise(); + m_deferredPromises.append(deferredPromise.releaseNonNull()); + return result; +} + +template<typename IDLType> +inline JSC::JSValue DOMPromiseProxy<IDLType>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject) +{ + return resolvePromise(lexicalGlobalObject, globalObject, [this](auto& deferredPromise) { + deferredPromise.template resolve<IDLType>(m_valueOrException->returnValue()); + }); +} + +template<> +inline JSC::JSValue DOMPromiseProxy<IDLAny>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject) +{ + return resolvePromise(lexicalGlobalObject, globalObject, [this](auto& deferredPromise) { + deferredPromise.resolveWithJSValue(m_valueOrException->returnValue().get()); + }); +} + +template<typename IDLType> +inline void DOMPromiseProxy<IDLType>::clear() +{ + m_valueOrException = std::nullopt; + m_deferredPromises.clear(); +} + +template<typename IDLType> +inline bool DOMPromiseProxy<IDLType>::isFulfilled() const +{ + return m_valueOrException.has_value(); +} + +template<typename IDLType> +inline void DOMPromiseProxy<IDLType>::resolve(typename IDLType::StorageType value) +{ + ASSERT(!m_valueOrException); + + m_valueOrException = ExceptionOr<Value> { std::forward<typename IDLType::StorageType>(value) }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->template resolve<IDLType>(m_valueOrException->returnValue()); +} + +template<> +inline void DOMPromiseProxy<IDLAny>::resolve(typename IDLAny::StorageType value) +{ + ASSERT(!m_valueOrException); + + m_valueOrException = ExceptionOr<Value> { std::forward<typename IDLAny::StorageType>(value) }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->resolveWithJSValue(m_valueOrException->returnValue().get()); +} + +template<typename IDLType> +inline void DOMPromiseProxy<IDLType>::resolveWithNewlyCreated(typename IDLType::StorageType value) +{ + ASSERT(!m_valueOrException); + + m_valueOrException = ExceptionOr<Value> { std::forward<typename IDLType::StorageType>(value) }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->template resolveWithNewlyCreated<IDLType>(m_valueOrException->returnValue()); +} + +template<typename IDLType> +inline void DOMPromiseProxy<IDLType>::reject(Exception exception, RejectAsHandled rejectAsHandled) +{ + ASSERT(!m_valueOrException); + + m_valueOrException = ExceptionOr<Value> { WTFMove(exception) }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled); +} + + +// MARK: - DOMPromiseProxy<IDLUndefined> specialization + +inline JSC::JSValue DOMPromiseProxy<IDLUndefined>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + for (auto& deferredPromise : m_deferredPromises) { + if (deferredPromise->globalObject() == &globalObject) + return deferredPromise->promise(); + } + + // DeferredPromise can fail construction during worker abrupt termination. + auto deferredPromise = DeferredPromise::create(globalObject, DeferredPromise::Mode::RetainPromiseOnResolve); + if (!deferredPromise) + return JSC::jsUndefined(); + + if (m_valueOrException) { + if (m_valueOrException->hasException()) + deferredPromise->reject(m_valueOrException->exception()); + else + deferredPromise->resolve(); + } + + auto result = deferredPromise->promise(); + m_deferredPromises.append(deferredPromise.releaseNonNull()); + return result; +} + +inline void DOMPromiseProxy<IDLUndefined>::clear() +{ + m_valueOrException = std::nullopt; + m_deferredPromises.clear(); +} + +inline bool DOMPromiseProxy<IDLUndefined>::isFulfilled() const +{ + return m_valueOrException.has_value(); +} + +inline void DOMPromiseProxy<IDLUndefined>::resolve() +{ + ASSERT(!m_valueOrException); + m_valueOrException = ExceptionOr<void> { }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->resolve(); +} + +inline void DOMPromiseProxy<IDLUndefined>::reject(Exception exception, RejectAsHandled rejectAsHandled) +{ + ASSERT(!m_valueOrException); + m_valueOrException = ExceptionOr<void> { WTFMove(exception) }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled); +} + +// MARK: - DOMPromiseProxyWithResolveCallback<IDLType> implementation + +template<typename IDLType> +template <typename Class, typename BaseClass> +inline DOMPromiseProxyWithResolveCallback<IDLType>::DOMPromiseProxyWithResolveCallback(Class& object, typename IDLType::ParameterType (BaseClass::*function)()) + : m_resolveCallback(std::bind(function, &object)) +{ +} + +template<typename IDLType> +inline DOMPromiseProxyWithResolveCallback<IDLType>::DOMPromiseProxyWithResolveCallback(ResolveCallback&& function) + : m_resolveCallback(WTFMove(function)) +{ +} + +template<typename IDLType> +inline JSC::JSValue DOMPromiseProxyWithResolveCallback<IDLType>::promise(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + for (auto& deferredPromise : m_deferredPromises) { + if (deferredPromise->globalObject() == &globalObject) + return deferredPromise->promise(); + } + + // DeferredPromise can fail construction during worker abrupt termination. + auto deferredPromise = DeferredPromise::create(globalObject, DeferredPromise::Mode::RetainPromiseOnResolve); + if (!deferredPromise) + return JSC::jsUndefined(); + + if (m_valueOrException) { + if (m_valueOrException->hasException()) + deferredPromise->reject(m_valueOrException->exception()); + else + deferredPromise->template resolve<IDLType>(m_resolveCallback()); + } + + auto result = deferredPromise->promise(); + m_deferredPromises.append(deferredPromise.releaseNonNull()); + return result; +} + +template<typename IDLType> +inline void DOMPromiseProxyWithResolveCallback<IDLType>::clear() +{ + m_valueOrException = std::nullopt; + m_deferredPromises.clear(); +} + +template<typename IDLType> +inline bool DOMPromiseProxyWithResolveCallback<IDLType>::isFulfilled() const +{ + return m_valueOrException.has_value(); +} + +template<typename IDLType> +inline void DOMPromiseProxyWithResolveCallback<IDLType>::resolve(typename IDLType::ParameterType value) +{ + ASSERT(!m_valueOrException); + + m_valueOrException = ExceptionOr<void> { }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->template resolve<IDLType>(value); +} + +template<typename IDLType> +inline void DOMPromiseProxyWithResolveCallback<IDLType>::resolveWithNewlyCreated(typename IDLType::ParameterType value) +{ + ASSERT(!m_valueOrException); + + m_valueOrException = ExceptionOr<void> { }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->template resolveWithNewlyCreated<IDLType>(value); +} + +template<typename IDLType> +inline void DOMPromiseProxyWithResolveCallback<IDLType>::reject(Exception exception, RejectAsHandled rejectAsHandled) +{ + ASSERT(!m_valueOrException); + + m_valueOrException = ExceptionOr<void> { WTFMove(exception) }; + for (auto& deferredPromise : m_deferredPromises) + deferredPromise->reject(m_valueOrException->exception(), rejectAsHandled); +} + +} diff --git a/src/bun.js/bindings/webcore/ErrorCallback.cpp b/src/bun.js/bindings/webcore/ErrorCallback.cpp new file mode 100644 index 000000000..5b81eea06 --- /dev/null +++ b/src/bun.js/bindings/webcore/ErrorCallback.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config.h" +#include "ErrorCallback.h" + +#include "DOMException.h" +#include "ScriptExecutionContext.h" + +namespace WebCore { + +void ErrorCallback::scheduleCallback(ScriptExecutionContext& context, Ref<DOMException>&& exception) +{ + context.postTask([protectedThis = Ref { *this }, exception = WTFMove(exception)] (ScriptExecutionContext&) { + protectedThis->handleEvent(exception); + }); +} + +} diff --git a/src/bun.js/bindings/webcore/ErrorCallback.h b/src/bun.js/bindings/webcore/ErrorCallback.h new file mode 100644 index 000000000..8c1eaff9a --- /dev/null +++ b/src/bun.js/bindings/webcore/ErrorCallback.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 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 "ActiveDOMCallback.h" +#include "CallbackResult.h" +#include <wtf/Forward.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class DOMException; + +class ErrorCallback : public RefCounted<ErrorCallback>, public ActiveDOMCallback { +public: + using ActiveDOMCallback::ActiveDOMCallback; + + virtual CallbackResult<void> handleEvent(DOMException&) = 0; + + // Helper to post callback task. + void scheduleCallback(ScriptExecutionContext&, Ref<DOMException>&&); +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ErrorCallback.idl b/src/bun.js/bindings/webcore/ErrorCallback.idl new file mode 100644 index 000000000..4dd3901da --- /dev/null +++ b/src/bun.js/bindings/webcore/ErrorCallback.idl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 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. + */ + +callback ErrorCallback = undefined (DOMException error); diff --git a/src/bun.js/bindings/webcore/ErrorEvent.cpp b/src/bun.js/bindings/webcore/ErrorEvent.cpp new file mode 100644 index 000000000..4f6c618f7 --- /dev/null +++ b/src/bun.js/bindings/webcore/ErrorEvent.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2016 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ErrorEvent.h" + +#include "DOMWrapperWorld.h" +#include "EventNames.h" +#include <JavaScriptCore/HeapInlines.h> +#include <JavaScriptCore/StrongInlines.h> +// #include <wtf/IsoMallocInlines.h> + +namespace WebCore { +using namespace JSC; + +WTF_MAKE_ISO_ALLOCATED_IMPL(ErrorEvent); + +ErrorEvent::ErrorEvent(const AtomString& type, const Init& initializer, IsTrusted isTrusted) + : Event(type, initializer, isTrusted) + , m_message(initializer.message) + , m_fileName(initializer.filename) + , m_lineNumber(initializer.lineno) + , m_columnNumber(initializer.colno) + , m_error(initializer.error) +{ +} + +ErrorEvent::ErrorEvent(const AtomString& type, const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, JSC::Strong<JSC::Unknown> error) + : Event(type, CanBubble::No, IsCancelable::Yes) + , m_message(message) + , m_fileName(fileName) + , m_lineNumber(lineNumber) + , m_columnNumber(columnNumber) + , m_error(error.get()) +{ +} + +ErrorEvent::ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, JSC::Strong<JSC::Unknown> error) + : ErrorEvent(eventNames().errorEvent, message, fileName, lineNumber, columnNumber, error) +{ +} + +ErrorEvent::~ErrorEvent() = default; + +EventInterface ErrorEvent::eventInterface() const +{ + return ErrorEventInterfaceType; +} + +JSValue ErrorEvent::error(JSGlobalObject& globalObject) +{ + if (!m_error) + return jsNull(); + + JSValue error = m_error.getValue(); + // if (!isWorldCompatible(globalObject, error)) { + // // We need to make sure ErrorEvents do not leak their error property across isolated DOM worlds. + // // Ideally, we would check that the worlds have different privileges but that's not possible yet. + // auto serializedError = trySerializeError(globalObject); + // if (!serializedError) + // return jsNull(); + // return serializedError->deserialize(globalObject, &globalObject); + // } + + return error; +} + +// RefPtr<SerializedScriptValue> ErrorEvent::trySerializeError(JSGlobalObject& exec) +// { +// // if (!m_serializedError && !m_triedToSerialize) { +// // m_serializedError = SerializedScriptValue::create(exec, m_error.getValue(), SerializationErrorMode::NonThrowing); +// // m_triedToSerialize = true; +// // } +// return 0; +// } + +bool ErrorEvent::isErrorEvent() const +{ + return true; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ErrorEvent.h b/src/bun.js/bindings/webcore/ErrorEvent.h new file mode 100644 index 000000000..400c91dae --- /dev/null +++ b/src/bun.js/bindings/webcore/ErrorEvent.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2016 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +#pragma once + +#include "Event.h" +#include "JSValueInWrappedObject.h" +// #include "SerializedScriptValue.h" +#include <JavaScriptCore/Strong.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class ErrorEvent final : public Event { + WTF_MAKE_ISO_ALLOCATED(ErrorEvent); + +public: + static Ref<ErrorEvent> create(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, JSC::Strong<JSC::Unknown> error) + { + return adoptRef(*new ErrorEvent(message, fileName, lineNumber, columnNumber, error)); + } + + static Ref<ErrorEvent> create(const AtomString& type, const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, JSC::Strong<JSC::Unknown> error) + { + return adoptRef(*new ErrorEvent(type, message, fileName, lineNumber, columnNumber, error)); + } + + struct Init : EventInit { + String message; + String filename; + unsigned lineno { 0 }; + unsigned colno { 0 }; + JSC::JSValue error; + }; + + static Ref<ErrorEvent> create(const AtomString& type, const Init& initializer, IsTrusted isTrusted = IsTrusted::No) + { + return adoptRef(*new ErrorEvent(type, initializer, isTrusted)); + } + + virtual ~ErrorEvent(); + + const String& message() const { return m_message; } + const String& filename() const { return m_fileName; } + unsigned lineno() const { return m_lineNumber; } + unsigned colno() const { return m_columnNumber; } + JSC::JSValue error(JSC::JSGlobalObject&); + + const JSValueInWrappedObject& originalError() const { return m_error; } + // SerializedScriptValue* serializedError() const { return m_serializedError.get(); } + + EventInterface eventInterface() const override; + + // RefPtr<SerializedScriptValue> trySerializeError(JSC::JSGlobalObject&); + +private: + ErrorEvent(const AtomString& type, const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, JSC::Strong<JSC::Unknown> error); + ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, JSC::Strong<JSC::Unknown> error); + ErrorEvent(const AtomString&, const Init&, IsTrusted); + + bool isErrorEvent() const override; + + String m_message; + String m_fileName; + unsigned m_lineNumber; + unsigned m_columnNumber; + JSValueInWrappedObject m_error; + // RefPtr<SerializedScriptValue> m_serializedError; + bool m_triedToSerialize { false }; +}; + +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_EVENT(ErrorEvent) diff --git a/src/bun.js/bindings/webcore/ErrorEvent.idl b/src/bun.js/bindings/webcore/ErrorEvent.idl new file mode 100644 index 000000000..1ea1ccff1 --- /dev/null +++ b/src/bun.js/bindings/webcore/ErrorEvent.idl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2016 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +[ + Exposed=*, + JSCustomMarkFunction, +] interface ErrorEvent : Event { + constructor(DOMString type, optional ErrorEventInit eventInitDict); + + readonly attribute DOMString message; + readonly attribute USVString filename; + readonly attribute unsigned long lineno; + readonly attribute unsigned long colno; + [CallWith=CurrentGlobalObject] readonly attribute any error; +}; + +dictionary ErrorEventInit : EventInit { + DOMString message = ""; + USVString filename = ""; + unsigned long lineno = 0; + unsigned long colno = 0; + any error = null; +}; diff --git a/src/bun.js/bindings/webcore/Event.cpp b/src/bun.js/bindings/webcore/Event.cpp new file mode 100644 index 000000000..f488f0106 --- /dev/null +++ b/src/bun.js/bindings/webcore/Event.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de) + * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "Event.h" + +// #include "DOMWindow.h" +// #include "Document.h" +#include "EventNames.h" +#include "EventPath.h" +#include "EventTarget.h" +// #include "InspectorInstrumentation.h" +// #include "Performance.h" +// #include "UserGestureIndicator.h" +// #include "WorkerGlobalScope.h" +#include <wtf/HexNumber.h> +// #include <wtf/IsoMallocInlines.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/text/TextStream.h> + +namespace WebCore { + +WTF_MAKE_ISO_ALLOCATED_IMPL(Event); + +ALWAYS_INLINE Event::Event(MonotonicTime createTime, const AtomString& type, IsTrusted isTrusted, CanBubble canBubble, IsCancelable cancelable, IsComposed composed) + : m_isInitialized { !type.isNull() } + , m_canBubble { canBubble == CanBubble::Yes } + , m_cancelable { cancelable == IsCancelable::Yes } + , m_composed { composed == IsComposed::Yes } + , m_propagationStopped { false } + , m_immediatePropagationStopped { false } + , m_wasCanceled { false } + , m_defaultHandled { false } + , m_isDefaultEventHandlerIgnored { false } + , m_isTrusted { isTrusted == IsTrusted::Yes } + , m_isExecutingPassiveEventListener { false } + , m_currentTargetIsInShadowTree { false } + , m_eventPhase { NONE } + , m_type { type } + , m_createTime { createTime } +{ +} + +Event::Event(IsTrusted isTrusted) + : Event { MonotonicTime::now(), {}, isTrusted, CanBubble::No, IsCancelable::No, IsComposed::No } +{ +} + +Event::Event(const AtomString& eventType, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed) + : Event { MonotonicTime::now(), eventType, IsTrusted::Yes, canBubble, isCancelable, isComposed } +{ + ASSERT(!eventType.isNull()); +} + +Event::Event(const AtomString& eventType, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed, MonotonicTime timestamp, IsTrusted isTrusted) + : Event { timestamp, eventType, isTrusted, canBubble, isCancelable, isComposed } +{ + ASSERT(!eventType.isNull()); +} + +Event::Event(const AtomString& eventType, const EventInit& initializer, IsTrusted isTrusted) + : Event { MonotonicTime::now(), eventType, isTrusted, + initializer.bubbles ? CanBubble::Yes : CanBubble::No, + initializer.cancelable ? IsCancelable::Yes : IsCancelable::No, + initializer.composed ? IsComposed::Yes : IsComposed::No } +{ + ASSERT(!eventType.isNull()); +} + +Event::~Event() = default; + +Ref<Event> Event::create(const AtomString& type, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed) +{ + return adoptRef(*new Event(type, canBubble, isCancelable, isComposed)); +} + +Ref<Event> Event::createForBindings() +{ + return adoptRef(*new Event); +} + +Ref<Event> Event::create(const AtomString& type, const EventInit& initializer, IsTrusted isTrusted) +{ + return adoptRef(*new Event(type, initializer, isTrusted)); +} + +void Event::initEvent(const AtomString& eventTypeArg, bool canBubbleArg, bool cancelableArg) +{ + if (isBeingDispatched()) + return; + + m_isInitialized = true; + m_propagationStopped = false; + m_immediatePropagationStopped = false; + m_wasCanceled = false; + m_isTrusted = false; + m_target = nullptr; + m_type = eventTypeArg; + m_canBubble = canBubbleArg; + m_cancelable = cancelableArg; + + m_underlyingEvent = nullptr; +} + +void Event::setTarget(RefPtr<EventTarget>&& target) +{ + if (m_target == target) + return; + + m_target = WTFMove(target); + if (m_target) + receivedTarget(); +} + +void Event::setCurrentTarget(EventTarget* currentTarget, std::optional<bool> isInShadowTree) +{ + m_currentTarget = currentTarget; + m_currentTargetIsInShadowTree = false; // m_currentTargetIsInShadowTree = isInShadowTree ? *isInShadowTree : (is<Node>(currentTarget) && downcast<Node>(*currentTarget).isInShadowTree()); +} + +Vector<EventTarget*> Event::composedPath() const +{ + // if (!m_eventPath) + return Vector<EventTarget*>(); + // return m_eventPath->computePathUnclosedToTarget(*m_currentTarget); +} + +void Event::setUnderlyingEvent(Event* underlyingEvent) +{ + // Prohibit creation of a cycle by doing nothing if a cycle would be created. + for (Event* event = underlyingEvent; event; event = event->underlyingEvent()) { + if (event == this) + return; + } + m_underlyingEvent = underlyingEvent; +} + +DOMHighResTimeStamp Event::timeStampForBindings(ScriptExecutionContext& context) const +{ + // TODO: + return 0.0; + // Performance* performance = nullptr; + // if (is<WorkerGlobalScope>(context)) + // performance = &downcast<WorkerGlobalScope>(context).performance(); + // else if (auto* window = downcast<Document>(context).domWindow()) + // performance = &window->performance(); + + // if (!performance) + // return 0; + + // return std::max(performance->relativeTimeFromTimeOriginInReducedResolution(m_createTime), 0.); +} + +void Event::resetBeforeDispatch() +{ + m_defaultHandled = false; +} + +void Event::resetAfterDispatch() +{ + m_eventPath = nullptr; + setCurrentTarget(nullptr); + m_eventPhase = NONE; + m_propagationStopped = false; + m_immediatePropagationStopped = false; + + // InspectorInstrumentation::eventDidResetAfterDispatch(*this); +} + +String Event::debugDescription() const +{ + return makeString(type(), " phase ", eventPhase(), bubbles() ? " bubbles " : " ", cancelable() ? "cancelable " : " ", "0x"_s, hex(reinterpret_cast<uintptr_t>(this), Lowercase)); +} + +TextStream& operator<<(TextStream& ts, const Event& event) +{ + ts << event.debugDescription(); + return ts; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/Event.h b/src/bun.js/bindings/webcore/Event.h new file mode 100644 index 000000000..5b7d5cba2 --- /dev/null +++ b/src/bun.js/bindings/webcore/Event.h @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de) + * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) + * Copyright (C) 2003-2017 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +#include "config.h" + +#include "DOMHighResTimeStamp.h" +#include "EventInit.h" +#include "EventInterfaces.h" +#include "EventOptions.h" +#include "ExceptionOr.h" +#include "ScriptWrappable.h" +#include <wtf/MonotonicTime.h> +#include <wtf/TypeCasts.h> +#include <wtf/text/AtomString.h> + +namespace WTF { +class TextStream; +} + +namespace WebCore { + +class EventPath; +class EventTarget; +class ScriptExecutionContext; + +class Event : public ScriptWrappable, public RefCounted<Event> { + WTF_MAKE_ISO_ALLOCATED(Event); + +public: + using IsTrusted = EventIsTrusted; + using CanBubble = EventCanBubble; + using IsCancelable = EventIsCancelable; + using IsComposed = EventIsComposed; + + enum PhaseType : uint8_t { + NONE = 0, + CAPTURING_PHASE = 1, + AT_TARGET = 2, + BUBBLING_PHASE = 3 + }; + + WEBCORE_EXPORT static Ref<Event> create(const AtomString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No); + static Ref<Event> createForBindings(); + static Ref<Event> create(const AtomString& type, const EventInit&, IsTrusted = IsTrusted::No); + + virtual ~Event(); + + WEBCORE_EXPORT void initEvent(const AtomString& type, bool canBubble, bool cancelable); + + bool isInitialized() const { return m_isInitialized; } + + const AtomString& type() const { return m_type; } + void setType(const AtomString& type) { m_type = type; } + + EventTarget* target() const { return m_target.get(); } + void setTarget(RefPtr<EventTarget>&&); + + EventTarget* currentTarget() const { return m_currentTarget.get(); } + void setCurrentTarget(EventTarget*, std::optional<bool> isInShadowTree = std::nullopt); + bool currentTargetIsInShadowTree() const { return m_currentTargetIsInShadowTree; } + + unsigned short eventPhase() const { return m_eventPhase; } + void setEventPhase(PhaseType phase) { m_eventPhase = phase; } + + bool bubbles() const { return m_canBubble; } + bool cancelable() const { return m_cancelable; } + bool composed() const { return m_composed; } + + DOMHighResTimeStamp timeStampForBindings(ScriptExecutionContext&) const; + MonotonicTime timeStamp() const { return m_createTime; } + + void setEventPath(const EventPath& path) { UNUSED_PARAM(path); } + Vector<EventTarget*> composedPath() const; + + void stopPropagation() { m_propagationStopped = true; } + void stopImmediatePropagation() { m_immediatePropagationStopped = true; } + + bool isTrusted() const { return m_isTrusted; } + void setUntrusted() { m_isTrusted = false; } + + bool legacyReturnValue() const { return !m_wasCanceled; } + void setLegacyReturnValue(bool); + + virtual EventInterface eventInterface() const { return EventInterfaceType; } + + virtual bool isBeforeTextInsertedEvent() const { return false; } + virtual bool isBeforeUnloadEvent() const { return false; } + virtual bool isClipboardEvent() const { return false; } + virtual bool isCompositionEvent() const { return false; } + virtual bool isErrorEvent() const { return false; } + virtual bool isFocusEvent() const { return false; } + virtual bool isInputEvent() const { return false; } + virtual bool isKeyboardEvent() const { return false; } + virtual bool isMouseEvent() const { return false; } + virtual bool isPointerEvent() const { return false; } + virtual bool isTextEvent() const { return false; } + virtual bool isTouchEvent() const { return false; } + virtual bool isUIEvent() const { return false; } + virtual bool isVersionChangeEvent() const { return false; } + virtual bool isWheelEvent() const { return false; } + + bool propagationStopped() const { return m_propagationStopped || m_immediatePropagationStopped; } + bool immediatePropagationStopped() const { return m_immediatePropagationStopped; } + + void resetBeforeDispatch(); + void resetAfterDispatch(); + + bool defaultPrevented() const { return m_wasCanceled; } + void preventDefault(); + + bool defaultHandled() const { return m_defaultHandled; } + void setDefaultHandled() { m_defaultHandled = true; } + + bool isDefaultEventHandlerIgnored() const { return m_isDefaultEventHandlerIgnored; } + void setIsDefaultEventHandlerIgnored() { m_isDefaultEventHandlerIgnored = true; } + + void setInPassiveListener(bool value) { m_isExecutingPassiveEventListener = value; } + + bool cancelBubble() const { return propagationStopped(); } + void setCancelBubble(bool); + + Event* underlyingEvent() const { return m_underlyingEvent.get(); } + void setUnderlyingEvent(Event*); + + // Returns true if the dispatch flag is set. + // https://dom.spec.whatwg.org/#dispatch-flag + bool isBeingDispatched() const { return eventPhase(); } + + virtual EventTarget* relatedTarget() const { return nullptr; } + virtual void setRelatedTarget(EventTarget*) {} + + virtual String debugDescription() const; + +protected: + explicit Event(IsTrusted = IsTrusted::No); + Event(const AtomString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No); + Event(const AtomString& type, CanBubble, IsCancelable, IsComposed, MonotonicTime timestamp, IsTrusted isTrusted = IsTrusted::Yes); + Event(const AtomString& type, const EventInit&, IsTrusted); + + virtual void receivedTarget() {} + +private: + explicit Event(MonotonicTime createTime, const AtomString& type, IsTrusted, CanBubble, IsCancelable, IsComposed); + + void setCanceledFlagIfPossible(); + + unsigned m_isInitialized : 1; + unsigned m_canBubble : 1; + unsigned m_cancelable : 1; + unsigned m_composed : 1; + + unsigned m_propagationStopped : 1; + unsigned m_immediatePropagationStopped : 1; + unsigned m_wasCanceled : 1; + unsigned m_defaultHandled : 1; + unsigned m_isDefaultEventHandlerIgnored : 1; + unsigned m_isTrusted : 1; + unsigned m_isExecutingPassiveEventListener : 1; + unsigned m_currentTargetIsInShadowTree : 1; + + unsigned m_eventPhase : 2; + + AtomString m_type; + + RefPtr<EventTarget> m_currentTarget; + const EventPath* m_eventPath { nullptr }; + RefPtr<EventTarget> m_target; + MonotonicTime m_createTime; + + RefPtr<Event> m_underlyingEvent; +}; + +inline void Event::preventDefault() +{ + setCanceledFlagIfPossible(); +} + +inline void Event::setLegacyReturnValue(bool returnValue) +{ + if (!returnValue) + setCanceledFlagIfPossible(); +} + +// https://dom.spec.whatwg.org/#set-the-canceled-flag +inline void Event::setCanceledFlagIfPossible() +{ + if (m_cancelable && !m_isExecutingPassiveEventListener) + m_wasCanceled = true; + // FIXME: Specification suggests we log something to the console when preventDefault is called but + // doesn't do anything because the event is not cancelable or is executing passive event listeners. +} + +inline void Event::setCancelBubble(bool cancel) +{ + if (cancel) + m_propagationStopped = true; +} + +WTF::TextStream& operator<<(WTF::TextStream&, const Event&); + +} // namespace WebCore + +#define SPECIALIZE_TYPE_TRAITS_EVENT(ToValueTypeName) \ + SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ + static bool isType(const WebCore::Event& event) { return event.is##ToValueTypeName(); } \ + SPECIALIZE_TYPE_TRAITS_END() diff --git a/src/bun.js/bindings/webcore/Event.idl b/src/bun.js/bindings/webcore/Event.idl new file mode 100644 index 000000000..2d6ba61f7 --- /dev/null +++ b/src/bun.js/bindings/webcore/Event.idl @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2006, 2007, 2009, 2011, 2017 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +typedef double DOMHighResTimeStamp; + +[ + CustomToJSObject, + DOMJIT, + ExportToWrappedFunction, + Exposed=*, + JSCustomHeader, +] interface Event { + constructor(DOMString type, optional EventInit eventInitDict); + + readonly attribute DOMString type; + readonly attribute EventTarget? target; + readonly attribute EventTarget? currentTarget; + sequence<EventTarget> composedPath(); + + const unsigned short NONE = 0; + const unsigned short CAPTURING_PHASE = 1; + const unsigned short AT_TARGET = 2; + const unsigned short BUBBLING_PHASE = 3; + readonly attribute unsigned short eventPhase; + + undefined stopPropagation(); + attribute boolean cancelBubble; // historical alias of .stopPropagation. + undefined stopImmediatePropagation(); + + readonly attribute boolean bubbles; + readonly attribute boolean cancelable; + undefined preventDefault(); + readonly attribute boolean defaultPrevented; + readonly attribute boolean composed; + + [LegacyUnforgeable] readonly attribute boolean isTrusted; + [CallWith=RelevantScriptExecutionContext, ImplementedAs=timeStampForBindings] readonly attribute DOMHighResTimeStamp timeStamp; + + undefined initEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false); // Historical. + + // IE extensions that may get standardized (https://github.com/whatwg/dom/issues/334). + [ImplementedAs=target] readonly attribute EventTarget srcElement; + [ImplementedAs=legacyReturnValue] attribute boolean returnValue; +}; diff --git a/src/bun.js/bindings/webcore/EventContext.cpp b/src/bun.js/bindings/webcore/EventContext.cpp new file mode 100644 index 000000000..c80863a7d --- /dev/null +++ b/src/bun.js/bindings/webcore/EventContext.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Google Inc. All Rights Reserved. + * Copyright (C) 2017 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 "EventContext.h" + +// #include "DOMWindow.h" +// #include "Document.h" +#include "EventNames.h" +// #include "FocusEvent.h" +// #include "HTMLFormElement.h" +// #include "MouseEvent.h" +// #include "TouchEvent.h" + +namespace WebCore { + +EventContext::~EventContext() = default; + +void EventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const +{ + event.setTarget(m_target.get()); + event.setCurrentTarget(m_currentTarget.get(), m_currentTargetIsInShadowTree); + + if (!m_node || UNLIKELY(m_type == Type::Window)) { + m_currentTarget->fireEventListeners(event, phase); + return; + } + + if (!m_node->hasEventTargetData()) + return; + + m_node->fireEventListeners(event, phase); +} + +#if ASSERT_ENABLED + +bool EventContext::isUnreachableNode(EventTarget* target) const +{ + // FIXME: Checks also for SVG elements. + return false; +} + +#endif + +} diff --git a/src/bun.js/bindings/webcore/EventContext.h b/src/bun.js/bindings/webcore/EventContext.h new file mode 100644 index 000000000..8fbd3c19f --- /dev/null +++ b/src/bun.js/bindings/webcore/EventContext.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2010 Google Inc. All Rights Reserved. + * Copyright (C) 2017 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. + * + */ + +#pragma once + +#include "root.h" +#include "Event.h" + +#include "Node.h" + +namespace WebCore { + +class EventContext { + WTF_MAKE_FAST_ALLOCATED; + +public: + using EventInvokePhase = EventTarget::EventInvokePhase; + + enum class Type : uint8_t { + Normal = 0, + MouseOrFocus, + Touch, + Window, + }; + + EventContext(Type, Node*, EventTarget* currentTarget, EventTarget* origin, int closedShadowDepth); + EventContext(Type, Node&, Node* currentTarget, EventTarget* origin, int closedShadowDepth); + ~EventContext(); + + Node* node() const { return m_node.get(); } + EventTarget* currentTarget() const { return m_currentTarget.get(); } + // bool isCurrentTargetInShadowTree() const { return m_currentTargetIsInShadowTree; } + bool isCurrentTargetInShadowTree() const { return false; } + EventTarget* target() const { return m_target.get(); } + // int closedShadowDepth() const { return m_closedShadowDepth; } + int closedShadowDepth() const { return 0; } + + void handleLocalEvents(Event&, EventInvokePhase) const; + + // bool isMouseOrFocusEventContext() const { return m_type == Type::MouseOrFocus; } + bool isMouseOrFocusEventContext() const { return false; } + // bool isTouchEventContext() const { return m_type == Type::Touch; } + bool isTouchEventContext() const { return false; } + // bool isWindowContext() const { return m_type == Type::Window; } + bool isWindowContext() const { return false; } + + Node* relatedTarget() const { return m_relatedTarget.get(); } + void setRelatedTarget(Node*); + +#if ENABLE(TOUCH_EVENTS) + enum TouchListType { Touches, + TargetTouches, + ChangedTouches }; + TouchList& touchList(TouchListType); +#endif + +private: + inline EventContext(Type, Node* currentNode, RefPtr<EventTarget>&& currentTarget, EventTarget* origin, int closedShadowDepth, bool currentTargetIsInShadowTree = false); + +#if ENABLE(TOUCH_EVENTS) + void initializeTouchLists(); +#endif + +#if ASSERT_ENABLED + bool isUnreachableNode(EventTarget*) const; +#endif + + RefPtr<Node> m_node; + RefPtr<EventTarget> m_currentTarget; + RefPtr<EventTarget> m_target; + RefPtr<Node> m_relatedTarget; +#if ENABLE(TOUCH_EVENTS) + RefPtr<TouchList> m_touches; + RefPtr<TouchList> m_targetTouches; + RefPtr<TouchList> m_changedTouches; +#endif + int m_closedShadowDepth { 0 }; + bool m_currentTargetIsInShadowTree { false }; + bool m_contextNodeIsFormElement { false }; + Type m_type { Type::Normal }; +}; + +inline EventContext::EventContext(Type type, Node* node, RefPtr<EventTarget>&& currentTarget, EventTarget* origin, int closedShadowDepth, bool currentTargetIsInShadowTree) + : m_node { node } + , m_currentTarget { WTFMove(currentTarget) } + , m_target { origin } + , m_closedShadowDepth { closedShadowDepth } + , m_currentTargetIsInShadowTree { currentTargetIsInShadowTree } + , m_type { type } +{ + // ASSERT(!isUnreachableNode(m_target.get())); + // #if ENABLE(TOUCH_EVENTS) + // if (m_type == Type::Touch) + // initializeTouchLists(); + // #else + // ASSERT(m_type != Type::Touch); + // #endif +} + +inline EventContext::EventContext(Type type, Node* node, EventTarget* currentTarget, EventTarget* origin, int closedShadowDepth) + : EventContext(type, node, RefPtr { currentTarget }, origin, closedShadowDepth) +{ + // ASSERT(!is<Node>(currentTarget)); +} + +// This variant avoids calling EventTarget::ref() which is a virtual function call. +inline EventContext::EventContext(Type type, Node& node, Node* currentTarget, EventTarget* origin, int closedShadowDepth) + : EventContext(type, &node, RefPtr { currentTarget }, origin, closedShadowDepth, false) +{ + m_contextNodeIsFormElement = false; + // m_contextNodeIsFormElement = is<HTMLFormElement>(node); +} + +inline void EventContext::setRelatedTarget(Node* relatedTarget) +{ + ASSERT(!isUnreachableNode(relatedTarget)); + m_relatedTarget = relatedTarget; +} + +// #if ENABLE(TOUCH_EVENTS) + +// inline TouchList& EventContext::touchList(TouchListType type) +// { +// switch (type) { +// case Touches: +// return *m_touches; +// case TargetTouches: +// return *m_targetTouches; +// case ChangedTouches: +// return *m_changedTouches; +// } +// ASSERT_NOT_REACHED(); +// return *m_touches; +// } + +// #endif + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventDispatcher.cpp b/src/bun.js/bindings/webcore/EventDispatcher.cpp new file mode 100644 index 000000000..9c83aa0e2 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventDispatcher.cpp @@ -0,0 +1,239 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2001 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2004-2022 Apple Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (C) 2010, 2011, 2012, 2013 Google Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "Event.h" +#include "EventDispatcher.h" + +// #include "CompositionEvent.h" +#include "EventContext.h" +// #include "EventNames.h" +#include "EventPath.h" +// #include "Frame.h" +// #include "FrameLoader.h" +// #include "FrameView.h" +// #include "HTMLInputElement.h" +// #include "InputEvent.h" +// #include "KeyboardEvent.h" +// #include "Logging.h" +// #include "MouseEvent.h" +// #include "ScopedEventQueue.h" +// #include "ScriptDisallowedScope.h" +// #include "ShadowRoot.h" +// #include "TextEvent.h" +// #include "TouchEvent.h" +// #include <wtf/text/TextStream.h> + +namespace WebCore { + +// void EventDispatcher::dispatchScopedEvent(Node& node, Event& event) +// { +// // Need to set the target here so the scoped event queue knows which node to dispatch to. +// event.setTarget(EventPath::eventTargetRespectingTargetRules(node)); +// ScopedEventQueue::singleton().enqueueEvent(event); +// } + +static void callDefaultEventHandlersInBubblingOrder(Event& event, const EventPath& path) +{ + if (path.isEmpty()) + return; + + // Non-bubbling events call only one default event handler, the one for the target. + Ref rootNode { *path.contextAt(0).node() }; + rootNode->defaultEventHandler(event); + ASSERT(!event.defaultPrevented()); + + if (event.defaultHandled() || !event.bubbles()) + return; + + size_t size = path.size(); + for (size_t i = 1; i < size; ++i) { + Ref currentNode { *path.contextAt(i).node() }; + currentNode->defaultEventHandler(event); + ASSERT(!event.defaultPrevented()); + if (event.defaultHandled()) + return; + } +} + +// static bool isInShadowTree(EventTarget* target) +// { +// return is<Node>(target) && downcast<Node>(*target).isInShadowTree(); +// } + +static void dispatchEventInDOM(Event& event, const EventPath& path) +{ + // Invoke capturing event listeners in the reverse order. + for (size_t i = path.size(); i > 0; --i) { + const EventContext& eventContext = path.contextAt(i - 1); + if (eventContext.currentTarget() == eventContext.target()) + event.setEventPhase(Event::AT_TARGET); + else + event.setEventPhase(Event::CAPTURING_PHASE); + eventContext.handleLocalEvents(event, EventTarget::EventInvokePhase::Capturing); + if (event.propagationStopped()) + return; + } + + // Invoke bubbling event listeners. + size_t size = path.size(); + for (size_t i = 0; i < size; ++i) { + const EventContext& eventContext = path.contextAt(i); + if (eventContext.currentTarget() == eventContext.target()) + event.setEventPhase(Event::AT_TARGET); + else if (event.bubbles()) + event.setEventPhase(Event::BUBBLING_PHASE); + else + continue; + eventContext.handleLocalEvents(event, EventTarget::EventInvokePhase::Bubbling); + if (event.propagationStopped()) + return; + } +} + +static bool shouldSuppressEventDispatchInDOM(Node& node, Event& event) +{ + return false; + // if (!event.isTrusted()) + // return false; + + // auto frame = node.document().frame(); + // if (!frame) + // return false; + + // if (!frame->mainFrame().loader().shouldSuppressTextInputFromEditing()) + // return false; + + // if (is<TextEvent>(event)) { + // auto& textEvent = downcast<TextEvent>(event); + // return textEvent.isKeyboard() || textEvent.isComposition(); + // } + + // return is<CompositionEvent>(event) || is<InputEvent>(event) || is<KeyboardEvent>(event); +} + +// static HTMLInputElement* findInputElementInEventPath(const EventPath& path) +// { +// size_t size = path.size(); +// for (size_t i = 0; i < size; ++i) { +// const EventContext& eventContext = path.contextAt(i); +// if (is<HTMLInputElement>(eventContext.currentTarget())) +// return downcast<HTMLInputElement>(eventContext.currentTarget()); +// } +// return nullptr; +// } + +void EventDispatcher::dispatchEvent(Node& node, Event& event) +{ + // ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isEventDispatchAllowedInSubtree(node)); + + // LOG_WITH_STREAM(Events, stream << "EventDispatcher::dispatchEvent " << event << " on node " << node); + + Ref protectedNode { node }; + // RefPtr protectedView { node.document().view() }; + + EventPath eventPath { node, event }; + + std::optional<bool> shouldClearTargetsAfterDispatch; + // for (size_t i = eventPath.size(); i > 0; --i) { + // const EventContext& eventContext = eventPath.contextAt(i - 1); + // // FIXME: We should also set shouldClearTargetsAfterDispatch to true if an EventTarget object in eventContext's touch target list + // // is a node and its root is a shadow root. + // if (eventContext.target()) { + // shouldClearTargetsAfterDispatch = isInShadowTree(eventContext.target()) || isInShadowTree(eventContext.relatedTarget()); + // break; + // } + // } + + // ChildNodesLazySnapshot::takeChildNodesLazySnapshot(); + + event.resetBeforeDispatch(); + event.setTarget(node); + // event.setTarget(EventPath::eventTargetRespectingTargetRules(node)); + if (!event.target()) + return; + + // InputElementClickState clickHandlingState; + + // bool isActivationEvent = event.type() == eventNames().clickEvent; + // RefPtr inputForLegacyPreActivationBehavior = dynamicDowncast<HTMLInputElement>(node); + // if (!inputForLegacyPreActivationBehavior && isActivationEvent && event.bubbles()) + // inputForLegacyPreActivationBehavior = findInputElementInEventPath(eventPath); + // if (inputForLegacyPreActivationBehavior) + // inputForLegacyPreActivationBehavior->willDispatchEvent(event, clickHandlingState); + + if (shouldSuppressEventDispatchInDOM(node, event)) + event.stopPropagation(); + + if (!event.propagationStopped() && !eventPath.isEmpty()) { + event.setEventPath(eventPath); + dispatchEventInDOM(event, eventPath); + } + + event.resetAfterDispatch(); + + // if (clickHandlingState.stateful) + // inputForLegacyPreActivationBehavior->didDispatchClickEvent(event, clickHandlingState); + + // Call default event handlers. While the DOM does have a concept of preventing + // default handling, the detail of which handlers are called is an internal + // implementation detail and not part of the DOM. + if (!event.defaultPrevented() && !event.defaultHandled() && !event.isDefaultEventHandlerIgnored()) { + // FIXME: Not clear why we need to reset the target for the default event handlers. + // We should research this, and remove this code if possible. + auto* finalTarget = event.target(); + // event.setTarget(EventPath::eventTargetRespectingTargetRules(node)); + event.setTarget(node); + callDefaultEventHandlersInBubblingOrder(event, eventPath); + event.setTarget(finalTarget); + } + + if (shouldClearTargetsAfterDispatch.value_or(false)) { + event.setTarget(nullptr); + event.setRelatedTarget(nullptr); + // FIXME: We should also clear the event's touch target list. + } +} + +template<typename T> +static void dispatchEventWithType(const Vector<T*>& targets, Event& event) +{ + ASSERT(targets.size() >= 1); + ASSERT(*targets.begin()); + + EventPath eventPath { targets }; + event.setTarget(*targets.begin()); + event.setEventPath(eventPath); + event.resetBeforeDispatch(); + dispatchEventInDOM(event, eventPath); + event.resetAfterDispatch(); +} + +void EventDispatcher::dispatchEvent(const Vector<EventTarget*>& targets, Event& event) +{ + dispatchEventWithType<EventTarget>(targets, event); +} + +} diff --git a/src/bun.js/bindings/webcore/EventDispatcher.h b/src/bun.js/bindings/webcore/EventDispatcher.h new file mode 100644 index 000000000..63ee34bfb --- /dev/null +++ b/src/bun.js/bindings/webcore/EventDispatcher.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011-2013 Google Inc. All rights reserved. + * Copyright (C) 2013-2017 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include <wtf/Forward.h> +#include "Node.h" + +namespace WebCore { + +class Element; +class Event; +class EventTarget; + +namespace EventDispatcher { + +void dispatchEvent(Node&, Event&); +void dispatchEvent(const Vector<EventTarget*>&, Event&); + +// void dispatchScopedEvent(Node&, Event&); + +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventFactory.cpp b/src/bun.js/bindings/webcore/EventFactory.cpp new file mode 100644 index 000000000..3677b9dfe --- /dev/null +++ b/src/bun.js/bindings/webcore/EventFactory.cpp @@ -0,0 +1,316 @@ +/* + * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. + * + * Copyright (C) 2011 Google 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 GOOGLE, 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 "EventHeaders.h" +#include "JSDOMWrapperCache.h" +#include "JSDOMGlobalObject.h" +#include <JavaScriptCore/StructureInlines.h> + +namespace WebCore { + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<Event>&& impl) +{ + switch (impl->eventInterface()) { + // case AnimationEventInterfaceType: + // return createWrapper<AnimationEvent>(globalObject, WTFMove(impl)); + // case AnimationPlaybackEventInterfaceType: + // return createWrapper<AnimationPlaybackEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(APPLE_PAY) + // case ApplePayCancelEventInterfaceType: + // return createWrapper<ApplePayCancelEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(APPLE_PAY_COUPON_CODE) + // case ApplePayCouponCodeChangedEventInterfaceType: + // return createWrapper<ApplePayCouponCodeChangedEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(APPLE_PAY) + // case ApplePayPaymentAuthorizedEventInterfaceType: + // return createWrapper<ApplePayPaymentAuthorizedEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(APPLE_PAY) + // case ApplePayPaymentMethodSelectedEventInterfaceType: + // return createWrapper<ApplePayPaymentMethodSelectedEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(APPLE_PAY) + // case ApplePayShippingContactSelectedEventInterfaceType: + // return createWrapper<ApplePayShippingContactSelectedEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(APPLE_PAY) + // case ApplePayShippingMethodSelectedEventInterfaceType: + // return createWrapper<ApplePayShippingMethodSelectedEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(APPLE_PAY) + // case ApplePayValidateMerchantEventInterfaceType: + // return createWrapper<ApplePayValidateMerchantEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_AUDIO) + // case AudioProcessingEventInterfaceType: + // return createWrapper<AudioProcessingEvent>(globalObject, WTFMove(impl)); + // #endif + case EventInterfaceType: { + return createWrapper<Event>(globalObject, WTFMove(impl)); + } + // case BeforeUnloadEventInterfaceType: + // return createWrapper<BeforeUnloadEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(MEDIA_RECORDER) + // case BlobEventInterfaceType: + // return createWrapper<BlobEvent>(globalObject, WTFMove(impl)); + // #endif + // case ClipboardEventInterfaceType: + // return createWrapper<ClipboardEvent>(globalObject, WTFMove(impl)); + // case CloseEventInterfaceType: + // return createWrapper<CloseEvent>(globalObject, WTFMove(impl)); + // case CompositionEventInterfaceType: + // return createWrapper<CompositionEvent>(globalObject, WTFMove(impl)); + // case CustomEventInterfaceType: + // return createWrapper<CustomEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(DEVICE_ORIENTATION) + // case DeviceMotionEventInterfaceType: + // return createWrapper<DeviceMotionEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(DEVICE_ORIENTATION) + // case DeviceOrientationEventInterfaceType: + // return createWrapper<DeviceOrientationEvent>(globalObject, WTFMove(impl)); + // #endif + // case DragEventInterfaceType: + // return createWrapper<DragEvent>(globalObject, WTFMove(impl)); + case ErrorEventInterfaceType: { + return createWrapper<ErrorEvent>(globalObject, WTFMove(impl)); + } + // #if ENABLE(SERVICE_WORKER) + // case ExtendableEventInterfaceType: + // return createWrapper<ExtendableEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(SERVICE_WORKER) + // case ExtendableMessageEventInterfaceType: + // return createWrapper<ExtendableMessageEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(SERVICE_WORKER) + // case FetchEventInterfaceType: + // return createWrapper<FetchEvent>(globalObject, WTFMove(impl)); + // #endif + // case FocusEventInterfaceType: + // return createWrapper<FocusEvent>(globalObject, WTFMove(impl)); + // case FormDataEventInterfaceType: + // return createWrapper<FormDataEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(GAMEPAD) + // case GamepadEventInterfaceType: + // return createWrapper<GamepadEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS) + // case GestureEventInterfaceType: + // return createWrapper<GestureEvent>(globalObject, WTFMove(impl)); + // #endif + // case HashChangeEventInterfaceType: + // return createWrapper<HashChangeEvent>(globalObject, WTFMove(impl)); + // case IDBVersionChangeEventInterfaceType: + // return createWrapper<IDBVersionChangeEvent>(globalObject, WTFMove(impl)); + // case InputEventInterfaceType: + // return createWrapper<InputEvent>(globalObject, WTFMove(impl)); + // case KeyboardEventInterfaceType: + // return createWrapper<KeyboardEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(ENCRYPTED_MEDIA) + // case MediaEncryptedEventInterfaceType: + // return createWrapper<MediaEncryptedEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(ENCRYPTED_MEDIA) + // case MediaKeyMessageEventInterfaceType: + // return createWrapper<MediaKeyMessageEvent>(globalObject, WTFMove(impl)); + // #endif + // case MediaQueryListEventInterfaceType: + // return createWrapper<MediaQueryListEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(MEDIA_RECORDER) + // case MediaRecorderErrorEventInterfaceType: + // return createWrapper<MediaRecorderErrorEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(MEDIA_STREAM) + // case MediaStreamTrackEventInterfaceType: + // return createWrapper<MediaStreamTrackEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(PAYMENT_REQUEST) + // case MerchantValidationEventInterfaceType: + // return createWrapper<MerchantValidationEvent>(globalObject, WTFMove(impl)); + // #endif + case MessageEventInterfaceType: + return createWrapper<MessageEvent>(globalObject, WTFMove(impl)); + // case MouseEventInterfaceType: + // return createWrapper<MouseEvent>(globalObject, WTFMove(impl)); + // case MutationEventInterfaceType: + // return createWrapper<MutationEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(NOTIFICATION_EVENT) + // case NotificationEventInterfaceType: + // return createWrapper<NotificationEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_AUDIO) + // case OfflineAudioCompletionEventInterfaceType: + // return createWrapper<OfflineAudioCompletionEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(MEDIA_STREAM) + // case OverconstrainedErrorEventInterfaceType: + // return createWrapper<OverconstrainedErrorEvent>(globalObject, WTFMove(impl)); + // #endif + // case OverflowEventInterfaceType: + // return createWrapper<OverflowEvent>(globalObject, WTFMove(impl)); + // case PageTransitionEventInterfaceType: + // return createWrapper<PageTransitionEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(PAYMENT_REQUEST) + // case PaymentMethodChangeEventInterfaceType: + // return createWrapper<PaymentMethodChangeEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(PAYMENT_REQUEST) + // case PaymentRequestUpdateEventInterfaceType: + // return createWrapper<PaymentRequestUpdateEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(PICTURE_IN_PICTURE_API) + // case PictureInPictureEventInterfaceType: + // return createWrapper<PictureInPictureEvent>(globalObject, WTFMove(impl)); + // #endif + // case PointerEventInterfaceType: + // return createWrapper<PointerEvent>(globalObject, WTFMove(impl)); + // case PopStateEventInterfaceType: + // return createWrapper<PopStateEvent>(globalObject, WTFMove(impl)); + // case ProgressEventInterfaceType: + // return createWrapper<ProgressEvent>(globalObject, WTFMove(impl)); + // case PromiseRejectionEventInterfaceType: + // return createWrapper<PromiseRejectionEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(SERVICE_WORKER) + // case PushEventInterfaceType: + // return createWrapper<PushEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(SERVICE_WORKER) + // case PushSubscriptionChangeEventInterfaceType: + // return createWrapper<PushSubscriptionChangeEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCDTMFToneChangeEventInterfaceType: + // return createWrapper<RTCDTMFToneChangeEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCDataChannelEventInterfaceType: + // return createWrapper<RTCDataChannelEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCErrorEventInterfaceType: + // return createWrapper<RTCErrorEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCPeerConnectionIceErrorEventInterfaceType: + // return createWrapper<RTCPeerConnectionIceErrorEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCPeerConnectionIceEventInterfaceType: + // return createWrapper<RTCPeerConnectionIceEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCRtpSFrameTransformErrorEventInterfaceType: + // return createWrapper<RTCRtpSFrameTransformErrorEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCTrackEventInterfaceType: + // return createWrapper<RTCTrackEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCTransformEventInterfaceType: + // return createWrapper<RTCTransformEvent>(globalObject, WTFMove(impl)); + // #endif + // case SVGZoomEventInterfaceType: + // return createWrapper<SVGZoomEvent>(globalObject, WTFMove(impl)); + // case SecurityPolicyViolationEventInterfaceType: + // return createWrapper<SecurityPolicyViolationEvent>(globalObject, WTFMove(impl)); + // case SpeechRecognitionErrorEventInterfaceType: + // return createWrapper<SpeechRecognitionErrorEvent>(globalObject, WTFMove(impl)); + // case SpeechRecognitionEventInterfaceType: + // return createWrapper<SpeechRecognitionEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(SPEECH_SYNTHESIS) + // case SpeechSynthesisErrorEventInterfaceType: + // return createWrapper<SpeechSynthesisErrorEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(SPEECH_SYNTHESIS) + // case SpeechSynthesisEventInterfaceType: + // return createWrapper<SpeechSynthesisEvent>(globalObject, WTFMove(impl)); + // #endif + // case StorageEventInterfaceType: + // return createWrapper<StorageEvent>(globalObject, WTFMove(impl)); + // case SubmitEventInterfaceType: + // return createWrapper<SubmitEvent>(globalObject, WTFMove(impl)); + // case TextEventInterfaceType: + // return createWrapper<TextEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(TOUCH_EVENTS) + // case TouchEventInterfaceType: + // return createWrapper<TouchEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(VIDEO) + // case TrackEventInterfaceType: + // return createWrapper<TrackEvent>(globalObject, WTFMove(impl)); + // #endif + // case TransitionEventInterfaceType: + // return createWrapper<TransitionEvent>(globalObject, WTFMove(impl)); + // case UIEventInterfaceType: + // return createWrapper<UIEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(WEBGL) + // case WebGLContextEventInterfaceType: + // return createWrapper<WebGLContextEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(LEGACY_ENCRYPTED_MEDIA) + // case WebKitMediaKeyMessageEventInterfaceType: + // return createWrapper<WebKitMediaKeyMessageEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(LEGACY_ENCRYPTED_MEDIA) + // case WebKitMediaKeyNeededEventInterfaceType: + // return createWrapper<WebKitMediaKeyNeededEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WIRELESS_PLAYBACK_TARGET) + // case WebKitPlaybackTargetAvailabilityEventInterfaceType: + // return createWrapper<WebKitPlaybackTargetAvailabilityEvent>(globalObject, WTFMove(impl)); + // #endif + // case WheelEventInterfaceType: + // return createWrapper<WheelEvent>(globalObject, WTFMove(impl)); + // case XMLHttpRequestProgressEventInterfaceType: + // return createWrapper<XMLHttpRequestProgressEvent>(globalObject, WTFMove(impl)); + // #if ENABLE(WEBXR) + // case XRInputSourceEventInterfaceType: + // return createWrapper<XRInputSourceEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEBXR) + // case XRInputSourcesChangeEventInterfaceType: + // return createWrapper<XRInputSourcesChangeEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEBXR) + // case XRReferenceSpaceEventInterfaceType: + // return createWrapper<XRReferenceSpaceEvent>(globalObject, WTFMove(impl)); + // #endif + // #if ENABLE(WEBXR) + // case XRSessionEventInterfaceType: + // return createWrapper<XRSessionEvent>(globalObject, WTFMove(impl)); + // #endif + // } + return createWrapper<Event>(globalObject, WTFMove(impl)); + } +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventHeaders.h b/src/bun.js/bindings/webcore/EventHeaders.h new file mode 100644 index 000000000..347d333d0 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventHeaders.h @@ -0,0 +1,302 @@ +/* + * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. + * + * Copyright (C) 2011 Google 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 GOOGLE, 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. + */ + +#ifndef EventHeaders_h +#define EventHeaders_h + +// #include "AnimationEvent.h" +// #include "JSAnimationEvent.h" +// #include "AnimationPlaybackEvent.h" +// #include "JSAnimationPlaybackEvent.h" +// #if ENABLE(APPLE_PAY) +// #include "ApplePayCancelEvent.h" +// #include "JSApplePayCancelEvent.h" +// #endif +// #if ENABLE(APPLE_PAY_COUPON_CODE) +// #include "ApplePayCouponCodeChangedEvent.h" +// #include "JSApplePayCouponCodeChangedEvent.h" +// #endif +// #if ENABLE(APPLE_PAY) +// #include "ApplePayPaymentAuthorizedEvent.h" +// #include "JSApplePayPaymentAuthorizedEvent.h" +// #endif +// #if ENABLE(APPLE_PAY) +// #include "ApplePayPaymentMethodSelectedEvent.h" +// #include "JSApplePayPaymentMethodSelectedEvent.h" +// #endif +// #if ENABLE(APPLE_PAY) +// #include "ApplePayShippingContactSelectedEvent.h" +// #include "JSApplePayShippingContactSelectedEvent.h" +// #endif +// #if ENABLE(APPLE_PAY) +// #include "ApplePayShippingMethodSelectedEvent.h" +// #include "JSApplePayShippingMethodSelectedEvent.h" +// #endif +// #if ENABLE(APPLE_PAY) +// #include "ApplePayValidateMerchantEvent.h" +// #include "JSApplePayValidateMerchantEvent.h" +// #endif +// #if ENABLE(WEB_AUDIO) +// #include "AudioProcessingEvent.h" +// #include "JSAudioProcessingEvent.h" +// #endif +#include "Event.h" +#include "JSEvent.h" +// #include "BeforeUnloadEvent.h" +// #include "JSBeforeUnloadEvent.h" +// #if ENABLE(MEDIA_RECORDER) +// #include "BlobEvent.h" +// #include "JSBlobEvent.h" +// #endif +// #include "ClipboardEvent.h" +// #include "JSClipboardEvent.h" +// #include "CloseEvent.h" +// #include "JSCloseEvent.h" +// #include "CompositionEvent.h" +// #include "JSCompositionEvent.h" +// #include "CustomEvent.h" +// #include "JSCustomEvent.h" +// #if ENABLE(DEVICE_ORIENTATION) +// #include "DeviceMotionEvent.h" +// #include "JSDeviceMotionEvent.h" +// #endif +// #if ENABLE(DEVICE_ORIENTATION) +// #include "DeviceOrientationEvent.h" +// #include "JSDeviceOrientationEvent.h" +// #endif +// #include "DragEvent.h" +// #include "JSDragEvent.h" +#include "ErrorEvent.h" +#include "JSErrorEvent.h" +// #if ENABLE(SERVICE_WORKER) +// #include "ExtendableEvent.h" +// #include "JSExtendableEvent.h" +// #endif +// #if ENABLE(SERVICE_WORKER) +// #include "ExtendableMessageEvent.h" +// #include "JSExtendableMessageEvent.h" +// #endif +// #if ENABLE(SERVICE_WORKER) +// #include "FetchEvent.h" +// #include "JSFetchEvent.h" +// #endif +// #include "FocusEvent.h" +// #include "JSFocusEvent.h" +// #include "FormDataEvent.h" +// #include "JSFormDataEvent.h" +// #if ENABLE(GAMEPAD) +// #include "GamepadEvent.h" +// #include "JSGamepadEvent.h" +// #endif +// #if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS) +// #include "GestureEvent.h" +// #include "JSGestureEvent.h" +// #endif +// #include "HashChangeEvent.h" +// #include "JSHashChangeEvent.h" +// #include "IDBVersionChangeEvent.h" +// #include "JSIDBVersionChangeEvent.h" +// #include "InputEvent.h" +// #include "JSInputEvent.h" +// #include "KeyboardEvent.h" +// #include "JSKeyboardEvent.h" +// #if ENABLE(ENCRYPTED_MEDIA) +// #include "MediaEncryptedEvent.h" +// #include "JSMediaEncryptedEvent.h" +// #endif +// #if ENABLE(ENCRYPTED_MEDIA) +// #include "MediaKeyMessageEvent.h" +// #include "JSMediaKeyMessageEvent.h" +// #endif +// #include "MediaQueryListEvent.h" +// #include "JSMediaQueryListEvent.h" +// #if ENABLE(MEDIA_RECORDER) +// #include "MediaRecorderErrorEvent.h" +// #include "JSMediaRecorderErrorEvent.h" +// #endif +// #if ENABLE(MEDIA_STREAM) +// #include "MediaStreamTrackEvent.h" +// #include "JSMediaStreamTrackEvent.h" +// #endif +// #if ENABLE(PAYMENT_REQUEST) +// #include "MerchantValidationEvent.h" +// #include "JSMerchantValidationEvent.h" +// #endif +#include "MessageEvent.h" +#include "JSMessageEvent.h" +// #include "MouseEvent.h" +// #include "JSMouseEvent.h" +// #include "MutationEvent.h" +// #include "JSMutationEvent.h" +// #if ENABLE(NOTIFICATION_EVENT) +// #include "NotificationEvent.h" +// #include "JSNotificationEvent.h" +// #endif +// #if ENABLE(WEB_AUDIO) +// #include "OfflineAudioCompletionEvent.h" +// #include "JSOfflineAudioCompletionEvent.h" +// #endif +// #if ENABLE(MEDIA_STREAM) +// #include "OverconstrainedErrorEvent.h" +// #include "JSOverconstrainedErrorEvent.h" +// #endif +// #include "OverflowEvent.h" +// #include "JSOverflowEvent.h" +// #include "PageTransitionEvent.h" +// #include "JSPageTransitionEvent.h" +// #if ENABLE(PAYMENT_REQUEST) +// #include "PaymentMethodChangeEvent.h" +// #include "JSPaymentMethodChangeEvent.h" +// #endif +// #if ENABLE(PAYMENT_REQUEST) +// #include "PaymentRequestUpdateEvent.h" +// #include "JSPaymentRequestUpdateEvent.h" +// #endif +// #if ENABLE(PICTURE_IN_PICTURE_API) +// #include "PictureInPictureEvent.h" +// #include "JSPictureInPictureEvent.h" +// #endif +// #include "PointerEvent.h" +// #include "JSPointerEvent.h" +// #include "PopStateEvent.h" +// #include "JSPopStateEvent.h" +// #include "ProgressEvent.h" +// #include "JSProgressEvent.h" +// #include "PromiseRejectionEvent.h" +// #include "JSPromiseRejectionEvent.h" +// #if ENABLE(SERVICE_WORKER) +// #include "PushEvent.h" +// #include "JSPushEvent.h" +// #endif +// #if ENABLE(SERVICE_WORKER) +// #include "PushSubscriptionChangeEvent.h" +// #include "JSPushSubscriptionChangeEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCDTMFToneChangeEvent.h" +// #include "JSRTCDTMFToneChangeEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCDataChannelEvent.h" +// #include "JSRTCDataChannelEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCErrorEvent.h" +// #include "JSRTCErrorEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCPeerConnectionIceErrorEvent.h" +// #include "JSRTCPeerConnectionIceErrorEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCPeerConnectionIceEvent.h" +// #include "JSRTCPeerConnectionIceEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCRtpSFrameTransformErrorEvent.h" +// #include "JSRTCRtpSFrameTransformErrorEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCTrackEvent.h" +// #include "JSRTCTrackEvent.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "RTCTransformEvent.h" +// #include "JSRTCTransformEvent.h" +// #endif +// #include "SVGZoomEvent.h" +// #include "JSSVGZoomEvent.h" +// #include "SecurityPolicyViolationEvent.h" +// #include "JSSecurityPolicyViolationEvent.h" +// #include "SpeechRecognitionErrorEvent.h" +// #include "JSSpeechRecognitionErrorEvent.h" +// #include "SpeechRecognitionEvent.h" +// #include "JSSpeechRecognitionEvent.h" +// #if ENABLE(SPEECH_SYNTHESIS) +// #include "SpeechSynthesisErrorEvent.h" +// #include "JSSpeechSynthesisErrorEvent.h" +// #endif +// #if ENABLE(SPEECH_SYNTHESIS) +// #include "SpeechSynthesisEvent.h" +// #include "JSSpeechSynthesisEvent.h" +// #endif +// #include "StorageEvent.h" +// #include "JSStorageEvent.h" +// #include "SubmitEvent.h" +// #include "JSSubmitEvent.h" +// #include "TextEvent.h" +// #include "JSTextEvent.h" +// #if ENABLE(TOUCH_EVENTS) +// #include "TouchEvent.h" +// #include "JSTouchEvent.h" +// #endif +// #if ENABLE(VIDEO) +// #include "TrackEvent.h" +// #include "JSTrackEvent.h" +// #endif +// #include "TransitionEvent.h" +// #include "JSTransitionEvent.h" +// #include "UIEvent.h" +// #include "JSUIEvent.h" +// #if ENABLE(WEBGL) +// #include "WebGLContextEvent.h" +// #include "JSWebGLContextEvent.h" +// #endif +// #if ENABLE(LEGACY_ENCRYPTED_MEDIA) +// #include "WebKitMediaKeyMessageEvent.h" +// #include "JSWebKitMediaKeyMessageEvent.h" +// #endif +// #if ENABLE(LEGACY_ENCRYPTED_MEDIA) +// #include "WebKitMediaKeyNeededEvent.h" +// #include "JSWebKitMediaKeyNeededEvent.h" +// #endif +// #if ENABLE(WIRELESS_PLAYBACK_TARGET) +// #include "WebKitPlaybackTargetAvailabilityEvent.h" +// #include "JSWebKitPlaybackTargetAvailabilityEvent.h" +// #endif +// #include "WheelEvent.h" +// #include "JSWheelEvent.h" +// #include "XMLHttpRequestProgressEvent.h" +// #include "JSXMLHttpRequestProgressEvent.h" +// #if ENABLE(WEBXR) +// #include "XRInputSourceEvent.h" +// #include "JSXRInputSourceEvent.h" +// #endif +// #if ENABLE(WEBXR) +// #include "XRInputSourcesChangeEvent.h" +// #include "JSXRInputSourcesChangeEvent.h" +// #endif +// #if ENABLE(WEBXR) +// #include "XRReferenceSpaceEvent.h" +// #include "JSXRReferenceSpaceEvent.h" +// #endif +// #if ENABLE(WEBXR) +// #include "XRSessionEvent.h" +// #include "JSXRSessionEvent.h" +// #endif + +#endif // EventHeaders_h diff --git a/src/bun.js/bindings/webcore/EventInit.h b/src/bun.js/bindings/webcore/EventInit.h new file mode 100644 index 000000000..0e588593c --- /dev/null +++ b/src/bun.js/bindings/webcore/EventInit.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016-2018 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 + +namespace WebCore { + +struct EventInit { + bool bubbles { false }; + bool cancelable { false }; + bool composed { false }; + + template<class Encoder> void encode(Encoder&) const; + template<class Decoder> static WARN_UNUSED_RETURN bool decode(Decoder&, EventInit&); +}; + +template<class Encoder> +void EventInit::encode(Encoder& encoder) const +{ + encoder << bubbles; + encoder << cancelable; + encoder << composed; +} + +template<class Decoder> +bool EventInit::decode(Decoder& decoder, EventInit& eventInit) +{ + if (!decoder.decode(eventInit.bubbles)) + return false; + if (!decoder.decode(eventInit.cancelable)) + return false; + if (!decoder.decode(eventInit.composed)) + return false; + return true; +} + +} diff --git a/src/bun.js/bindings/webcore/EventInit.idl b/src/bun.js/bindings/webcore/EventInit.idl new file mode 100644 index 000000000..e55a03034 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventInit.idl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 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. + */ + +dictionary EventInit { + boolean bubbles = false; + boolean cancelable = false; + boolean composed = false; +}; diff --git a/src/bun.js/bindings/webcore/EventInterfaces.h b/src/bun.js/bindings/webcore/EventInterfaces.h new file mode 100644 index 000000000..5bb0962b6 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventInterfaces.h @@ -0,0 +1,165 @@ +/* + * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. + * + * Copyright (C) 2011 Google 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 GOOGLE, 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. + */ + +#pragma once + +namespace WebCore { + +enum EventInterface { +#if ENABLE(APPLE_PAY) + ApplePayCancelEventInterfaceType = 1, + ApplePayPaymentAuthorizedEventInterfaceType = 2, + ApplePayPaymentMethodSelectedEventInterfaceType = 3, + ApplePayShippingContactSelectedEventInterfaceType = 4, + ApplePayShippingMethodSelectedEventInterfaceType = 5, + ApplePayValidateMerchantEventInterfaceType = 6, +#endif +#if ENABLE(APPLE_PAY_COUPON_CODE) + ApplePayCouponCodeChangedEventInterfaceType = 7, +#endif +#if ENABLE(DEVICE_ORIENTATION) + DeviceMotionEventInterfaceType = 8, + DeviceOrientationEventInterfaceType = 9, +#endif +#if ENABLE(ENCRYPTED_MEDIA) + MediaEncryptedEventInterfaceType = 10, + MediaKeyMessageEventInterfaceType = 11, +#endif +#if ENABLE(GAMEPAD) + GamepadEventInterfaceType = 12, +#endif +#if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS) + GestureEventInterfaceType = 13, +#endif +#if ENABLE(LEGACY_ENCRYPTED_MEDIA) + WebKitMediaKeyMessageEventInterfaceType = 14, + WebKitMediaKeyNeededEventInterfaceType = 15, +#endif +#if ENABLE(MEDIA_RECORDER) + BlobEventInterfaceType = 16, + MediaRecorderErrorEventInterfaceType = 17, +#endif +#if ENABLE(MEDIA_STREAM) + MediaStreamTrackEventInterfaceType = 18, + OverconstrainedErrorEventInterfaceType = 19, +#endif +#if ENABLE(NOTIFICATION_EVENT) + NotificationEventInterfaceType = 20, +#endif +#if ENABLE(ORIENTATION_EVENTS) +#endif +#if ENABLE(PAYMENT_REQUEST) + MerchantValidationEventInterfaceType = 21, + PaymentMethodChangeEventInterfaceType = 22, + PaymentRequestUpdateEventInterfaceType = 23, +#endif +#if ENABLE(PICTURE_IN_PICTURE_API) + PictureInPictureEventInterfaceType = 24, +#endif +#if ENABLE(SERVICE_WORKER) + ExtendableEventInterfaceType = 25, + ExtendableMessageEventInterfaceType = 26, + FetchEventInterfaceType = 27, + PushEventInterfaceType = 28, + PushSubscriptionChangeEventInterfaceType = 29, +#endif +#if ENABLE(SPEECH_SYNTHESIS) + SpeechSynthesisErrorEventInterfaceType = 30, + SpeechSynthesisEventInterfaceType = 31, +#endif +#if ENABLE(TOUCH_EVENTS) + TouchEventInterfaceType = 32, +#endif +#if ENABLE(VIDEO) + TrackEventInterfaceType = 33, +#endif +#if ENABLE(WEBGL) + WebGLContextEventInterfaceType = 34, +#endif +#if ENABLE(WEBXR) + XRInputSourceEventInterfaceType = 35, + XRInputSourcesChangeEventInterfaceType = 36, + XRReferenceSpaceEventInterfaceType = 37, + XRSessionEventInterfaceType = 38, +#endif +#if ENABLE(WEB_AUDIO) + AudioProcessingEventInterfaceType = 39, + OfflineAudioCompletionEventInterfaceType = 40, +#endif +#if ENABLE(WEB_RTC) + RTCDTMFToneChangeEventInterfaceType = 41, + RTCDataChannelEventInterfaceType = 42, + RTCErrorEventInterfaceType = 43, + RTCPeerConnectionIceErrorEventInterfaceType = 44, + RTCPeerConnectionIceEventInterfaceType = 45, + RTCRtpSFrameTransformErrorEventInterfaceType = 46, + RTCTrackEventInterfaceType = 47, + RTCTransformEventInterfaceType = 48, +#endif +#if ENABLE(WIRELESS_PLAYBACK_TARGET) + WebKitPlaybackTargetAvailabilityEventInterfaceType = 49, +#endif + AnimationEventInterfaceType = 50, + AnimationPlaybackEventInterfaceType = 51, + BeforeUnloadEventInterfaceType = 52, + ClipboardEventInterfaceType = 53, + CloseEventInterfaceType = 54, + CompositionEventInterfaceType = 55, + CustomEventInterfaceType = 56, + DragEventInterfaceType = 57, + ErrorEventInterfaceType = 58, + EventInterfaceType = 59, + FocusEventInterfaceType = 60, + FormDataEventInterfaceType = 61, + HashChangeEventInterfaceType = 62, + IDBVersionChangeEventInterfaceType = 63, + InputEventInterfaceType = 64, + KeyboardEventInterfaceType = 65, + MediaQueryListEventInterfaceType = 66, + MessageEventInterfaceType = 67, + MouseEventInterfaceType = 68, + MutationEventInterfaceType = 69, + OverflowEventInterfaceType = 70, + PageTransitionEventInterfaceType = 71, + PointerEventInterfaceType = 72, + PopStateEventInterfaceType = 73, + ProgressEventInterfaceType = 74, + PromiseRejectionEventInterfaceType = 75, + SVGZoomEventInterfaceType = 76, + SecurityPolicyViolationEventInterfaceType = 77, + SpeechRecognitionErrorEventInterfaceType = 78, + SpeechRecognitionEventInterfaceType = 79, + StorageEventInterfaceType = 80, + SubmitEventInterfaceType = 81, + TextEventInterfaceType = 82, + TransitionEventInterfaceType = 83, + UIEventInterfaceType = 84, + WheelEventInterfaceType = 85, + XMLHttpRequestProgressEventInterfaceType = 86, +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventListener.h b/src/bun.js/bindings/webcore/EventListener.h new file mode 100644 index 000000000..7ceb38b1e --- /dev/null +++ b/src/bun.js/bindings/webcore/EventListener.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2006-2021 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +#include <wtf/RefCounted.h> +#include <wtf/WeakPtr.h> + +namespace JSC { +class AbstractSlotVisitor; +class JSObject; +class SlotVisitor; +} + +namespace WebCore { + +class ScriptExecutionContext; +class Event; +class EventTarget; + +class EventListener : public RefCounted<EventListener>, public CanMakeWeakPtr<EventListener> { +public: + enum Type { + JSEventListenerType, + ImageEventListenerType, + ObjCEventListenerType, + CPPEventListenerType, + ConditionEventListenerType, + GObjectEventListenerType, + NativeEventListenerType, + SVGTRefTargetEventListenerType, + PDFDocumentEventListenerType, + }; + + virtual ~EventListener() = default; + virtual bool operator==(const EventListener&) const = 0; + virtual void handleEvent(ScriptExecutionContext&, Event&) = 0; + + virtual void visitJSFunction(JSC::AbstractSlotVisitor&) { } + virtual void visitJSFunction(JSC::SlotVisitor&) { } + + virtual bool isAttribute() const { return false; } + Type type() const { return m_type; } + +#if ASSERT_ENABLED + virtual void checkValidityForEventTarget(EventTarget&) { } +#endif + + virtual JSC::JSObject* jsFunction() const { return nullptr; } + virtual JSC::JSObject* wrapper() const { return nullptr; } + +protected: + explicit EventListener(Type type) + : m_type(type) + { + } + +private: + Type m_type; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventListener.idl b/src/bun.js/bindings/webcore/EventListener.idl new file mode 100644 index 000000000..5813a3500 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventListener.idl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006 Apple Inc. + * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://dom.spec.whatwg.org/#callbackdef-eventlistener +// FIXME: This should be a callback interface. +[ + LegacyNoInterfaceObject +] interface EventListener { + undefined handleEvent(Event event); +}; diff --git a/src/bun.js/bindings/webcore/EventListenerMap.cpp b/src/bun.js/bindings/webcore/EventListenerMap.cpp new file mode 100644 index 000000000..5014cfa00 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventListenerMap.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2001 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2011 Andreas Kling (kling@webkit.org) + * + * 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 "EventListenerMap.h" + +#include "AddEventListenerOptions.h" +#include "Event.h" +#include "EventTarget.h" +#include "JSEventListener.h" +#include <wtf/MainThread.h> +#include <wtf/StdLibExtras.h> +#include <wtf/Vector.h> + + +namespace WebCore { + +EventListenerMap::EventListenerMap() = default; + +bool EventListenerMap::containsCapturing(const AtomString& eventType) const +{ + auto* listeners = find(eventType); + if (!listeners) + return false; + + for (auto& eventListener : *listeners) { + if (eventListener->useCapture()) + return true; + } + return false; +} + +bool EventListenerMap::containsActive(const AtomString& eventType) const +{ + auto* listeners = find(eventType); + if (!listeners) + return false; + + for (auto& eventListener : *listeners) { + if (!eventListener->isPassive()) + return true; + } + return false; +} + +void EventListenerMap::clear() +{ + Locker locker { m_lock }; + + for (auto& entry : m_entries) { + for (auto& listener : entry.second) + listener->markAsRemoved(); + } + + m_entries.clear(); +} + +Vector<AtomString> EventListenerMap::eventTypes() const +{ + return m_entries.map([](auto& entry) { + return entry.first; + }); +} + +static inline size_t findListener(const EventListenerVector& listeners, EventListener& listener, bool useCapture) +{ + for (size_t i = 0; i < listeners.size(); ++i) { + auto& registeredListener = listeners[i]; + if (registeredListener->callback() == listener && registeredListener->useCapture() == useCapture) + return i; + } + return notFound; +} + +void EventListenerMap::replace(const AtomString& eventType, EventListener& oldListener, Ref<EventListener>&& newListener, const RegisteredEventListener::Options& options) +{ + Locker locker { m_lock }; + + auto* listeners = find(eventType); + ASSERT(listeners); + size_t index = findListener(*listeners, oldListener, options.capture); + ASSERT(index != notFound); + auto& registeredListener = listeners->at(index); + registeredListener->markAsRemoved(); + registeredListener = RegisteredEventListener::create(WTFMove(newListener), options); +} + +bool EventListenerMap::add(const AtomString& eventType, Ref<EventListener>&& listener, const RegisteredEventListener::Options& options) +{ + Locker locker { m_lock }; + + if (auto* listeners = find(eventType)) { + if (findListener(*listeners, listener, options.capture) != notFound) + return false; // Duplicate listener. + listeners->append(RegisteredEventListener::create(WTFMove(listener), options)); + return true; + } + + m_entries.append({ eventType, EventListenerVector { RegisteredEventListener::create(WTFMove(listener), options) } }); + return true; +} + +static bool removeListenerFromVector(EventListenerVector& listeners, EventListener& listener, bool useCapture) +{ + size_t indexOfRemovedListener = findListener(listeners, listener, useCapture); + if (UNLIKELY(indexOfRemovedListener == notFound)) + return false; + + listeners[indexOfRemovedListener]->markAsRemoved(); + listeners.remove(indexOfRemovedListener); + return true; +} + +bool EventListenerMap::remove(const AtomString& eventType, EventListener& listener, bool useCapture) +{ + Locker locker { m_lock }; + + for (unsigned i = 0; i < m_entries.size(); ++i) { + if (m_entries[i].first == eventType) { + bool wasRemoved = removeListenerFromVector(m_entries[i].second, listener, useCapture); + if (m_entries[i].second.isEmpty()) + m_entries.remove(i); + return wasRemoved; + } + } + + return false; +} + +EventListenerVector* EventListenerMap::find(const AtomString& eventType) +{ + for (auto& entry : m_entries) { + if (entry.first == eventType) + return &entry.second; + } + + return nullptr; +} + +static void removeFirstListenerCreatedFromMarkup(EventListenerVector& listenerVector) +{ + bool foundListener = listenerVector.removeFirstMatching([] (const auto& registeredListener) { + if (JSEventListener::wasCreatedFromMarkup(registeredListener->callback())) { + registeredListener->markAsRemoved(); + return true; + } + return false; + }); + ASSERT_UNUSED(foundListener, foundListener); +} + +void EventListenerMap::removeFirstEventListenerCreatedFromMarkup(const AtomString& eventType) +{ + Locker locker { m_lock }; + + for (unsigned i = 0; i < m_entries.size(); ++i) { + if (m_entries[i].first == eventType) { + removeFirstListenerCreatedFromMarkup(m_entries[i].second); + if (m_entries[i].second.isEmpty()) + m_entries.remove(i); + return; + } + } +} + +static void copyListenersNotCreatedFromMarkupToTarget(const AtomString& eventType, EventListenerVector& listenerVector, EventTarget* target) +{ + for (auto& registeredListener : listenerVector) { + // Event listeners created from markup have already been transfered to the shadow tree during cloning. + if (JSEventListener::wasCreatedFromMarkup(registeredListener->callback())) + continue; + target->addEventListener(eventType, registeredListener->callback(), registeredListener->useCapture()); + } +} + +void EventListenerMap::copyEventListenersNotCreatedFromMarkupToTarget(EventTarget* target) +{ + for (auto& entry : m_entries) + copyListenersNotCreatedFromMarkupToTarget(entry.first, entry.second, target); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventListenerMap.h b/src/bun.js/bindings/webcore/EventListenerMap.h new file mode 100644 index 000000000..d5b83c220 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventListenerMap.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2001 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2011 Andreas Kling (kling@webkit.org) + * + * 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. + * + */ + +#pragma once + +#include "RegisteredEventListener.h" +#include <atomic> +#include <memory> +#include <wtf/Forward.h> +#include <wtf/Lock.h> +#include <wtf/text/AtomString.h> + +namespace WebCore { + +class EventTarget; + +using EventListenerVector = Vector<RefPtr<RegisteredEventListener>, 1, CrashOnOverflow, 2>; + +class EventListenerMap { +public: + EventListenerMap(); + + bool isEmpty() const { return m_entries.isEmpty(); } + bool contains(const AtomString& eventType) const { return find(eventType); } + bool containsCapturing(const AtomString& eventType) const; + bool containsActive(const AtomString& eventType) const; + + void clear(); + + void replace(const AtomString& eventType, EventListener& oldListener, Ref<EventListener>&& newListener, const RegisteredEventListener::Options&); + bool add(const AtomString& eventType, Ref<EventListener>&&, const RegisteredEventListener::Options&); + bool remove(const AtomString& eventType, EventListener&, bool useCapture); + WEBCORE_EXPORT EventListenerVector* find(const AtomString& eventType); + const EventListenerVector* find(const AtomString& eventType) const { return const_cast<EventListenerMap*>(this)->find(eventType); } + Vector<AtomString> eventTypes() const; + + void removeFirstEventListenerCreatedFromMarkup(const AtomString& eventType); + void copyEventListenersNotCreatedFromMarkupToTarget(EventTarget*); + + template<typename Visitor> void visitJSEventListeners(Visitor&); + Lock& lock() { return m_lock; } + +private: + Vector<std::pair<AtomString, EventListenerVector>> m_entries; + Lock m_lock; +}; + +template<typename Visitor> +void EventListenerMap::visitJSEventListeners(Visitor& visitor) +{ + Locker locker { m_lock }; + for (auto& entry : m_entries) { + for (auto& eventListener : entry.second) + eventListener->callback().visitJSFunction(visitor); + } +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventListenerOptions.h b/src/bun.js/bindings/webcore/EventListenerOptions.h new file mode 100644 index 000000000..101b44bce --- /dev/null +++ b/src/bun.js/bindings/webcore/EventListenerOptions.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016-2020 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. + */ + +#pragma once + +namespace WebCore { + +struct EventListenerOptions { + EventListenerOptions(bool capture = false) + : capture(capture) + { } + + bool capture { false }; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventListenerOptions.idl b/src/bun.js/bindings/webcore/EventListenerOptions.idl new file mode 100644 index 000000000..70bb94225 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventListenerOptions.idl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016-2020 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. + */ + +dictionary EventListenerOptions { + boolean capture = false; +}; diff --git a/src/bun.js/bindings/webcore/EventModifierInit.h b/src/bun.js/bindings/webcore/EventModifierInit.h new file mode 100644 index 000000000..82fe54e17 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventModifierInit.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 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 "UIEventInit.h" + +namespace WebCore { + +struct EventModifierInit : UIEventInit { + bool ctrlKey { false }; + bool shiftKey { false }; + bool altKey { false }; + bool metaKey { false }; + + bool modifierAltGraph { false }; + bool modifierCapsLock { false }; +}; + +} diff --git a/src/bun.js/bindings/webcore/EventNames.cpp b/src/bun.js/bindings/webcore/EventNames.cpp new file mode 100644 index 000000000..42c4eb1cf --- /dev/null +++ b/src/bun.js/bindings/webcore/EventNames.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2005, 2015 Apple Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "EventNames.h" + +namespace WebCore { + +#define INITIALIZE_EVENT_NAME(name) \ + name##Event(makeAtomString(#name)), + +EventNames::EventNames() + : DOM_EVENT_NAMES_FOR_EACH(INITIALIZE_EVENT_NAME) dummy(0) +{ +} + +thread_local std::unique_ptr<EventNames> eventNames_; + +const EventNames& eventNames() +{ + if (!eventNames_) + eventNames_ = EventNames::create(); + return *eventNames_; +} + +} diff --git a/src/bun.js/bindings/webcore/EventNames.h b/src/bun.js/bindings/webcore/EventNames.h new file mode 100644 index 000000000..ebd451814 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventNames.h @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2005, 2007, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2006 Jon Shier (jshier@iastate.edu) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +// #include "ThreadGlobalData.h" +#include "EventTarget.h" +#include <array> +#include <functional> +#include <wtf/text/AtomString.h> + +namespace WebCore { + +#define DOM_EVENT_NAMES_FOR_EACH(macro) \ + macro(error) \ + macro(abort) \ + macro(close) \ + macro(open) \ + macro(message) \ + macro(messageerror) + +// macro(DOMActivate) \ + // macro(DOMCharacterDataModified) \ + // macro(DOMContentLoaded) \ + // macro(DOMNodeInserted) \ + // macro(DOMNodeInsertedIntoDocument) \ + // macro(DOMNodeRemoved) \ + // macro(DOMNodeRemovedFromDocument) \ + // macro(DOMSubtreeModified) \ + // macro(abort) \ + // macro(activate) \ + // macro(active) \ + // macro(addsourcebuffer) \ + // macro(addstream) \ + // macro(addtrack) \ + // macro(afterprint) \ + // macro(animationcancel) \ + // macro(animationend) \ + // macro(animationiteration) \ + // macro(animationstart) \ + // macro(audioend) \ + // macro(audioprocess) \ + // macro(audiostart) \ + // macro(autocomplete) \ + // macro(autocompleteerror) \ + // macro(beforecopy) \ + // macro(beforecut) \ + // macro(beforeinput) \ + // macro(beforeload) \ + // macro(beforepaste) \ + // macro(beforeprint) \ + // macro(beforeunload) \ + // macro(beginEvent) \ + // macro(blocked) \ + // macro(blur) \ + // macro(boundary) \ + // macro(bufferedamountlow) \ + // macro(cached) \ + // macro(cancel) \ + // macro(canplay) \ + // macro(canplaythrough) \ + // macro(change) \ + // macro(chargingchange) \ + // macro(chargingtimechange) \ + // macro(checking) \ + // macro(click) \ + // macro(close) \ + // macro(closing) \ + // macro(complete) \ + // macro(compositionend) \ + // macro(compositionstart) \ + // macro(compositionupdate) \ + // macro(connect) \ + // macro(connectionstatechange) \ + // macro(connecting) \ + // macro(contextmenu) \ + // macro(controllerchange) \ + // macro(coordinatorstatechange) \ + // macro(copy) \ + // macro(cuechange) \ + // macro(cut) \ + // macro(dataavailable) \ + // macro(datachannel) \ + // macro(dblclick) \ + // macro(devicechange) \ + // macro(devicemotion) \ + // macro(deviceorientation) \ + // macro(dischargingtimechange) \ + // macro(disconnect) \ + // macro(downloading) \ + // macro(drag) \ + // macro(dragend) \ + // macro(dragenter) \ + // macro(dragleave) \ + // macro(dragover) \ + // macro(dragstart) \ + // macro(drop) \ + // macro(durationchange) \ + // macro(emptied) \ + // macro(encrypted) \ + // macro(end) \ + // macro(endEvent) \ + // macro(ended) \ + // macro(enter) \ + // macro(enterpictureinpicture) \ + // macro(error) \ + // macro(exit) \ + // macro(fetch) \ + // macro(finish) \ + // macro(focus) \ + // macro(focusin) \ + // macro(focusout) \ + // macro(formdata) \ + // macro(gamepadconnected) \ + // macro(gamepaddisconnected) \ + // macro(gatheringstatechange) \ + // macro(gesturechange) \ + // macro(gestureend) \ + // macro(gesturescrollend) \ + // macro(gesturescrollstart) \ + // macro(gesturescrollupdate) \ + // macro(gesturestart) \ + // macro(gesturetap) \ + // macro(gesturetapdown) \ + // macro(gotpointercapture) \ + // macro(hashchange) \ + // macro(icecandidate) \ + // macro(icecandidateerror) \ + // macro(iceconnectionstatechange) \ + // macro(icegatheringstatechange) \ + // macro(inactive) \ + // macro(input) \ + // macro(inputsourceschange) \ + // macro(install) \ + // macro(invalid) \ + // macro(keydown) \ + // macro(keypress) \ + // macro(keystatuseschange) \ + // macro(keyup) \ + // macro(languagechange) \ + // macro(leavepictureinpicture) \ + // macro(levelchange) \ + // macro(load) \ + // macro(loadeddata) \ + // macro(loadedmetadata) \ + // macro(loadend) \ + // macro(loading) \ + // macro(loadingdone) \ + // macro(loadingerror) \ + // macro(loadstart) \ + // macro(lostpointercapture) \ + // macro(mark) \ + // macro(merchantvalidation) \ + // macro(message) \ + // macro(messageerror) \ + // macro(mousedown) \ + // macro(mouseenter) \ + // macro(mouseleave) \ + // macro(mousemove) \ + // macro(mouseout) \ + // macro(mouseover) \ + // macro(mouseup) \ + // macro(mousewheel) \ + // macro(mute) \ + // macro(negotiationneeded) \ + // macro(nexttrack) \ + // macro(nomatch) \ + // macro(notificationclick) \ + // macro(notificationclose) \ + // macro(noupdate) \ + // macro(obsolete) \ + // macro(offline) \ + // macro(online) \ + // macro(orientationchange) \ + // macro(overflowchanged) \ + // macro(pagehide) \ + // macro(pageshow) \ + // macro(paste) \ + // macro(pause) \ + // macro(payerdetailchange) \ + // macro(paymentauthorized) \ + // macro(paymentmethodchange) \ + // macro(paymentmethodselected) \ + // macro(play) \ + // macro(playing) \ + // macro(pointerlockchange) \ + // macro(pointerlockerror) \ + // macro(pointercancel) \ + // macro(pointerdown) \ + // macro(pointerenter) \ + // macro(pointerleave) \ + // macro(pointermove) \ + // macro(pointerout) \ + // macro(pointerover) \ + // macro(pointerup) \ + // macro(popstate) \ + // macro(previoustrack) \ + // macro(processorerror) \ + // macro(progress) \ + // macro(push) \ + // macro(pushsubscriptionchange) \ + // macro(ratechange) \ + // macro(readystatechange) \ + // macro(rejectionhandled) \ + // macro(remove) \ + // macro(removesourcebuffer) \ + // macro(removestream) \ + // macro(removetrack) \ + // macro(reset) \ + // macro(resize) \ + // macro(resourcetimingbufferfull) \ + // macro(result) \ + // macro(resume) \ + // macro(rtctransform) \ + // macro(scroll) \ + // macro(search) \ + // macro(securitypolicyviolation) \ + // macro(seeked) \ + // macro(seeking) \ + // macro(select) \ + // macro(selectend) \ + // macro(selectionchange) \ + // macro(selectstart) \ + // macro(shippingaddresschange) \ + // macro(shippingcontactselected) \ + // macro(shippingmethodselected) \ + // macro(shippingoptionchange) \ + // macro(show) \ + // macro(signalingstatechange) \ + // macro(slotchange) \ + // macro(soundend) \ + // macro(soundstart) \ + // macro(sourceclose) \ + // macro(sourceended) \ + // macro(sourceopen) \ + // macro(speechend) \ + // macro(speechstart) \ + // macro(squeeze) \ + // macro(squeezestart) \ + // macro(squeezeend) \ + // macro(stalled) \ + // macro(start) \ + // macro(started) \ + // macro(statechange) \ + // macro(stop) \ + // macro(storage) \ + // macro(submit) \ + // macro(success) \ + // macro(suspend) \ + // macro(textInput) \ + // macro(timeout) \ + // macro(timeupdate) \ + // macro(toggle) \ + // macro(tonechange) \ + // macro(touchcancel) \ + // macro(touchend) \ + // macro(touchforcechange) \ + // macro(touchmove) \ + // macro(touchstart) \ + // macro(track) \ + // macro(transitioncancel) \ + // macro(transitionend) \ + // macro(transitionrun) \ + // macro(transitionstart) \ + // macro(uncapturederror) \ + // macro(unhandledrejection) \ + // macro(unload) \ + // macro(unmute) \ + // macro(update) \ + // macro(updateend) \ + // macro(updatefound) \ + // macro(updateready) \ + // macro(updatestart) \ + // macro(upgradeneeded) \ + // macro(validatemerchant) \ + // macro(versionchange) \ + // macro(visibilitychange) \ + // macro(voiceschanged) \ + // macro(volumechange) \ + // macro(waiting) \ + // macro(waitingforkey) \ + // macro(webglcontextchanged) \ + // macro(webglcontextcreationerror) \ + // macro(webglcontextlost) \ + // macro(webglcontextrestored) \ + // macro(webkitAnimationEnd) \ + // macro(webkitAnimationIteration) \ + // macro(webkitAnimationStart) \ + // macro(webkitBeforeTextInserted) \ + // macro(webkitTransitionEnd) \ + // macro(webkitbeginfullscreen) \ + // macro(webkitcurrentplaybacktargetiswirelesschanged) \ + // macro(webkitendfullscreen) \ + // macro(webkitfullscreenchange) \ + // macro(webkitfullscreenerror) \ + // macro(webkitkeyadded) \ + // macro(webkitkeyerror) \ + // macro(webkitkeymessage) \ + // macro(webkitmouseforcechanged) \ + // macro(webkitmouseforcedown) \ + // macro(webkitmouseforcewillbegin) \ + // macro(webkitmouseforceup) \ + // macro(webkitneedkey) \ + // macro(webkitnetworkinfochange) \ + // macro(webkitplaybacktargetavailabilitychanged) \ + // macro(webkitpresentationmodechanged) \ + // macro(webkitremovesourcebuffer) \ + // macro(webkitsourceclose) \ + // macro(webkitsourceended) \ + // macro(webkitsourceopen) \ + macro(wheel) \ + macro(write) \ + macro(writeend) \ + macro(writestart) \ + macro(zoom) \ +// end of DOM_EVENT_NAMES_FOR_EACH + +struct EventNames { + WTF_MAKE_NONCOPYABLE(EventNames); + WTF_MAKE_FAST_ALLOCATED; + +public: +#define DOM_EVENT_NAMES_DECLARE(name) const AtomString name##Event; + DOM_EVENT_NAMES_FOR_EACH(DOM_EVENT_NAMES_DECLARE) +#undef DOM_EVENT_NAMES_DECLARE + + // FIXME: The friend declaration to makeUnique below does not work in windows port. + // + // template<class T, class... Args> + // friend typename std::_Unique_if<T>::_Single_object makeUnique(Args&&...); + // + // This create function should be deleted later and is only for keeping EventNames as private. + // makeUnique should be used instead. + // + template<class... Args> + static std::unique_ptr<EventNames> create(Args&&... args) + { + return std::unique_ptr<EventNames>(new EventNames(std::forward<Args>(args)...)); + } + + // FIXME: Inelegant to call these both event names and event types. + // We should choose one term and stick to it. + bool isWheelEventType(const AtomString& eventType) const; + bool isGestureEventType(const AtomString& eventType) const; + bool isTouchRelatedEventType(const AtomString& eventType, EventTarget&) const; + bool isTouchScrollBlockingEventType(const AtomString& eventType) const; +#if ENABLE(GAMEPAD) + bool isGamepadEventType(const AtomString& eventType) const; +#endif + + std::array<std::reference_wrapper<const AtomString>, 0> touchRelatedEventNames() const; + std::array<std::reference_wrapper<const AtomString>, 0> extendedTouchRelatedEventNames() const; + std::array<std::reference_wrapper<const AtomString>, 0> gestureEventNames() const; + +private: + EventNames(); // Private to prevent accidental call to EventNames() instead of eventNames(). + // friend class ThreadGlobalData; // Allow ThreadGlobalData to create the per-thread EventNames object. + + int dummy; // Needed to make initialization macro work. +}; + +const EventNames& eventNames(); + +inline bool EventNames::isGestureEventType(const AtomString& eventType) const +{ + return false; // eventType == gesturestartEvent || eventType == gesturechangeEvent || eventType == gestureendEvent; +} + +inline bool EventNames::isTouchScrollBlockingEventType(const AtomString& eventType) const +{ + return false; +} + +inline bool EventNames::isTouchRelatedEventType(const AtomString& eventType, EventTarget& target) const +{ + return false; +} + +inline bool EventNames::isWheelEventType(const AtomString& eventType) const +{ + return false; +} + +inline std::array<std::reference_wrapper<const AtomString>, 0> EventNames::touchRelatedEventNames() const +{ + return { {} }; +} + +inline std::array<std::reference_wrapper<const AtomString>, 0> EventNames::extendedTouchRelatedEventNames() const +{ + return { {} }; +} + +inline std::array<std::reference_wrapper<const AtomString>, 0> EventNames::gestureEventNames() const +{ + return { {} }; +} + +// inline std::array<std::reference_wrapper<const AtomString>, 13> EventNames::touchRelatedEventNames() const +// { +// return { { touchstartEvent, touchmoveEvent, touchendEvent, touchcancelEvent, touchforcechangeEvent, pointeroverEvent, pointerenterEvent, pointerdownEvent, pointermoveEvent, pointerupEvent, pointeroutEvent, pointerleaveEvent, pointercancelEvent } }; +// } + +// inline std::array<std::reference_wrapper<const AtomString>, 16> EventNames::extendedTouchRelatedEventNames() const +// { +// return { { touchstartEvent, touchmoveEvent, touchendEvent, touchcancelEvent, touchforcechangeEvent, pointeroverEvent, pointerenterEvent, pointerdownEvent, pointermoveEvent, pointerupEvent, pointeroutEvent, pointerleaveEvent, pointercancelEvent, mousedownEvent, mousemoveEvent, mouseupEvent } }; +// } + +// inline std::array<std::reference_wrapper<const AtomString>, 3> EventNames::gestureEventNames() const +// { +// return { { gesturestartEvent, gesturechangeEvent, gestureendEvent } }; +// } + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventNames.in b/src/bun.js/bindings/webcore/EventNames.in new file mode 100644 index 000000000..8c0fb6072 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventNames.in @@ -0,0 +1,101 @@ +namespace="Event" +factoryFunction=toNewlyCreated +useNamespaceAsSuffix=false + +Event +Events interfaceName=Event +HTMLEvents interfaceName=Event +AnimationEvent +AnimationPlaybackEvent +BeforeLoadEvent interfaceName=Event +BeforeUnloadEvent +ClipboardEvent +CloseEvent +CompositionEvent +CustomEvent +DragEvent +ExtendableEvent conditional=SERVICE_WORKER +ExtendableMessageEvent conditional=SERVICE_WORKER +ErrorEvent +FetchEvent conditional=SERVICE_WORKER +FocusEvent +FormDataEvent +HashChangeEvent +InputEvent +InputEvents interfaceName=InputEvent +KeyboardEvent +KeyboardEvents interfaceName=KeyboardEvent +MediaQueryListEvent +MessageEvent +MouseEvent +MouseEvents interfaceName=MouseEvent +MutationEvent +MutationEvents interfaceName=MutationEvent +OverflowEvent +PageTransitionEvent +PopStateEvent +ProgressEvent +PromiseRejectionEvent +PushEvent conditional=SERVICE_WORKER +PushSubscriptionChangeEvent conditional=SERVICE_WORKER +SubmitEvent +TextEvent +TransitionEvent +UIEvent +UIEvents interfaceName=UIEvent +WheelEvent +XMLHttpRequestProgressEvent +ApplePayCancelEvent conditional=APPLE_PAY +ApplePayCouponCodeChangedEvent conditional=APPLE_PAY_COUPON_CODE +ApplePayPaymentAuthorizedEvent conditional=APPLE_PAY +ApplePayPaymentMethodSelectedEvent conditional=APPLE_PAY +ApplePayShippingContactSelectedEvent conditional=APPLE_PAY +ApplePayShippingMethodSelectedEvent conditional=APPLE_PAY +ApplePayValidateMerchantEvent conditional=APPLE_PAY +AudioProcessingEvent conditional=WEB_AUDIO +BlobEvent conditional=MEDIA_RECORDER +OfflineAudioCompletionEvent conditional=WEB_AUDIO +MediaRecorderErrorEvent conditional=MEDIA_RECORDER +MediaStreamTrackEvent conditional=MEDIA_STREAM +MerchantValidationEvent conditional=PAYMENT_REQUEST +PaymentMethodChangeEvent conditional=PAYMENT_REQUEST +PaymentRequestUpdateEvent conditional=PAYMENT_REQUEST +RTCErrorEvent conditional=WEB_RTC +RTCPeerConnectionIceErrorEvent conditional=WEB_RTC +RTCPeerConnectionIceEvent conditional=WEB_RTC +RTCDataChannelEvent conditional=WEB_RTC +RTCDTMFToneChangeEvent conditional=WEB_RTC +RTCRtpSFrameTransformErrorEvent conditional=WEB_RTC +RTCTrackEvent conditional=WEB_RTC +RTCTransformEvent conditional=WEB_RTC +SpeechRecognitionErrorEvent +SpeechRecognitionEvent +SpeechSynthesisErrorEvent conditional=SPEECH_SYNTHESIS +SpeechSynthesisEvent conditional=SPEECH_SYNTHESIS +WebGLContextEvent conditional=WEBGL +StorageEvent +SVGEvents interfaceName=Event +SVGZoomEvent +SVGZoomEvents interfaceName=SVGZoomEvent +IDBVersionChangeEvent +TouchEvent conditional=TOUCH_EVENTS +DeviceMotionEvent conditional=DEVICE_ORIENTATION +DeviceOrientationEvent conditional=DEVICE_ORIENTATION +OrientationEvent interfaceName=Event, conditional=ORIENTATION_EVENTS +WebKitMediaKeyMessageEvent conditional=LEGACY_ENCRYPTED_MEDIA +WebKitMediaKeyNeededEvent conditional=LEGACY_ENCRYPTED_MEDIA +TrackEvent conditional=VIDEO +SecurityPolicyViolationEvent +GestureEvent conditional=IOS_GESTURE_EVENTS|MAC_GESTURE_EVENTS +WebKitPlaybackTargetAvailabilityEvent conditional=WIRELESS_PLAYBACK_TARGET +GamepadEvent conditional=GAMEPAD +OverconstrainedErrorEvent conditional=MEDIA_STREAM +MediaEncryptedEvent conditional=ENCRYPTED_MEDIA +MediaKeyMessageEvent conditional=ENCRYPTED_MEDIA +PointerEvent +PictureInPictureEvent conditional=PICTURE_IN_PICTURE_API +XRInputSourceEvent conditional=WEBXR +XRInputSourcesChangeEvent conditional=WEBXR +XRReferenceSpaceEvent conditional=WEBXR +XRSessionEvent conditional=WEBXR +NotificationEvent conditional=NOTIFICATION_EVENT diff --git a/src/bun.js/bindings/webcore/EventOptions.h b/src/bun.js/bindings/webcore/EventOptions.h new file mode 100644 index 000000000..ec59b6980 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventOptions.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 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 + +namespace WebCore { + +enum class EventIsTrusted : bool { No, Yes }; +enum class EventCanBubble : bool { No, Yes }; +enum class EventIsCancelable : bool { No, Yes }; +enum class EventIsComposed : bool { No, Yes }; + +} diff --git a/src/bun.js/bindings/webcore/EventPath.cpp b/src/bun.js/bindings/webcore/EventPath.cpp new file mode 100644 index 000000000..30dbb5de9 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventPath.cpp @@ -0,0 +1,423 @@ +// /* +// * Copyright (C) 2013 Google Inc. All rights reserved. +// * Copyright (C) 2013-2022 Apple Inc. All rights reserved. +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Library General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Library General Public License for more details. +// * +// * You should have received a copy of the GNU Library General Public License +// * along with this library; see the file COPYING.LIB. If not, write to +// * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// * Boston, MA 02110-1301, USA. +// */ + +// #include "config.h" +// #include "EventPath.h" + +// // #include "DOMWindow.h" +// #include "Event.h" +// #include "EventContext.h" +// #include "EventNames.h" +// // #include "FullscreenManager.h" +// // #include "HTMLSlotElement.h" +// // #include "MouseEvent.h" +// #include "Node.h" +// // #include "PseudoElement.h" +// // #include "ShadowRoot.h" +// // #include "TouchEvent.h" + +// namespace WebCore { + +// static inline bool shouldEventCrossShadowBoundary(Event& event, ShadowRoot& shadowRoot, EventTarget& target) +// { +// // #if ENABLE(FULLSCREEN_API) && ENABLE(VIDEO) +// // // Video-only full screen is a mode where we use the shadow DOM as an implementation +// // // detail that should not be detectable by the web content. +// // if (is<Node>(target)) { +// // if (auto* element = downcast<Node>(target).document().fullscreenManager().currentFullscreenElement()) { +// // // FIXME: We assume that if the full screen element is a media element that it's +// // // the video-only full screen. Both here and elsewhere. But that is probably wrong. +// // if (element->isMediaElement() && shadowRoot.host() == element) +// // return false; +// // } +// // } +// // #endif + +// bool targetIsInShadowRoot = is<Node>(target) && &downcast<Node>(target).treeScope().rootNode() == &shadowRoot; +// return !targetIsInShadowRoot || event.composed(); +// } + +// static Node* nodeOrHostIfPseudoElement(Node* node) +// { +// retur nnode; +// // return is<PseudoElement>(*node) ? downcast<PseudoElement>(*node).hostElement() : node; +// } + +// class RelatedNodeRetargeter { +// public: +// RelatedNodeRetargeter(Node& relatedNode, Node& target); + +// Node* currentNode(Node& currentTreeScope); +// void moveToNewTreeScope(TreeScope* previousTreeScope, TreeScope& newTreeScope); + +// private: +// Node* nodeInLowestCommonAncestor(); +// void collectTreeScopes(); + +// void checkConsistency(Node& currentTarget); + +// Node& m_relatedNode; +// Node* m_retargetedRelatedNode; +// Vector<TreeScope*, 8> m_ancestorTreeScopes; +// unsigned m_lowestCommonAncestorIndex { 0 }; +// bool m_hasDifferentTreeRoot { false }; +// }; + +// EventPath::EventPath(Node& originalTarget, Event& event) +// { +// buildPath(originalTarget, event); + +// if (auto* relatedTarget = event.relatedTarget(); is<Node>(relatedTarget) && !m_path.isEmpty()) +// setRelatedTarget(originalTarget, downcast<Node>(*relatedTarget)); + +// #if ENABLE(TOUCH_EVENTS) +// if (is<TouchEvent>(event)) +// retargetTouchLists(downcast<TouchEvent>(event)); +// #endif +// } + +// void EventPath::buildPath(Node& originalTarget, Event& event) +// { +// UNUSED_PARAM(originalTarget); +// UNUSED_PARAM(event); +// // EventContext::Type contextType = [&]() { +// // if (is<MouseEvent>(event) || event.isFocusEvent()) +// // return EventContext::Type::MouseOrFocus; +// // #if ENABLE(TOUCH_EVENTS) +// // if (is<TouchEvent>(event)) +// // return EventContext::Type::Touch; +// // #endif +// // return EventContext::Type::Normal; +// // }(); + +// // Node* node = nodeOrHostIfPseudoElement(&originalTarget); +// // Node* target = node ? eventTargetRespectingTargetRules(*node) : nullptr; +// // int closedShadowDepth = 0; +// // // Depths are used to decided which nodes are excluded in event.composedPath when the tree is mutated during event dispatching. +// // // They could be negative for nodes outside the shadow tree of the target node. +// // while (node) { +// // while (node) { +// // m_path.append(EventContext { contextType, *node, eventTargetRespectingTargetRules(*node), target, closedShadowDepth }); + +// // if (is<ShadowRoot>(*node)) +// // break; + +// // ContainerNode* parent = node->parentNode(); +// // if (UNLIKELY(!parent)) { +// // // https://dom.spec.whatwg.org/#interface-document +// // if (is<Document>(*node) && event.type() != eventNames().loadEvent) { +// // ASSERT(target); +// // if (target) { +// // if (auto* window = downcast<Document>(*node).domWindow()) +// // m_path.append(EventContext { EventContext::Type::Window, node, window, target, closedShadowDepth }); +// // } +// // } +// // return; +// // } + +// // if (auto* shadowRootOfParent = parent->shadowRoot(); UNLIKELY(shadowRootOfParent)) { +// // if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) { +// // if (shadowRootOfParent->mode() != ShadowRootMode::Open) +// // closedShadowDepth++; +// // // node is assigned to a slot. Continue dispatching the event at this slot. +// // parent = assignedSlot; +// // } +// // } +// // node = parent; +// // } + +// // bool exitingShadowTreeOfTarget = &target->treeScope() == &node->treeScope(); +// // ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node); +// // if (!shouldEventCrossShadowBoundary(event, shadowRoot, originalTarget)) +// // return; +// // node = shadowRoot.host(); +// // if (shadowRoot.mode() != ShadowRootMode::Open) +// // closedShadowDepth--; +// // if (exitingShadowTreeOfTarget) +// // target = eventTargetRespectingTargetRules(*node); +// } +// } + +// void EventPath::setRelatedTarget(Node& origin, Node& relatedNode) +// { +// UNUSED_PARAM(origin); +// UNUSED_PARAM(relatedNode); +// // RelatedNodeRetargeter retargeter(relatedNode, *m_path[0].node()); + +// // bool originIsRelatedTarget = &origin == &relatedNode; +// // Node& rootNodeInOriginTreeScope = origin.treeScope().rootNode(); +// // TreeScope* previousTreeScope = nullptr; +// // size_t originalEventPathSize = m_path.size(); +// // for (unsigned contextIndex = 0; contextIndex < originalEventPathSize; contextIndex++) { +// // auto& context = m_path[contextIndex]; +// // if (!context.isMouseOrFocusEventContext()) { +// // ASSERT(context.isWindowContext()); +// // continue; +// // } + +// // Node& currentTarget = *context.node(); +// // TreeScope& currentTreeScope = currentTarget.treeScope(); +// // if (UNLIKELY(previousTreeScope && ¤tTreeScope != previousTreeScope)) +// // retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope); + +// // Node* currentRelatedNode = retargeter.currentNode(currentTarget); +// // if (UNLIKELY(!originIsRelatedTarget && context.target() == currentRelatedNode)) { +// // m_path.shrink(contextIndex); +// // break; +// // } + +// // context.setRelatedTarget(currentRelatedNode); + +// // if (UNLIKELY(originIsRelatedTarget && context.node() == &rootNodeInOriginTreeScope)) { +// // m_path.shrink(contextIndex + 1); +// // break; +// // } + +// // previousTreeScope = ¤tTreeScope; +// // } +// } + +// #if ENABLE(TOUCH_EVENTS) + +// void EventPath::retargetTouch(EventContext::TouchListType type, const Touch& touch) +// { +// auto* eventTarget = touch.target(); +// if (!is<Node>(eventTarget)) +// return; + +// RelatedNodeRetargeter retargeter(downcast<Node>(*eventTarget), *m_path[0].node()); +// TreeScope* previousTreeScope = nullptr; +// for (auto& context : m_path) { +// Node& currentTarget = *context.node(); +// TreeScope& currentTreeScope = currentTarget.treeScope(); +// if (UNLIKELY(previousTreeScope && ¤tTreeScope != previousTreeScope)) +// retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope); + +// if (context.isTouchEventContext()) { +// Node* currentRelatedNode = retargeter.currentNode(currentTarget); +// context.touchList(type).append(touch.cloneWithNewTarget(currentRelatedNode)); +// } else +// ASSERT(context.isWindowContext()); + +// previousTreeScope = ¤tTreeScope; +// } +// } + +// void EventPath::retargetTouchList(EventContext::TouchListType type, const TouchList* list) +// { +// for (unsigned i = 0, length = list ? list->length() : 0; i < length; ++i) +// retargetTouch(type, *list->item(i)); +// } + +// void EventPath::retargetTouchLists(const TouchEvent& event) +// { +// retargetTouchList(EventContext::TouchListType::Touches, event.touches()); +// retargetTouchList(EventContext::TouchListType::TargetTouches, event.targetTouches()); +// retargetTouchList(EventContext::TouchListType::ChangedTouches, event.changedTouches()); +// } + +// #endif + +// // https://dom.spec.whatwg.org/#dom-event-composedpath +// // Any node whose depth computed in EventPath::buildPath is greater than the context object is excluded. +// // Because we can exit out of a closed shadow tree and re-enter another closed shadow tree via a slot, +// // we decrease the *allowed depth* whenever we moved to a "shallower" (closer-to-document) tree. +// Vector<EventTarget*> EventPath::computePathUnclosedToTarget(const EventTarget& target) const +// { +// Vector<EventTarget*> path; +// auto pathSize = m_path.size(); +// RELEASE_ASSERT(pathSize); +// path.reserveInitialCapacity(pathSize); + +// auto currentTargetIndex = m_path.findIf([&target](auto& context) { +// return context.currentTarget() == ⌖ +// }); +// RELEASE_ASSERT(currentTargetIndex != notFound); +// auto currentTargetDepth = m_path[currentTargetIndex].closedShadowDepth(); + +// auto appendTargetWithLesserDepth = [&path](const EventContext& currentContext, int& currentDepthAllowed) { +// auto depth = currentContext.closedShadowDepth(); +// bool contextIsInsideInnerShadowTree = depth > currentDepthAllowed; +// if (contextIsInsideInnerShadowTree) +// return; +// bool movedOutOfShadowTree = depth < currentDepthAllowed; +// if (movedOutOfShadowTree) +// currentDepthAllowed = depth; +// path.uncheckedAppend(currentContext.currentTarget()); +// }; + +// auto currentDepthAllowed = currentTargetDepth; +// auto i = currentTargetIndex; +// do { +// appendTargetWithLesserDepth(m_path[i], currentDepthAllowed); +// } while (i--); +// path.reverse(); + +// currentDepthAllowed = currentTargetDepth; +// for (auto i = currentTargetIndex + 1; i < pathSize; ++i) +// appendTargetWithLesserDepth(m_path[i], currentDepthAllowed); + +// return path; +// } + +// EventPath::EventPath(const Vector<EventTarget*>& targets) +// { +// m_path = targets.map([&](auto* target) { +// ASSERT(target); +// ASSERT(!is<Node>(target)); +// return EventContext { EventContext::Type::Normal, nullptr, target, *targets.begin(), 0 }; +// }); +// } + +// static Node* moveOutOfAllShadowRoots(Node& startingNode) +// { +// Node* node = &startingNode; +// while (node->isInShadowTree()) +// node = downcast<ShadowRoot>(node->treeScope().rootNode()).host(); +// return node; +// } + +// RelatedNodeRetargeter::RelatedNodeRetargeter(Node& relatedNode, Node& target) +// : m_relatedNode(relatedNode) +// , m_retargetedRelatedNode(&relatedNode) +// { +// auto& targetTreeScope = target.treeScope(); +// TreeScope* currentTreeScope = &m_relatedNode.treeScope(); +// if (LIKELY(currentTreeScope == &targetTreeScope && target.isConnected() && m_relatedNode.isConnected())) +// return; + +// if (¤tTreeScope->documentScope() != &targetTreeScope.documentScope()) { +// m_hasDifferentTreeRoot = true; +// m_retargetedRelatedNode = nullptr; +// return; +// } +// if (relatedNode.isConnected() != target.isConnected()) { +// m_hasDifferentTreeRoot = true; +// m_retargetedRelatedNode = moveOutOfAllShadowRoots(relatedNode); +// return; +// } + +// collectTreeScopes(); + +// // FIXME: We should collect this while constructing the event path. +// Vector<TreeScope*, 8> targetTreeScopeAncestors; +// for (TreeScope* currentTreeScope = &targetTreeScope; currentTreeScope; currentTreeScope = currentTreeScope->parentTreeScope()) +// targetTreeScopeAncestors.append(currentTreeScope); +// ASSERT_WITH_SECURITY_IMPLICATION(!targetTreeScopeAncestors.isEmpty()); + +// unsigned i = m_ancestorTreeScopes.size(); +// unsigned j = targetTreeScopeAncestors.size(); +// ASSERT_WITH_SECURITY_IMPLICATION(m_ancestorTreeScopes.last() == targetTreeScopeAncestors.last()); +// while (m_ancestorTreeScopes[i - 1] == targetTreeScopeAncestors[j - 1]) { +// i--; +// j--; +// if (!i || !j) +// break; +// } + +// bool lowestCommonAncestorIsDocumentScope = i + 1 == m_ancestorTreeScopes.size(); +// if (lowestCommonAncestorIsDocumentScope && !relatedNode.isConnected() && !target.isConnected()) { +// Node& relatedNodeAncestorInDocumentScope = i ? *downcast<ShadowRoot>(m_ancestorTreeScopes[i - 1]->rootNode()).shadowHost() : relatedNode; +// Node& targetAncestorInDocumentScope = j ? *downcast<ShadowRoot>(targetTreeScopeAncestors[j - 1]->rootNode()).shadowHost() : target; +// if (&targetAncestorInDocumentScope.rootNode() != &relatedNodeAncestorInDocumentScope.rootNode()) { +// m_hasDifferentTreeRoot = true; +// m_retargetedRelatedNode = moveOutOfAllShadowRoots(relatedNode); +// return; +// } +// } + +// m_lowestCommonAncestorIndex = i; +// m_retargetedRelatedNode = nodeInLowestCommonAncestor(); +// } + +// inline Node* RelatedNodeRetargeter::currentNode(Node& currentTarget) +// { +// checkConsistency(currentTarget); +// return m_retargetedRelatedNode; +// } + +// void RelatedNodeRetargeter::moveToNewTreeScope(TreeScope* previousTreeScope, TreeScope& newTreeScope) +// { +// if (m_hasDifferentTreeRoot) +// return; + +// auto& currentRelatedNodeScope = m_retargetedRelatedNode->treeScope(); +// if (previousTreeScope != ¤tRelatedNodeScope) { +// // currentRelatedNode is still outside our shadow tree. New tree scope may contain currentRelatedNode +// // but there is no need to re-target it. Moving into a slot (thereby a deeper shadow tree) doesn't matter. +// return; +// } + +// bool enteredSlot = newTreeScope.parentTreeScope() == previousTreeScope; +// if (enteredSlot) { +// if (m_lowestCommonAncestorIndex) { +// if (m_ancestorTreeScopes.isEmpty()) +// collectTreeScopes(); +// bool relatedNodeIsInSlot = m_ancestorTreeScopes[m_lowestCommonAncestorIndex - 1] == &newTreeScope; +// if (relatedNodeIsInSlot) { +// m_lowestCommonAncestorIndex--; +// m_retargetedRelatedNode = nodeInLowestCommonAncestor(); +// ASSERT(&newTreeScope == &m_retargetedRelatedNode->treeScope()); +// } +// } else +// ASSERT(m_retargetedRelatedNode == &m_relatedNode); +// } else { +// ASSERT(previousTreeScope->parentTreeScope() == &newTreeScope); +// m_lowestCommonAncestorIndex++; +// ASSERT_WITH_SECURITY_IMPLICATION(m_ancestorTreeScopes.isEmpty() || m_lowestCommonAncestorIndex < m_ancestorTreeScopes.size()); +// m_retargetedRelatedNode = downcast<ShadowRoot>(currentRelatedNodeScope.rootNode()).host(); +// ASSERT(&newTreeScope == &m_retargetedRelatedNode->treeScope()); +// } +// } + +// inline Node* RelatedNodeRetargeter::nodeInLowestCommonAncestor() +// { +// if (!m_lowestCommonAncestorIndex) +// return &m_relatedNode; +// auto& rootNode = m_ancestorTreeScopes[m_lowestCommonAncestorIndex - 1]->rootNode(); +// return downcast<ShadowRoot>(rootNode).host(); +// } + +// void RelatedNodeRetargeter::collectTreeScopes() +// { +// ASSERT(m_ancestorTreeScopes.isEmpty()); +// for (TreeScope* currentTreeScope = &m_relatedNode.treeScope(); currentTreeScope; currentTreeScope = currentTreeScope->parentTreeScope()) +// m_ancestorTreeScopes.append(currentTreeScope); +// ASSERT_WITH_SECURITY_IMPLICATION(!m_ancestorTreeScopes.isEmpty()); +// } + +// #if !ASSERT_ENABLED + +// inline void RelatedNodeRetargeter::checkConsistency(Node&) +// { +// } + +// #else // ASSERT_ENABLED + +// void RelatedNodeRetargeter::checkConsistency(Node& currentTarget) +// { +// if (!m_retargetedRelatedNode) +// return; +// ASSERT(!currentTarget.isClosedShadowHidden(*m_retargetedRelatedNode)); +// ASSERT(m_retargetedRelatedNode == currentTarget.treeScope().retargetToScope(m_relatedNode).ptr()); +// } + +// #endif // ASSERT_ENABLED +// } diff --git a/src/bun.js/bindings/webcore/EventPath.h b/src/bun.js/bindings/webcore/EventPath.h new file mode 100644 index 000000000..feb86fb7b --- /dev/null +++ b/src/bun.js/bindings/webcore/EventPath.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * Copyright (C) 2013-2017 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "EventContext.h" +// #include "PseudoElement.h" +// #include "SVGElement.h" +// #include "SVGUseElement.h" +#include <wtf/Forward.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class Touch; + +class EventPath { +public: + EventPath(Node& origin, Event&); + explicit EventPath(const Vector<EventTarget*>&); + + bool isEmpty() const { return m_path.isEmpty(); } + size_t size() const { return m_path.size(); } + const EventContext& contextAt(size_t i) const { return m_path[i]; } + EventContext& contextAt(size_t i) { return m_path[i]; } + + Vector<EventTarget*> computePathUnclosedToTarget(const EventTarget&) const; + + static Node* eventTargetRespectingTargetRules(Node&); + +private: + void buildPath(Node& origin, Event&); + void setRelatedTarget(Node& origin, Node&); + +#if ENABLE(TOUCH_EVENTS) + void retargetTouch(EventContext::TouchListType, const Touch&); + void retargetTouchList(EventContext::TouchListType, const TouchList*); + void retargetTouchLists(const TouchEvent&); +#endif + + Vector<EventContext, 16> m_path; +}; + +inline Node* EventPath::eventTargetRespectingTargetRules(Node& referenceNode) +{ + // if (is<PseudoElement>(referenceNode)) + // return downcast<PseudoElement>(referenceNode).hostElement(); + + // // Events sent to elements inside an SVG use element's shadow tree go to the use element. + // if (is<SVGElement>(referenceNode)) { + // if (auto useElement = downcast<SVGElement>(referenceNode).correspondingUseElement()) + // return useElement.get(); + // } + + return &referenceNode; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventSender.h b/src/bun.js/bindings/webcore/EventSender.h new file mode 100644 index 000000000..d69a6e5e9 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventSender.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2012 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 "Timer.h" +#include <wtf/Vector.h> +#include <wtf/WeakPtr.h> + +namespace WebCore { + +class Page; + +template<typename T> class EventSender { + WTF_MAKE_NONCOPYABLE(EventSender); WTF_MAKE_FAST_ALLOCATED; +public: + explicit EventSender(const AtomString& eventType); + + const AtomString& eventType() const { return m_eventType; } + void dispatchEventSoon(T&); + void cancelEvent(T&); + void dispatchPendingEvents(Page*); + +#if ASSERT_ENABLED + bool hasPendingEvents(T& sender) const + { + return m_dispatchSoonList.find(&sender) != notFound || m_dispatchingList.find(&sender) != notFound; + } +#endif + +private: + void timerFired() { dispatchPendingEvents(nullptr); } + + AtomString m_eventType; + Timer m_timer; + Vector<WeakPtr<T>> m_dispatchSoonList; + Vector<WeakPtr<T>> m_dispatchingList; +}; + +template<typename T> EventSender<T>::EventSender(const AtomString& eventType) + : m_eventType(eventType) + , m_timer(*this, &EventSender::timerFired) +{ +} + +template<typename T> void EventSender<T>::dispatchEventSoon(T& sender) +{ + m_dispatchSoonList.append(sender); + if (!m_timer.isActive()) + m_timer.startOneShot(0_s); +} + +template<typename T> void EventSender<T>::cancelEvent(T& sender) +{ + // Remove instances of this sender from both lists. + // Use loops because we allow multiple instances to get into the lists. + for (auto& event : m_dispatchSoonList) { + if (event == &sender) + event = nullptr; + } + for (auto& event : m_dispatchingList) { + if (event == &sender) + event = nullptr; + } +} + +template<typename T> void EventSender<T>::dispatchPendingEvents(Page* page) +{ + // Need to avoid re-entering this function; if new dispatches are + // scheduled before the parent finishes processing the list, they + // will set a timer and eventually be processed. + if (!m_dispatchingList.isEmpty()) + return; + + m_timer.stop(); + + m_dispatchSoonList.checkConsistency(); + + m_dispatchingList = std::exchange(m_dispatchSoonList, { }); + for (auto& event : m_dispatchingList) { + if (auto sender = event.get()) { + event = nullptr; + if (!page || sender->document().page() == page) + sender->dispatchPendingEvent(this); + else + dispatchEventSoon(*sender); + } + } + m_dispatchingList.clear(); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventTarget.cpp b/src/bun.js/bindings/webcore/EventTarget.cpp new file mode 100644 index 000000000..3b7128b7a --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTarget.cpp @@ -0,0 +1,391 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2001 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2004-2021 Apple Inc. All rights reserved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * + * 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 "Event.h" + +#include "EventTarget.h" + +#include "AddEventListenerOptions.h" +#include "DOMWrapperWorld.h" +#include "EventNames.h" +#include "EventTargetConcrete.h" +// #include "HTMLBodyElement.h" +// #include "HTMLHtmlElement.h" +// #include "InspectorInstrumentation.h" +#include "JSErrorHandler.h" +#include "JSEventListener.h" +// #include "Logging.h" +// #include "Quirks.h" +// #include "ScriptController.h" +// #include "ScriptDisallowedScope.h" +// #include "Settings.h" +// #include <wtf/IsoMallocInlines.h> +#include <wtf/MainThread.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/Ref.h> +#include <wtf/SetForScope.h> +#include <wtf/StdLibExtras.h> +#include <wtf/Vector.h> + +namespace WebCore { + +WTF_MAKE_ISO_ALLOCATED_IMPL(EventTarget); +WTF_MAKE_ISO_ALLOCATED_IMPL(EventTargetWithInlineData); + +Ref<EventTarget> EventTarget::create(ScriptExecutionContext& context) +{ + return EventTargetConcrete::create(context); +} + +EventTarget::~EventTarget() = default; + +bool EventTarget::isNode() const +{ + return false; +} + +bool EventTarget::isPaymentRequest() const +{ + return false; +} + +bool EventTarget::addEventListener(const AtomString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options) +{ +#if ASSERT_ENABLED + listener->checkValidityForEventTarget(*this); +#endif + + if (options.signal && options.signal->aborted()) + return false; + + auto passive = options.passive; + + // if (!passive.has_value() && Quirks::shouldMakeEventListenerPassive(*this, eventType, listener.get())) + // passive = true; + + bool listenerCreatedFromScript = is<JSEventListener>(listener) && !downcast<JSEventListener>(listener.get()).wasCreatedFromMarkup(); + + if (!ensureEventTargetData().eventListenerMap.add(eventType, listener.copyRef(), { options.capture, passive.value_or(false), options.once })) + return false; + + if (options.signal) { + options.signal->addAlgorithm([weakThis = WeakPtr { *this }, eventType, listener = WeakPtr { listener }, capture = options.capture] { + if (weakThis && listener) + weakThis->removeEventListener(eventType, *listener, capture); + }); + } + + // if (listenerCreatedFromScript) + // InspectorInstrumentation::didAddEventListener(*this, eventType, listener.get(), options.capture); + + // if (eventNames().isWheelEventType(eventType)) + // invalidateEventListenerRegions(); + + eventListenersDidChange(); + return true; +} + +void EventTarget::addEventListenerForBindings(const AtomString& eventType, RefPtr<EventListener>&& listener, AddEventListenerOptionsOrBoolean&& variant) +{ + if (!listener) + return; + + auto visitor = WTF::makeVisitor([&](const AddEventListenerOptions& options) { addEventListener(eventType, listener.releaseNonNull(), options); }, [&](bool capture) { addEventListener(eventType, listener.releaseNonNull(), capture); }); + + std::visit(visitor, variant); +} + +void EventTarget::removeEventListenerForBindings(const AtomString& eventType, RefPtr<EventListener>&& listener, EventListenerOptionsOrBoolean&& variant) +{ + if (!listener) + return; + + auto visitor = WTF::makeVisitor([&](const EventListenerOptions& options) { removeEventListener(eventType, *listener, options); }, [&](bool capture) { removeEventListener(eventType, *listener, capture); }); + + std::visit(visitor, variant); +} + +bool EventTarget::removeEventListener(const AtomString& eventType, EventListener& listener, const EventListenerOptions& options) +{ + auto* data = eventTargetData(); + if (!data) + return false; + + // InspectorInstrumentation::willRemoveEventListener(*this, eventType, listener, options.capture); + + if (data->eventListenerMap.remove(eventType, listener, options.capture)) { + if (eventNames().isWheelEventType(eventType)) + invalidateEventListenerRegions(); + + eventListenersDidChange(); + return true; + } + return false; +} + +template<typename JSMaybeErrorEventListener> +void EventTarget::setAttributeEventListener(const AtomString& eventType, JSC::JSValue listener, JSC::JSObject& jsEventTarget) +{ + auto& isolatedWorld = worldForDOMObject(jsEventTarget); + auto* existingListener = attributeEventListener(eventType, isolatedWorld); + if (!listener.isObject()) { + if (existingListener) + removeEventListener(eventType, *existingListener, false); + } else if (existingListener) { + bool capture = false; + + // InspectorInstrumentation::willRemoveEventListener(*this, eventType, *existingListener, capture); + existingListener->replaceJSFunctionForAttributeListener(asObject(listener), &jsEventTarget); + // InspectorInstrumentation::didAddEventListener(*this, eventType, *existingListener, capture); + } else + addEventListener(eventType, JSMaybeErrorEventListener::create(*asObject(listener), jsEventTarget, true, isolatedWorld), {}); +} + +template void EventTarget::setAttributeEventListener<JSErrorHandler>(const AtomString& eventType, JSC::JSValue listener, JSC::JSObject& jsEventTarget); +template void EventTarget::setAttributeEventListener<JSEventListener>(const AtomString& eventType, JSC::JSValue listener, JSC::JSObject& jsEventTarget); + +bool EventTarget::setAttributeEventListener(const AtomString& eventType, RefPtr<EventListener>&& listener, DOMWrapperWorld& isolatedWorld) +{ + auto* existingListener = attributeEventListener(eventType, isolatedWorld); + if (!listener) { + if (existingListener) + removeEventListener(eventType, *existingListener, false); + return false; + } + // if (existingListener) { + // InspectorInstrumentation::willRemoveEventListener(*this, eventType, *existingListener, false); + +#if ASSERT_ENABLED + listener->checkValidityForEventTarget(*this); +#endif + + auto listenerPointer = listener.copyRef(); + eventTargetData()->eventListenerMap.replace(eventType, *existingListener, listener.releaseNonNull(), {}); + + // InspectorInstrumentation::didAddEventListener(*this, eventType, *listenerPointer, false); + + return true; + + return addEventListener(eventType, listener.releaseNonNull(), {}); +} + +JSEventListener* EventTarget::attributeEventListener(const AtomString& eventType, DOMWrapperWorld& isolatedWorld) +{ + for (auto& eventListener : eventListeners(eventType)) { + auto& listener = eventListener->callback(); + if (listener.type() != EventListener::JSEventListenerType) + continue; + + auto& jsListener = downcast<JSEventListener>(listener); + if (jsListener.isAttribute() && &jsListener.isolatedWorld() == &isolatedWorld) + return &jsListener; + } + + return nullptr; +} + +bool EventTarget::hasActiveEventListeners(const AtomString& eventType) const +{ + auto* data = eventTargetData(); + return data && data->eventListenerMap.containsActive(eventType); +} + +ExceptionOr<bool> EventTarget::dispatchEventForBindings(Event& event) +{ + if (!event.isInitialized() || event.isBeingDispatched()) + return Exception { InvalidStateError }; + + if (!scriptExecutionContext()) + return false; + + event.setUntrusted(); + + dispatchEvent(event); + return event.legacyReturnValue(); +} + +void EventTarget::dispatchEvent(Event& event) +{ + // FIXME: We should always use EventDispatcher. + ASSERT(event.isInitialized()); + ASSERT(!event.isBeingDispatched()); + + event.setTarget(this); + event.setCurrentTarget(this); + event.setEventPhase(Event::AT_TARGET); + event.resetBeforeDispatch(); + fireEventListeners(event, EventInvokePhase::Capturing); + fireEventListeners(event, EventInvokePhase::Bubbling); + event.resetAfterDispatch(); +} + +void EventTarget::uncaughtExceptionInEventHandler() +{ +} + +static const AtomString& legacyType(const Event& event) +{ + + return nullAtom(); +} + +// https://dom.spec.whatwg.org/#concept-event-listener-invoke +void EventTarget::fireEventListeners(Event& event, EventInvokePhase phase) +{ + ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::isEventAllowedInMainThread()); + ASSERT(event.isInitialized()); + + auto* data = eventTargetData(); + if (!data) + return; + + SetForScope firingEventListenersScope(data->isFiringEventListeners, true); + + if (auto* listenersVector = data->eventListenerMap.find(event.type())) { + innerInvokeEventListeners(event, *listenersVector, phase); + return; + } + + // Only fall back to legacy types for trusted events. + if (!event.isTrusted()) + return; + + const AtomString& legacyTypeName = legacyType(event); + if (!legacyTypeName.isNull()) { + if (auto* legacyListenersVector = data->eventListenerMap.find(legacyTypeName)) { + AtomString typeName = event.type(); + event.setType(legacyTypeName); + innerInvokeEventListeners(event, *legacyListenersVector, phase); + event.setType(typeName); + } + } +} + +// Intentionally creates a copy of the listeners vector to avoid event listeners added after this point from being run. +// Note that removal still has an effect due to the removed field in RegisteredEventListener. +// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke +void EventTarget::innerInvokeEventListeners(Event& event, EventListenerVector listeners, EventInvokePhase phase) +{ + Ref<EventTarget> protectedThis(*this); + ASSERT(!listeners.isEmpty()); + ASSERT(scriptExecutionContext()); + + auto& context = *scriptExecutionContext(); + // bool contextIsDocument = is<Document>(context); + // if (contextIsDocument) + // InspectorInstrumentation::willDispatchEvent(downcast<Document>(context), event); + + for (auto& registeredListener : listeners) { + if (UNLIKELY(registeredListener->wasRemoved())) + continue; + + if (phase == EventInvokePhase::Capturing && !registeredListener->useCapture()) + continue; + if (phase == EventInvokePhase::Bubbling && registeredListener->useCapture()) + continue; + + // if (InspectorInstrumentation::isEventListenerDisabled(*this, event.type(), registeredListener->callback(), registeredListener->useCapture())) + // continue; + + // If stopImmediatePropagation has been called, we just break out immediately, without + // handling any more events on this target. + if (event.immediatePropagationStopped()) + break; + + // Make sure the JS wrapper and function stay alive until the end of this scope. Otherwise, + // event listeners with 'once' flag may get collected as soon as they get unregistered below, + // before we call the js function. + JSC::EnsureStillAliveScope wrapperProtector(registeredListener->callback().wrapper()); + JSC::EnsureStillAliveScope jsFunctionProtector(registeredListener->callback().jsFunction()); + + // Do this before invocation to avoid reentrancy issues. + if (registeredListener->isOnce()) + removeEventListener(event.type(), registeredListener->callback(), registeredListener->useCapture()); + + if (registeredListener->isPassive()) + event.setInPassiveListener(true); + +#if ASSERT_ENABLED + registeredListener->callback().checkValidityForEventTarget(*this); +#endif + + // InspectorInstrumentation::willHandleEvent(context, event, *registeredListener); + registeredListener->callback().handleEvent(context, event); + // InspectorInstrumentation::didHandleEvent(context, event, *registeredListener); + + // if (registeredListener->isPassive()) + // event.setInPassiveListener(false); + } + + // if (contextIsDocument) + // InspectorInstrumentation::didDispatchEvent(downcast<Document>(context), event); +} + +Vector<AtomString> EventTarget::eventTypes() +{ + if (auto* data = eventTargetData()) + return data->eventListenerMap.eventTypes(); + return {}; +} + +const EventListenerVector& EventTarget::eventListeners(const AtomString& eventType) +{ + auto* data = eventTargetData(); + auto* listenerVector = data ? data->eventListenerMap.find(eventType) : nullptr; + static NeverDestroyed<EventListenerVector> emptyVector; + return listenerVector ? *listenerVector : emptyVector.get(); +} + +void EventTarget::removeAllEventListeners() +{ + // auto& threadData = threadGlobalData(); + // RELEASE_ASSERT(!threadData.isInRemoveAllEventListeners()); + + // threadData.setIsInRemoveAllEventListeners(true); + + auto* data = eventTargetData(); + if (data && !data->eventListenerMap.isEmpty()) { + // if (data->eventListenerMap.contains(eventNames().wheelEvent) || data->eventListenerMap.contains(eventNames().mousewheelEvent)) + // invalidateEventListenerRegions(); + + data->eventListenerMap.clear(); + eventListenersDidChange(); + } + + // threadData.setIsInRemoveAllEventListeners(false); +} + +void EventTarget::invalidateEventListenerRegions() +{ +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventTarget.h b/src/bun.js/bindings/webcore/EventTarget.h new file mode 100644 index 000000000..b763393d7 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTarget.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2001 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2004-2021 Apple Inc. All rights reserved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * + * 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. + */ + +#pragma once + +#include "EventListenerMap.h" +#include "EventListenerOptions.h" +#include "EventTargetInterfaces.h" +#include "ExceptionOr.h" +#include "ScriptWrappable.h" +#include <memory> +#include <variant> +#include <wtf/Forward.h> +// #include <wtf/IsoMalloc.h> + +#include <wtf/WeakPtr.h> + +#include "root.h" + +namespace JSC { +class JSValue; +class JSObject; +} + +namespace WebCore { + +struct AddEventListenerOptions; +class DOMWrapperWorld; +class JSEventListener; + +struct EventTargetData { + WTF_MAKE_NONCOPYABLE(EventTargetData); + WTF_MAKE_FAST_ALLOCATED; + +public: + EventTargetData() = default; + EventListenerMap eventListenerMap; + bool isFiringEventListeners { false }; +}; + +class EventTarget : public ScriptWrappable, public CanMakeWeakPtr<EventTarget> { + WTF_MAKE_ISO_ALLOCATED(EventTarget); + +public: + static Ref<EventTarget> create(ScriptExecutionContext&); + + void ref() { refEventTarget(); } + void deref() { derefEventTarget(); } + + virtual EventTargetInterface eventTargetInterface() const = 0; + virtual ScriptExecutionContext* scriptExecutionContext() const = 0; + + WEBCORE_EXPORT virtual bool isNode() const; + WEBCORE_EXPORT virtual bool isPaymentRequest() const; + + using AddEventListenerOptionsOrBoolean = std::variant<AddEventListenerOptions, bool>; + WEBCORE_EXPORT void addEventListenerForBindings(const AtomString& eventType, RefPtr<EventListener>&&, AddEventListenerOptionsOrBoolean&&); + using EventListenerOptionsOrBoolean = std::variant<EventListenerOptions, bool>; + WEBCORE_EXPORT void removeEventListenerForBindings(const AtomString& eventType, RefPtr<EventListener>&&, EventListenerOptionsOrBoolean&&); + WEBCORE_EXPORT ExceptionOr<bool> dispatchEventForBindings(Event&); + + WEBCORE_EXPORT virtual bool addEventListener(const AtomString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&); + WEBCORE_EXPORT virtual bool removeEventListener(const AtomString& eventType, EventListener&, const EventListenerOptions& = {}); + + WEBCORE_EXPORT virtual void removeAllEventListeners(); + WEBCORE_EXPORT virtual void dispatchEvent(Event&); + WEBCORE_EXPORT virtual void uncaughtExceptionInEventHandler(); + + // Used for legacy "onevent" attributes. + template<typename JSMaybeErrorEventListener> + void setAttributeEventListener(const AtomString& eventType, JSC::JSValue listener, JSC::JSObject& jsEventTarget); + bool setAttributeEventListener(const AtomString& eventType, RefPtr<EventListener>&&, DOMWrapperWorld&); + JSEventListener* attributeEventListener(const AtomString& eventType, DOMWrapperWorld&); + + bool hasEventListeners() const; + bool hasEventListeners(const AtomString& eventType) const; + bool hasCapturingEventListeners(const AtomString& eventType); + bool hasActiveEventListeners(const AtomString& eventType) const; + + Vector<AtomString> eventTypes(); + const EventListenerVector& eventListeners(const AtomString& eventType); + + enum class EventInvokePhase { Capturing, + Bubbling }; + void fireEventListeners(Event&, EventInvokePhase); + bool isFiringEventListeners() const; + + template<typename Visitor> void visitJSEventListeners(Visitor&); + void invalidateJSEventListeners(JSC::JSObject*); + + const EventTargetData* eventTargetData() const; + +protected: + WEBCORE_EXPORT virtual ~EventTarget(); + + virtual EventTargetData* eventTargetData() = 0; + virtual EventTargetData* eventTargetDataConcurrently() = 0; + virtual EventTargetData& ensureEventTargetData() = 0; + + virtual void eventListenersDidChange() {} + +private: + virtual void refEventTarget() = 0; + virtual void derefEventTarget() = 0; + + void innerInvokeEventListeners(Event&, EventListenerVector, EventInvokePhase); + void invalidateEventListenerRegions(); +}; + +class EventTargetWithInlineData : public EventTarget { + WTF_MAKE_ISO_ALLOCATED_EXPORT(EventTargetWithInlineData, WEBCORE_EXPORT); + +protected: + EventTargetData* eventTargetData() final { return &m_eventTargetData; } + EventTargetData* eventTargetDataConcurrently() final { return &m_eventTargetData; } + EventTargetData& ensureEventTargetData() final { return m_eventTargetData; } + +private: + EventTargetData m_eventTargetData; +}; + +inline const EventTargetData* EventTarget::eventTargetData() const +{ + return const_cast<EventTarget*>(this)->eventTargetData(); +} + +inline bool EventTarget::isFiringEventListeners() const +{ + auto* data = eventTargetData(); + return data && data->isFiringEventListeners; +} + +inline bool EventTarget::hasEventListeners() const +{ + auto* data = eventTargetData(); + return data && !data->eventListenerMap.isEmpty(); +} + +inline bool EventTarget::hasEventListeners(const AtomString& eventType) const +{ + auto* data = eventTargetData(); + return data && data->eventListenerMap.contains(eventType); +} + +inline bool EventTarget::hasCapturingEventListeners(const AtomString& eventType) +{ + auto* data = eventTargetData(); + return data && data->eventListenerMap.containsCapturing(eventType); +} + +template<typename Visitor> +void EventTarget::visitJSEventListeners(Visitor& visitor) +{ + if (auto* data = eventTargetDataConcurrently()) + data->eventListenerMap.visitJSEventListeners(visitor); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventTarget.idl b/src/bun.js/bindings/webcore/EventTarget.idl new file mode 100644 index 000000000..3c3264b6e --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTarget.idl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2006-2017 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +[ + CustomToJSObject, + Exposed=*, + IsImmutablePrototypeExoticObjectOnPrototype, + JSCustomHeader, + JSCustomMarkFunction, + JSCustomToNativeObject, +] interface EventTarget { + [CallWith=CurrentScriptExecutionContext] constructor(); + + [ImplementedAs=addEventListenerForBindings] undefined addEventListener([AtomString] DOMString type, EventListener? listener, optional (AddEventListenerOptions or boolean) options = false); + [ImplementedAs=removeEventListenerForBindings] undefined removeEventListener([AtomString] DOMString type, EventListener? listener, optional (EventListenerOptions or boolean) options = false); + [ImplementedAs=dispatchEventForBindings] boolean dispatchEvent(Event event); +}; diff --git a/src/bun.js/bindings/webcore/EventTargetConcrete.cpp b/src/bun.js/bindings/webcore/EventTargetConcrete.cpp new file mode 100644 index 000000000..ded224beb --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTargetConcrete.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 Alexey Shvayka <shvaikalesh@gmail.com>. + * + * 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. + */ + +#include "config.h" +#include "EventTargetConcrete.h" + +namespace WebCore { + +WTF_MAKE_ISO_ALLOCATED_IMPL(EventTargetConcrete); + +Ref<EventTargetConcrete> EventTargetConcrete::create(ScriptExecutionContext& context) +{ + return adoptRef(*new EventTargetConcrete(context)); +} + +EventTargetConcrete::EventTargetConcrete(ScriptExecutionContext& context) + : ContextDestructionObserver(&context) +{ +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventTargetConcrete.h b/src/bun.js/bindings/webcore/EventTargetConcrete.h new file mode 100644 index 000000000..202be2d9e --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTargetConcrete.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 Alexey Shvayka <shvaikalesh@gmail.com>. + * + * 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 "root.h" +#include "ContextDestructionObserver.h" +#include "EventTarget.h" +#include "EventTargetInterfaces.h" +#include "ScriptExecutionContext.h" +// #include <wtf/IsoMallocInlines.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class EventTargetConcrete final : public RefCounted<EventTargetConcrete>, public EventTargetWithInlineData, private ContextDestructionObserver { + WTF_MAKE_ISO_ALLOCATED(EventTargetConcrete); + +public: + static Ref<EventTargetConcrete> create(ScriptExecutionContext&); + + bool hasEventTargetData() const { return true; } + + using RefCounted::deref; + using RefCounted::ref; + +private: + explicit EventTargetConcrete(ScriptExecutionContext&); + + EventTargetInterface eventTargetInterface() const final { return EventTargetInterfaceType; } + ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } + + void refEventTarget() final { ref(); } + void derefEventTarget() final { deref(); } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventTargetFactory.cpp b/src/bun.js/bindings/webcore/EventTargetFactory.cpp new file mode 100644 index 000000000..b52214fe0 --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTargetFactory.cpp @@ -0,0 +1,281 @@ +/* + * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. + * + * Copyright (C) 2011 Google 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 GOOGLE, 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 "EventTargetHeaders.h" +#include "JSDOMWrapperCache.h" + +#include "JSDOMGlobalObject.h" +#include <JavaScriptCore/StructureInlines.h> + +namespace WebCore { + +JSC::JSValue toJS(JSC::JSGlobalObject* state, JSDOMGlobalObject* globalObject, EventTarget& impl) +{ + switch (impl.eventTargetInterface()) { + case EventTargetInterfaceType: + break; + case AbortSignalEventTargetInterfaceType: + return toJS(state, globalObject, static_cast<AbortSignal&>(impl)); + // #if ENABLE(APPLE_PAY) + // case ApplePaySessionEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<ApplePaySession&>(impl)); + // #endif + // #if ENABLE(WEB_AUDIO) + // case AudioNodeEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<AudioNode&>(impl)); + // #endif + // #if ENABLE(VIDEO) + // case AudioTrackListEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<AudioTrackList&>(impl)); + // #endif + // #if ENABLE(WEB_AUDIO) + // case BaseAudioContextEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<BaseAudioContext&>(impl)); + // #endif + // case BroadcastChannelEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<BroadcastChannel&>(impl)); + // case ClipboardEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<Clipboard&>(impl)); + // case DOMApplicationCacheEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<DOMApplicationCache&>(impl)); + // case DOMWindowEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<DOMWindow&>(impl)); + // case DedicatedWorkerGlobalScopeEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<DedicatedWorkerGlobalScope&>(impl)); + // case EventSourceEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<EventSource&>(impl)); + // case FileReaderEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<FileReader&>(impl)); + // case FontFaceSetEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<FontFaceSet&>(impl)); + // case GPUDeviceEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<GPUDevice&>(impl)); + // case IDBDatabaseEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<IDBDatabase&>(impl)); + // case IDBOpenDBRequestEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<IDBOpenDBRequest&>(impl)); + // case IDBRequestEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<IDBRequest&>(impl)); + // case IDBTransactionEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<IDBTransaction&>(impl)); + // #if ENABLE(VIDEO) + // case MediaControllerEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaController&>(impl)); + // #endif + // #if ENABLE(MEDIA_STREAM) + // case MediaDevicesEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaDevices&>(impl)); + // #endif + // #if ENABLE(ENCRYPTED_MEDIA) + // case MediaKeySessionEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaKeySession&>(impl)); + // #endif + // case MediaQueryListEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaQueryList&>(impl)); + // #if ENABLE(MEDIA_RECORDER) + // case MediaRecorderEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaRecorder&>(impl)); + // #endif + // #if ENABLE(MEDIA_SESSION_COORDINATOR) + // case MediaSessionCoordinatorEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaSessionCoordinator&>(impl)); + // #endif + // #if ENABLE(MEDIA_SOURCE) + // case MediaSourceEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaSource&>(impl)); + // #endif + // #if ENABLE(MEDIA_STREAM) + // case MediaStreamEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaStream&>(impl)); + // #endif + // #if ENABLE(MEDIA_STREAM) + // case MediaStreamTrackEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MediaStreamTrack&>(impl)); + // #endif + // case MessagePortEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<MessagePort&>(impl)); + // case NodeEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<Node&>(impl)); + // #if ENABLE(NOTIFICATIONS) + // case NotificationEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<Notification&>(impl)); + // #endif + // #if ENABLE(OFFSCREEN_CANVAS) + // case OffscreenCanvasEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<OffscreenCanvas&>(impl)); + // #endif + // #if ENABLE(PAYMENT_REQUEST) + // case PaymentRequestEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<PaymentRequest&>(impl)); + // #endif + // #if ENABLE(PAYMENT_REQUEST) + // case PaymentResponseEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<PaymentResponse&>(impl)); + // #endif + // case PerformanceEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<Performance&>(impl)); + // case PermissionStatusEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<PermissionStatus&>(impl)); + // #if ENABLE(PICTURE_IN_PICTURE_API) + // case PictureInPictureWindowEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<PictureInPictureWindow&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCDTMFSenderEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCDTMFSender&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCDataChannelEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCDataChannel&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCDtlsTransportEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCDtlsTransport&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCIceTransportEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCIceTransport&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCPeerConnectionEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCPeerConnection&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCRtpSFrameTransformEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCRtpSFrameTransform&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCRtpScriptTransformEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCRtpScriptTransform&>(impl)); + // #endif + // #if ENABLE(WEB_RTC) + // case RTCSctpTransportEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RTCSctpTransport&>(impl)); + // #endif + // #if ENABLE(WIRELESS_PLAYBACK_TARGET) + // case RemotePlaybackEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<RemotePlayback&>(impl)); + // #endif + // #if ENABLE(SERVICE_WORKER) + // case ServiceWorkerEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<ServiceWorker&>(impl)); + // #endif + // #if ENABLE(SERVICE_WORKER) + // case ServiceWorkerContainerEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<ServiceWorkerContainer&>(impl)); + // #endif + // #if ENABLE(SERVICE_WORKER) + // case ServiceWorkerGlobalScopeEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<ServiceWorkerGlobalScope&>(impl)); + // #endif + // #if ENABLE(SERVICE_WORKER) + // case ServiceWorkerRegistrationEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<ServiceWorkerRegistration&>(impl)); + // #endif + // case SharedWorkerEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<SharedWorker&>(impl)); + // case SharedWorkerGlobalScopeEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<SharedWorkerGlobalScope&>(impl)); + // #if ENABLE(MEDIA_SOURCE) + // case SourceBufferEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<SourceBuffer&>(impl)); + // #endif + // #if ENABLE(MEDIA_SOURCE) + // case SourceBufferListEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<SourceBufferList&>(impl)); + // #endif + // case SpeechRecognitionEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<SpeechRecognition&>(impl)); + // #if ENABLE(SPEECH_SYNTHESIS) + // case SpeechSynthesisEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<SpeechSynthesis&>(impl)); + // #endif + // #if ENABLE(SPEECH_SYNTHESIS) + // case SpeechSynthesisUtteranceEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<SpeechSynthesisUtterance&>(impl)); + // #endif + // #if ENABLE(VIDEO) + // case TextTrackEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<TextTrack&>(impl)); + // #endif + // #if ENABLE(VIDEO) + // case TextTrackCueEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<TextTrackCue&>(impl)); + // #endif + // #if ENABLE(VIDEO) + // case TextTrackCueGenericEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<TextTrackCueGeneric&>(impl)); + // #endif + // #if ENABLE(VIDEO) + // case TextTrackListEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<TextTrackList&>(impl)); + // #endif + // #if ENABLE(VIDEO) + // case VideoTrackListEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<VideoTrackList&>(impl)); + // #endif + // case VisualViewportEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<VisualViewport&>(impl)); + // case WebAnimationEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<WebAnimation&>(impl)); + // #if ENABLE(LEGACY_ENCRYPTED_MEDIA) + // case WebKitMediaKeySessionEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<WebKitMediaKeySession&>(impl)); + // #endif + case WebSocketEventTargetInterfaceType: + return toJS(state, globalObject, static_cast<WebSocket&>(impl)); + // #if ENABLE(WEBXR) + // case WebXRLayerEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<WebXRLayer&>(impl)); + // #endif + // #if ENABLE(WEBXR) + // case WebXRSessionEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<WebXRSession&>(impl)); + // #endif + // #if ENABLE(WEBXR) + // case WebXRSpaceEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<WebXRSpace&>(impl)); + // #endif + // #if ENABLE(WEBXR) + // case WebXRSystemEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<WebXRSystem&>(impl)); + // #endif + // case WorkerEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<Worker&>(impl)); + // case WorkletGlobalScopeEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<WorkletGlobalScope&>(impl)); + // case XMLHttpRequestEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<XMLHttpRequest&>(impl)); + // case XMLHttpRequestUploadEventTargetInterfaceType: + // return toJS(state, globalObject, static_cast<XMLHttpRequestUpload&>(impl)); + // } + } + return wrap(state, globalObject, impl); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/EventTargetHeaders.h b/src/bun.js/bindings/webcore/EventTargetHeaders.h new file mode 100644 index 000000000..ae6ee0d3f --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTargetHeaders.h @@ -0,0 +1,266 @@ +/* + * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. + * + * Copyright (C) 2011 Google 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 GOOGLE, 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. + */ + +#ifndef EventTargetHeaders_h +#define EventTargetHeaders_h + +#include "AbortSignal.h" +#include "JSAbortSignal.h" +// #if ENABLE(APPLE_PAY) +// #include "ApplePaySession.h" +// #include "JSApplePaySession.h" +// #endif +// #if ENABLE(WEB_AUDIO) +// #include "AudioNode.h" +// #include "JSAudioNode.h" +// #endif +// #if ENABLE(VIDEO) +// #include "AudioTrackList.h" +// #include "JSAudioTrackList.h" +// #endif +// #if ENABLE(WEB_AUDIO) +// #include "BaseAudioContext.h" +// #include "JSBaseAudioContext.h" +// #endif +// #include "BroadcastChannel.h" +// #include "Clipboard.h" +// #include "DOMApplicationCache.h" +// #include "DOMWindow.h" +// #include "DedicatedWorkerGlobalScope.h" +// #include "EventSource.h" +// #include "FileReader.h" +// #include "FontFaceSet.h" +// #include "GPUDevice.h" +// #include "IDBDatabase.h" +// #include "IDBOpenDBRequest.h" +// #include "IDBRequest.h" +// #include "IDBTransaction.h" +// #include "JSBroadcastChannel.h" +// #include "JSClipboard.h" +// #include "JSDOMApplicationCache.h" +// #include "JSDOMWindow.h" +// #include "JSDedicatedWorkerGlobalScope.h" +// #include "JSEventSource.h" +// #include "JSFileReader.h" +// #include "JSFontFaceSet.h" +// #include "JSGPUDevice.h" +// #include "JSIDBDatabase.h" +// #include "JSIDBOpenDBRequest.h" +// #include "JSIDBRequest.h" +// #include "JSIDBTransaction.h" +// #if ENABLE(VIDEO) +// #include "JSMediaController.h" +// #include "MediaController.h" +// #endif +// #if ENABLE(MEDIA_STREAM) +// #include "JSMediaDevices.h" +// #include "MediaDevices.h" +// #endif +// #if ENABLE(ENCRYPTED_MEDIA) +// #include "JSMediaKeySession.h" +// #include "MediaKeySession.h" +// #endif +// #include "JSMediaQueryList.h" +// #include "MediaQueryList.h" +// #if ENABLE(MEDIA_RECORDER) +// #include "JSMediaRecorder.h" +// #include "MediaRecorder.h" +// #endif +// #if ENABLE(MEDIA_SESSION_COORDINATOR) +// #include "JSMediaSessionCoordinator.h" +// #include "MediaSessionCoordinator.h" +// #endif +// #if ENABLE(MEDIA_SOURCE) +// #include "JSMediaSource.h" +// #include "MediaSource.h" +// #endif +// #if ENABLE(MEDIA_STREAM) +// #include "JSMediaStream.h" +// #include "MediaStream.h" +// #endif +// #if ENABLE(MEDIA_STREAM) +// #include "JSMediaStreamTrack.h" +// #include "MediaStreamTrack.h" +// #endif +// #include "MessagePort.h" +// #include "JSMessagePort.h" +// #include "JSNode.h" +#include "Node.h" +// #if ENABLE(NOTIFICATIONS) +// #include "JSNotification.h" +// #include "Notification.h" +// #endif +// #if ENABLE(OFFSCREEN_CANVAS) +// #include "JSOffscreenCanvas.h" +// #include "OffscreenCanvas.h" +// #endif +// #if ENABLE(PAYMENT_REQUEST) +// #include "JSPaymentRequest.h" +// #include "PaymentRequest.h" +// #endif +// #if ENABLE(PAYMENT_REQUEST) +// #include "JSPaymentResponse.h" +// #include "PaymentResponse.h" +// #endif +// #include "JSPerformance.h" +// #include "JSPermissionStatus.h" +// #include "Performance.h" +// #include "PermissionStatus.h" +// #if ENABLE(PICTURE_IN_PICTURE_API) +// #include "JSPictureInPictureWindow.h" +// #include "PictureInPictureWindow.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCDTMFSender.h" +// #include "RTCDTMFSender.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCDataChannel.h" +// #include "RTCDataChannel.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCDtlsTransport.h" +// #include "RTCDtlsTransport.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCIceTransport.h" +// #include "RTCIceTransport.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCPeerConnection.h" +// #include "RTCPeerConnection.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCRtpSFrameTransform.h" +// #include "RTCRtpSFrameTransform.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCRtpScriptTransform.h" +// #include "RTCRtpScriptTransform.h" +// #endif +// #if ENABLE(WEB_RTC) +// #include "JSRTCSctpTransport.h" +// #include "RTCSctpTransport.h" +// #endif +// #if ENABLE(WIRELESS_PLAYBACK_TARGET) +// #include "JSRemotePlayback.h" +// #include "RemotePlayback.h" +// #endif +// #if ENABLE(SERVICE_WORKER) +// #include "JSServiceWorker.h" +// #include "ServiceWorker.h" +// #endif +// #if ENABLE(SERVICE_WORKER) +// #include "JSServiceWorkerContainer.h" +// #include "ServiceWorkerContainer.h" +// #endif +// #if ENABLE(SERVICE_WORKER) +// #include "JSServiceWorkerGlobalScope.h" +// #include "ServiceWorkerGlobalScope.h" +// #endif +// #if ENABLE(SERVICE_WORKER) +// #include "JSServiceWorkerRegistration.h" +// #include "ServiceWorkerRegistration.h" +// #endif +// #include "JSSharedWorker.h" +// #include "JSSharedWorkerGlobalScope.h" +// #include "SharedWorker.h" +// #include "SharedWorkerGlobalScope.h" +// #if ENABLE(MEDIA_SOURCE) +// #include "JSSourceBuffer.h" +// #include "SourceBuffer.h" +// #endif +// #if ENABLE(MEDIA_SOURCE) +// #include "JSSourceBufferList.h" +// #include "SourceBufferList.h" +// #endif +// #include "JSSpeechRecognition.h" +// #include "SpeechRecognition.h" +// #if ENABLE(SPEECH_SYNTHESIS) +// #include "JSSpeechSynthesis.h" +// #include "SpeechSynthesis.h" +// #endif +// #if ENABLE(SPEECH_SYNTHESIS) +// #include "JSSpeechSynthesisUtterance.h" +// #include "SpeechSynthesisUtterance.h" +// #endif +// #if ENABLE(VIDEO) +// #include "JSTextTrack.h" +// #include "TextTrack.h" +// #endif +// #if ENABLE(VIDEO) +// #include "JSTextTrackCue.h" +// #include "TextTrackCue.h" +// #endif +// #if ENABLE(VIDEO) +// #include "JSTextTrackCueGeneric.h" +// #include "TextTrackCueGeneric.h" +// #endif +// #if ENABLE(VIDEO) +// #include "JSTextTrackList.h" +// #include "TextTrackList.h" +// #endif +// #if ENABLE(VIDEO) +// #include "JSVideoTrackList.h" +// #include "VideoTrackList.h" +// #endif +// #include "VisualViewport.h" +// #include "JSVisualViewport.h" +// #include "WebAnimation.h" +// #include "JSWebAnimation.h" +// #if ENABLE(LEGACY_ENCRYPTED_MEDIA) +// #include "JSWebKitMediaKeySession.h" +// #include "WebKitMediaKeySession.h" +// #endif +#include "WebSocket.h" +#include "JSWebSocket.h" +// #if ENABLE(WEBXR) +// #include "JSWebXRLayer.h" +// #include "WebXRLayer.h" +// #endif +// #if ENABLE(WEBXR) +// #include "JSWebXRSession.h" +// #include "WebXRSession.h" +// #endif +// #if ENABLE(WEBXR) +// #include "JSWebXRSpace.h" +// #include "WebXRSpace.h" +// #endif +// #if ENABLE(WEBXR) +// #include "JSWebXRSystem.h" +// #include "WebXRSystem.h" +// #endif +// #include "Worker.h" +// #include "JSWorker.h" +// #include "WorkletGlobalScope.h" +// #include "JSWorkletGlobalScope.h" +// #include "XMLHttpRequest.h" +// #include "JSXMLHttpRequest.h" +// #include "XMLHttpRequestUpload.h" +// #include "JSXMLHttpRequestUpload.h" + +#endif // EventTargetHeaders_h diff --git a/src/bun.js/bindings/webcore/EventTargetInterfaces.h b/src/bun.js/bindings/webcore/EventTargetInterfaces.h new file mode 100644 index 000000000..0226d0c0e --- /dev/null +++ b/src/bun.js/bindings/webcore/EventTargetInterfaces.h @@ -0,0 +1,145 @@ +/* + * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. + * + * Copyright (C) 2011 Google 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 GOOGLE, 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. + */ + +#pragma once + +namespace WebCore { + +enum EventTargetInterface { +#if ENABLE(APPLE_PAY) + ApplePaySessionEventTargetInterfaceType = 1, +#endif +#if ENABLE(ENCRYPTED_MEDIA) + MediaKeySessionEventTargetInterfaceType = 2, +#endif +#if ENABLE(LEGACY_ENCRYPTED_MEDIA) + WebKitMediaKeySessionEventTargetInterfaceType = 3, +#endif +#if ENABLE(MEDIA_RECORDER) + MediaRecorderEventTargetInterfaceType = 4, +#endif +#if ENABLE(MEDIA_SESSION_COORDINATOR) + MediaSessionCoordinatorEventTargetInterfaceType = 5, +#endif +#if ENABLE(MEDIA_SOURCE) + MediaSourceEventTargetInterfaceType = 6, + SourceBufferEventTargetInterfaceType = 7, + SourceBufferListEventTargetInterfaceType = 8, +#endif +#if ENABLE(MEDIA_STREAM) + MediaDevicesEventTargetInterfaceType = 9, + MediaStreamEventTargetInterfaceType = 10, + MediaStreamTrackEventTargetInterfaceType = 11, +#endif +#if ENABLE(NOTIFICATIONS) + NotificationEventTargetInterfaceType = 12, +#endif +#if ENABLE(OFFSCREEN_CANVAS) + OffscreenCanvasEventTargetInterfaceType = 13, +#endif +#if ENABLE(PAYMENT_REQUEST) + PaymentRequestEventTargetInterfaceType = 14, + PaymentResponseEventTargetInterfaceType = 15, +#endif +#if ENABLE(PICTURE_IN_PICTURE_API) + PictureInPictureWindowEventTargetInterfaceType = 16, +#endif +#if ENABLE(SERVICE_WORKER) + ServiceWorkerEventTargetInterfaceType = 17, + ServiceWorkerContainerEventTargetInterfaceType = 18, + ServiceWorkerGlobalScopeEventTargetInterfaceType = 19, + ServiceWorkerRegistrationEventTargetInterfaceType = 20, +#endif +#if ENABLE(SPEECH_SYNTHESIS) + SpeechSynthesisEventTargetInterfaceType = 21, + SpeechSynthesisUtteranceEventTargetInterfaceType = 22, +#endif +#if ENABLE(VIDEO) + AudioTrackListEventTargetInterfaceType = 23, + MediaControllerEventTargetInterfaceType = 24, + TextTrackEventTargetInterfaceType = 25, + TextTrackCueEventTargetInterfaceType = 26, + TextTrackCueGenericEventTargetInterfaceType = 27, + TextTrackListEventTargetInterfaceType = 28, + VideoTrackListEventTargetInterfaceType = 29, +#endif +#if ENABLE(WEBXR) + WebXRLayerEventTargetInterfaceType = 30, + WebXRSessionEventTargetInterfaceType = 31, + WebXRSpaceEventTargetInterfaceType = 32, + WebXRSystemEventTargetInterfaceType = 33, +#endif +#if ENABLE(WEB_AUDIO) + AudioNodeEventTargetInterfaceType = 34, + BaseAudioContextEventTargetInterfaceType = 35, +#endif +#if ENABLE(WEB_RTC) + RTCDTMFSenderEventTargetInterfaceType = 36, + RTCDataChannelEventTargetInterfaceType = 37, + RTCDtlsTransportEventTargetInterfaceType = 38, + RTCIceTransportEventTargetInterfaceType = 39, + RTCPeerConnectionEventTargetInterfaceType = 40, + RTCRtpSFrameTransformEventTargetInterfaceType = 41, + RTCRtpScriptTransformEventTargetInterfaceType = 42, + RTCSctpTransportEventTargetInterfaceType = 43, +#endif +#if ENABLE(WIRELESS_PLAYBACK_TARGET) + RemotePlaybackEventTargetInterfaceType = 44, +#endif + EventTargetInterfaceType = 45, + AbortSignalEventTargetInterfaceType = 46, + BroadcastChannelEventTargetInterfaceType = 47, + ClipboardEventTargetInterfaceType = 48, + DOMApplicationCacheEventTargetInterfaceType = 49, + DOMWindowEventTargetInterfaceType = 50, + DedicatedWorkerGlobalScopeEventTargetInterfaceType = 51, + EventSourceEventTargetInterfaceType = 52, + FileReaderEventTargetInterfaceType = 53, + FontFaceSetEventTargetInterfaceType = 54, + GPUDeviceEventTargetInterfaceType = 55, + IDBDatabaseEventTargetInterfaceType = 56, + IDBOpenDBRequestEventTargetInterfaceType = 57, + IDBRequestEventTargetInterfaceType = 58, + IDBTransactionEventTargetInterfaceType = 59, + MediaQueryListEventTargetInterfaceType = 60, + MessagePortEventTargetInterfaceType = 61, + NodeEventTargetInterfaceType = 62, + PerformanceEventTargetInterfaceType = 63, + PermissionStatusEventTargetInterfaceType = 64, + SharedWorkerEventTargetInterfaceType = 65, + SharedWorkerGlobalScopeEventTargetInterfaceType = 66, + SpeechRecognitionEventTargetInterfaceType = 67, + VisualViewportEventTargetInterfaceType = 68, + WebAnimationEventTargetInterfaceType = 69, + WebSocketEventTargetInterfaceType = 70, + WorkerEventTargetInterfaceType = 71, + WorkletGlobalScopeEventTargetInterfaceType = 72, + XMLHttpRequestEventTargetInterfaceType = 73, + XMLHttpRequestUploadEventTargetInterfaceType = 74, +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ExceptionDetails.h b/src/bun.js/bindings/webcore/ExceptionDetails.h new file mode 100644 index 000000000..d25c2e462 --- /dev/null +++ b/src/bun.js/bindings/webcore/ExceptionDetails.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 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. + */ + +#pragma once + +#include "wtf/text/WTFString.h" + +namespace WebCore { + +struct ExceptionDetails { + enum class Type : uint8_t { + Script, + InvalidTargetFrame, + AppBoundDomain, + }; + + String message; + int lineNumber { 0 }; + int columnNumber { 0 }; + Type type { Type::Script }; + + // This bizarre explicit initialization of String is because older compilers (like on High Sierra) + // don't properly handle partial initialization lists unless every struct member has an explicit default value. + // Once we stop building on those platforms we can remove this. + String sourceURL {}; +}; + +} // namespace WebCore + +namespace WTF { +template<> struct EnumTraits<WebCore::ExceptionDetails::Type> { + using values = EnumValues< + WebCore::ExceptionDetails::Type, + WebCore::ExceptionDetails::Type::Script, + WebCore::ExceptionDetails::Type::InvalidTargetFrame, + WebCore::ExceptionDetails::Type::AppBoundDomain>; +}; +} diff --git a/src/bun.js/bindings/webcore/ExtendedDOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/ExtendedDOMClientIsoSubspaces.h new file mode 100644 index 000000000..174eaa194 --- /dev/null +++ b/src/bun.js/bindings/webcore/ExtendedDOMClientIsoSubspaces.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 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 + * 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. + */ + +#pragma once + +#include "DOMClientIsoSubspaces.h" + +namespace WebCore { + +class ExtendedDOMClientIsoSubspaces : public DOMClientIsoSubspaces { +public: + ExtendedDOMClientIsoSubspaces() = default; +}; + +} // namespace WebCore + +namespace WebCore { +using ExtendedDOMClientIsoSubspaces = WebCore::ExtendedDOMClientIsoSubspaces; +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/ExtendedDOMIsoSubspaces.h b/src/bun.js/bindings/webcore/ExtendedDOMIsoSubspaces.h new file mode 100644 index 000000000..d5ccb4288 --- /dev/null +++ b/src/bun.js/bindings/webcore/ExtendedDOMIsoSubspaces.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 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 + * 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. + */ + +#pragma once + +#include "DOMIsoSubspaces.h" + +namespace WebCore { + +class ExtendedDOMIsoSubspaces : public DOMIsoSubspaces { +public: + ExtendedDOMIsoSubspaces() = default; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/FetchHeaders.cpp b/src/bun.js/bindings/webcore/FetchHeaders.cpp new file mode 100644 index 000000000..26af08f1a --- /dev/null +++ b/src/bun.js/bindings/webcore/FetchHeaders.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2016 Canon Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions + * are required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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. + */ + +#include "config.h" +#include "FetchHeaders.h" + +#include "HTTPParsers.h" + +namespace WebCore { + +// https://fetch.spec.whatwg.org/#concept-headers-remove-privileged-no-cors-request-headers +static void removePrivilegedNoCORSRequestHeaders(HTTPHeaderMap& headers) +{ + headers.remove(HTTPHeaderName::Range); +} + +static ExceptionOr<bool> canWriteHeader(const String& name, const String& value, const String& combinedValue, FetchHeaders::Guard guard) +{ + if (!isValidHTTPToken(name)) + return Exception { TypeError, makeString("Invalid header name: '", name, "'") }; + ASSERT(value.isEmpty() || (!isHTTPSpace(value[0]) && !isHTTPSpace(value[value.length() - 1]))); + if (!isValidHTTPHeaderValue((value))) + return Exception { TypeError, makeString("Header '", name, "' has invalid value: '", value, "'") }; + if (guard == FetchHeaders::Guard::Immutable) + return Exception { TypeError, "Headers object's guard is 'immutable'"_s }; + if (guard == FetchHeaders::Guard::Request && isForbiddenHeaderName(name)) + return false; + if (guard == FetchHeaders::Guard::RequestNoCors && !combinedValue.isEmpty() && !isSimpleHeader(name, combinedValue)) + return false; + if (guard == FetchHeaders::Guard::Response && isForbiddenResponseHeaderName(name)) + return false; + return true; +} + +static ExceptionOr<void> appendToHeaderMap(const String& name, const String& value, HTTPHeaderMap& headers, FetchHeaders::Guard guard) +{ + String normalizedValue = stripLeadingAndTrailingHTTPSpaces(value); + String combinedValue = normalizedValue; + if (headers.contains(name)) + combinedValue = makeString(headers.get(name), ", ", normalizedValue); + auto canWriteResult = canWriteHeader(name, normalizedValue, combinedValue, guard); + if (canWriteResult.hasException()) + return canWriteResult.releaseException(); + if (!canWriteResult.releaseReturnValue()) + return { }; + headers.set(name, combinedValue); + + if (guard == FetchHeaders::Guard::RequestNoCors) + removePrivilegedNoCORSRequestHeaders(headers); + + return { }; +} + +static ExceptionOr<void> appendToHeaderMap(const HTTPHeaderMap::HTTPHeaderMapConstIterator::KeyValue& header, HTTPHeaderMap& headers, FetchHeaders::Guard guard) +{ + String normalizedValue = stripLeadingAndTrailingHTTPSpaces(header.value); + auto canWriteResult = canWriteHeader(header.key, normalizedValue, header.value, guard); + if (canWriteResult.hasException()) + return canWriteResult.releaseException(); + if (!canWriteResult.releaseReturnValue()) + return { }; + if (header.keyAsHTTPHeaderName) + headers.add(header.keyAsHTTPHeaderName.value(), header.value); + else + headers.add(header.key, header.value); + + if (guard == FetchHeaders::Guard::RequestNoCors) + removePrivilegedNoCORSRequestHeaders(headers); + + return { }; +} + +// https://fetch.spec.whatwg.org/#concept-headers-fill +static ExceptionOr<void> fillHeaderMap(HTTPHeaderMap& headers, const FetchHeaders::Init& headersInit, FetchHeaders::Guard guard) +{ + if (std::holds_alternative<Vector<Vector<String>>>(headersInit)) { + auto& sequence = std::get<Vector<Vector<String>>>(headersInit); + for (auto& header : sequence) { + if (header.size() != 2) + return Exception { TypeError, "Header sub-sequence must contain exactly two items"_s }; + auto result = appendToHeaderMap(header[0], header[1], headers, guard); + if (result.hasException()) + return result.releaseException(); + } + } else { + auto& record = std::get<Vector<KeyValuePair<String, String>>>(headersInit); + for (auto& header : record) { + auto result = appendToHeaderMap(header.key, header.value, headers, guard); + if (result.hasException()) + return result.releaseException(); + } + } + + return { }; +} + +ExceptionOr<Ref<FetchHeaders>> FetchHeaders::create(std::optional<Init>&& headersInit) +{ + HTTPHeaderMap headers; + + if (headersInit) { + auto result = fillHeaderMap(headers, *headersInit, Guard::None); + if (result.hasException()) + return result.releaseException(); + } + + return adoptRef(*new FetchHeaders { Guard::None, WTFMove(headers) }); +} + +ExceptionOr<void> FetchHeaders::fill(const Init& headerInit) +{ + return fillHeaderMap(m_headers, headerInit, m_guard); +} + +ExceptionOr<void> FetchHeaders::fill(const FetchHeaders& otherHeaders) +{ + for (auto& header : otherHeaders.m_headers) { + auto result = appendToHeaderMap(header, m_headers, m_guard); + if (result.hasException()) + return result.releaseException(); + } + + return { }; +} + +ExceptionOr<void> FetchHeaders::append(const String& name, const String& value) +{ + return appendToHeaderMap(name, value, m_headers, m_guard); +} + +// https://fetch.spec.whatwg.org/#dom-headers-delete +ExceptionOr<void> FetchHeaders::remove(const String& name) +{ + if (!isValidHTTPToken(name)) + return Exception { TypeError, makeString("Invalid header name: '", name, "'") }; + if (m_guard == FetchHeaders::Guard::Immutable) + return Exception { TypeError, "Headers object's guard is 'immutable'"_s }; + if (m_guard == FetchHeaders::Guard::Request && isForbiddenHeaderName(name)) + return { }; + if (m_guard == FetchHeaders::Guard::RequestNoCors && !isNoCORSSafelistedRequestHeaderName(name) && !isPriviledgedNoCORSRequestHeaderName(name)) + return { }; + if (m_guard == FetchHeaders::Guard::Response && isForbiddenResponseHeaderName(name)) + return { }; + + m_headers.remove(name); + + if (m_guard == FetchHeaders::Guard::RequestNoCors) + removePrivilegedNoCORSRequestHeaders(m_headers); + + return { }; +} + +ExceptionOr<String> FetchHeaders::get(const String& name) const +{ + if (!isValidHTTPToken(name)) + return Exception { TypeError, makeString("Invalid header name: '", name, "'") }; + return m_headers.get(name); +} + +ExceptionOr<bool> FetchHeaders::has(const String& name) const +{ + if (!isValidHTTPToken(name)) + return Exception { TypeError, makeString("Invalid header name: '", name, "'") }; + return m_headers.contains(name); +} + +ExceptionOr<void> FetchHeaders::set(const String& name, const String& value) +{ + String normalizedValue = stripLeadingAndTrailingHTTPSpaces(value); + auto canWriteResult = canWriteHeader(name, normalizedValue, normalizedValue, m_guard); + if (canWriteResult.hasException()) + return canWriteResult.releaseException(); + if (!canWriteResult.releaseReturnValue()) + return { }; + + m_headers.set(name, normalizedValue); + + if (m_guard == FetchHeaders::Guard::RequestNoCors) + removePrivilegedNoCORSRequestHeaders(m_headers); + + return { }; +} + +void FetchHeaders::filterAndFill(const HTTPHeaderMap& headers, Guard guard) +{ + for (auto& header : headers) { + String normalizedValue = stripLeadingAndTrailingHTTPSpaces(header.value); + auto canWriteResult = canWriteHeader(header.key, normalizedValue, header.value, guard); + if (canWriteResult.hasException()) + continue; + if (!canWriteResult.releaseReturnValue()) + continue; + if (header.keyAsHTTPHeaderName) + m_headers.add(header.keyAsHTTPHeaderName.value(), header.value); + else + m_headers.add(header.key, header.value); + } +} + +std::optional<KeyValuePair<String, String>> FetchHeaders::Iterator::next() +{ + while (m_currentIndex < m_keys.size()) { + auto key = m_keys[m_currentIndex++]; + auto value = m_headers->m_headers.get(key); + if (!value.isNull()) + return KeyValuePair<String, String> { WTFMove(key), WTFMove(value) }; + } + return std::nullopt; +} + +FetchHeaders::Iterator::Iterator(FetchHeaders& headers) + : m_headers(headers) +{ + m_keys.reserveInitialCapacity(headers.m_headers.size()); + for (auto& header : headers.m_headers) + m_keys.uncheckedAppend(header.key.convertToASCIILowercase()); + std::sort(m_keys.begin(), m_keys.end(), WTF::codePointCompareLessThan); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/FetchHeaders.h b/src/bun.js/bindings/webcore/FetchHeaders.h new file mode 100644 index 000000000..b116cf978 --- /dev/null +++ b/src/bun.js/bindings/webcore/FetchHeaders.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2016 Canon Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions + * are required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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 "ExceptionOr.h" +#include "HTTPHeaderMap.h" +#include <variant> +#include <wtf/HashTraits.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class FetchHeaders : public RefCounted<FetchHeaders> { +public: + enum class Guard { + None, + Immutable, + Request, + RequestNoCors, + Response + }; + + using Init = std::variant<Vector<Vector<String>>, Vector<KeyValuePair<String, String>>>; + static ExceptionOr<Ref<FetchHeaders>> create(std::optional<Init>&&); + + static Ref<FetchHeaders> create(Guard guard = Guard::None, HTTPHeaderMap&& headers = {}) { return adoptRef(*new FetchHeaders { guard, WTFMove(headers) }); } + static Ref<FetchHeaders> create(const FetchHeaders& headers) { return adoptRef(*new FetchHeaders { headers }); } + + ExceptionOr<void> append(const String& name, const String& value); + ExceptionOr<void> remove(const String&); + ExceptionOr<String> get(const String&) const; + ExceptionOr<bool> has(const String&) const; + ExceptionOr<void> set(const String& name, const String& value); + + ExceptionOr<void> fill(const Init&); + ExceptionOr<void> fill(const FetchHeaders&); + void filterAndFill(const HTTPHeaderMap&, Guard); + + inline uint32_t size() + { + return m_headers.size(); + } + + String fastGet(HTTPHeaderName name) const { return m_headers.get(name); } + bool fastHas(HTTPHeaderName name) const { return m_headers.contains(name); } + void fastSet(HTTPHeaderName name, const String& value) { m_headers.set(name, value); } + + class Iterator { + public: + explicit Iterator(FetchHeaders&); + std::optional<KeyValuePair<String, String>> next(); + + private: + Ref<FetchHeaders> m_headers; + size_t m_currentIndex { 0 }; + Vector<String> m_keys; + }; + Iterator createIterator() { return Iterator { *this }; } + + void setInternalHeaders(HTTPHeaderMap&& headers) { m_headers = WTFMove(headers); } + const HTTPHeaderMap& internalHeaders() const { return m_headers; } + + void setGuard(Guard); + Guard guard() const { return m_guard; } + + FetchHeaders(Guard, HTTPHeaderMap&&); + explicit FetchHeaders(const FetchHeaders&); + +private: + Guard m_guard; + HTTPHeaderMap m_headers; +}; + +inline FetchHeaders::FetchHeaders(Guard guard, HTTPHeaderMap&& headers) + : m_guard(guard) + , m_headers(WTFMove(headers)) +{ +} + +inline FetchHeaders::FetchHeaders(const FetchHeaders& other) + : RefCounted<FetchHeaders>() + , m_guard(other.m_guard) + , m_headers(other.m_headers) +{ +} + +inline void FetchHeaders::setGuard(Guard guard) +{ + ASSERT(!m_headers.size()); + m_guard = guard; +} + +} // namespace WebCore + +namespace WTF { + +template<> struct EnumTraits<WebCore::FetchHeaders::Guard> { + using values = EnumValues< + WebCore::FetchHeaders::Guard, + WebCore::FetchHeaders::Guard::None, + WebCore::FetchHeaders::Guard::Immutable, + WebCore::FetchHeaders::Guard::Request, + WebCore::FetchHeaders::Guard::RequestNoCors, + WebCore::FetchHeaders::Guard::Response>; +}; + +} diff --git a/src/bun.js/bindings/webcore/FetchHeaders.idl b/src/bun.js/bindings/webcore/FetchHeaders.idl new file mode 100644 index 000000000..daa0ebb8e --- /dev/null +++ b/src/bun.js/bindings/webcore/FetchHeaders.idl @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 Canon Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions + * are required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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. + */ + +typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) HeadersInit; + +[ + Exposed=(Window,Worker), + InterfaceName=Headers, +] interface FetchHeaders { + constructor(optional HeadersInit init); + + undefined append(ByteString name, ByteString value); + [ImplementedAs=remove] undefined delete(ByteString name); + ByteString? get(ByteString name); + boolean has(ByteString name); + undefined set(ByteString name, ByteString value); + + iterable<ByteString, ByteString>; +}; diff --git a/src/bun.js/bindings/webcore/HTTPHeaderField.cpp b/src/bun.js/bindings/webcore/HTTPHeaderField.cpp new file mode 100644 index 000000000..a4d101bdd --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderField.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2017 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 "HTTPHeaderField.h" + +namespace WebCore { + +namespace RFC7230 { + +bool isTokenCharacter(UChar c) +{ + return isASCIIAlpha(c) || isASCIIDigit(c) + || c == '!' || c == '#' || c == '$' + || c == '%' || c == '&' || c == '\'' + || c == '*' || c == '+' || c == '-' + || c == '.' || c == '^' || c == '_' + || c == '`' || c == '|' || c == '~'; +} + +bool isDelimiter(UChar c) +{ + return c == '(' || c == ')' || c == ',' + || c == '/' || c == ':' || c == ';' + || c == '<' || c == '=' || c == '>' + || c == '?' || c == '@' || c == '[' + || c == '\\' || c == ']' || c == '{' + || c == '}' || c == '"'; +} + +static bool isVisibleCharacter(UChar c) +{ + return isTokenCharacter(c) || isDelimiter(c); +} + +bool isWhitespace(UChar c) +{ + return c == ' ' || c == '\t'; +} + +template<size_t min, size_t max> +static bool isInRange(UChar c) +{ + return c >= min && c <= max; +} + +static bool isOBSText(UChar c) +{ + return isInRange<0x80, 0xFF>(c); +} + +static bool isQuotedTextCharacter(UChar c) +{ + return isWhitespace(c) + || c == 0x21 + || isInRange<0x23, 0x5B>(c) + || isInRange<0x5D, 0x7E>(c) + || isOBSText(c); +} + +bool isQuotedPairSecondOctet(UChar c) +{ + return isWhitespace(c) + || isVisibleCharacter(c) + || isOBSText(c); +} + +bool isCommentText(UChar c) +{ + return isWhitespace(c) + || isInRange<0x21, 0x27>(c) + || isInRange<0x2A, 0x5B>(c) + || isInRange<0x5D, 0x7E>(c) + || isOBSText(c); +} + +static bool isValidName(StringView name) +{ + if (!name.length()) + return false; + for (size_t i = 0; i < name.length(); ++i) { + if (!isTokenCharacter(name[i])) + return false; + } + return true; +} + +static bool isValidValue(StringView value) +{ + enum class State { + OptionalWhitespace, + Token, + QuotedString, + Comment, + }; + State state = State::OptionalWhitespace; + size_t commentDepth = 0; + bool hadNonWhitespace = false; + + for (size_t i = 0; i < value.length(); ++i) { + UChar c = value[i]; + switch (state) { + case State::OptionalWhitespace: + if (isWhitespace(c)) + continue; + hadNonWhitespace = true; + if (isTokenCharacter(c)) { + state = State::Token; + continue; + } + if (c == '"') { + state = State::QuotedString; + continue; + } + if (c == '(') { + ASSERT(!commentDepth); + ++commentDepth; + state = State::Comment; + continue; + } + return false; + + case State::Token: + if (isTokenCharacter(c)) + continue; + state = State::OptionalWhitespace; + continue; + case State::QuotedString: + if (c == '"') { + state = State::OptionalWhitespace; + continue; + } + if (c == '\\') { + ++i; + if (i == value.length()) + return false; + if (!isQuotedPairSecondOctet(value[i])) + return false; + continue; + } + if (!isQuotedTextCharacter(c)) + return false; + continue; + case State::Comment: + if (c == '(') { + ++commentDepth; + continue; + } + if (c == ')') { + --commentDepth; + if (!commentDepth) + state = State::OptionalWhitespace; + continue; + } + if (c == '\\') { + ++i; + if (i == value.length()) + return false; + if (!isQuotedPairSecondOctet(value[i])) + return false; + continue; + } + if (!isCommentText(c)) + return false; + continue; + } + } + + switch (state) { + case State::OptionalWhitespace: + case State::Token: + return hadNonWhitespace; + case State::QuotedString: + case State::Comment: + // Unclosed comments or quotes are invalid values. + break; + } + return false; +} + +} // namespace RFC7230 + +std::optional<HTTPHeaderField> HTTPHeaderField::create(String&& unparsedName, String&& unparsedValue) +{ + StringView strippedName = StringView(unparsedName).stripLeadingAndTrailingMatchedCharacters(RFC7230::isWhitespace); + StringView strippedValue = StringView(unparsedValue).stripLeadingAndTrailingMatchedCharacters(RFC7230::isWhitespace); + if (!RFC7230::isValidName(strippedName) || !RFC7230::isValidValue(strippedValue)) + return std::nullopt; + + String name = strippedName.length() == unparsedName.length() ? WTFMove(unparsedName) : strippedName.toString(); + String value = strippedValue.length() == unparsedValue.length() ? WTFMove(unparsedValue) : strippedValue.toString(); + return {{ WTFMove(name), WTFMove(value) }}; +} + +} diff --git a/src/bun.js/bindings/webcore/HTTPHeaderField.h b/src/bun.js/bindings/webcore/HTTPHeaderField.h new file mode 100644 index 000000000..c5fbc1b43 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderField.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2017 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. + */ + +#pragma once + +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class WEBCORE_EXPORT HTTPHeaderField { +public: + static std::optional<HTTPHeaderField> create(String&& name, String&& value); + + const String& name() const { return m_name; } + const String& value() const { return m_value; } + + template<class Encoder> void encode(Encoder&) const; + template<class Decoder> static std::optional<HTTPHeaderField> decode(Decoder&); + +private: + HTTPHeaderField(String&& name, String&& value) + : m_name(WTFMove(name)) + , m_value(WTFMove(value)) + { } + String m_name; + String m_value; +}; + +template<class Encoder> +void HTTPHeaderField::encode(Encoder& encoder) const +{ + encoder << m_name; + encoder << m_value; +} + +template<class Decoder> +std::optional<HTTPHeaderField> HTTPHeaderField::decode(Decoder& decoder) +{ + std::optional<String> name; + decoder >> name; + if (!name) + return std::nullopt; + + std::optional<String> value; + decoder >> value; + if (!value) + return std::nullopt; + + return {{ WTFMove(*name), WTFMove(*value) }}; +} + +namespace RFC7230 { +bool isTokenCharacter(UChar); +bool isWhitespace(UChar); +bool isCommentText(UChar); +bool isQuotedPairSecondOctet(UChar); +bool isDelimiter(UChar); +} // namespace RFC7230 + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/HTTPHeaderMap.cpp b/src/bun.js/bindings/webcore/HTTPHeaderMap.cpp new file mode 100644 index 000000000..bd516cf6c --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderMap.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 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 are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "HTTPHeaderMap.h" + +#include <utility> +#include <wtf/CrossThreadCopier.h> +#include <wtf/text/StringView.h> + +namespace WebCore { + +HTTPHeaderMap::HTTPHeaderMap() +{ +} + +HTTPHeaderMap HTTPHeaderMap::isolatedCopy() const & +{ + HTTPHeaderMap map; + map.m_commonHeaders = crossThreadCopy(m_commonHeaders); + map.m_uncommonHeaders = crossThreadCopy(m_uncommonHeaders); + return map; +} + +HTTPHeaderMap HTTPHeaderMap::isolatedCopy() && +{ + HTTPHeaderMap map; + map.m_commonHeaders = crossThreadCopy(WTFMove(m_commonHeaders)); + map.m_uncommonHeaders = crossThreadCopy(WTFMove(m_uncommonHeaders)); + return map; +} + +String HTTPHeaderMap::get(const String& name) const +{ + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) + return get(headerName); + + return getUncommonHeader(name); +} + +String HTTPHeaderMap::getUncommonHeader(const String& name) const +{ + auto index = m_uncommonHeaders.findIf([&](auto& header) { + return equalIgnoringASCIICase(header.key, name); + }); + return index != notFound ? m_uncommonHeaders[index].value : String(); +} + +#if USE(CF) + +void HTTPHeaderMap::set(CFStringRef name, const String& value) +{ + // Fast path: avoid constructing a temporary String in the common header case. + if (auto* nameCharacters = CFStringGetCStringPtr(name, kCFStringEncodingASCII)) { + unsigned length = CFStringGetLength(name); + HTTPHeaderName headerName; + if (findHTTPHeaderName(StringView(nameCharacters, length), headerName)) + set(headerName, value); + else + setUncommonHeader(String(nameCharacters, length), value); + + return; + } + + set(String(name), value); +} + +#endif // USE(CF) + +void HTTPHeaderMap::set(const String& name, const String& value) +{ + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) { + set(headerName, value); + return; + } + + setUncommonHeader(name, value); +} + +void HTTPHeaderMap::setUncommonHeader(const String& name, const String& value) +{ + auto index = m_uncommonHeaders.findIf([&](auto& header) { + return equalIgnoringASCIICase(header.key, name); + }); + if (index == notFound) + m_uncommonHeaders.append(UncommonHeader { name, value }); + else + m_uncommonHeaders[index].value = value; +} + +void HTTPHeaderMap::add(const String& name, const String& value) +{ + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) { + add(headerName, value); + return; + } + auto index = m_uncommonHeaders.findIf([&](auto& header) { + return equalIgnoringASCIICase(header.key, name); + }); + if (index == notFound) + m_uncommonHeaders.append(UncommonHeader { name, value }); + else + m_uncommonHeaders[index].value = makeString(m_uncommonHeaders[index].value, ", ", value); +} + +void HTTPHeaderMap::append(const String& name, const String& value) +{ + ASSERT(!contains(name)); + + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) + m_commonHeaders.append(CommonHeader { headerName, value }); + else + m_uncommonHeaders.append(UncommonHeader { name, value }); +} + +bool HTTPHeaderMap::addIfNotPresent(HTTPHeaderName headerName, const String& value) +{ + if (contains(headerName)) + return false; + + m_commonHeaders.append(CommonHeader { headerName, value }); + return true; +} + +bool HTTPHeaderMap::contains(const String& name) const +{ + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) + return contains(headerName); + + return m_uncommonHeaders.findIf([&](auto& header) { + return equalIgnoringASCIICase(header.key, name); + }) != notFound; +} + +bool HTTPHeaderMap::remove(const String& name) +{ + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) + return remove(headerName); + + return m_uncommonHeaders.removeFirstMatching([&](auto& header) { + return equalIgnoringASCIICase(header.key, name); + }); +} + +String HTTPHeaderMap::get(HTTPHeaderName name) const +{ + auto index = m_commonHeaders.findIf([&](auto& header) { + return header.key == name; + }); + return index != notFound ? m_commonHeaders[index].value : String(); +} + +void HTTPHeaderMap::set(HTTPHeaderName name, const String& value) +{ + auto index = m_commonHeaders.findIf([&](auto& header) { + return header.key == name; + }); + if (index == notFound) + m_commonHeaders.append(CommonHeader { name, value }); + else + m_commonHeaders[index].value = value; +} + +bool HTTPHeaderMap::contains(HTTPHeaderName name) const +{ + return m_commonHeaders.findIf([&](auto& header) { + return header.key == name; + }) != notFound; +} + +bool HTTPHeaderMap::remove(HTTPHeaderName name) +{ + return m_commonHeaders.removeFirstMatching([&](auto& header) { + return header.key == name; + }); +} + +void HTTPHeaderMap::add(HTTPHeaderName name, const String& value) +{ + auto index = m_commonHeaders.findIf([&](auto& header) { + return header.key == name; + }); + if (index != notFound) + m_commonHeaders[index].value = makeString(m_commonHeaders[index].value, ", ", value); + else + m_commonHeaders.append(CommonHeader { name, value }); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/HTTPHeaderMap.h b/src/bun.js/bindings/webcore/HTTPHeaderMap.h new file mode 100644 index 000000000..1fe19d311 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderMap.h @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2006 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google 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. + */ + +#pragma once + +#include "HTTPHeaderNames.h" +#include <utility> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +// FIXME: Not every header fits into a map. Notably, multiple Set-Cookie header fields are needed to set multiple cookies. + +class HTTPHeaderMap { +public: + struct CommonHeader { + HTTPHeaderName key; + String value; + + CommonHeader isolatedCopy() const & { return { key , value.isolatedCopy() }; } + CommonHeader isolatedCopy() && { return { key , WTFMove(value).isolatedCopy() }; } + template <class Encoder> void encode(Encoder&) const; + template <class Decoder> static std::optional<CommonHeader> decode(Decoder&); + + bool operator==(const CommonHeader& other) const { return key == other.key && value == other.value; } + }; + + struct UncommonHeader { + String key; + String value; + + UncommonHeader isolatedCopy() const & { return { key.isolatedCopy() , value.isolatedCopy() }; } + UncommonHeader isolatedCopy() && { return { WTFMove(key).isolatedCopy() , WTFMove(value).isolatedCopy() }; } + template <class Encoder> void encode(Encoder&) const; + template <class Decoder> static std::optional<UncommonHeader> decode(Decoder&); + + bool operator==(const UncommonHeader& other) const { return key == other.key && value == other.value; } + }; + + typedef Vector<CommonHeader, 0, CrashOnOverflow, 6> CommonHeadersVector; + typedef Vector<UncommonHeader, 0, CrashOnOverflow, 0> UncommonHeadersVector; + + class HTTPHeaderMapConstIterator { + public: + HTTPHeaderMapConstIterator(const HTTPHeaderMap& table, CommonHeadersVector::const_iterator commonHeadersIt, UncommonHeadersVector::const_iterator uncommonHeadersIt) + : m_table(table) + , m_commonHeadersIt(commonHeadersIt) + , m_uncommonHeadersIt(uncommonHeadersIt) + { + if (!updateKeyValue(m_commonHeadersIt)) + updateKeyValue(m_uncommonHeadersIt); + } + + struct KeyValue { + String key; + std::optional<HTTPHeaderName> keyAsHTTPHeaderName; + String value; + }; + + const KeyValue* get() const + { + ASSERT(*this != m_table.end()); + return &m_keyValue; + } + const KeyValue& operator*() const { return *get(); } + const KeyValue* operator->() const { return get(); } + + HTTPHeaderMapConstIterator& operator++() + { + if (m_commonHeadersIt != m_table.m_commonHeaders.end()) { + if (updateKeyValue(++m_commonHeadersIt)) + return *this; + } else + ++m_uncommonHeadersIt; + + updateKeyValue(m_uncommonHeadersIt); + return *this; + } + + bool operator!=(const HTTPHeaderMapConstIterator& other) const { return !(*this == other); } + bool operator==(const HTTPHeaderMapConstIterator& other) const + { + return m_commonHeadersIt == other.m_commonHeadersIt && m_uncommonHeadersIt == other.m_uncommonHeadersIt; + } + + private: + bool updateKeyValue(CommonHeadersVector::const_iterator it) + { + if (it == m_table.commonHeaders().end()) + return false; + m_keyValue.key = httpHeaderNameString(it->key).toStringWithoutCopying(); + m_keyValue.keyAsHTTPHeaderName = it->key; + m_keyValue.value = it->value; + return true; + } + bool updateKeyValue(UncommonHeadersVector::const_iterator it) + { + if (it == m_table.uncommonHeaders().end()) + return false; + m_keyValue.key = it->key; + m_keyValue.keyAsHTTPHeaderName = std::nullopt; + m_keyValue.value = it->value; + return true; + } + + const HTTPHeaderMap& m_table; + CommonHeadersVector::const_iterator m_commonHeadersIt; + UncommonHeadersVector::const_iterator m_uncommonHeadersIt; + KeyValue m_keyValue; + }; + typedef HTTPHeaderMapConstIterator const_iterator; + + WEBCORE_EXPORT HTTPHeaderMap(); + + // Gets a copy of the data suitable for passing to another thread. + WEBCORE_EXPORT HTTPHeaderMap isolatedCopy() const &; + WEBCORE_EXPORT HTTPHeaderMap isolatedCopy() &&; + + bool isEmpty() const { return m_commonHeaders.isEmpty() && m_uncommonHeaders.isEmpty(); } + int size() const { return m_commonHeaders.size() + m_uncommonHeaders.size(); } + + void clear() + { + m_commonHeaders.clear(); + m_uncommonHeaders.clear(); + } + + void shrinkToFit() + { + m_commonHeaders.shrinkToFit(); + m_uncommonHeaders.shrinkToFit(); + } + + WEBCORE_EXPORT String get(const String& name) const; + WEBCORE_EXPORT void set(const String& name, const String& value); + WEBCORE_EXPORT void add(const String& name, const String& value); + WEBCORE_EXPORT void append(const String& name, const String& value); + WEBCORE_EXPORT bool contains(const String&) const; + WEBCORE_EXPORT bool remove(const String&); + +#if USE(CF) + void set(CFStringRef name, const String& value); +#ifdef __OBJC__ + void set(NSString *name, const String& value) { set((__bridge CFStringRef)name, value); } +#endif +#endif + + WEBCORE_EXPORT String get(HTTPHeaderName) const; + void set(HTTPHeaderName, const String& value); + void add(HTTPHeaderName, const String& value); + bool addIfNotPresent(HTTPHeaderName, const String&); + WEBCORE_EXPORT bool contains(HTTPHeaderName) const; + WEBCORE_EXPORT bool remove(HTTPHeaderName); + + // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead. + template<size_t length> String get(const char (&)[length]) const = delete; + template<size_t length> void set(const char (&)[length], const String&) = delete; + template<size_t length> bool contains(const char (&)[length]) = delete; + template<size_t length> bool remove(const char (&)[length]) = delete; + + const CommonHeadersVector& commonHeaders() const { return m_commonHeaders; } + const UncommonHeadersVector& uncommonHeaders() const { return m_uncommonHeaders; } + CommonHeadersVector& commonHeaders() { return m_commonHeaders; } + UncommonHeadersVector& uncommonHeaders() { return m_uncommonHeaders; } + + const_iterator begin() const { return const_iterator(*this, m_commonHeaders.begin(), m_uncommonHeaders.begin()); } + const_iterator end() const { return const_iterator(*this, m_commonHeaders.end(), m_uncommonHeaders.end()); } + + friend bool operator==(const HTTPHeaderMap& a, const HTTPHeaderMap& b) + { + if (a.m_commonHeaders.size() != b.m_commonHeaders.size() || a.m_uncommonHeaders.size() != b.m_uncommonHeaders.size()) + return false; + for (auto& commonHeader : a.m_commonHeaders) { + if (b.get(commonHeader.key) != commonHeader.value) + return false; + } + for (auto& uncommonHeader : a.m_uncommonHeaders) { + if (b.getUncommonHeader(uncommonHeader.key) != uncommonHeader.value) + return false; + } + return true; + } + + friend bool operator!=(const HTTPHeaderMap& a, const HTTPHeaderMap& b) + { + return !(a == b); + } + + template <class Encoder> void encode(Encoder&) const; + template <class Decoder> static WARN_UNUSED_RETURN bool decode(Decoder&, HTTPHeaderMap&); + +private: + void setUncommonHeader(const String& name, const String& value); + WEBCORE_EXPORT String getUncommonHeader(const String& name) const; + + CommonHeadersVector m_commonHeaders; + UncommonHeadersVector m_uncommonHeaders; +}; + +template <class Encoder> +void HTTPHeaderMap::CommonHeader::encode(Encoder& encoder) const +{ + encoder << key; + encoder << value; +} + +template <class Decoder> +auto HTTPHeaderMap::CommonHeader::decode(Decoder& decoder) -> std::optional<CommonHeader> +{ + HTTPHeaderName name; + if (!decoder.decode(name)) + return std::nullopt; + String value; + if (!decoder.decode(value)) + return std::nullopt; + + return CommonHeader { name, WTFMove(value) }; +} + +template <class Encoder> +void HTTPHeaderMap::UncommonHeader::encode(Encoder& encoder) const +{ + encoder << key; + encoder << value; +} + +template <class Decoder> +auto HTTPHeaderMap::UncommonHeader::decode(Decoder& decoder) -> std::optional<UncommonHeader> +{ + String name; + if (!decoder.decode(name)) + return std::nullopt; + String value; + if (!decoder.decode(value)) + return std::nullopt; + + return UncommonHeader { WTFMove(name), WTFMove(value) }; +} + +template <class Encoder> +void HTTPHeaderMap::encode(Encoder& encoder) const +{ + encoder << m_commonHeaders; + encoder << m_uncommonHeaders; +} + +template <class Decoder> +bool HTTPHeaderMap::decode(Decoder& decoder, HTTPHeaderMap& headerMap) +{ + if (!decoder.decode(headerMap.m_commonHeaders)) + return false; + + if (!decoder.decode(headerMap.m_uncommonHeaders)) + return false; + + return true; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/HTTPHeaderNames.cpp b/src/bun.js/bindings/webcore/HTTPHeaderNames.cpp new file mode 100644 index 000000000..2846f15e5 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderNames.cpp @@ -0,0 +1,718 @@ +/* C++ code produced by gperf version 3.0.3 */ +/* Command-line: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/gperf --key-positions='*' -D -n -s 2 --output-file=HTTPHeaderNames.cpp HTTPHeaderNames.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + +#line 2 "HTTPHeaderNames.gperf" + +/* + * Copyright (C) 2014 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. + */ + +/// This file is generated by create-http-header-name-table, do not edit. + +#include "config.h" +#include "HTTPHeaderNames.h" + +#include <wtf/text/StringView.h> + +IGNORE_WARNINGS_BEGIN("implicit-fallthrough") + +// Older versions of gperf like to use the `register` keyword. +#define register + +namespace WebCore { + +static const struct HeaderNameString { + const char* const name; + unsigned length; +} headerNameStrings[] = { + { "Accept", 6 }, + { "Accept-Charset", 14 }, + { "Accept-Encoding", 15 }, + { "Accept-Language", 15 }, + { "Accept-Ranges", 13 }, + { "Access-Control-Allow-Credentials", 32 }, + { "Access-Control-Allow-Headers", 28 }, + { "Access-Control-Allow-Methods", 28 }, + { "Access-Control-Allow-Origin", 27 }, + { "Access-Control-Expose-Headers", 29 }, + { "Access-Control-Max-Age", 22 }, + { "Access-Control-Request-Headers", 30 }, + { "Access-Control-Request-Method", 29 }, + { "Age", 3 }, + { "Authorization", 13 }, + { "Cache-Control", 13 }, + { "Connection", 10 }, + { "Content-Disposition", 19 }, + { "Content-Encoding", 16 }, + { "Content-Language", 16 }, + { "Content-Length", 14 }, + { "Content-Location", 16 }, + { "Content-Range", 13 }, + { "Content-Security-Policy", 23 }, + { "Content-Security-Policy-Report-Only", 35 }, + { "Content-Type", 12 }, + { "Cookie", 6 }, + { "Cookie2", 7 }, + { "Cross-Origin-Embedder-Policy", 28 }, + { "Cross-Origin-Embedder-Policy-Report-Only", 40 }, + { "Cross-Origin-Opener-Policy", 26 }, + { "Cross-Origin-Opener-Policy-Report-Only", 38 }, + { "Cross-Origin-Resource-Policy", 28 }, + { "DNT", 3 }, + { "Date", 4 }, + { "Default-Style", 13 }, + { "ETag", 4 }, + { "Expect", 6 }, + { "Expires", 7 }, + { "Host", 4 }, + { "Icy-MetaInt", 11 }, + { "Icy-Metadata", 12 }, + { "If-Match", 8 }, + { "If-Modified-Since", 17 }, + { "If-None-Match", 13 }, + { "If-Range", 8 }, + { "If-Unmodified-Since", 19 }, + { "Keep-Alive", 10 }, + { "Last-Event-ID", 13 }, + { "Last-Modified", 13 }, + { "Link", 4 }, + { "Location", 8 }, + { "Origin", 6 }, + { "Ping-From", 9 }, + { "Ping-To", 7 }, + { "Pragma", 6 }, + { "Proxy-Authorization", 19 }, + { "Purpose", 7 }, + { "Range", 5 }, + { "Referer", 7 }, + { "Referrer-Policy", 15 }, + { "Refresh", 7 }, + { "Report-To", 9 }, + { "Sec-Fetch-Dest", 14 }, + { "Sec-Fetch-Mode", 14 }, + { "Sec-WebSocket-Accept", 20 }, + { "Sec-WebSocket-Extensions", 24 }, + { "Sec-WebSocket-Key", 17 }, + { "Sec-WebSocket-Protocol", 22 }, + { "Sec-WebSocket-Version", 21 }, + { "Server-Timing", 13 }, + { "Service-Worker", 14 }, + { "Service-Worker-Allowed", 22 }, + { "Service-Worker-Navigation-Preload", 33 }, + { "Set-Cookie", 10 }, + { "Set-Cookie2", 11 }, + { "SourceMap", 9 }, + { "TE", 2 }, + { "Timing-Allow-Origin", 19 }, + { "Trailer", 7 }, + { "Transfer-Encoding", 17 }, + { "Upgrade", 7 }, + { "Upgrade-Insecure-Requests", 25 }, + { "User-Agent", 10 }, + { "Vary", 4 }, + { "Via", 3 }, + { "X-Content-Type-Options", 22 }, + { "X-DNS-Prefetch-Control", 22 }, + { "X-Frame-Options", 15 }, + { "X-SourceMap", 11 }, + { "X-Temp-Tablet", 13 }, + { "X-XSS-Protection", 16 }, +}; + + +#line 149 "HTTPHeaderNames.gperf" +struct HeaderNameHashEntry { + const char* name; + HTTPHeaderName headerName; +}; +enum + { + TOTAL_KEYWORDS = 92, + MIN_WORD_LENGTH = 2, + MAX_WORD_LENGTH = 40, + MIN_HASH_VALUE = 5, + MAX_HASH_VALUE = 815 + }; + +/* maximum key range = 811, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRNCMP +#define GPERF_CASE_STRNCMP 1 +static int +gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) +{ + for (; n > 0;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + { + n--; + continue; + } + return (int)c1 - (int)c2; + } + return 0; +} +#endif + +class HTTPHeaderNamesHash +{ +private: + static inline unsigned int header_name_hash_function (const char *str, unsigned int len); +public: + static const struct HeaderNameHashEntry *findHeaderNameImpl (const char *str, unsigned int len); +}; + +inline unsigned int +HTTPHeaderNamesHash::header_name_hash_function (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 0, 816, 816, 816, 816, + 5, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 0, 40, 0, 115, 0, + 120, 10, 155, 5, 816, 4, 45, 155, 5, 0, + 30, 0, 5, 60, 5, 5, 135, 55, 50, 15, + 60, 816, 816, 816, 816, 816, 816, 0, 40, 0, + 115, 0, 120, 10, 155, 5, 816, 4, 45, 155, + 5, 0, 30, 0, 5, 60, 5, 5, 135, 55, + 50, 15, 60, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816 + }; + register unsigned int hval = 0; + + switch (len) + { + default: + hval += asso_values[(unsigned char)str[39]]; + /*FALLTHROUGH*/ + case 39: + hval += asso_values[(unsigned char)str[38]]; + /*FALLTHROUGH*/ + case 38: + hval += asso_values[(unsigned char)str[37]]; + /*FALLTHROUGH*/ + case 37: + hval += asso_values[(unsigned char)str[36]]; + /*FALLTHROUGH*/ + case 36: + hval += asso_values[(unsigned char)str[35]]; + /*FALLTHROUGH*/ + case 35: + hval += asso_values[(unsigned char)str[34]]; + /*FALLTHROUGH*/ + case 34: + hval += asso_values[(unsigned char)str[33]]; + /*FALLTHROUGH*/ + case 33: + hval += asso_values[(unsigned char)str[32]]; + /*FALLTHROUGH*/ + case 32: + hval += asso_values[(unsigned char)str[31]]; + /*FALLTHROUGH*/ + case 31: + hval += asso_values[(unsigned char)str[30]]; + /*FALLTHROUGH*/ + case 30: + hval += asso_values[(unsigned char)str[29]]; + /*FALLTHROUGH*/ + case 29: + hval += asso_values[(unsigned char)str[28]]; + /*FALLTHROUGH*/ + case 28: + hval += asso_values[(unsigned char)str[27]]; + /*FALLTHROUGH*/ + case 27: + hval += asso_values[(unsigned char)str[26]]; + /*FALLTHROUGH*/ + case 26: + hval += asso_values[(unsigned char)str[25]]; + /*FALLTHROUGH*/ + case 25: + hval += asso_values[(unsigned char)str[24]]; + /*FALLTHROUGH*/ + case 24: + hval += asso_values[(unsigned char)str[23]]; + /*FALLTHROUGH*/ + case 23: + hval += asso_values[(unsigned char)str[22]]; + /*FALLTHROUGH*/ + case 22: + hval += asso_values[(unsigned char)str[21]]; + /*FALLTHROUGH*/ + case 21: + hval += asso_values[(unsigned char)str[20]]; + /*FALLTHROUGH*/ + case 20: + hval += asso_values[(unsigned char)str[19]]; + /*FALLTHROUGH*/ + case 19: + hval += asso_values[(unsigned char)str[18]]; + /*FALLTHROUGH*/ + case 18: + hval += asso_values[(unsigned char)str[17]]; + /*FALLTHROUGH*/ + case 17: + hval += asso_values[(unsigned char)str[16]]; + /*FALLTHROUGH*/ + case 16: + hval += asso_values[(unsigned char)str[15]]; + /*FALLTHROUGH*/ + case 15: + hval += asso_values[(unsigned char)str[14]]; + /*FALLTHROUGH*/ + case 14: + hval += asso_values[(unsigned char)str[13]]; + /*FALLTHROUGH*/ + case 13: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval; +} + +static const struct HeaderNameHashEntry header_name_wordlist[] = + { +#line 236 "HTTPHeaderNames.gperf" + {"TE", HTTPHeaderName::TE}, +#line 185 "HTTPHeaderNames.gperf" + {"Cookie", HTTPHeaderName::Cookie}, +#line 172 "HTTPHeaderNames.gperf" + {"Age", HTTPHeaderName::Age}, +#line 186 "HTTPHeaderNames.gperf" + {"Cookie2", HTTPHeaderName::Cookie2}, +#line 195 "HTTPHeaderNames.gperf" + {"ETag", HTTPHeaderName::ETag}, +#line 217 "HTTPHeaderNames.gperf" + {"Range", HTTPHeaderName::Range}, +#line 175 "HTTPHeaderNames.gperf" + {"Connection", HTTPHeaderName::Connection}, +#line 211 "HTTPHeaderNames.gperf" + {"Origin", HTTPHeaderName::Origin}, +#line 159 "HTTPHeaderNames.gperf" + {"Accept", HTTPHeaderName::Accept}, +#line 181 "HTTPHeaderNames.gperf" + {"Content-Range", HTTPHeaderName::ContentRange}, +#line 221 "HTTPHeaderNames.gperf" + {"Report-To", HTTPHeaderName::ReportTo}, +#line 213 "HTTPHeaderNames.gperf" + {"Ping-To", HTTPHeaderName::PingTo}, +#line 209 "HTTPHeaderNames.gperf" + {"Link", HTTPHeaderName::Link}, +#line 210 "HTTPHeaderNames.gperf" + {"Location", HTTPHeaderName::Location}, +#line 238 "HTTPHeaderNames.gperf" + {"Trailer", HTTPHeaderName::Trailer}, +#line 184 "HTTPHeaderNames.gperf" + {"Content-Type", HTTPHeaderName::ContentType}, +#line 233 "HTTPHeaderNames.gperf" + {"Set-Cookie", HTTPHeaderName::SetCookie}, +#line 234 "HTTPHeaderNames.gperf" + {"Set-Cookie2", HTTPHeaderName::SetCookie2}, +#line 180 "HTTPHeaderNames.gperf" + {"Content-Location", HTTPHeaderName::ContentLocation}, +#line 196 "HTTPHeaderNames.gperf" + {"Expect", HTTPHeaderName::Expect}, +#line 242 "HTTPHeaderNames.gperf" + {"User-Agent", HTTPHeaderName::UserAgent}, +#line 178 "HTTPHeaderNames.gperf" + {"Content-Language", HTTPHeaderName::ContentLanguage}, +#line 162 "HTTPHeaderNames.gperf" + {"Accept-Language", HTTPHeaderName::AcceptLanguage}, +#line 163 "HTTPHeaderNames.gperf" + {"Accept-Ranges", HTTPHeaderName::AcceptRanges}, +#line 193 "HTTPHeaderNames.gperf" + {"Date", HTTPHeaderName::Date}, +#line 192 "HTTPHeaderNames.gperf" + {"DNT", HTTPHeaderName::DNT}, +#line 216 "HTTPHeaderNames.gperf" + {"Purpose", HTTPHeaderName::Purpose}, +#line 218 "HTTPHeaderNames.gperf" + {"Referer", HTTPHeaderName::Referer}, +#line 244 "HTTPHeaderNames.gperf" + {"Via", HTTPHeaderName::Via}, +#line 204 "HTTPHeaderNames.gperf" + {"If-Range", HTTPHeaderName::IfRange}, +#line 197 "HTTPHeaderNames.gperf" + {"Expires", HTTPHeaderName::Expires}, +#line 243 "HTTPHeaderNames.gperf" + {"Vary", HTTPHeaderName::Vary}, +#line 177 "HTTPHeaderNames.gperf" + {"Content-Encoding", HTTPHeaderName::ContentEncoding}, +#line 240 "HTTPHeaderNames.gperf" + {"Upgrade", HTTPHeaderName::Upgrade}, +#line 161 "HTTPHeaderNames.gperf" + {"Accept-Encoding", HTTPHeaderName::AcceptEncoding}, +#line 199 "HTTPHeaderNames.gperf" + {"Icy-MetaInt", HTTPHeaderName::IcyMetaInt}, +#line 214 "HTTPHeaderNames.gperf" + {"Pragma", HTTPHeaderName::Pragma}, +#line 182 "HTTPHeaderNames.gperf" + {"Content-Security-Policy", HTTPHeaderName::ContentSecurityPolicy}, +#line 174 "HTTPHeaderNames.gperf" + {"Cache-Control", HTTPHeaderName::CacheControl}, +#line 206 "HTTPHeaderNames.gperf" + {"Keep-Alive", HTTPHeaderName::KeepAlive}, +#line 198 "HTTPHeaderNames.gperf" + {"Host", HTTPHeaderName::Host}, +#line 245 "HTTPHeaderNames.gperf" + {"X-Content-Type-Options", HTTPHeaderName::XContentTypeOptions}, +#line 219 "HTTPHeaderNames.gperf" + {"Referrer-Policy", HTTPHeaderName::ReferrerPolicy}, +#line 179 "HTTPHeaderNames.gperf" + {"Content-Length", HTTPHeaderName::ContentLength}, +#line 226 "HTTPHeaderNames.gperf" + {"Sec-WebSocket-Key", HTTPHeaderName::SecWebSocketKey}, +#line 173 "HTTPHeaderNames.gperf" + {"Authorization", HTTPHeaderName::Authorization}, +#line 235 "HTTPHeaderNames.gperf" + {"SourceMap", HTTPHeaderName::SourceMap}, +#line 224 "HTTPHeaderNames.gperf" + {"Sec-WebSocket-Accept", HTTPHeaderName::SecWebSocketAccept}, +#line 160 "HTTPHeaderNames.gperf" + {"Accept-Charset", HTTPHeaderName::AcceptCharset}, +#line 230 "HTTPHeaderNames.gperf" + {"Service-Worker", HTTPHeaderName::ServiceWorker}, +#line 250 "HTTPHeaderNames.gperf" + {"X-XSS-Protection", HTTPHeaderName::XXSSProtection}, +#line 189 "HTTPHeaderNames.gperf" + {"Cross-Origin-Opener-Policy", HTTPHeaderName::CrossOriginOpenerPolicy}, +#line 200 "HTTPHeaderNames.gperf" + {"Icy-Metadata", HTTPHeaderName::IcyMetadata}, +#line 248 "HTTPHeaderNames.gperf" + {"X-SourceMap", HTTPHeaderName::XSourceMap}, +#line 227 "HTTPHeaderNames.gperf" + {"Sec-WebSocket-Protocol", HTTPHeaderName::SecWebSocketProtocol}, +#line 176 "HTTPHeaderNames.gperf" + {"Content-Disposition", HTTPHeaderName::ContentDisposition}, +#line 183 "HTTPHeaderNames.gperf" + {"Content-Security-Policy-Report-Only", HTTPHeaderName::ContentSecurityPolicyReportOnly}, +#line 191 "HTTPHeaderNames.gperf" + {"Cross-Origin-Resource-Policy", HTTPHeaderName::CrossOriginResourcePolicy}, +#line 212 "HTTPHeaderNames.gperf" + {"Ping-From", HTTPHeaderName::PingFrom}, +#line 249 "HTTPHeaderNames.gperf" + {"X-Temp-Tablet", HTTPHeaderName::XTempTablet}, +#line 239 "HTTPHeaderNames.gperf" + {"Transfer-Encoding", HTTPHeaderName::TransferEncoding}, +#line 220 "HTTPHeaderNames.gperf" + {"Refresh", HTTPHeaderName::Refresh}, +#line 215 "HTTPHeaderNames.gperf" + {"Proxy-Authorization", HTTPHeaderName::ProxyAuthorization}, +#line 167 "HTTPHeaderNames.gperf" + {"Access-Control-Allow-Origin", HTTPHeaderName::AccessControlAllowOrigin}, +#line 237 "HTTPHeaderNames.gperf" + {"Timing-Allow-Origin", HTTPHeaderName::TimingAllowOrigin}, +#line 207 "HTTPHeaderNames.gperf" + {"Last-Event-ID", HTTPHeaderName::LastEventID}, +#line 241 "HTTPHeaderNames.gperf" + {"Upgrade-Insecure-Requests", HTTPHeaderName::UpgradeInsecureRequests}, +#line 229 "HTTPHeaderNames.gperf" + {"Server-Timing", HTTPHeaderName::ServerTiming}, +#line 169 "HTTPHeaderNames.gperf" + {"Access-Control-Max-Age", HTTPHeaderName::AccessControlMaxAge}, +#line 190 "HTTPHeaderNames.gperf" + {"Cross-Origin-Opener-Policy-Report-Only", HTTPHeaderName::CrossOriginOpenerPolicyReportOnly}, +#line 225 "HTTPHeaderNames.gperf" + {"Sec-WebSocket-Extensions", HTTPHeaderName::SecWebSocketExtensions}, +#line 194 "HTTPHeaderNames.gperf" + {"Default-Style", HTTPHeaderName::DefaultStyle}, +#line 228 "HTTPHeaderNames.gperf" + {"Sec-WebSocket-Version", HTTPHeaderName::SecWebSocketVersion}, +#line 247 "HTTPHeaderNames.gperf" + {"X-Frame-Options", HTTPHeaderName::XFrameOptions}, +#line 201 "HTTPHeaderNames.gperf" + {"If-Match", HTTPHeaderName::IfMatch}, +#line 203 "HTTPHeaderNames.gperf" + {"If-None-Match", HTTPHeaderName::IfNoneMatch}, +#line 222 "HTTPHeaderNames.gperf" + {"Sec-Fetch-Dest", HTTPHeaderName::SecFetchDest}, +#line 231 "HTTPHeaderNames.gperf" + {"Service-Worker-Allowed", HTTPHeaderName::ServiceWorkerAllowed}, +#line 164 "HTTPHeaderNames.gperf" + {"Access-Control-Allow-Credentials", HTTPHeaderName::AccessControlAllowCredentials}, +#line 170 "HTTPHeaderNames.gperf" + {"Access-Control-Request-Headers", HTTPHeaderName::AccessControlRequestHeaders}, +#line 246 "HTTPHeaderNames.gperf" + {"X-DNS-Prefetch-Control", HTTPHeaderName::XDNSPrefetchControl}, +#line 223 "HTTPHeaderNames.gperf" + {"Sec-Fetch-Mode", HTTPHeaderName::SecFetchMode}, +#line 208 "HTTPHeaderNames.gperf" + {"Last-Modified", HTTPHeaderName::LastModified}, +#line 232 "HTTPHeaderNames.gperf" + {"Service-Worker-Navigation-Preload", HTTPHeaderName::ServiceWorkerNavigationPreload}, +#line 168 "HTTPHeaderNames.gperf" + {"Access-Control-Expose-Headers", HTTPHeaderName::AccessControlExposeHeaders}, +#line 165 "HTTPHeaderNames.gperf" + {"Access-Control-Allow-Headers", HTTPHeaderName::AccessControlAllowHeaders}, +#line 187 "HTTPHeaderNames.gperf" + {"Cross-Origin-Embedder-Policy", HTTPHeaderName::CrossOriginEmbedderPolicy}, +#line 171 "HTTPHeaderNames.gperf" + {"Access-Control-Request-Method", HTTPHeaderName::AccessControlRequestMethod}, +#line 202 "HTTPHeaderNames.gperf" + {"If-Modified-Since", HTTPHeaderName::IfModifiedSince}, +#line 205 "HTTPHeaderNames.gperf" + {"If-Unmodified-Since", HTTPHeaderName::IfUnmodifiedSince}, +#line 188 "HTTPHeaderNames.gperf" + {"Cross-Origin-Embedder-Policy-Report-Only", HTTPHeaderName::CrossOriginEmbedderPolicyReportOnly}, +#line 166 "HTTPHeaderNames.gperf" + {"Access-Control-Allow-Methods", HTTPHeaderName::AccessControlAllowMethods} + }; + +static const signed char lookup[] = + { + -1, -1, -1, -1, -1, 0, -1, -1, -1, 1, 2, -1, -1, -1, + 3, 4, -1, -1, -1, -1, 5, -1, -1, -1, -1, 6, -1, -1, + -1, -1, 7, -1, -1, -1, -1, 8, -1, -1, -1, -1, 9, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, -1, -1, 11, + -1, -1, -1, 12, 13, -1, -1, -1, -1, 14, -1, -1, -1, -1, + 15, -1, -1, -1, 16, -1, -1, -1, -1, 17, 18, -1, -1, -1, + -1, 19, -1, -1, -1, -1, 20, -1, -1, -1, -1, 21, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, + -1, -1, -1, 23, -1, -1, -1, -1, 24, -1, -1, -1, -1, 25, + -1, -1, -1, -1, 26, -1, -1, -1, -1, 27, -1, -1, -1, -1, + 28, -1, -1, -1, -1, 29, -1, -1, -1, -1, 30, -1, -1, -1, + -1, 31, -1, -1, -1, -1, 32, -1, -1, -1, -1, 33, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 34, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, + -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 37, -1, -1, -1, -1, 38, -1, -1, -1, 39, 40, -1, -1, -1, + -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, 42, -1, -1, + -1, -1, 43, -1, -1, 44, -1, -1, -1, -1, -1, -1, 45, -1, + -1, -1, -1, 46, -1, -1, -1, 47, 48, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 49, 50, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 52, -1, -1, -1, -1, 53, -1, -1, + -1, 54, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, + -1, -1, -1, 57, -1, -1, -1, -1, 58, -1, -1, -1, -1, 59, + -1, -1, -1, -1, 60, -1, -1, -1, -1, 61, -1, -1, -1, -1, + 62, -1, -1, -1, -1, 63, -1, -1, -1, -1, 64, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, + -1, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67, -1, + -1, -1, -1, 68, -1, -1, -1, -1, 69, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 70, 71, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 72, 73, -1, -1, -1, -1, 74, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 77, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 78, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 79, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 80, -1, -1, -1, -1, 81, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, -1, -1, + -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 86, -1, -1, -1, -1, 87, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 89, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 90, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 91 + }; + +const struct HeaderNameHashEntry * +HTTPHeaderNamesHash::findHeaderNameImpl (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + unsigned int key = header_name_hash_function (str, len); + + if (key <= MAX_HASH_VALUE) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = header_name_wordlist[index].name; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') + return &header_name_wordlist[index]; + } + } + } + return 0; +} +#line 251 "HTTPHeaderNames.gperf" + +bool findHTTPHeaderName(StringView stringView, HTTPHeaderName& headerName) +{ + unsigned length = stringView.length(); + if (length > maxHTTPHeaderNameLength || length < minHTTPHeaderNameLength) + return false; + + if (stringView.is8Bit()) { + if (auto nameAndString = HTTPHeaderNamesHash::findHeaderNameImpl(reinterpret_cast<const char*>(stringView.characters8()), length)) { + headerName = nameAndString->headerName; + return true; + } + } else { + LChar characters[maxHTTPHeaderNameLength]; + for (unsigned i = 0; i < length; ++i) { + UChar character = stringView.characters16()[i]; + if (!isASCII(character)) + return false; + + characters[i] = static_cast<LChar>(character); + } + + if (auto nameAndString = HTTPHeaderNamesHash::findHeaderNameImpl(reinterpret_cast<const char*>(characters), length)) { + headerName = nameAndString->headerName; + return true; + } + } + + return false; +} + +StringView httpHeaderNameString(HTTPHeaderName headerName) +{ + ASSERT(static_cast<unsigned>(headerName) < numHTTPHeaderNames); + + const auto& name = headerNameStrings[static_cast<unsigned>(headerName)]; + + return StringView { reinterpret_cast<const LChar*>(name.name), static_cast<unsigned>(name.length) }; +} + +} // namespace WebCore + +#if defined(__clang__) +IGNORE_WARNINGS_END +#endif diff --git a/src/bun.js/bindings/webcore/HTTPHeaderNames.gperf b/src/bun.js/bindings/webcore/HTTPHeaderNames.gperf new file mode 100644 index 000000000..66a4b24e8 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderNames.gperf @@ -0,0 +1,295 @@ + +%{ +/* + * Copyright (C) 2014 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. + */ + +/// This file is generated by create-http-header-name-table, do not edit. + +#include "config.h" +#include "HTTPHeaderNames.h" + +#include <wtf/text/StringView.h> + +IGNORE_WARNINGS_BEGIN("implicit-fallthrough") + +// Older versions of gperf like to use the `register` keyword. +#define register + +namespace WebCore { + +static const struct HeaderNameString { + const char* const name; + unsigned length; +} headerNameStrings[] = { + { "Accept", 6 }, + { "Accept-Charset", 14 }, + { "Accept-Encoding", 15 }, + { "Accept-Language", 15 }, + { "Accept-Ranges", 13 }, + { "Access-Control-Allow-Credentials", 32 }, + { "Access-Control-Allow-Headers", 28 }, + { "Access-Control-Allow-Methods", 28 }, + { "Access-Control-Allow-Origin", 27 }, + { "Access-Control-Expose-Headers", 29 }, + { "Access-Control-Max-Age", 22 }, + { "Access-Control-Request-Headers", 30 }, + { "Access-Control-Request-Method", 29 }, + { "Age", 3 }, + { "Authorization", 13 }, + { "Cache-Control", 13 }, + { "Connection", 10 }, + { "Content-Disposition", 19 }, + { "Content-Encoding", 16 }, + { "Content-Language", 16 }, + { "Content-Length", 14 }, + { "Content-Location", 16 }, + { "Content-Range", 13 }, + { "Content-Security-Policy", 23 }, + { "Content-Security-Policy-Report-Only", 35 }, + { "Content-Type", 12 }, + { "Cookie", 6 }, + { "Cookie2", 7 }, + { "Cross-Origin-Embedder-Policy", 28 }, + { "Cross-Origin-Embedder-Policy-Report-Only", 40 }, + { "Cross-Origin-Opener-Policy", 26 }, + { "Cross-Origin-Opener-Policy-Report-Only", 38 }, + { "Cross-Origin-Resource-Policy", 28 }, + { "DNT", 3 }, + { "Date", 4 }, + { "Default-Style", 13 }, + { "ETag", 4 }, + { "Expect", 6 }, + { "Expires", 7 }, + { "Host", 4 }, + { "Icy-MetaInt", 11 }, + { "Icy-Metadata", 12 }, + { "If-Match", 8 }, + { "If-Modified-Since", 17 }, + { "If-None-Match", 13 }, + { "If-Range", 8 }, + { "If-Unmodified-Since", 19 }, + { "Keep-Alive", 10 }, + { "Last-Event-ID", 13 }, + { "Last-Modified", 13 }, + { "Link", 4 }, + { "Location", 8 }, + { "Origin", 6 }, + { "Ping-From", 9 }, + { "Ping-To", 7 }, + { "Pragma", 6 }, + { "Proxy-Authorization", 19 }, + { "Purpose", 7 }, + { "Range", 5 }, + { "Referer", 7 }, + { "Referrer-Policy", 15 }, + { "Refresh", 7 }, + { "Report-To", 9 }, + { "Sec-Fetch-Dest", 14 }, + { "Sec-Fetch-Mode", 14 }, + { "Sec-WebSocket-Accept", 20 }, + { "Sec-WebSocket-Extensions", 24 }, + { "Sec-WebSocket-Key", 17 }, + { "Sec-WebSocket-Protocol", 22 }, + { "Sec-WebSocket-Version", 21 }, + { "Server-Timing", 13 }, + { "Service-Worker", 14 }, + { "Service-Worker-Allowed", 22 }, + { "Service-Worker-Navigation-Preload", 33 }, + { "Set-Cookie", 10 }, + { "Set-Cookie2", 11 }, + { "SourceMap", 9 }, + { "TE", 2 }, + { "Timing-Allow-Origin", 19 }, + { "Trailer", 7 }, + { "Transfer-Encoding", 17 }, + { "Upgrade", 7 }, + { "Upgrade-Insecure-Requests", 25 }, + { "User-Agent", 10 }, + { "Vary", 4 }, + { "Via", 3 }, + { "X-Content-Type-Options", 22 }, + { "X-DNS-Prefetch-Control", 22 }, + { "X-Frame-Options", 15 }, + { "X-SourceMap", 11 }, + { "X-Temp-Tablet", 13 }, + { "X-XSS-Protection", 16 }, +}; + + +%} + +%language=C++ +%readonly-tables +%global-table +%compare-strncmp +%ignore-case +%struct-type +struct HeaderNameHashEntry { + const char* name; + HTTPHeaderName headerName; +}; +%define class-name HTTPHeaderNamesHash +%define lookup-function-name findHeaderNameImpl +%define hash-function-name header_name_hash_function +%define word-array-name header_name_wordlist +%enum +%% +Accept, HTTPHeaderName::Accept +Accept-Charset, HTTPHeaderName::AcceptCharset +Accept-Encoding, HTTPHeaderName::AcceptEncoding +Accept-Language, HTTPHeaderName::AcceptLanguage +Accept-Ranges, HTTPHeaderName::AcceptRanges +Access-Control-Allow-Credentials, HTTPHeaderName::AccessControlAllowCredentials +Access-Control-Allow-Headers, HTTPHeaderName::AccessControlAllowHeaders +Access-Control-Allow-Methods, HTTPHeaderName::AccessControlAllowMethods +Access-Control-Allow-Origin, HTTPHeaderName::AccessControlAllowOrigin +Access-Control-Expose-Headers, HTTPHeaderName::AccessControlExposeHeaders +Access-Control-Max-Age, HTTPHeaderName::AccessControlMaxAge +Access-Control-Request-Headers, HTTPHeaderName::AccessControlRequestHeaders +Access-Control-Request-Method, HTTPHeaderName::AccessControlRequestMethod +Age, HTTPHeaderName::Age +Authorization, HTTPHeaderName::Authorization +Cache-Control, HTTPHeaderName::CacheControl +Connection, HTTPHeaderName::Connection +Content-Disposition, HTTPHeaderName::ContentDisposition +Content-Encoding, HTTPHeaderName::ContentEncoding +Content-Language, HTTPHeaderName::ContentLanguage +Content-Length, HTTPHeaderName::ContentLength +Content-Location, HTTPHeaderName::ContentLocation +Content-Range, HTTPHeaderName::ContentRange +Content-Security-Policy, HTTPHeaderName::ContentSecurityPolicy +Content-Security-Policy-Report-Only, HTTPHeaderName::ContentSecurityPolicyReportOnly +Content-Type, HTTPHeaderName::ContentType +Cookie, HTTPHeaderName::Cookie +Cookie2, HTTPHeaderName::Cookie2 +Cross-Origin-Embedder-Policy, HTTPHeaderName::CrossOriginEmbedderPolicy +Cross-Origin-Embedder-Policy-Report-Only, HTTPHeaderName::CrossOriginEmbedderPolicyReportOnly +Cross-Origin-Opener-Policy, HTTPHeaderName::CrossOriginOpenerPolicy +Cross-Origin-Opener-Policy-Report-Only, HTTPHeaderName::CrossOriginOpenerPolicyReportOnly +Cross-Origin-Resource-Policy, HTTPHeaderName::CrossOriginResourcePolicy +DNT, HTTPHeaderName::DNT +Date, HTTPHeaderName::Date +Default-Style, HTTPHeaderName::DefaultStyle +ETag, HTTPHeaderName::ETag +Expect, HTTPHeaderName::Expect +Expires, HTTPHeaderName::Expires +Host, HTTPHeaderName::Host +Icy-MetaInt, HTTPHeaderName::IcyMetaInt +Icy-Metadata, HTTPHeaderName::IcyMetadata +If-Match, HTTPHeaderName::IfMatch +If-Modified-Since, HTTPHeaderName::IfModifiedSince +If-None-Match, HTTPHeaderName::IfNoneMatch +If-Range, HTTPHeaderName::IfRange +If-Unmodified-Since, HTTPHeaderName::IfUnmodifiedSince +Keep-Alive, HTTPHeaderName::KeepAlive +Last-Event-ID, HTTPHeaderName::LastEventID +Last-Modified, HTTPHeaderName::LastModified +Link, HTTPHeaderName::Link +Location, HTTPHeaderName::Location +Origin, HTTPHeaderName::Origin +Ping-From, HTTPHeaderName::PingFrom +Ping-To, HTTPHeaderName::PingTo +Pragma, HTTPHeaderName::Pragma +Proxy-Authorization, HTTPHeaderName::ProxyAuthorization +Purpose, HTTPHeaderName::Purpose +Range, HTTPHeaderName::Range +Referer, HTTPHeaderName::Referer +Referrer-Policy, HTTPHeaderName::ReferrerPolicy +Refresh, HTTPHeaderName::Refresh +Report-To, HTTPHeaderName::ReportTo +Sec-Fetch-Dest, HTTPHeaderName::SecFetchDest +Sec-Fetch-Mode, HTTPHeaderName::SecFetchMode +Sec-WebSocket-Accept, HTTPHeaderName::SecWebSocketAccept +Sec-WebSocket-Extensions, HTTPHeaderName::SecWebSocketExtensions +Sec-WebSocket-Key, HTTPHeaderName::SecWebSocketKey +Sec-WebSocket-Protocol, HTTPHeaderName::SecWebSocketProtocol +Sec-WebSocket-Version, HTTPHeaderName::SecWebSocketVersion +Server-Timing, HTTPHeaderName::ServerTiming +Service-Worker, HTTPHeaderName::ServiceWorker +Service-Worker-Allowed, HTTPHeaderName::ServiceWorkerAllowed +Service-Worker-Navigation-Preload, HTTPHeaderName::ServiceWorkerNavigationPreload +Set-Cookie, HTTPHeaderName::SetCookie +Set-Cookie2, HTTPHeaderName::SetCookie2 +SourceMap, HTTPHeaderName::SourceMap +TE, HTTPHeaderName::TE +Timing-Allow-Origin, HTTPHeaderName::TimingAllowOrigin +Trailer, HTTPHeaderName::Trailer +Transfer-Encoding, HTTPHeaderName::TransferEncoding +Upgrade, HTTPHeaderName::Upgrade +Upgrade-Insecure-Requests, HTTPHeaderName::UpgradeInsecureRequests +User-Agent, HTTPHeaderName::UserAgent +Vary, HTTPHeaderName::Vary +Via, HTTPHeaderName::Via +X-Content-Type-Options, HTTPHeaderName::XContentTypeOptions +X-DNS-Prefetch-Control, HTTPHeaderName::XDNSPrefetchControl +X-Frame-Options, HTTPHeaderName::XFrameOptions +X-SourceMap, HTTPHeaderName::XSourceMap +X-Temp-Tablet, HTTPHeaderName::XTempTablet +X-XSS-Protection, HTTPHeaderName::XXSSProtection +%% +bool findHTTPHeaderName(StringView stringView, HTTPHeaderName& headerName) +{ + unsigned length = stringView.length(); + if (length > maxHTTPHeaderNameLength || length < minHTTPHeaderNameLength) + return false; + + if (stringView.is8Bit()) { + if (auto nameAndString = HTTPHeaderNamesHash::findHeaderNameImpl(reinterpret_cast<const char*>(stringView.characters8()), length)) { + headerName = nameAndString->headerName; + return true; + } + } else { + LChar characters[maxHTTPHeaderNameLength]; + for (unsigned i = 0; i < length; ++i) { + UChar character = stringView.characters16()[i]; + if (!isASCII(character)) + return false; + + characters[i] = static_cast<LChar>(character); + } + + if (auto nameAndString = HTTPHeaderNamesHash::findHeaderNameImpl(reinterpret_cast<const char*>(characters), length)) { + headerName = nameAndString->headerName; + return true; + } + } + + return false; +} + +StringView httpHeaderNameString(HTTPHeaderName headerName) +{ + ASSERT(static_cast<unsigned>(headerName) < numHTTPHeaderNames); + + const auto& name = headerNameStrings[static_cast<unsigned>(headerName)]; + + return StringView { reinterpret_cast<const LChar*>(name.name), static_cast<unsigned>(name.length) }; +} + +} // namespace WebCore + +#if defined(__clang__) +IGNORE_WARNINGS_END +#endif diff --git a/src/bun.js/bindings/webcore/HTTPHeaderNames.h b/src/bun.js/bindings/webcore/HTTPHeaderNames.h new file mode 100644 index 000000000..066d40e90 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderNames.h @@ -0,0 +1,242 @@ + +/* + * Copyright (C) 2014 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. + */ + +/// This file is generated by create-http-header-name-table, do not edit. + +#ifndef HTTPHeaderNames_h +#define HTTPHeaderNames_h + +#include <wtf/Forward.h> + +namespace WebCore { + +enum class HTTPHeaderName { + Accept, + AcceptCharset, + AcceptEncoding, + AcceptLanguage, + AcceptRanges, + AccessControlAllowCredentials, + AccessControlAllowHeaders, + AccessControlAllowMethods, + AccessControlAllowOrigin, + AccessControlExposeHeaders, + AccessControlMaxAge, + AccessControlRequestHeaders, + AccessControlRequestMethod, + Age, + Authorization, + CacheControl, + Connection, + ContentDisposition, + ContentEncoding, + ContentLanguage, + ContentLength, + ContentLocation, + ContentRange, + ContentSecurityPolicy, + ContentSecurityPolicyReportOnly, + ContentType, + Cookie, + Cookie2, + CrossOriginEmbedderPolicy, + CrossOriginEmbedderPolicyReportOnly, + CrossOriginOpenerPolicy, + CrossOriginOpenerPolicyReportOnly, + CrossOriginResourcePolicy, + DNT, + Date, + DefaultStyle, + ETag, + Expect, + Expires, + Host, + IcyMetaInt, + IcyMetadata, + IfMatch, + IfModifiedSince, + IfNoneMatch, + IfRange, + IfUnmodifiedSince, + KeepAlive, + LastEventID, + LastModified, + Link, + Location, + Origin, + PingFrom, + PingTo, + Pragma, + ProxyAuthorization, + Purpose, + Range, + Referer, + ReferrerPolicy, + Refresh, + ReportTo, + SecFetchDest, + SecFetchMode, + SecWebSocketAccept, + SecWebSocketExtensions, + SecWebSocketKey, + SecWebSocketProtocol, + SecWebSocketVersion, + ServerTiming, + ServiceWorker, + ServiceWorkerAllowed, + ServiceWorkerNavigationPreload, + SetCookie, + SetCookie2, + SourceMap, + TE, + TimingAllowOrigin, + Trailer, + TransferEncoding, + Upgrade, + UpgradeInsecureRequests, + UserAgent, + Vary, + Via, + XContentTypeOptions, + XDNSPrefetchControl, + XFrameOptions, + XSourceMap, + XTempTablet, + XXSSProtection, +}; + +const unsigned numHTTPHeaderNames = 92; +const size_t minHTTPHeaderNameLength = 2; +const size_t maxHTTPHeaderNameLength = 40; + +bool findHTTPHeaderName(StringView, HTTPHeaderName&); +WEBCORE_EXPORT StringView httpHeaderNameString(HTTPHeaderName); + +} // namespace WebCore + +namespace WTF { + +template<> struct EnumTraits<WebCore::HTTPHeaderName> { + using values = EnumValues< + WebCore::HTTPHeaderName, + WebCore::HTTPHeaderName::Accept, + WebCore::HTTPHeaderName::AcceptCharset, + WebCore::HTTPHeaderName::AcceptEncoding, + WebCore::HTTPHeaderName::AcceptLanguage, + WebCore::HTTPHeaderName::AcceptRanges, + WebCore::HTTPHeaderName::AccessControlAllowCredentials, + WebCore::HTTPHeaderName::AccessControlAllowHeaders, + WebCore::HTTPHeaderName::AccessControlAllowMethods, + WebCore::HTTPHeaderName::AccessControlAllowOrigin, + WebCore::HTTPHeaderName::AccessControlExposeHeaders, + WebCore::HTTPHeaderName::AccessControlMaxAge, + WebCore::HTTPHeaderName::AccessControlRequestHeaders, + WebCore::HTTPHeaderName::AccessControlRequestMethod, + WebCore::HTTPHeaderName::Age, + WebCore::HTTPHeaderName::Authorization, + WebCore::HTTPHeaderName::CacheControl, + WebCore::HTTPHeaderName::Connection, + WebCore::HTTPHeaderName::ContentDisposition, + WebCore::HTTPHeaderName::ContentEncoding, + WebCore::HTTPHeaderName::ContentLanguage, + WebCore::HTTPHeaderName::ContentLength, + WebCore::HTTPHeaderName::ContentLocation, + WebCore::HTTPHeaderName::ContentRange, + WebCore::HTTPHeaderName::ContentSecurityPolicy, + WebCore::HTTPHeaderName::ContentSecurityPolicyReportOnly, + WebCore::HTTPHeaderName::ContentType, + WebCore::HTTPHeaderName::Cookie, + WebCore::HTTPHeaderName::Cookie2, + WebCore::HTTPHeaderName::CrossOriginEmbedderPolicy, + WebCore::HTTPHeaderName::CrossOriginEmbedderPolicyReportOnly, + WebCore::HTTPHeaderName::CrossOriginOpenerPolicy, + WebCore::HTTPHeaderName::CrossOriginOpenerPolicyReportOnly, + WebCore::HTTPHeaderName::CrossOriginResourcePolicy, + WebCore::HTTPHeaderName::DNT, + WebCore::HTTPHeaderName::Date, + WebCore::HTTPHeaderName::DefaultStyle, + WebCore::HTTPHeaderName::ETag, + WebCore::HTTPHeaderName::Expect, + WebCore::HTTPHeaderName::Expires, + WebCore::HTTPHeaderName::Host, + WebCore::HTTPHeaderName::IcyMetaInt, + WebCore::HTTPHeaderName::IcyMetadata, + WebCore::HTTPHeaderName::IfMatch, + WebCore::HTTPHeaderName::IfModifiedSince, + WebCore::HTTPHeaderName::IfNoneMatch, + WebCore::HTTPHeaderName::IfRange, + WebCore::HTTPHeaderName::IfUnmodifiedSince, + WebCore::HTTPHeaderName::KeepAlive, + WebCore::HTTPHeaderName::LastEventID, + WebCore::HTTPHeaderName::LastModified, + WebCore::HTTPHeaderName::Link, + WebCore::HTTPHeaderName::Location, + WebCore::HTTPHeaderName::Origin, + WebCore::HTTPHeaderName::PingFrom, + WebCore::HTTPHeaderName::PingTo, + WebCore::HTTPHeaderName::Pragma, + WebCore::HTTPHeaderName::ProxyAuthorization, + WebCore::HTTPHeaderName::Purpose, + WebCore::HTTPHeaderName::Range, + WebCore::HTTPHeaderName::Referer, + WebCore::HTTPHeaderName::ReferrerPolicy, + WebCore::HTTPHeaderName::Refresh, + WebCore::HTTPHeaderName::ReportTo, + WebCore::HTTPHeaderName::SecFetchDest, + WebCore::HTTPHeaderName::SecFetchMode, + WebCore::HTTPHeaderName::SecWebSocketAccept, + WebCore::HTTPHeaderName::SecWebSocketExtensions, + WebCore::HTTPHeaderName::SecWebSocketKey, + WebCore::HTTPHeaderName::SecWebSocketProtocol, + WebCore::HTTPHeaderName::SecWebSocketVersion, + WebCore::HTTPHeaderName::ServerTiming, + WebCore::HTTPHeaderName::ServiceWorker, + WebCore::HTTPHeaderName::ServiceWorkerAllowed, + WebCore::HTTPHeaderName::ServiceWorkerNavigationPreload, + WebCore::HTTPHeaderName::SetCookie, + WebCore::HTTPHeaderName::SetCookie2, + WebCore::HTTPHeaderName::SourceMap, + WebCore::HTTPHeaderName::TE, + WebCore::HTTPHeaderName::TimingAllowOrigin, + WebCore::HTTPHeaderName::Trailer, + WebCore::HTTPHeaderName::TransferEncoding, + WebCore::HTTPHeaderName::Upgrade, + WebCore::HTTPHeaderName::UpgradeInsecureRequests, + WebCore::HTTPHeaderName::UserAgent, + WebCore::HTTPHeaderName::Vary, + WebCore::HTTPHeaderName::Via, + WebCore::HTTPHeaderName::XContentTypeOptions, + WebCore::HTTPHeaderName::XDNSPrefetchControl, + WebCore::HTTPHeaderName::XFrameOptions, + WebCore::HTTPHeaderName::XSourceMap, + WebCore::HTTPHeaderName::XTempTablet, + WebCore::HTTPHeaderName::XXSSProtection + >; +}; + +} // namespace WTF + +#endif // HTTPHeaderNames_h diff --git a/src/bun.js/bindings/webcore/HTTPHeaderNames.in b/src/bun.js/bindings/webcore/HTTPHeaderNames.in new file mode 100644 index 000000000..9edb2b2d7 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderNames.in @@ -0,0 +1,119 @@ +// +// Copyright (C) 2014 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. +// + +Accept +Accept-Charset +Accept-Language +Accept-Encoding +Accept-Ranges +Access-Control-Allow-Credentials +Access-Control-Allow-Headers +Access-Control-Allow-Methods +Access-Control-Allow-Origin +Access-Control-Expose-Headers +Access-Control-Max-Age +Access-Control-Request-Headers +Access-Control-Request-Method +Age +Authorization +Cache-Control +Connection +Content-Disposition +Content-Encoding +Content-Language +Content-Length +Content-Location +Content-Security-Policy +Content-Security-Policy-Report-Only +Content-Type +Content-Range +Cookie +Cookie2 +Cross-Origin-Embedder-Policy +Cross-Origin-Embedder-Policy-Report-Only +Cross-Origin-Opener-Policy +Cross-Origin-Opener-Policy-Report-Only +Cross-Origin-Resource-Policy +Date +DNT +Default-Style +ETag +Expect +Expires +Host +If-Match +If-Modified-Since +If-None-Match +If-Range +If-Unmodified-Since +Keep-Alive +Last-Event-ID +Last-Modified +Link +Location +Origin +Ping-From +Ping-To +Purpose +Pragma +Proxy-Authorization +Range +Referer +Referrer-Policy +Refresh +Report-To +Sec-Fetch-Dest +Sec-Fetch-Mode +Sec-WebSocket-Accept +Sec-WebSocket-Extensions +Sec-WebSocket-Key +Sec-WebSocket-Protocol +Sec-WebSocket-Version +Server-Timing +Service-Worker +Service-Worker-Allowed +Service-Worker-Navigation-Preload +Set-Cookie +Set-Cookie2 +SourceMap +TE +Timing-Allow-Origin +Trailer +Transfer-Encoding +Upgrade +Upgrade-Insecure-Requests +User-Agent +Vary +Via +X-Content-Type-Options +X-DNS-Prefetch-Control +X-Frame-Options +X-SourceMap +X-XSS-Protection +X-Temp-Tablet + +// These headers are specific to GStreamer. +Icy-MetaInt +Icy-Metadata diff --git a/src/bun.js/bindings/webcore/HTTPHeaderValues.cpp b/src/bun.js/bindings/webcore/HTTPHeaderValues.cpp new file mode 100644 index 000000000..b4869e846 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderValues.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016-2017 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. + */ + +#include "config.h" +#include "HTTPHeaderValues.h" + +#include <wtf/NeverDestroyed.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +namespace HTTPHeaderValues { + +const String& textPlainContentType() +{ + static NeverDestroyed<const String> contentType(MAKE_STATIC_STRING_IMPL("text/plain;charset=UTF-8")); + return contentType; +} + +const String& formURLEncodedContentType() +{ + static NeverDestroyed<const String> contentType(MAKE_STATIC_STRING_IMPL("application/x-www-form-urlencoded;charset=UTF-8")); + return contentType; +} + +const String& applicationJSONContentType() +{ + // The default encoding is UTF-8: https://www.ietf.org/rfc/rfc4627.txt. + static NeverDestroyed<const String> contentType(MAKE_STATIC_STRING_IMPL("application/json")); + return contentType; +} + +const String& noCache() +{ + static NeverDestroyed<const String> value(MAKE_STATIC_STRING_IMPL("no-cache")); + return value; +} + +const String& maxAge0() +{ + static NeverDestroyed<const String> value(MAKE_STATIC_STRING_IMPL("max-age=0")); + return value; +} + +} + +} diff --git a/src/bun.js/bindings/webcore/HTTPHeaderValues.h b/src/bun.js/bindings/webcore/HTTPHeaderValues.h new file mode 100644 index 000000000..6345a9a8f --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPHeaderValues.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 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 <wtf/Forward.h> + +namespace WebCore { + +namespace HTTPHeaderValues { + +const String& textPlainContentType(); +const String& formURLEncodedContentType(); +WEBCORE_EXPORT const String& applicationJSONContentType(); +const String& noCache(); +WEBCORE_EXPORT const String& maxAge0(); +} + +} diff --git a/src/bun.js/bindings/webcore/HTTPParsers.cpp b/src/bun.js/bindings/webcore/HTTPParsers.cpp new file mode 100644 index 000000000..335afcec1 --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPParsers.cpp @@ -0,0 +1,1076 @@ +/* + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * Copyright (C) 2006-2017 Apple Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2011 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. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#include "config.h" +#include "HTTPParsers.h" + +#include "CommonAtomStrings.h" +#include "HTTPHeaderField.h" +#include "HTTPHeaderNames.h" +#include "ParsedContentType.h" +#include <wtf/CheckedArithmetic.h> +#include <wtf/DateMath.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/text/StringToIntegerConversion.h> +#include <wtf/unicode/CharacterNames.h> + +namespace WebCore { + +// True if characters which satisfy the predicate are present, incrementing +// "pos" to the next character which does not satisfy the predicate. +// Note: might return pos == str.length(). +static inline bool skipWhile(const String& str, unsigned& pos, const Function<bool(const UChar)>& predicate) +{ + const unsigned start = pos; + const unsigned len = str.length(); + while (pos < len && predicate(str[pos])) + ++pos; + return pos != start; +} + +// true if there is more to parse, after incrementing pos past whitespace. +// Note: Might return pos == str.length() +static inline bool skipWhiteSpace(const String& str, unsigned& pos) +{ + skipWhile(str, pos, RFC7230::isWhitespace); + return pos < str.length(); +} + +// Returns true if the function can match the whole token (case insensitive) +// incrementing pos on match, otherwise leaving pos unchanged. +// Note: Might return pos == str.length() +static inline bool skipToken(const String& str, unsigned& pos, const char* token) +{ + unsigned len = str.length(); + unsigned current = pos; + + while (current < len && *token) { + if (toASCIILower(str[current]) != *token++) + return false; + ++current; + } + + if (*token) + return false; + + pos = current; + return true; +} + +// True if the expected equals sign is seen and there is more to follow. +static inline bool skipEquals(const String& str, unsigned& pos) +{ + return skipWhiteSpace(str, pos) && str[pos++] == '=' && skipWhiteSpace(str, pos); +} + +// True if a value present, incrementing pos to next space or semicolon, if any. +// Note: might return pos == str.length(). +static inline bool skipValue(const String& str, unsigned& pos) +{ + unsigned start = pos; + unsigned len = str.length(); + while (pos < len) { + if (str[pos] == ' ' || str[pos] == '\t' || str[pos] == ';') + break; + ++pos; + } + return pos != start; +} + +// See RFC 7230, Section 3.1.2. +bool isValidReasonPhrase(const String& value) +{ + for (unsigned i = 0; i < value.length(); ++i) { + UChar c = value[i]; + if (c == 0x7F || !isLatin1(c) || (c < 0x20 && c != '\t')) + return false; + } + return true; +} + +// See https://fetch.spec.whatwg.org/#concept-header +bool isValidHTTPHeaderValue(const String& value) +{ + UChar c = value[0]; + if (c == ' ' || c == '\t') + return false; + c = value[value.length() - 1]; + if (c == ' ' || c == '\t') + return false; + for (unsigned i = 0; i < value.length(); ++i) { + c = value[i]; + if (c == 0x00 || c == 0x0A || c == 0x0D) + return false; + } + return true; +} + +// See RFC 7231, Section 5.3.2. +bool isValidAcceptHeaderValue(const String& value) +{ + for (unsigned i = 0; i < value.length(); ++i) { + UChar c = value[i]; + + // First check for alphanumeric for performance reasons then allowlist four delimiter characters. + if (isASCIIAlphanumeric(c) || c == ',' || c == '/' || c == ';' || c == '=') + continue; + + ASSERT(isLatin1(c)); + if (c == 0x7F || (c < 0x20 && c != '\t')) + return false; + + if (RFC7230::isDelimiter(c)) + return false; + } + + return true; +} + +static bool containsCORSUnsafeRequestHeaderBytes(const String& value) +{ + for (unsigned i = 0; i < value.length(); ++i) { + UChar c = value[i]; + // https://fetch.spec.whatwg.org/#cors-unsafe-request-header-byte + if ((c < 0x20 && c != '\t') || (c == '"' || c == '(' || c == ')' || c == ':' || c == '<' || c == '>' || c == '?' || c == '@' || c == '[' || c == '\\' || c == ']' || c == 0x7B || c == '{' || c == '}' || c == 0x7F)) + return true; + } + + return false; +} + +// See RFC 7231, Section 5.3.5 and 3.1.3.2. +// https://fetch.spec.whatwg.org/#cors-safelisted-request-header +bool isValidLanguageHeaderValue(const String& value) +{ + for (unsigned i = 0; i < value.length(); ++i) { + UChar c = value[i]; + if (isASCIIAlphanumeric(c) || c == ' ' || c == '*' || c == ',' || c == '-' || c == '.' || c == ';' || c == '=') + continue; + return false; + } + return true; +} + +// See RFC 7230, Section 3.2.6. +bool isValidHTTPToken(StringView value) +{ + if (value.isEmpty()) + return false; + for (UChar c : value.codeUnits()) { + if (!RFC7230::isTokenCharacter(c)) + return false; + } + return true; +} + +bool isValidHTTPToken(const String& value) +{ + return isValidHTTPToken(StringView(value)); +} + +#if USE(GLIB) +// True if the character at the given position satisifies a predicate, incrementing "pos" by one. +// Note: Might return pos == str.length() +static inline bool skipCharacter(const String& value, unsigned& pos, Function<bool(const UChar)>&& predicate) +{ + if (pos < value.length() && predicate(value[pos])) { + ++pos; + return true; + } + return false; +} + +// True if the "expected" character is at the given position, incrementing "pos" by one. +// Note: Might return pos == str.length() +static inline bool skipCharacter(const String& value, unsigned& pos, const UChar expected) +{ + return skipCharacter(value, pos, [expected](const UChar c) { + return c == expected; + }); +} + +// True if a quoted pair is present, incrementing "pos" to the position after the quoted pair. +// Note: Might return pos == str.length() +// See RFC 7230, Section 3.2.6. +static constexpr auto QuotedPairStartCharacter = '\\'; +static bool skipQuotedPair(const String& value, unsigned& pos) +{ + // quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + return skipCharacter(value, pos, QuotedPairStartCharacter) + && skipCharacter(value, pos, RFC7230::isQuotedPairSecondOctet); +} + +// True if a comment is present, incrementing "pos" to the position after the comment. +// Note: Might return pos == str.length() +// See RFC 7230, Section 3.2.6. +static constexpr auto CommentStartCharacter = '('; +static constexpr auto CommentEndCharacter = ')'; +static bool skipComment(const String& value, unsigned& pos) +{ + // comment = "(" *( ctext / quoted-pair / comment ) ")" + // ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text + if (!skipCharacter(value, pos, CommentStartCharacter)) + return false; + + const unsigned end = value.length(); + while (pos < end && value[pos] != CommentEndCharacter) { + switch (value[pos]) { + case CommentStartCharacter: + if (!skipComment(value, pos)) + return false; + break; + case QuotedPairStartCharacter: + if (!skipQuotedPair(value, pos)) + return false; + break; + default: + if (!skipWhile(value, pos, RFC7230::isCommentText)) + return false; + } + } + return skipCharacter(value, pos, CommentEndCharacter); +} + +// True if an HTTP header token is present, incrementing "pos" to the position after it. +// Note: Might return pos == str.length() +// See RFC 7230, Section 3.2.6. +static bool skipHTTPToken(const String& value, unsigned& pos) +{ + return skipWhile(value, pos, RFC7230::isTokenCharacter); +} + +// True if a product specifier (as in an User-Agent header) is present, incrementing "pos" to the position after it. +// Note: Might return pos == str.length() +// See RFC 7231, Section 5.5.3. +static bool skipUserAgentProduct(const String& value, unsigned& pos) +{ + // product = token ["/" product-version] + // product-version = token + if (!skipHTTPToken(value, pos)) + return false; + if (skipCharacter(value, pos, '/')) + return skipHTTPToken(value, pos); + return true; +} + +// See RFC 7231, Section 5.5.3 +bool isValidUserAgentHeaderValue(const String& value) +{ + // User-Agent = product *( RWS ( product / comment ) ) + unsigned pos = 0; + if (!skipUserAgentProduct(value, pos)) + return false; + + while (pos < value.length()) { + if (!skipWhiteSpace(value, pos)) + return false; + if (value[pos] == CommentStartCharacter) { + if (!skipComment(value, pos)) + return false; + } else { + if (!skipUserAgentProduct(value, pos)) + return false; + } + } + + return pos == value.length(); +} +#endif + +static const size_t maxInputSampleSize = 128; +template<typename CharType> +static String trimInputSample(CharType* p, size_t length) +{ + if (length <= maxInputSampleSize) + return String(p, length); + return makeString(StringView(p, length).left(maxInputSampleSize), horizontalEllipsis); +} + +std::optional<WallTime> parseHTTPDate(const String& value) +{ + double dateInMillisecondsSinceEpoch = parseDateFromNullTerminatedCharacters(value.utf8().data()); + if (!std::isfinite(dateInMillisecondsSinceEpoch)) + return std::nullopt; + // This assumes system_clock epoch equals Unix epoch which is true for all implementations but unspecified. + // FIXME: The parsing function should be switched to WallTime too. + return WallTime::fromRawSeconds(dateInMillisecondsSinceEpoch / 1000.0); +} + +// FIXME: This function doesn't comply with RFC 6266. +// For example, this function doesn't handle the interaction between " and ; +// that arises from quoted-string, nor does this function properly unquote +// attribute values. Further this function appears to process parameter names +// in a case-sensitive manner. (There are likely other bugs as well.) +StringView filenameFromHTTPContentDisposition(StringView value) +{ + for (auto keyValuePair : value.split(';')) { + size_t valueStartPos = keyValuePair.find('='); + if (valueStartPos == notFound) + continue; + + auto key = keyValuePair.left(valueStartPos).stripWhiteSpace(); + + if (key.isEmpty() || key != "filename") + continue; + + auto value = keyValuePair.substring(valueStartPos + 1).stripWhiteSpace(); + + // Remove quotes if there are any + if (value.length() > 1 && value[0] == '\"') + value = value.substring(1, value.length() - 2); + + return value; + } + + return String(); +} + +String extractMIMETypeFromMediaType(const String& mediaType) +{ + unsigned position = 0; + unsigned length = mediaType.length(); + + for (; position < length; ++position) { + UChar c = mediaType[position]; + if (c != '\t' && c != ' ') + break; + } + + if (position == length) + return mediaType; + + unsigned typeStart = position; + + unsigned typeEnd = position; + for (; position < length; ++position) { + UChar c = mediaType[position]; + + // While RFC 2616 does not allow it, other browsers allow multiple values in the HTTP media + // type header field, Content-Type. In such cases, the media type string passed here may contain + // the multiple values separated by commas. For now, this code ignores text after the first comma, + // which prevents it from simply failing to parse such types altogether. Later for better + // compatibility we could consider using the first or last valid MIME type instead. + // See https://bugs.webkit.org/show_bug.cgi?id=25352 for more discussion. + if (c == ',') + break; + + if (c == '\t' || c == ' ' || c == ';') + break; + + typeEnd = position + 1; + } + + return mediaType.substring(typeStart, typeEnd - typeStart); +} + +StringView extractCharsetFromMediaType(StringView mediaType) +{ + unsigned charsetPos = 0, charsetLen = 0; + size_t pos = 0; + unsigned length = mediaType.length(); + + while (pos < length) { + pos = mediaType.findIgnoringASCIICase("charset"_s, pos); + if (pos == notFound || pos == 0) { + charsetLen = 0; + break; + } + + // is what we found a beginning of a word? + if (mediaType[pos - 1] > ' ' && mediaType[pos - 1] != ';') { + pos += 7; + continue; + } + + pos += 7; + + // skip whitespace + while (pos < length && mediaType[pos] <= ' ') + ++pos; + + if (pos >= length) + break; + + if (mediaType[pos++] != '=') // this "charset" substring wasn't a parameter name, but there may be others + continue; + + while (pos < length && (mediaType[pos] <= ' ' || mediaType[pos] == '"' || mediaType[pos] == '\'')) + ++pos; + + // we don't handle spaces within quoted parameter values, because charset names cannot have any + unsigned endpos = pos; + while (endpos < length && mediaType[endpos] > ' ' && mediaType[endpos] != '"' && mediaType[endpos] != '\'' && mediaType[endpos] != ';') + ++endpos; + + charsetPos = pos; + charsetLen = endpos - pos; + break; + } + return mediaType.substring(charsetPos, charsetLen); +} + +XSSProtectionDisposition parseXSSProtectionHeader(const String& header, String& failureReason, unsigned& failurePosition, String& reportURL) +{ + static NeverDestroyed<String> failureReasonInvalidToggle(MAKE_STATIC_STRING_IMPL("expected 0 or 1")); + static NeverDestroyed<String> failureReasonInvalidSeparator(MAKE_STATIC_STRING_IMPL("expected semicolon")); + static NeverDestroyed<String> failureReasonInvalidEquals(MAKE_STATIC_STRING_IMPL("expected equals sign")); + static NeverDestroyed<String> failureReasonInvalidMode(MAKE_STATIC_STRING_IMPL("invalid mode directive")); + static NeverDestroyed<String> failureReasonInvalidReport(MAKE_STATIC_STRING_IMPL("invalid report directive")); + static NeverDestroyed<String> failureReasonDuplicateMode(MAKE_STATIC_STRING_IMPL("duplicate mode directive")); + static NeverDestroyed<String> failureReasonDuplicateReport(MAKE_STATIC_STRING_IMPL("duplicate report directive")); + static NeverDestroyed<String> failureReasonInvalidDirective(MAKE_STATIC_STRING_IMPL("unrecognized directive")); + + unsigned pos = 0; + + if (!skipWhiteSpace(header, pos)) + return XSSProtectionDisposition::Enabled; + + if (header[pos] == '0') + return XSSProtectionDisposition::Disabled; + + if (header[pos++] != '1') { + failureReason = failureReasonInvalidToggle; + return XSSProtectionDisposition::Invalid; + } + + XSSProtectionDisposition result = XSSProtectionDisposition::Enabled; + bool modeDirectiveSeen = false; + bool reportDirectiveSeen = false; + + while (1) { + // At end of previous directive: consume whitespace, semicolon, and whitespace. + if (!skipWhiteSpace(header, pos)) + return result; + + if (header[pos++] != ';') { + failureReason = failureReasonInvalidSeparator; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + + if (!skipWhiteSpace(header, pos)) + return result; + + // At start of next directive. + if (skipToken(header, pos, "mode")) { + if (modeDirectiveSeen) { + failureReason = failureReasonDuplicateMode; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + modeDirectiveSeen = true; + if (!skipEquals(header, pos)) { + failureReason = failureReasonInvalidEquals; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + if (!skipToken(header, pos, "block")) { + failureReason = failureReasonInvalidMode; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + result = XSSProtectionDisposition::BlockEnabled; + } else if (skipToken(header, pos, "report")) { + if (reportDirectiveSeen) { + failureReason = failureReasonDuplicateReport; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + reportDirectiveSeen = true; + if (!skipEquals(header, pos)) { + failureReason = failureReasonInvalidEquals; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + size_t startPos = pos; + if (!skipValue(header, pos)) { + failureReason = failureReasonInvalidReport; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + reportURL = header.substring(startPos, pos - startPos); + failurePosition = startPos; // If later semantic check deems unacceptable. + } else { + failureReason = failureReasonInvalidDirective; + failurePosition = pos; + return XSSProtectionDisposition::Invalid; + } + } +} + +ContentTypeOptionsDisposition parseContentTypeOptionsHeader(StringView header) +{ + StringView leftToken = header.left(header.find(',')); + if (equalLettersIgnoringASCIICase(stripLeadingAndTrailingHTTPSpaces(leftToken), "nosniff"_s)) + return ContentTypeOptionsDisposition::Nosniff; + return ContentTypeOptionsDisposition::None; +} + +// For example: "HTTP/1.1 200 OK" => "OK". +// Note that HTTP/2 does not include a reason phrase, so we return the empty atom. +AtomString extractReasonPhraseFromHTTPStatusLine(const String& statusLine) +{ + StringView view = statusLine; + size_t spacePos = view.find(' '); + + // Remove status code from the status line. + spacePos = view.find(' ', spacePos + 1); + if (spacePos == notFound) + return emptyAtom(); + + return view.substring(spacePos + 1).toAtomString(); +} + +XFrameOptionsDisposition parseXFrameOptionsHeader(StringView header) +{ + XFrameOptionsDisposition result = XFrameOptionsDisposition::None; + + if (header.isEmpty()) + return result; + + for (auto currentHeader : header.split(',')) { + currentHeader = currentHeader.stripWhiteSpace(); + XFrameOptionsDisposition currentValue = XFrameOptionsDisposition::None; + if (equalLettersIgnoringASCIICase(currentHeader, "deny"_s)) + currentValue = XFrameOptionsDisposition::Deny; + else if (equalLettersIgnoringASCIICase(currentHeader, "sameorigin"_s)) + currentValue = XFrameOptionsDisposition::SameOrigin; + else if (equalLettersIgnoringASCIICase(currentHeader, "allowall"_s)) + currentValue = XFrameOptionsDisposition::AllowAll; + else + currentValue = XFrameOptionsDisposition::Invalid; + + if (result == XFrameOptionsDisposition::None) + result = currentValue; + else if (result != currentValue) + return XFrameOptionsDisposition::Conflict; + } + return result; +} + +// https://fetch.spec.whatwg.org/#concept-header-list-get-structured-header +// FIXME: For now, this assumes the type is "item". +std::optional<std::pair<StringView, HashMap<String, String>>> parseStructuredFieldValue(StringView header) +{ + header = stripLeadingAndTrailingHTTPSpaces(header); + if (header.isEmpty()) + return std::nullopt; + + // Parse a token (https://datatracker.ietf.org/doc/html/rfc8941#section-4.2.6). + if (!isASCIIAlpha(header[0]) && header[0] != '*') + return std::nullopt; + size_t index = 1; + while (index < header.length()) { + UChar c = header[index]; + if (!RFC7230::isTokenCharacter(c) && c != ':' && c != '/') + break; + ++index; + } + StringView bareItem = header.left(index); + + // Parse parameters (https://datatracker.ietf.org/doc/html/rfc8941#section-4.2.3.2). + HashMap<String, String> parameters; + while (index < header.length()) { + if (header[index] != ';') + break; + ++index; // Consume ';'. + while (index < header.length() && header[index] == ' ') + ++index; + if (index == header.length()) + return std::nullopt; + // Parse a key (https://datatracker.ietf.org/doc/html/rfc8941#section-4.2.3.3) + if (!isASCIILower(header[index])) + return std::nullopt; + size_t keyStart = index++; + while (index < header.length()) { + UChar c = header[index]; + if (!isASCIILower(c) && !isASCIIDigit(c) && c != '_' && c != '-' && c != '.' && c != '*') + break; + ++index; + } + StringView key = header.substring(keyStart, index - keyStart); + String value = trueAtom(); + if (index < header.length() && header[index] == '=') { + ++index; // Consume '='. + if (isASCIIAlpha(header[index]) || header[index] == '*') { + // https://datatracker.ietf.org/doc/html/rfc8941#section-4.2.6 + size_t valueStart = index++; + while (index < header.length()) { + UChar c = header[index]; + if (!RFC7230::isTokenCharacter(c) && c != ':' && c != '/') + break; + ++index; + } + value = header.substring(valueStart, index - valueStart).toString(); + } else if (header[index] == '"') { + // https://datatracker.ietf.org/doc/html/rfc8941#section-4.2.5 + StringBuilder valueBuilder; + ++index; // Skip DQUOTE. + while (index < header.length()) { + if (header[index] == '\\') { + ++index; + if (index == header.length()) + return std::nullopt; + if (header[index] != '\\' && header[index] != '"') + return std::nullopt; + valueBuilder.append(header[index]); + } else if (header[index] == '\"') { + value = valueBuilder.toString(); + break; + } else if (header[index] <= 0x1F || (header[index] >= 0x7F && header[index] <= 0xFF)) // Not in VCHAR or SP. + return std::nullopt; + else + valueBuilder.append(header[index]); + ++index; + } + if (index == header.length()) + return std::nullopt; + ++index; // Skip DQUOTE. + } else + return std::nullopt; + } + parameters.set(key.toString(), WTFMove(value)); + } + if (index != header.length()) + return std::nullopt; + return std::make_pair(bareItem, parameters); +} + +bool parseRange(StringView range, long long& rangeOffset, long long& rangeEnd, long long& rangeSuffixLength) +{ + // The format of "Range" header is defined in RFC 2616 Section 14.35.1. + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.1 + // We don't support multiple range requests. + + rangeOffset = rangeEnd = rangeSuffixLength = -1; + + // The "bytes" unit identifier should be present. + static const unsigned bytesLength = 6; + if (!startsWithLettersIgnoringASCIICase(range, "bytes="_s)) + return false; + + StringView byteRange = range.substring(bytesLength); + + // The '-' character needs to be present. + int index = byteRange.find('-'); + if (index == -1) + return false; + + // If the '-' character is at the beginning, the suffix length, which specifies the last N bytes, is provided. + // Example: + // -500 + if (!index) { + if (auto value = parseInteger<long long>(byteRange.substring(index + 1))) + rangeSuffixLength = *value; + return true; + } + + // Otherwise, the first-byte-position and the last-byte-position are provied. + // Examples: + // 0-499 + // 500- + auto firstBytePos = parseInteger<long long>(byteRange.left(index)); + if (!firstBytePos) + return false; + + auto lastBytePosStr = stripLeadingAndTrailingHTTPSpaces(byteRange.substring(index + 1)); + long long lastBytePos = -1; + if (!lastBytePosStr.isEmpty()) { + auto value = parseInteger<long long>(lastBytePosStr); + if (!value) + return false; + lastBytePos = *value; + } + + if (*firstBytePos < 0 || !(lastBytePos == -1 || lastBytePos >= *firstBytePos)) + return false; + + rangeOffset = *firstBytePos; + rangeEnd = lastBytePos; + return true; +} + +template<typename CharacterType> +static inline bool isValidHeaderNameCharacter(CharacterType character) +{ + // https://tools.ietf.org/html/rfc7230#section-3.2 + // A header name should only contain one or more of + // alphanumeric or ! # $ % & ' * + - . ^ _ ` | ~ + if (isASCIIAlphanumeric(character)) + return true; + switch (character) { + case '!': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '*': + case '+': + case '-': + case '.': + case '^': + case '_': + case '`': + case '|': + case '~': + return true; + default: + return false; + } +} + +size_t parseHTTPHeader(const uint8_t* start, size_t length, String& failureReason, StringView& nameStr, String& valueStr, bool strict) +{ + auto p = start; + auto end = start + length; + + Vector<uint8_t> name; + Vector<uint8_t> value; + + bool foundFirstNameChar = false; + const uint8_t* namePtr = nullptr; + size_t nameSize = 0; + + nameStr = StringView(); + valueStr = String(); + + for (; p < end; p++) { + switch (*p) { + case '\r': + if (name.isEmpty()) { + if (p + 1 < end && *(p + 1) == '\n') + return (p + 2) - start; + failureReason = makeString("CR doesn't follow LF in header name at ", trimInputSample(p, end - p)); + return 0; + } + failureReason = makeString("Unexpected CR in header name at ", trimInputSample(name.data(), name.size())); + return 0; + case '\n': + failureReason = makeString("Unexpected LF in header name at ", trimInputSample(name.data(), name.size())); + return 0; + case ':': + break; + default: + if (!isValidHeaderNameCharacter(*p)) { + if (name.size() < 1) + failureReason = "Unexpected start character in header name"_s; + else + failureReason = makeString("Unexpected character in header name at ", trimInputSample(name.data(), name.size())); + return 0; + } + name.append(*p); + if (!foundFirstNameChar) { + namePtr = p; + foundFirstNameChar = true; + } + continue; + } + if (*p == ':') { + ++p; + break; + } + } + + nameSize = name.size(); + nameStr = StringView(namePtr, nameSize); + + for (; p < end && *p == 0x20; p++) { + } + + for (; p < end; p++) { + switch (*p) { + case '\r': + break; + case '\n': + if (strict) { + failureReason = makeString("Unexpected LF in header value at ", trimInputSample(value.data(), value.size())); + return 0; + } + break; + default: + value.append(*p); + } + if (*p == '\r' || (!strict && *p == '\n')) { + ++p; + break; + } + } + if (p >= end || (strict && *p != '\n')) { + failureReason = makeString("CR doesn't follow LF after header value at ", trimInputSample(p, end - p)); + return 0; + } + valueStr = String::fromUTF8(value.data(), value.size()); + if (valueStr.isNull()) { + failureReason = "Invalid UTF-8 sequence in header value"_s; + return 0; + } + return p - start; +} + +size_t parseHTTPRequestBody(const uint8_t* data, size_t length, Vector<uint8_t>& body) +{ + body.clear(); + body.append(data, length); + + return length; +} + +// Implements <https://fetch.spec.whatwg.org/#forbidden-header-name>. +bool isForbiddenHeaderName(const String& name) +{ + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) { + switch (headerName) { + case HTTPHeaderName::AcceptCharset: + case HTTPHeaderName::AcceptEncoding: + case HTTPHeaderName::AccessControlRequestHeaders: + case HTTPHeaderName::AccessControlRequestMethod: + case HTTPHeaderName::Connection: + case HTTPHeaderName::ContentLength: + case HTTPHeaderName::Cookie: + case HTTPHeaderName::Cookie2: + case HTTPHeaderName::Date: + case HTTPHeaderName::DNT: + case HTTPHeaderName::Expect: + case HTTPHeaderName::Host: + case HTTPHeaderName::KeepAlive: + case HTTPHeaderName::Origin: + case HTTPHeaderName::Referer: + case HTTPHeaderName::TE: + case HTTPHeaderName::Trailer: + case HTTPHeaderName::TransferEncoding: + case HTTPHeaderName::Upgrade: + case HTTPHeaderName::Via: + return true; + default: + break; + } + } + return startsWithLettersIgnoringASCIICase(name, "sec-"_s) || startsWithLettersIgnoringASCIICase(name, "proxy-"_s); +} + +// Implements <https://fetch.spec.whatwg.org/#no-cors-safelisted-request-header-name>. +bool isNoCORSSafelistedRequestHeaderName(const String& name) +{ + HTTPHeaderName headerName; + if (findHTTPHeaderName(name, headerName)) { + switch (headerName) { + case HTTPHeaderName::Accept: + case HTTPHeaderName::AcceptLanguage: + case HTTPHeaderName::ContentLanguage: + case HTTPHeaderName::ContentType: + return true; + default: + break; + } + } + return false; +} + +// Implements <https://fetch.spec.whatwg.org/#privileged-no-cors-request-header-name>. +bool isPriviledgedNoCORSRequestHeaderName(const String& name) +{ + return equalLettersIgnoringASCIICase(name, "range"_s); +} + +// Implements <https://fetch.spec.whatwg.org/#forbidden-response-header-name>. +bool isForbiddenResponseHeaderName(const String& name) +{ + return equalLettersIgnoringASCIICase(name, "set-cookie"_s) || equalLettersIgnoringASCIICase(name, "set-cookie2"_s); +} + +// Implements <https://fetch.spec.whatwg.org/#forbidden-method>. +bool isForbiddenMethod(const String& name) +{ + return equalLettersIgnoringASCIICase(name, "connect"_s) || equalLettersIgnoringASCIICase(name, "trace"_s) || equalLettersIgnoringASCIICase(name, "track"_s); +} + +bool isSimpleHeader(const String& name, const String& value) +{ + HTTPHeaderName headerName; + if (!findHTTPHeaderName(name, headerName)) + return false; + return isCrossOriginSafeRequestHeader(headerName, value); +} + +bool isCrossOriginSafeHeader(HTTPHeaderName name, const HTTPHeaderSet& accessControlExposeHeaderSet) +{ + switch (name) { + case HTTPHeaderName::CacheControl: + case HTTPHeaderName::ContentLanguage: + case HTTPHeaderName::ContentLength: + case HTTPHeaderName::ContentType: + case HTTPHeaderName::Expires: + case HTTPHeaderName::LastModified: + case HTTPHeaderName::Pragma: + case HTTPHeaderName::Accept: + return true; + case HTTPHeaderName::SetCookie: + case HTTPHeaderName::SetCookie2: + return false; + default: + break; + } + return accessControlExposeHeaderSet.contains<ASCIICaseInsensitiveStringViewHashTranslator>(httpHeaderNameString(name)); +} + +bool isCrossOriginSafeHeader(const String& name, const HTTPHeaderSet& accessControlExposeHeaderSet) +{ +#if ASSERT_ENABLED + HTTPHeaderName headerName; + ASSERT(!findHTTPHeaderName(name, headerName)); +#endif + return accessControlExposeHeaderSet.contains(name); +} + +static bool isSimpleRangeHeaderValue(const String& value) +{ + if (!value.startsWith("bytes="_s)) + return false; + + unsigned start = 0; + unsigned end = 0; + bool hasHyphen = false; + + for (size_t cptr = 6; cptr < value.length(); ++cptr) { + auto character = value[cptr]; + if (character >= '0' && character <= '9') { + if (productOverflows<unsigned>(hasHyphen ? end : start, 10)) + return false; + auto newDecimal = (hasHyphen ? end : start) * 10; + auto sum = Checked<unsigned, RecordOverflow>(newDecimal) + Checked<unsigned, RecordOverflow>(character - '0'); + if (sum.hasOverflowed()) + return false; + + if (hasHyphen) + end = sum.value(); + else + start = sum.value(); + continue; + } + if (character == '-' && !hasHyphen) { + hasHyphen = true; + continue; + } + return false; + } + + return hasHyphen && (!end || start < end); +} + +// Implements https://fetch.spec.whatwg.org/#cors-safelisted-request-header +bool isCrossOriginSafeRequestHeader(HTTPHeaderName name, const String& value) +{ + if (value.length() > 128) + return false; + + switch (name) { + case HTTPHeaderName::Accept: + if (!isValidAcceptHeaderValue(value)) + return false; + break; + case HTTPHeaderName::AcceptLanguage: + case HTTPHeaderName::ContentLanguage: + if (!isValidLanguageHeaderValue(value)) + return false; + break; + case HTTPHeaderName::ContentType: { + // Preflight is required for MIME types that can not be sent via form submission. + if (containsCORSUnsafeRequestHeaderBytes(value)) + return false; + auto parsedContentType = ParsedContentType::create(value); + if (!parsedContentType) + return false; + String mimeType = parsedContentType->mimeType(); + if (!(equalLettersIgnoringASCIICase(mimeType, "application/x-www-form-urlencoded"_s) || equalLettersIgnoringASCIICase(mimeType, "multipart/form-data"_s) || equalLettersIgnoringASCIICase(mimeType, "text/plain"_s))) + return false; + break; + } + case HTTPHeaderName::Range: + if (!isSimpleRangeHeaderValue(value)) + return false; + break; + default: + // FIXME: Should we also make safe other headers (DPR, Downlink, Save-Data...)? That would require validating their values. + return false; + } + return true; +} + +// Implements <https://fetch.spec.whatwg.org/#concept-method-normalize>. +String normalizeHTTPMethod(const String& method) +{ + const ASCIILiteral methods[] = { "DELETE"_s, "GET"_s, "HEAD"_s, "OPTIONS"_s, "POST"_s, "PUT"_s }; + for (auto value : methods) { + if (equalIgnoringASCIICase(method, value)) { + // Don't bother allocating a new string if it's already all uppercase. + if (method == value) + break; + return value; + } + } + return method; +} + +// Defined by https://tools.ietf.org/html/rfc7231#section-4.2.1 +bool isSafeMethod(const String& method) +{ + const ASCIILiteral safeMethods[] = { "GET"_s, "HEAD"_s, "OPTIONS"_s, "TRACE"_s }; + for (auto value : safeMethods) { + if (equalIgnoringASCIICase(method, value)) + return true; + } + return false; +} + +CrossOriginResourcePolicy parseCrossOriginResourcePolicyHeader(StringView header) +{ + auto strippedHeader = stripLeadingAndTrailingHTTPSpaces(header); + + if (strippedHeader.isEmpty()) + return CrossOriginResourcePolicy::None; + + if (strippedHeader == "same-origin") + return CrossOriginResourcePolicy::SameOrigin; + + if (strippedHeader == "same-site") + return CrossOriginResourcePolicy::SameSite; + + if (strippedHeader == "cross-origin") + return CrossOriginResourcePolicy::CrossOrigin; + + return CrossOriginResourcePolicy::Invalid; +} + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/HTTPParsers.h b/src/bun.js/bindings/webcore/HTTPParsers.h new file mode 100644 index 000000000..917ab2eae --- /dev/null +++ b/src/bun.js/bindings/webcore/HTTPParsers.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2011 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. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 <wtf/HashSet.h> +#include <wtf/WallTime.h> +#include <wtf/text/StringHash.h> + +namespace WebCore { + +typedef HashSet<String, ASCIICaseInsensitiveHash> HTTPHeaderSet; + +enum class HTTPHeaderName; + +enum class XSSProtectionDisposition { + Invalid, + Disabled, + Enabled, + BlockEnabled, +}; + +enum class ContentTypeOptionsDisposition : bool { + None, + Nosniff +}; + +enum class XFrameOptionsDisposition : uint8_t { + None, + Deny, + SameOrigin, + AllowAll, + Invalid, + Conflict +}; + +enum class CrossOriginResourcePolicy : uint8_t { + None, + CrossOrigin, + SameOrigin, + SameSite, + Invalid +}; + +bool isValidReasonPhrase(const String&); +bool isValidHTTPHeaderValue(const String&); +bool isValidAcceptHeaderValue(const String&); +bool isValidLanguageHeaderValue(const String&); +#if USE(GLIB) +WEBCORE_EXPORT bool isValidUserAgentHeaderValue(const String&); +#endif +bool isValidHTTPToken(const String&); +bool isValidHTTPToken(StringView); +std::optional<WallTime> parseHTTPDate(const String&); +StringView filenameFromHTTPContentDisposition(StringView); +WEBCORE_EXPORT String extractMIMETypeFromMediaType(const String&); +StringView extractCharsetFromMediaType(const String&); +XSSProtectionDisposition parseXSSProtectionHeader(const String& header, String& failureReason, unsigned& failurePosition, String& reportURL); +AtomString extractReasonPhraseFromHTTPStatusLine(const String&); +WEBCORE_EXPORT XFrameOptionsDisposition parseXFrameOptionsHeader(StringView); +std::optional<std::pair<StringView, HashMap<String, String>>> parseStructuredFieldValue(StringView header); + +// -1 could be set to one of the return parameters to indicate the value is not specified. +WEBCORE_EXPORT bool parseRange(const String&, long long& rangeOffset, long long& rangeEnd, long long& rangeSuffixLength); + +ContentTypeOptionsDisposition parseContentTypeOptionsHeader(StringView header); + +// Parsing Complete HTTP Messages. +size_t parseHTTPHeader(const uint8_t* data, size_t length, String& failureReason, StringView& nameStr, String& valueStr, bool strict = true); +size_t parseHTTPRequestBody(const uint8_t* data, size_t length, Vector<uint8_t>& body); + +// HTTP Header routine as per https://fetch.spec.whatwg.org/#terminology-headers +bool isForbiddenHeaderName(const String&); +bool isNoCORSSafelistedRequestHeaderName(const String&); +bool isPriviledgedNoCORSRequestHeaderName(const String&); +bool isForbiddenResponseHeaderName(const String&); +bool isForbiddenMethod(const String&); +bool isSimpleHeader(const String& name, const String& value); +bool isCrossOriginSafeHeader(HTTPHeaderName, const HTTPHeaderSet&); +bool isCrossOriginSafeHeader(const String&, const HTTPHeaderSet&); +bool isCrossOriginSafeRequestHeader(HTTPHeaderName, const String&); + +String normalizeHTTPMethod(const String&); +bool isSafeMethod(const String&); + +WEBCORE_EXPORT CrossOriginResourcePolicy parseCrossOriginResourcePolicyHeader(StringView); + +inline bool isHTTPSpace(UChar character) +{ + return character <= ' ' && (character == ' ' || character == '\n' || character == '\t' || character == '\r'); +} + +// Strip leading and trailing whitespace as defined in https://fetch.spec.whatwg.org/#concept-header-value-normalize. +inline String stripLeadingAndTrailingHTTPSpaces(const String& string) +{ + return string.stripLeadingAndTrailingCharacters(isHTTPSpace); +} + +inline StringView stripLeadingAndTrailingHTTPSpaces(StringView string) +{ + return string.stripLeadingAndTrailingMatchedCharacters(isHTTPSpace); +} + +template<class HashType> +bool addToAccessControlAllowList(const String& string, unsigned start, unsigned end, HashSet<String, HashType>& set) +{ + StringImpl* stringImpl = string.impl(); + if (!stringImpl) + return true; + + // Skip white space from start. + while (start <= end && isHTTPSpace((*stringImpl)[start])) + ++start; + + // only white space + if (start > end) + return true; + + // Skip white space from end. + while (end && isHTTPSpace((*stringImpl)[end])) + --end; + + auto token = string.substring(start, end - start + 1); + if (!isValidHTTPToken(token)) + return false; + + set.add(WTFMove(token)); + return true; +} + +template<class HashType = DefaultHash<String>> +std::optional<HashSet<String, HashType>> parseAccessControlAllowList(const String& string) +{ + HashSet<String, HashType> set; + unsigned start = 0; + size_t end; + while ((end = string.find(',', start)) != notFound) { + if (start != end) { + if (!addToAccessControlAllowList(string, start, end - 1, set)) + return {}; + } + start = end + 1; + } + if (start != string.length()) { + if (!addToAccessControlAllowList(string, start, string.length() - 1, set)) + return {}; + } + return set; +} + +} diff --git a/src/bun.js/bindings/webcore/InternalWritableStream.cpp b/src/bun.js/bindings/webcore/InternalWritableStream.cpp new file mode 100644 index 000000000..d3988c908 --- /dev/null +++ b/src/bun.js/bindings/webcore/InternalWritableStream.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2020-2021 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 CANON 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 CANON 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 "InternalWritableStream.h" + +#include "Exception.h" +#include "WebCoreJSClientData.h" + +namespace WebCore { + +static ExceptionOr<JSC::JSValue> invokeWritableStreamFunction(JSC::JSGlobalObject& globalObject, const JSC::Identifier& identifier, const JSC::MarkedArgumentBuffer& arguments) +{ + JSC::VM& vm = globalObject.vm(); + JSC::JSLockHolder lock(vm); + + auto scope = DECLARE_CATCH_SCOPE(vm); + + auto function = globalObject.get(&globalObject, identifier); + ASSERT(function.isCallable()); + scope.assertNoExceptionExceptTermination(); + + auto callData = JSC::getCallData(function); + + auto result = call(&globalObject, function, callData, JSC::jsUndefined(), arguments); + RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError }); + + return result; +} + +ExceptionOr<Ref<InternalWritableStream>> InternalWritableStream::createFromUnderlyingSink(JSDOMGlobalObject& globalObject, JSC::JSValue underlyingSink, JSC::JSValue strategy) +{ + auto* clientData = static_cast<JSVMClientData*>(globalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().createInternalWritableStreamFromUnderlyingSinkPrivateName(); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(underlyingSink); + arguments.append(strategy); + ASSERT(!arguments.hasOverflowed()); + + auto result = invokeWritableStreamFunction(globalObject, privateName, arguments); + if (UNLIKELY(result.hasException())) + return result.releaseException(); + + ASSERT(result.returnValue().isObject()); + return adoptRef(*new InternalWritableStream(globalObject, *result.returnValue().toObject(&globalObject))); +} + +Ref<InternalWritableStream> InternalWritableStream::fromObject(JSDOMGlobalObject& globalObject, JSC::JSObject& object) +{ + return adoptRef(*new InternalWritableStream(globalObject, object)); +} + +bool InternalWritableStream::locked() const +{ + auto* globalObject = this->globalObject(); + if (!globalObject) + return false; + + auto scope = DECLARE_CATCH_SCOPE(globalObject->vm()); + + auto* clientData = static_cast<JSVMClientData*>(globalObject->vm().clientData); + auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().isWritableStreamLockedPrivateName(); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(guardedObject()); + ASSERT(!arguments.hasOverflowed()); + + auto result = invokeWritableStreamFunction(*globalObject, privateName, arguments); + if (scope.exception()) + scope.clearException(); + + return result.hasException() ? false : result.returnValue().isTrue(); +} + +void InternalWritableStream::lock() +{ + auto* globalObject = this->globalObject(); + if (!globalObject) + return; + + auto scope = DECLARE_CATCH_SCOPE(globalObject->vm()); + + auto* clientData = static_cast<JSVMClientData*>(globalObject->vm().clientData); + auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().acquireWritableStreamDefaultWriterPrivateName(); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(guardedObject()); + ASSERT(!arguments.hasOverflowed()); + + invokeWritableStreamFunction(*globalObject, privateName, arguments); + if (UNLIKELY(scope.exception())) + scope.clearException(); +} + +JSC::JSValue InternalWritableStream::abort(JSC::JSGlobalObject& globalObject, JSC::JSValue reason) +{ + auto* clientData = static_cast<JSVMClientData*>(globalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().writableStreamAbortForBindingsPrivateName(); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(guardedObject()); + arguments.append(reason); + ASSERT(!arguments.hasOverflowed()); + + auto result = invokeWritableStreamFunction(globalObject, privateName, arguments); + if (result.hasException()) + return { }; + + return result.returnValue(); +} + +JSC::JSValue InternalWritableStream::close(JSC::JSGlobalObject& globalObject) +{ + auto* clientData = static_cast<JSVMClientData*>(globalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().writableStreamCloseForBindingsPrivateName(); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(guardedObject()); + ASSERT(!arguments.hasOverflowed()); + + auto result = invokeWritableStreamFunction(globalObject, privateName, arguments); + if (result.hasException()) + return { }; + + return result.returnValue(); +} + +JSC::JSValue InternalWritableStream::getWriter(JSC::JSGlobalObject& globalObject) +{ + auto* clientData = static_cast<JSVMClientData*>(globalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().acquireWritableStreamDefaultWriterPrivateName(); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(guardedObject()); + ASSERT(!arguments.hasOverflowed()); + + auto result = invokeWritableStreamFunction(globalObject, privateName, arguments); + if (result.hasException()) + return { }; + + return result.returnValue(); +} + +} diff --git a/src/bun.js/bindings/webcore/InternalWritableStream.h b/src/bun.js/bindings/webcore/InternalWritableStream.h new file mode 100644 index 000000000..a768f959d --- /dev/null +++ b/src/bun.js/bindings/webcore/InternalWritableStream.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020-2021 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 CANON 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 CANON 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. + */ + +#pragma once + +#include "ExceptionOr.h" +#include "JSDOMGuardedObject.h" +#include <JavaScriptCore/JSObject.h> + +namespace WebCore { +class InternalWritableStream final : public DOMGuarded<JSC::JSObject> { +public: + static ExceptionOr<Ref<InternalWritableStream>> createFromUnderlyingSink(JSDOMGlobalObject&, JSC::JSValue underlyingSink, JSC::JSValue strategy); + static Ref<InternalWritableStream> fromObject(JSDOMGlobalObject&, JSC::JSObject&); + + operator JSC::JSValue() const { return guarded(); } + + bool locked() const; + void lock(); + JSC::JSValue abort(JSC::JSGlobalObject&, JSC::JSValue); + JSC::JSValue close(JSC::JSGlobalObject&); + JSC::JSValue getWriter(JSC::JSGlobalObject&); + +private: + InternalWritableStream(JSDOMGlobalObject& globalObject, JSC::JSObject& jsObject) + : DOMGuarded<JSC::JSObject>(globalObject, jsObject) + { + } +}; + +} diff --git a/src/bun.js/bindings/webcore/JSAbortAlgorithm.cpp b/src/bun.js/bindings/webcore/JSAbortAlgorithm.cpp new file mode 100644 index 000000000..81310bbd5 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortAlgorithm.cpp @@ -0,0 +1,86 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSAbortAlgorithm.h" + +#include "JSDOMConvertBase.h" +#include "JSDOMExceptionHandling.h" +#include "ScriptExecutionContext.h" + +namespace WebCore { +using namespace JSC; + +JSAbortAlgorithm::JSAbortAlgorithm(VM& vm, JSObject* callback) + : AbortAlgorithm(jsCast<JSDOMGlobalObject*>(callback->globalObject())->scriptExecutionContext()) + , m_data(new JSCallbackDataStrong(vm, callback, this)) +{ +} + +JSAbortAlgorithm::~JSAbortAlgorithm() +{ + ScriptExecutionContext* context = scriptExecutionContext(); + // When the context is destroyed, all tasks with a reference to a callback + // should be deleted. So if the context is 0, we are on the context thread. + if (!context || context->isContextThread()) + delete m_data; + else + + context->postTask(new DeleteCallbackDataTask(m_data)); +#ifndef NDEBUG + m_data = nullptr; +#endif +} + +CallbackResult<typename IDLUndefined::ImplementationType> JSAbortAlgorithm::handleEvent() +{ + if (!canInvokeCallback()) + return CallbackResultType::UnableToExecute; + + Ref<JSAbortAlgorithm> protectedThis(*this); + + auto& globalObject = *jsCast<JSDOMGlobalObject*>(m_data->callback()->globalObject()); + auto& vm = globalObject.vm(); + + JSLockHolder lock(vm); + auto& lexicalGlobalObject = globalObject; + JSValue thisValue = jsUndefined(); + MarkedArgumentBuffer args; + ASSERT(!args.hasOverflowed()); + + NakedPtr<JSC::Exception> returnedException; + m_data->invokeCallback(vm, thisValue, args, JSCallbackData::CallbackType::Function, Identifier(), returnedException); + if (returnedException) { + reportException(&lexicalGlobalObject, returnedException); + return CallbackResultType::ExceptionThrown; + } + + return {}; +} + +JSC::JSValue toJS(AbortAlgorithm& impl) +{ + if (!static_cast<JSAbortAlgorithm&>(impl).callbackData()) + return jsNull(); + + return static_cast<JSAbortAlgorithm&>(impl).callbackData()->callback(); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSAbortAlgorithm.h b/src/bun.js/bindings/webcore/JSAbortAlgorithm.h new file mode 100644 index 000000000..9193ac7e6 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortAlgorithm.h @@ -0,0 +1,54 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "AbortAlgorithm.h" +#include "IDLTypes.h" +#include "JSCallbackData.h" +#include <wtf/Forward.h> + +namespace WebCore { + +class JSAbortAlgorithm final : public AbortAlgorithm { +public: + static Ref<JSAbortAlgorithm> create(JSC::VM& vm, JSC::JSObject* callback) + { + return adoptRef(*new JSAbortAlgorithm(vm, callback)); + } + + ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); } + + ~JSAbortAlgorithm() final; + JSCallbackDataStrong* callbackData() { return m_data; } + + // Functions + CallbackResult<typename IDLUndefined::ImplementationType> handleEvent() override; + +private: + JSAbortAlgorithm(JSC::VM&, JSC::JSObject* callback); + + JSCallbackDataStrong* m_data; +}; + +JSC::JSValue toJS(AbortAlgorithm&); +inline JSC::JSValue toJS(AbortAlgorithm* impl) { return impl ? toJS(*impl) : JSC::jsNull(); } + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSAbortController.cpp b/src/bun.js/bindings/webcore/JSAbortController.cpp new file mode 100644 index 000000000..b2ba038e3 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortController.cpp @@ -0,0 +1,295 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSAbortController.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSAbortSignal.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include "JavaScriptCore/FunctionPrototype.h" +#include "JavaScriptCore/HeapAnalyzer.h" + +#include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" +#include "JavaScriptCore/SlotVisitorMacros.h" +#include "JavaScriptCore/SubspaceInlines.h" +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +#include "weak_handle.h" + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsAbortControllerPrototypeFunction_abort); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsAbortControllerConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsAbortController_signal); + +class JSAbortControllerPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSAbortControllerPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSAbortControllerPrototype* ptr = new (NotNull, JSC::allocateCell<JSAbortControllerPrototype>(vm)) JSAbortControllerPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSAbortControllerPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSAbortControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSAbortControllerPrototype, JSAbortControllerPrototype::Base); + +using JSAbortControllerDOMConstructor = JSDOMConstructor<JSAbortController>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSAbortControllerDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSAbortControllerDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + auto* context = castedThis->scriptExecutionContext(); + if (UNLIKELY(!context)) + return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "AbortController"); + auto object = AbortController::create(*context); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<AbortController>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<AbortController>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSAbortControllerDOMConstructorConstruct, JSAbortControllerDOMConstructor::construct); + +template<> const ClassInfo JSAbortControllerDOMConstructor::s_info = { "AbortController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAbortControllerDOMConstructor) }; + +template<> JSValue JSAbortControllerDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSAbortControllerDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "AbortController"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSAbortController::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSAbortControllerPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsAbortControllerConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "signal"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsAbortController_signal), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "abort"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsAbortControllerPrototypeFunction_abort), (intptr_t)(0) } }, +}; + +const ClassInfo JSAbortControllerPrototype::s_info = { "AbortController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAbortControllerPrototype) }; + +void JSAbortControllerPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSAbortController::info(), JSAbortControllerPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSAbortController::s_info = { "AbortController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAbortController) }; + +JSAbortController::JSAbortController(Structure* structure, JSDOMGlobalObject& globalObject, Ref<AbortController>&& impl) + : JSDOMWrapper<AbortController>(structure, globalObject, WTFMove(impl)) +{ +} + +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."); +} + +JSObject* JSAbortController::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSAbortControllerPrototype::create(vm, &globalObject, JSAbortControllerPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSAbortController::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSAbortController>(vm, globalObject); +} + +JSValue JSAbortController::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSAbortControllerDOMConstructor, DOMConstructorID::AbortController>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSAbortController::destroy(JSC::JSCell* cell) +{ + JSAbortController* thisObject = static_cast<JSAbortController*>(cell); + thisObject->JSAbortController::~JSAbortController(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsAbortControllerConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& 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())); +} + +static inline JSValue jsAbortController_signalGetter(JSGlobalObject& lexicalGlobalObject, JSAbortController& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<AbortSignal>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.signal()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsAbortController_signal, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSAbortController>::get<jsAbortController_signalGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSC::EncodedJSValue jsAbortControllerPrototypeFunction_abortBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSAbortController>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + EnsureStillAliveScope argument0 = callFrame->argument(0); + auto reason = convert<IDLAny>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.abort(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), WTFMove(reason)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsAbortControllerPrototypeFunction_abort, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSAbortController>::call<jsAbortControllerPrototypeFunction_abortBody>(*lexicalGlobalObject, *callFrame, "abort"); +} + +JSC::GCClient::IsoSubspace* JSAbortController::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSAbortController, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForAbortController.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForAbortController = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForAbortController.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForAbortController = WTFMove(space); }); +} + +template<typename Visitor> +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())); +} + +DEFINE_VISIT_CHILDREN(JSAbortController); + +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()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSAbortControllerOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSAbortControllerOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsAbortController = static_cast<JSAbortController*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsAbortController->wrapped(), jsAbortController); +} + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<AbortController>&& impl) +{ + return createWrapper<AbortController>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, AbortController& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +AbortController* JSAbortController::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSAbortController*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSAbortController.dep b/src/bun.js/bindings/webcore/JSAbortController.dep new file mode 100644 index 000000000..c62eba8ee --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortController.dep @@ -0,0 +1 @@ +JSAbortController.h : diff --git a/src/bun.js/bindings/webcore/JSAbortController.h b/src/bun.js/bindings/webcore/JSAbortController.h new file mode 100644 index 000000000..7801a6207 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortController.h @@ -0,0 +1,98 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "root.h" + +#include "AbortController.h" +#include "JSDOMWrapper.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSAbortController : public JSDOMWrapper<AbortController> { +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()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static AbortController* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +protected: + JSAbortController(JSC::Structure*, JSDOMGlobalObject&, Ref<AbortController>&&); + + void finishCreation(JSC::VM&); +}; + +class JSAbortControllerOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, AbortController*) +{ + static NeverDestroyed<JSAbortControllerOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(AbortController* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, AbortController&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, AbortController* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<AbortController>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<AbortController>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<AbortController> { + using WrapperClass = JSAbortController; + using ToWrappedReturnType = AbortController*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSAbortSignal.cpp b/src/bun.js/bindings/webcore/JSAbortSignal.cpp new file mode 100644 index 000000000..bce823102 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortSignal.cpp @@ -0,0 +1,424 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSAbortSignal.h" + +#include "ActiveDOMObject.h" +#include "EventNames.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSAbortAlgorithm.h" +#include "JSAbortSignal.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructorNotConstructable.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertCallbacks.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "JSEventListener.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +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(jsAbortSignalPrototypeFunction_throwIfAborted); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsAbortSignalConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsAbortSignal_aborted); +static JSC_DECLARE_CUSTOM_GETTER(jsAbortSignal_reason); +static JSC_DECLARE_CUSTOM_GETTER(jsAbortSignal_onabort); +static JSC_DECLARE_CUSTOM_SETTER(setJSAbortSignal_onabort); + +class JSAbortSignalPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSAbortSignalPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSAbortSignalPrototype* ptr = new (NotNull, JSC::allocateCell<JSAbortSignalPrototype>(vm)) JSAbortSignalPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSAbortSignalPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSAbortSignalPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSAbortSignalPrototype, JSAbortSignalPrototype::Base); + +using JSAbortSignalDOMConstructor = JSDOMConstructorNotConstructable<JSAbortSignal>; + +/* Hash table for constructor */ + +static const HashTableValue JSAbortSignalConstructorTableValues[] = { + { "whenSignalAborted"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsAbortSignalConstructorFunction_whenSignalAborted), (intptr_t)(2) } }, + { "abort"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsAbortSignalConstructorFunction_abort), (intptr_t)(0) } }, + { "timeout"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsAbortSignalConstructorFunction_timeout), (intptr_t)(1) } }, +}; + +template<> const ClassInfo JSAbortSignalDOMConstructor::s_info = { "AbortSignal"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAbortSignalDOMConstructor) }; + +template<> JSValue JSAbortSignalDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + return JSEventTarget::getConstructor(vm, &globalObject); +} + +template<> void JSAbortSignalDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "AbortSignal"_s); + m_originalName.set(vm, this, nameString); + 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 (!(jsCast<JSDOMGlobalObject*>(&globalObject)->scriptExecutionContext()->isDocument() || jsCast<JSDOMGlobalObject*>(&globalObject)->scriptExecutionContext()->isWorkerGlobalScope())) { + auto propertyName = Identifier::fromString(vm, reinterpret_cast<const LChar*>("timeout"), strlen("timeout")); + 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, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsAbortSignalConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "aborted"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsAbortSignal_aborted), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "reason"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsAbortSignal_reason), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "onabort"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsAbortSignal_onabort), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSAbortSignal_onabort) } }, + { "throwIfAborted"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsAbortSignalPrototypeFunction_throwIfAborted), (intptr_t)(0) } }, +}; + +const ClassInfo JSAbortSignalPrototype::s_info = { "AbortSignal"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAbortSignalPrototype) }; + +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), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSAbortSignal::s_info = { "AbortSignal"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAbortSignal) }; + +JSAbortSignal::JSAbortSignal(Structure* structure, JSDOMGlobalObject& globalObject, Ref<AbortSignal>&& impl) + : JSEventTarget(structure, globalObject, WTFMove(impl)) +{ +} + +void JSAbortSignal::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); +} + +JSObject* JSAbortSignal::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSAbortSignalPrototype::create(vm, &globalObject, JSAbortSignalPrototype::createStructure(vm, &globalObject, JSEventTarget::prototype(vm, globalObject))); +} + +JSObject* JSAbortSignal::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSAbortSignal>(vm, globalObject); +} + +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, EncodedJSValue thisValue, PropertyName)) +{ + VM& 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())); +} + +static inline JSValue jsAbortSignal_abortedGetter(JSGlobalObject& lexicalGlobalObject, JSAbortSignal& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.aborted()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_aborted, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSAbortSignal>::get<jsAbortSignal_abortedGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsAbortSignal_reasonGetter(JSGlobalObject& lexicalGlobalObject, JSAbortSignal& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLAny>(lexicalGlobalObject, throwScope, impl.reason()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_reason, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSAbortSignal>::get<jsAbortSignal_reasonGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsAbortSignal_onabortGetter(JSGlobalObject& lexicalGlobalObject, JSAbortSignal& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return eventHandlerAttribute(thisObject.wrapped(), eventNames().abortEvent, worldForDOMObject(thisObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsAbortSignal_onabort, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSAbortSignal>::get<jsAbortSignal_onabortGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSAbortSignal_onabortSetter(JSGlobalObject& lexicalGlobalObject, JSAbortSignal& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + setEventHandlerAttribute<JSEventListener>(thisObject.wrapped(), eventNames().abortEvent, value, thisObject); + vm.writeBarrier(&thisObject, value); + ensureStillAliveHere(value); + + return true; +} + +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); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto* context = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)->scriptExecutionContext(); + if (UNLIKELY(!context)) + return JSValue::encode(jsUndefined()); + EnsureStillAliveScope argument0 = callFrame->argument(0); + auto reason = convert<IDLAny>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJSNewlyCreated<IDLInterface<AbortSignal>>(*lexicalGlobalObject, *jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), throwScope, AbortSignal::abort(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), *context, WTFMove(reason))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsAbortSignalConstructorFunction_abort, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSAbortSignal>::callStatic<jsAbortSignalConstructorFunction_abortBody>(*lexicalGlobalObject, *callFrame, "abort"); +} + +static inline JSC::EncodedJSValue jsAbortSignalConstructorFunction_timeoutBody(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 milliseconds = convert<IDLEnforceRangeAdaptor<IDLUnsignedLongLong>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJSNewlyCreated<IDLInterface<AbortSignal>>(*lexicalGlobalObject, *jsCast<JSDOMGlobalObject*>(lexicalGlobalObject), throwScope, AbortSignal::timeout(*context, WTFMove(milliseconds))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsAbortSignalConstructorFunction_timeout, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSAbortSignal>::callStatic<jsAbortSignalConstructorFunction_timeoutBody>(*lexicalGlobalObject, *callFrame, "timeout"); +} + +static inline JSC::EncodedJSValue jsAbortSignalPrototypeFunction_throwIfAbortedBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSAbortSignal>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.throwIfAborted(*jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsAbortSignalPrototypeFunction_throwIfAborted, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSAbortSignal>::call<jsAbortSignalPrototypeFunction_throwIfAbortedBody>(*lexicalGlobalObject, *callFrame, "throwIfAborted"); +} + +JSC::GCClient::IsoSubspace* JSAbortSignal::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSAbortSignal, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForAbortSignal.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForAbortSignal = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForAbortSignal.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForAbortSignal = WTFMove(space); }); +} + +template<typename Visitor> +void JSAbortSignal::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSAbortSignal*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +DEFINE_VISIT_CHILDREN(JSAbortSignal); + +template<typename Visitor> +void JSAbortSignal::visitOutputConstraints(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSAbortSignal*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitOutputConstraints(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +template void JSAbortSignal::visitOutputConstraints(JSCell*, AbstractSlotVisitor&); +template void JSAbortSignal::visitOutputConstraints(JSCell*, SlotVisitor&); +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()); + Base::analyzeHeap(cell, analyzer); +} + +void JSAbortSignalOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsAbortSignal = static_cast<JSAbortSignal*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsAbortSignal->wrapped(), jsAbortSignal); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7AbortSignal@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore11AbortSignalE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<AbortSignal>&& impl) +{ + + if constexpr (std::is_polymorphic_v<AbortSignal>) { +#if ENABLE(BINDING_INTEGRITY) + const void* actualVTablePointer = getVTablePointer(impl.ptr()); +#if PLATFORM(WIN) + void* expectedVTablePointer = __identifier("??_7AbortSignal@WebCore@@6B@"); +#else + void* expectedVTablePointer = &_ZTVN7WebCore11AbortSignalE[2]; +#endif + + // If you hit this assertion you either have a use after free bug, or + // AbortSignal has subclasses. If AbortSignal has subclasses that get passed + // to toJS() we currently require AbortSignal you to opt out of binding hardening + // by adding the SkipVTableValidation attribute to the interface IDL definition + RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); +#endif + } + return createWrapper<AbortSignal>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, AbortSignal& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +AbortSignal* JSAbortSignal::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSAbortSignal*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSAbortSignal.dep b/src/bun.js/bindings/webcore/JSAbortSignal.dep new file mode 100644 index 000000000..ae214b504 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortSignal.dep @@ -0,0 +1,2 @@ +JSAbortSignal.h : EventTarget.idl +EventTarget.idl : diff --git a/src/bun.js/bindings/webcore/JSAbortSignal.h b/src/bun.js/bindings/webcore/JSAbortSignal.h new file mode 100644 index 000000000..afca5f42c --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortSignal.h @@ -0,0 +1,102 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "AbortSignal.h" +#include "JSDOMWrapper.h" +#include "JSEventTarget.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSAbortSignal : public JSEventTarget { +public: + using Base = JSEventTarget; + 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()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static AbortSignal* toWrapped(JSC::VM&, JSC::JSValue); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + template<typename Visitor> void visitAdditionalChildren(Visitor&); + + template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + AbortSignal& wrapped() const + { + return static_cast<AbortSignal&>(Base::wrapped()); + } +protected: + JSAbortSignal(JSC::Structure*, JSDOMGlobalObject&, Ref<AbortSignal>&&); + + void finishCreation(JSC::VM&); +}; + +class JSAbortSignalOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, AbortSignal*) +{ + static NeverDestroyed<JSAbortSignalOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(AbortSignal* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, AbortSignal&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, AbortSignal* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<AbortSignal>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<AbortSignal>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<AbortSignal> { + using WrapperClass = JSAbortSignal; + using ToWrappedReturnType = AbortSignal*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp b/src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp new file mode 100644 index 000000000..bc3bab081 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019-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 + * 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 "JSDOMWrapper.h" +#include "wtf/NeverDestroyed.h" +#include "JSAbortSignal.h" + +namespace WebCore { + +bool JSAbortSignalOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::AbstractSlotVisitor& visitor, const char** reason) +{ + auto& abortSignal = JSC::jsCast<JSAbortSignal*>(handle.slot()->asCell())->wrapped(); + if (abortSignal.isFiringEventListeners()) { + if (UNLIKELY(reason)) + *reason = "EventTarget firing event listeners"; + return true; + } + + if (abortSignal.aborted()) + return false; + + if (abortSignal.isFollowingSignal()) + return true; + + if (abortSignal.hasAbortEventListener() && abortSignal.hasActiveTimeoutTimer()) + return true; + + return visitor.containsOpaqueRoot(&abortSignal); +} + +template<typename Visitor> +void JSAbortSignal::visitAdditionalChildren(Visitor& visitor) +{ + wrapped().reason().visit(visitor); +} + +DEFINE_VISIT_ADDITIONAL_CHILDREN(JSAbortSignal); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSAddEventListenerOptions.cpp b/src/bun.js/bindings/webcore/JSAddEventListenerOptions.cpp new file mode 100644 index 000000000..6ef60b2a3 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAddEventListenerOptions.cpp @@ -0,0 +1,92 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSAddEventListenerOptions.h" + +#include "JSAbortSignal.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include <JavaScriptCore/JSCInlines.h> + +namespace WebCore { +using namespace JSC; + +template<> AddEventListenerOptions convertDictionary<AddEventListenerOptions>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + AddEventListenerOptions result; + JSValue captureValue; + if (isNullOrUndefined) + captureValue = jsUndefined(); + else { + captureValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "capture"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!captureValue.isUndefined()) { + result.capture = convert<IDLBoolean>(lexicalGlobalObject, captureValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.capture = false; + JSValue onceValue; + if (isNullOrUndefined) + onceValue = jsUndefined(); + else { + onceValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "once"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!onceValue.isUndefined()) { + result.once = convert<IDLBoolean>(lexicalGlobalObject, onceValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.once = false; + JSValue passiveValue; + if (isNullOrUndefined) + passiveValue = jsUndefined(); + else { + passiveValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "passive"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!passiveValue.isUndefined()) { + result.passive = convert<IDLBoolean>(lexicalGlobalObject, passiveValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } + JSValue signalValue; + if (isNullOrUndefined) + signalValue = jsUndefined(); + else { + signalValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "signal"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!signalValue.isUndefined()) { + result.signal = convert<IDLInterface<AbortSignal>>(lexicalGlobalObject, signalValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } + return result; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSAddEventListenerOptions.dep b/src/bun.js/bindings/webcore/JSAddEventListenerOptions.dep new file mode 100644 index 000000000..da4d55f61 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAddEventListenerOptions.dep @@ -0,0 +1,2 @@ +AddEventListenerOptions.h : EventListenerOptions.idl +EventListenerOptions.idl : diff --git a/src/bun.js/bindings/webcore/JSAddEventListenerOptions.h b/src/bun.js/bindings/webcore/JSAddEventListenerOptions.h new file mode 100644 index 000000000..77b1ca7ed --- /dev/null +++ b/src/bun.js/bindings/webcore/JSAddEventListenerOptions.h @@ -0,0 +1,30 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "AddEventListenerOptions.h" +#include "JSDOMConvertDictionary.h" + +namespace WebCore { + +template<> AddEventListenerOptions convertDictionary<AddEventListenerOptions>(JSC::JSGlobalObject&, JSC::JSValue); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.cpp b/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.cpp new file mode 100644 index 000000000..d0e02a447 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.cpp @@ -0,0 +1,182 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSByteLengthQueuingStrategy.h" + +#include "ByteLengthQueuingStrategyBuiltins.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsByteLengthQueuingStrategyConstructor); + +class JSByteLengthQueuingStrategyPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSByteLengthQueuingStrategyPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSByteLengthQueuingStrategyPrototype* ptr = new (NotNull, JSC::allocateCell<JSByteLengthQueuingStrategyPrototype>(vm)) JSByteLengthQueuingStrategyPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSByteLengthQueuingStrategyPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSByteLengthQueuingStrategyPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSByteLengthQueuingStrategyPrototype, JSByteLengthQueuingStrategyPrototype::Base); + +using JSByteLengthQueuingStrategyDOMConstructor = JSDOMBuiltinConstructor<JSByteLengthQueuingStrategy>; + +template<> const ClassInfo JSByteLengthQueuingStrategyDOMConstructor::s_info = { "ByteLengthQueuingStrategy"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSByteLengthQueuingStrategyDOMConstructor) }; + +template<> JSValue JSByteLengthQueuingStrategyDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSByteLengthQueuingStrategyDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ByteLengthQueuingStrategy"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSByteLengthQueuingStrategy::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSByteLengthQueuingStrategyDOMConstructor::initializeExecutable(VM& vm) +{ + return byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSByteLengthQueuingStrategyPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsByteLengthQueuingStrategyConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "highWaterMark"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(byteLengthQueuingStrategyHighWaterMarkCodeGenerator), (intptr_t) (0) } }, + { "size"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(byteLengthQueuingStrategySizeCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSByteLengthQueuingStrategyPrototype::s_info = { "ByteLengthQueuingStrategy"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSByteLengthQueuingStrategyPrototype) }; + +void JSByteLengthQueuingStrategyPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSByteLengthQueuingStrategy::info(), JSByteLengthQueuingStrategyPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSByteLengthQueuingStrategy::s_info = { "ByteLengthQueuingStrategy"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSByteLengthQueuingStrategy) }; + +JSByteLengthQueuingStrategy::JSByteLengthQueuingStrategy(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSByteLengthQueuingStrategy::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSByteLengthQueuingStrategy::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSByteLengthQueuingStrategyPrototype::create(vm, &globalObject, JSByteLengthQueuingStrategyPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSByteLengthQueuingStrategy::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSByteLengthQueuingStrategy>(vm, globalObject); +} + +JSValue JSByteLengthQueuingStrategy::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSByteLengthQueuingStrategyDOMConstructor, DOMConstructorID::ByteLengthQueuingStrategy>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSByteLengthQueuingStrategy::destroy(JSC::JSCell* cell) +{ + JSByteLengthQueuingStrategy* thisObject = static_cast<JSByteLengthQueuingStrategy*>(cell); + thisObject->JSByteLengthQueuingStrategy::~JSByteLengthQueuingStrategy(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsByteLengthQueuingStrategyConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSByteLengthQueuingStrategyPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSByteLengthQueuingStrategy::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSByteLengthQueuingStrategy::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSByteLengthQueuingStrategy, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForByteLengthQueuingStrategy.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForByteLengthQueuingStrategy = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForByteLengthQueuingStrategy.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForByteLengthQueuingStrategy = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.dep b/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.dep new file mode 100644 index 000000000..0b697d758 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.dep @@ -0,0 +1 @@ +JSByteLengthQueuingStrategy.h : diff --git a/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.h b/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.h new file mode 100644 index 000000000..75d528814 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSByteLengthQueuingStrategy.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSByteLengthQueuingStrategy : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSByteLengthQueuingStrategy* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSByteLengthQueuingStrategy* ptr = new (NotNull, JSC::allocateCell<JSByteLengthQueuingStrategy>(globalObject->vm())) JSByteLengthQueuingStrategy(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSByteLengthQueuingStrategy(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSCallbackData.cpp b/src/bun.js/bindings/webcore/JSCallbackData.cpp new file mode 100644 index 000000000..671f168f7 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCallbackData.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2007-2021 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. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#include "config.h" + +#include "ZigGlobalObject.h" + +#include "JSCallbackData.h" + +#include "JSDOMBinding.h" +// #include "JSExecState.h" +// #include "JSExecStateInstrumentation.h" +#include <JavaScriptCore/Exception.h> + +namespace WebCore { +using namespace JSC; + +// https://webidl.spec.whatwg.org/#call-a-user-objects-operation +JSValue JSCallbackData::invokeCallback(VM& vm, JSObject* callback, JSValue thisValue, MarkedArgumentBuffer& args, CallbackType method, PropertyName functionName, NakedPtr<JSC::Exception>& returnedException) +{ + ASSERT(callback); + + // https://webidl.spec.whatwg.org/#ref-for-prepare-to-run-script makes callback's [[Realm]] a running JavaScript execution context, + // which is used for creating TypeError objects: https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist (step 4). + JSGlobalObject* lexicalGlobalObject = callback->globalObject(); + auto scope = DECLARE_CATCH_SCOPE(vm); + + JSValue function; + CallData callData; + + if (method != CallbackType::Object) { + function = callback; + callData = getCallData(callback); + } + if (callData.type == CallData::Type::None) { + if (method == CallbackType::Function) { + returnedException = JSC::Exception::create(vm, createTypeError(lexicalGlobalObject)); + return JSValue(); + } + + ASSERT(!functionName.isNull()); + function = callback->get(lexicalGlobalObject, functionName); + if (UNLIKELY(scope.exception())) { + returnedException = scope.exception(); + scope.clearException(); + return JSValue(); + } + + callData = getCallData(function); + if (callData.type == CallData::Type::None) { + returnedException = JSC::Exception::create(vm, createTypeError(lexicalGlobalObject, makeString("'", String(functionName.uid()), "' property of callback interface should be callable"))); + return JSValue(); + } + + thisValue = callback; + } + + ASSERT(!function.isEmpty()); + ASSERT(callData.type != CallData::Type::None); + + ScriptExecutionContext* context = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)->scriptExecutionContext(); + // We will fail to get the context if the frame has been detached. + if (!context) + return JSValue(); + + // JSExecState::instrumentFunction(context, callData); + + returnedException = nullptr; + JSValue result = JSC::profiledCall(lexicalGlobalObject, JSC::ProfilingReason::Other, function, callData, thisValue, args, returnedException); + + // InspectorInstrumentation::didCallFunction(context); + + return result; +} + +template<typename Visitor> +void JSCallbackDataWeak::visitJSFunction(Visitor& visitor) +{ + visitor.append(m_callback); +} + +template void JSCallbackDataWeak::visitJSFunction(JSC::AbstractSlotVisitor&); +template void JSCallbackDataWeak::visitJSFunction(JSC::SlotVisitor&); + +bool JSCallbackDataWeak::WeakOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, AbstractSlotVisitor& visitor, const char** reason) +{ + if (UNLIKELY(reason)) + *reason = "Context is opaque root"; // FIXME: what is the context. + return visitor.containsOpaqueRoot(context); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSCallbackData.h b/src/bun.js/bindings/webcore/JSCallbackData.h new file mode 100644 index 000000000..ddfaf6e39 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCallbackData.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2007-2021 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. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "JSDOMBinding.h" +#include "ScriptExecutionContext.h" +#include <JavaScriptCore/JSObject.h> +#include <JavaScriptCore/Strong.h> +#include <JavaScriptCore/StrongInlines.h> +#include <wtf/Threading.h> + +namespace WebCore { + +// We have to clean up this data on the context thread because unprotecting a +// JSObject on the wrong thread without synchronization would corrupt the heap +// (and synchronization would be slow). + +class JSCallbackData { + WTF_MAKE_FAST_ALLOCATED; + +public: + enum class CallbackType { Function, + Object, + FunctionOrObject }; + + WEBCORE_EXPORT static JSC::JSValue invokeCallback(JSC::VM&, JSC::JSObject* callback, JSC::JSValue thisValue, JSC::MarkedArgumentBuffer&, CallbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException); + +protected: + explicit JSCallbackData() = default; + + ~JSCallbackData() + { +#if !PLATFORM(IOS_FAMILY) + ASSERT(m_thread.ptr() == &Thread::current()); +#endif + } + +private: +#if ASSERT_ENABLED + Ref<Thread> m_thread { Thread::current() }; +#endif +}; + +class JSCallbackDataStrong : public JSCallbackData { +public: + JSCallbackDataStrong(JSC::VM& vm, JSC::JSObject* callback, void* = nullptr) + : m_callback(vm, callback) + { + } + + JSC::JSObject* callback() { return m_callback.get(); } + + JSC::JSValue invokeCallback(JSC::VM& vm, JSC::JSValue thisValue, JSC::MarkedArgumentBuffer& args, CallbackType callbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException) + { + return JSCallbackData::invokeCallback(vm, callback(), thisValue, args, callbackType, functionName, returnedException); + } + +private: + JSC::Strong<JSC::JSObject> m_callback; +}; + +class JSCallbackDataWeak : public JSCallbackData { +public: + JSCallbackDataWeak(JSC::VM&, JSC::JSObject* callback, void* owner) + : m_callback(callback, &m_weakOwner, owner) + { + } + + JSC::JSObject* callback() { return m_callback.get(); } + + JSC::JSValue invokeCallback(JSC::VM& vm, JSC::JSValue thisValue, JSC::MarkedArgumentBuffer& args, CallbackType callbackType, JSC::PropertyName functionName, NakedPtr<JSC::Exception>& returnedException) + { + return JSCallbackData::invokeCallback(vm, callback(), thisValue, args, callbackType, functionName, returnedException); + } + + template<typename Visitor> void visitJSFunction(Visitor&); + +private: + class WeakOwner : public JSC::WeakHandleOwner { + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) override; + }; + WeakOwner m_weakOwner; + JSC::Weak<JSC::JSObject> m_callback; +}; + +class DeleteCallbackDataTask : public EventLoopTask { +public: + template<typename CallbackDataType> + explicit DeleteCallbackDataTask(CallbackDataType* data) + : EventLoopTask(EventLoopTask::CleanupTask, [data](ScriptExecutionContext&) mutable { + delete data; + }) + { + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSCloseEvent.cpp b/src/bun.js/bindings/webcore/JSCloseEvent.cpp new file mode 100644 index 000000000..6c86ed3b3 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCloseEvent.cpp @@ -0,0 +1,377 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSCloseEvent.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +template<> CloseEvent::Init convertDictionary<CloseEvent::Init>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + CloseEvent::Init result; + JSValue bubblesValue; + if (isNullOrUndefined) + bubblesValue = jsUndefined(); + else { + bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!bubblesValue.isUndefined()) { + result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.bubbles = false; + JSValue cancelableValue; + if (isNullOrUndefined) + cancelableValue = jsUndefined(); + else { + cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!cancelableValue.isUndefined()) { + result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.cancelable = false; + JSValue composedValue; + if (isNullOrUndefined) + composedValue = jsUndefined(); + else { + composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!composedValue.isUndefined()) { + result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.composed = false; + JSValue codeValue; + if (isNullOrUndefined) + codeValue = jsUndefined(); + else { + codeValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "code"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!codeValue.isUndefined()) { + result.code = convert<IDLUnsignedShort>(lexicalGlobalObject, codeValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.code = 0; + JSValue reasonValue; + if (isNullOrUndefined) + reasonValue = jsUndefined(); + else { + reasonValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "reason"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!reasonValue.isUndefined()) { + result.reason = convert<IDLUSVString>(lexicalGlobalObject, reasonValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.reason = emptyString(); + JSValue wasCleanValue; + if (isNullOrUndefined) + wasCleanValue = jsUndefined(); + else { + wasCleanValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "wasClean"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!wasCleanValue.isUndefined()) { + result.wasClean = convert<IDLBoolean>(lexicalGlobalObject, wasCleanValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.wasClean = false; + return result; +} + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsCloseEventConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsCloseEvent_wasClean); +static JSC_DECLARE_CUSTOM_GETTER(jsCloseEvent_code); +static JSC_DECLARE_CUSTOM_GETTER(jsCloseEvent_reason); + +class JSCloseEventPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSCloseEventPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSCloseEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSCloseEventPrototype>(vm)) JSCloseEventPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCloseEventPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSCloseEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCloseEventPrototype, JSCloseEventPrototype::Base); + +using JSCloseEventDOMConstructor = JSDOMConstructor<JSCloseEvent>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSCloseEventDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSCloseEventDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto eventInitDict = convert<IDLDictionary<CloseEvent::Init>>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = CloseEvent::create(WTFMove(type), WTFMove(eventInitDict)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<CloseEvent>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<CloseEvent>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSCloseEventDOMConstructorConstruct, JSCloseEventDOMConstructor::construct); + +template<> const ClassInfo JSCloseEventDOMConstructor::s_info = { "CloseEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCloseEventDOMConstructor) }; + +template<> JSValue JSCloseEventDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + return JSEvent::getConstructor(vm, &globalObject); +} + +template<> void JSCloseEventDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "CloseEvent"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSCloseEvent::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSCloseEventPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsCloseEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "wasClean"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsCloseEvent_wasClean), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "code"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsCloseEvent_code), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "reason"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsCloseEvent_reason), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, +}; + +const ClassInfo JSCloseEventPrototype::s_info = { "CloseEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCloseEventPrototype) }; + +void JSCloseEventPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSCloseEvent::info(), JSCloseEventPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSCloseEvent::s_info = { "CloseEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCloseEvent) }; + +JSCloseEvent::JSCloseEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<CloseEvent>&& impl) + : JSEvent(structure, globalObject, WTFMove(impl)) +{ +} + +void JSCloseEvent::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, CloseEvent>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSCloseEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSCloseEventPrototype::create(vm, &globalObject, JSCloseEventPrototype::createStructure(vm, &globalObject, JSEvent::prototype(vm, globalObject))); +} + +JSObject* JSCloseEvent::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSCloseEvent>(vm, globalObject); +} + +JSValue JSCloseEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSCloseEventDOMConstructor, DOMConstructorID::CloseEvent>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsCloseEventConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSCloseEventPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSCloseEvent::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsCloseEvent_wasCleanGetter(JSGlobalObject& lexicalGlobalObject, JSCloseEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.wasClean()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsCloseEvent_wasClean, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSCloseEvent>::get<jsCloseEvent_wasCleanGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsCloseEvent_codeGetter(JSGlobalObject& lexicalGlobalObject, JSCloseEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedShort>(lexicalGlobalObject, throwScope, impl.code()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsCloseEvent_code, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSCloseEvent>::get<jsCloseEvent_codeGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsCloseEvent_reasonGetter(JSGlobalObject& lexicalGlobalObject, JSCloseEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.reason()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsCloseEvent_reason, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSCloseEvent>::get<jsCloseEvent_reasonGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +JSC::GCClient::IsoSubspace* JSCloseEvent::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSCloseEvent, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForCloseEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForCloseEvent = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForCloseEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForCloseEvent = WTFMove(space); }); +} + +void JSCloseEvent::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSCloseEvent*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7CloseEvent@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore10CloseEventE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<CloseEvent>&& impl) +{ + + if constexpr (std::is_polymorphic_v<CloseEvent>) { +#if ENABLE(BINDING_INTEGRITY) + const void* actualVTablePointer = getVTablePointer(impl.ptr()); +#if PLATFORM(WIN) + void* expectedVTablePointer = __identifier("??_7CloseEvent@WebCore@@6B@"); +#else + void* expectedVTablePointer = &_ZTVN7WebCore10CloseEventE[2]; +#endif + + // If you hit this assertion you either have a use after free bug, or + // CloseEvent has subclasses. If CloseEvent has subclasses that get passed + // to toJS() we currently require CloseEvent you to opt out of binding hardening + // by adding the SkipVTableValidation attribute to the interface IDL definition + RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); +#endif + } + return createWrapper<CloseEvent>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, CloseEvent& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +} diff --git a/src/bun.js/bindings/webcore/JSCloseEvent.dep b/src/bun.js/bindings/webcore/JSCloseEvent.dep new file mode 100644 index 000000000..25edceaab --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCloseEvent.dep @@ -0,0 +1,3 @@ +JSCloseEvent.h : Event.idl EventInit.idl +Event.idl : +EventInit.idl : diff --git a/src/bun.js/bindings/webcore/JSCloseEvent.h b/src/bun.js/bindings/webcore/JSCloseEvent.h new file mode 100644 index 000000000..d7f25493b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCloseEvent.h @@ -0,0 +1,82 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "CloseEvent.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMWrapper.h" +#include "JSEvent.h" + +namespace WebCore { + +class JSCloseEvent : public JSEvent { +public: + using Base = JSEvent; + using DOMWrapped = CloseEvent; + static JSCloseEvent* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<CloseEvent>&& impl) + { + JSCloseEvent* ptr = new (NotNull, JSC::allocateCell<JSCloseEvent>(globalObject->vm())) JSCloseEvent(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + CloseEvent& wrapped() const + { + return static_cast<CloseEvent&>(Base::wrapped()); + } +protected: + JSCloseEvent(JSC::Structure*, JSDOMGlobalObject&, Ref<CloseEvent>&&); + + void finishCreation(JSC::VM&); +}; + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, CloseEvent&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, CloseEvent* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<CloseEvent>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<CloseEvent>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<CloseEvent> { + using WrapperClass = JSCloseEvent; + using ToWrappedReturnType = CloseEvent*; +}; +template<> CloseEvent::Init convertDictionary<CloseEvent::Init>(JSC::JSGlobalObject&, JSC::JSValue); + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSCountQueuingStrategy.cpp b/src/bun.js/bindings/webcore/JSCountQueuingStrategy.cpp new file mode 100644 index 000000000..286897c2d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCountQueuingStrategy.cpp @@ -0,0 +1,182 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSCountQueuingStrategy.h" + +#include "CountQueuingStrategyBuiltins.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsCountQueuingStrategyConstructor); + +class JSCountQueuingStrategyPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSCountQueuingStrategyPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSCountQueuingStrategyPrototype* ptr = new (NotNull, JSC::allocateCell<JSCountQueuingStrategyPrototype>(vm)) JSCountQueuingStrategyPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCountQueuingStrategyPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSCountQueuingStrategyPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCountQueuingStrategyPrototype, JSCountQueuingStrategyPrototype::Base); + +using JSCountQueuingStrategyDOMConstructor = JSDOMBuiltinConstructor<JSCountQueuingStrategy>; + +template<> const ClassInfo JSCountQueuingStrategyDOMConstructor::s_info = { "CountQueuingStrategy"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCountQueuingStrategyDOMConstructor) }; + +template<> JSValue JSCountQueuingStrategyDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSCountQueuingStrategyDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "CountQueuingStrategy"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSCountQueuingStrategy::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSCountQueuingStrategyDOMConstructor::initializeExecutable(VM& vm) +{ + return countQueuingStrategyInitializeCountQueuingStrategyCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSCountQueuingStrategyPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsCountQueuingStrategyConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "highWaterMark"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(countQueuingStrategyHighWaterMarkCodeGenerator), (intptr_t) (0) } }, + { "size"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(countQueuingStrategySizeCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSCountQueuingStrategyPrototype::s_info = { "CountQueuingStrategy"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCountQueuingStrategyPrototype) }; + +void JSCountQueuingStrategyPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSCountQueuingStrategy::info(), JSCountQueuingStrategyPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSCountQueuingStrategy::s_info = { "CountQueuingStrategy"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCountQueuingStrategy) }; + +JSCountQueuingStrategy::JSCountQueuingStrategy(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSCountQueuingStrategy::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSCountQueuingStrategy::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSCountQueuingStrategyPrototype::create(vm, &globalObject, JSCountQueuingStrategyPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSCountQueuingStrategy::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSCountQueuingStrategy>(vm, globalObject); +} + +JSValue JSCountQueuingStrategy::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSCountQueuingStrategyDOMConstructor, DOMConstructorID::CountQueuingStrategy>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSCountQueuingStrategy::destroy(JSC::JSCell* cell) +{ + JSCountQueuingStrategy* thisObject = static_cast<JSCountQueuingStrategy*>(cell); + thisObject->JSCountQueuingStrategy::~JSCountQueuingStrategy(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsCountQueuingStrategyConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSCountQueuingStrategyPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSCountQueuingStrategy::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSCountQueuingStrategy::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSCountQueuingStrategy, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForCountQueuingStrategy.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForCountQueuingStrategy = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForCountQueuingStrategy.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForCountQueuingStrategy = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSCountQueuingStrategy.dep b/src/bun.js/bindings/webcore/JSCountQueuingStrategy.dep new file mode 100644 index 000000000..413363a34 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCountQueuingStrategy.dep @@ -0,0 +1 @@ +JSCountQueuingStrategy.h : diff --git a/src/bun.js/bindings/webcore/JSCountQueuingStrategy.h b/src/bun.js/bindings/webcore/JSCountQueuingStrategy.h new file mode 100644 index 000000000..0cd89d4fc --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCountQueuingStrategy.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSCountQueuingStrategy : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSCountQueuingStrategy* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSCountQueuingStrategy* ptr = new (NotNull, JSC::allocateCell<JSCountQueuingStrategy>(globalObject->vm())) JSCountQueuingStrategy(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSCountQueuingStrategy(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSCustomEvent.cpp b/src/bun.js/bindings/webcore/JSCustomEvent.cpp new file mode 100644 index 000000000..383688c42 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCustomEvent.cpp @@ -0,0 +1,380 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSCustomEvent.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +template<> CustomEvent::Init convertDictionary<CustomEvent::Init>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + CustomEvent::Init result; + JSValue bubblesValue; + if (isNullOrUndefined) + bubblesValue = jsUndefined(); + else { + bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!bubblesValue.isUndefined()) { + result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.bubbles = false; + JSValue cancelableValue; + if (isNullOrUndefined) + cancelableValue = jsUndefined(); + else { + cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!cancelableValue.isUndefined()) { + result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.cancelable = false; + JSValue composedValue; + if (isNullOrUndefined) + composedValue = jsUndefined(); + else { + composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!composedValue.isUndefined()) { + result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.composed = false; + JSValue detailValue; + if (isNullOrUndefined) + detailValue = jsUndefined(); + else { + detailValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "detail"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!detailValue.isUndefined()) { + result.detail = convert<IDLAny>(lexicalGlobalObject, detailValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.detail = jsNull(); + return result; +} + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsCustomEventPrototypeFunction_initCustomEvent); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsCustomEventConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsCustomEvent_detail); + +class JSCustomEventPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSCustomEventPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSCustomEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSCustomEventPrototype>(vm)) JSCustomEventPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCustomEventPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSCustomEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSCustomEventPrototype, JSCustomEventPrototype::Base); + +using JSCustomEventDOMConstructor = JSDOMConstructor<JSCustomEvent>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSCustomEventDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSCustomEventDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto eventInitDict = convert<IDLDictionary<CustomEvent::Init>>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = CustomEvent::create(type, WTFMove(eventInitDict)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<CustomEvent>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<CustomEvent>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSCustomEventDOMConstructorConstruct, JSCustomEventDOMConstructor::construct); + +template<> const ClassInfo JSCustomEventDOMConstructor::s_info = { "CustomEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCustomEventDOMConstructor) }; + +template<> JSValue JSCustomEventDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + return JSEvent::getConstructor(vm, &globalObject); +} + +template<> void JSCustomEventDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "CustomEvent"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSCustomEvent::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSCustomEventPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsCustomEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "detail"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsCustomEvent_detail), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "initCustomEvent"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsCustomEventPrototypeFunction_initCustomEvent), (intptr_t)(1) } }, +}; + +const ClassInfo JSCustomEventPrototype::s_info = { "CustomEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCustomEventPrototype) }; + +void JSCustomEventPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSCustomEvent::info(), JSCustomEventPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSCustomEvent::s_info = { "CustomEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCustomEvent) }; + +JSCustomEvent::JSCustomEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<CustomEvent>&& impl) + : JSEvent(structure, globalObject, WTFMove(impl)) +{ +} + +void JSCustomEvent::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, CustomEvent>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSCustomEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSCustomEventPrototype::create(vm, &globalObject, JSCustomEventPrototype::createStructure(vm, &globalObject, JSEvent::prototype(vm, globalObject))); +} + +JSObject* JSCustomEvent::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSCustomEvent>(vm, globalObject); +} + +JSValue JSCustomEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSCustomEventDOMConstructor, DOMConstructorID::CustomEvent>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsCustomEventConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSCustomEventPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSCustomEvent::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsCustomEvent_detailGetter(JSGlobalObject& lexicalGlobalObject, JSCustomEvent& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return thisObject.detail(lexicalGlobalObject); +} + +JSC_DEFINE_CUSTOM_GETTER(jsCustomEvent_detail, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSCustomEvent>::get<jsCustomEvent_detailGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSC::EncodedJSValue jsCustomEventPrototypeFunction_initCustomEventBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSCustomEvent>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto bubbles = convert<IDLBoolean>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument2 = callFrame->argument(2); + auto cancelable = convert<IDLBoolean>(*lexicalGlobalObject, argument2.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument3 = callFrame->argument(3); + auto detail = argument3.value().isUndefined() ? jsNull() : convert<IDLAny>(*lexicalGlobalObject, argument3.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initCustomEvent(type, WTFMove(bubbles), WTFMove(cancelable), WTFMove(detail)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsCustomEventPrototypeFunction_initCustomEvent, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSCustomEvent>::call<jsCustomEventPrototypeFunction_initCustomEventBody>(*lexicalGlobalObject, *callFrame, "initCustomEvent"); +} + +JSC::GCClient::IsoSubspace* JSCustomEvent::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSCustomEvent, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForCustomEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForCustomEvent = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForCustomEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForCustomEvent = WTFMove(space); }); +} + +template<typename Visitor> +void JSCustomEvent::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSCustomEvent*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +DEFINE_VISIT_CHILDREN(JSCustomEvent); + +template<typename Visitor> +void JSCustomEvent::visitOutputConstraints(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSCustomEvent*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitOutputConstraints(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +template void JSCustomEvent::visitOutputConstraints(JSCell*, AbstractSlotVisitor&); +template void JSCustomEvent::visitOutputConstraints(JSCell*, SlotVisitor&); +void JSCustomEvent::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSCustomEvent*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7CustomEvent@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore11CustomEventE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<CustomEvent>&& impl) +{ + + // if constexpr (std::is_polymorphic_v<CustomEvent>) { + // #if ENABLE(BINDING_INTEGRITY) + // const void* actualVTablePointer = getVTablePointer(impl.ptr()); + // #if PLATFORM(WIN) + // void* expectedVTablePointer = __identifier("??_7CustomEvent@WebCore@@6B@"); + // #else + // void* expectedVTablePointer = &_ZTVN7WebCore11CustomEventE[2]; + // #endif + + // // If you hit this assertion you either have a use after free bug, or + // // CustomEvent has subclasses. If CustomEvent has subclasses that get passed + // // to toJS() we currently require CustomEvent you to opt out of binding hardening + // // by adding the SkipVTableValidation attribute to the interface IDL definition + // RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); + // #endif + // } + return createWrapper<CustomEvent>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, CustomEvent& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +} diff --git a/src/bun.js/bindings/webcore/JSCustomEvent.dep b/src/bun.js/bindings/webcore/JSCustomEvent.dep new file mode 100644 index 000000000..443684f8c --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCustomEvent.dep @@ -0,0 +1,3 @@ +JSCustomEvent.h : Event.idl EventInit.idl +Event.idl : +EventInit.idl : diff --git a/src/bun.js/bindings/webcore/JSCustomEvent.h b/src/bun.js/bindings/webcore/JSCustomEvent.h new file mode 100644 index 000000000..309b4a4a8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSCustomEvent.h @@ -0,0 +1,89 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "CustomEvent.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMWrapper.h" +#include "JSEvent.h" + +namespace WebCore { + +class JSCustomEvent : public JSEvent { +public: + using Base = JSEvent; + using DOMWrapped = CustomEvent; + static JSCustomEvent* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<CustomEvent>&& impl) + { + JSCustomEvent* ptr = new (NotNull, JSC::allocateCell<JSCustomEvent>(globalObject->vm())) JSCustomEvent(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + template<typename Visitor> void visitAdditionalChildren(Visitor&); + + template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + + // Custom attributes + JSC::JSValue detail(JSC::JSGlobalObject&) const; + CustomEvent& wrapped() const + { + return static_cast<CustomEvent&>(Base::wrapped()); + } +protected: + JSCustomEvent(JSC::Structure*, JSDOMGlobalObject&, Ref<CustomEvent>&&); + + void finishCreation(JSC::VM&); +}; + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, CustomEvent&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, CustomEvent* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<CustomEvent>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<CustomEvent>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<CustomEvent> { + using WrapperClass = JSCustomEvent; + using ToWrappedReturnType = CustomEvent*; +}; +template<> CustomEvent::Init convertDictionary<CustomEvent::Init>(JSC::JSGlobalObject&, JSC::JSValue); + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMAttribute.h b/src/bun.js/bindings/webcore/JSDOMAttribute.h new file mode 100644 index 000000000..17b0f588c --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMAttribute.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003-2020 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * Copyright (C) 2012 Ericsson AB. All rights reserved. + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMCastThisValue.h" +#include "JSDOMExceptionHandling.h" + +namespace WebCore { + +template<typename JSClass> +class IDLAttribute { +public: + using Setter = bool(JSC::JSGlobalObject&, JSClass&, JSC::JSValue); + using SetterPassingPropertyName = bool(JSC::JSGlobalObject&, JSClass&, JSC::JSValue, JSC::PropertyName); + using StaticSetter = bool(JSC::JSGlobalObject&, JSC::JSValue); + using Getter = JSC::JSValue(JSC::JSGlobalObject&, JSClass&); + using GetterPassingPropertyName = JSC::JSValue(JSC::JSGlobalObject&, JSClass&, JSC::PropertyName); + using StaticGetter = JSC::JSValue(JSC::JSGlobalObject&); + + template<Setter setter, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static bool set(JSC::JSGlobalObject& lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue encodedValue, JSC::PropertyName attributeName) + { + auto throwScope = DECLARE_THROW_SCOPE(JSC::getVM(&lexicalGlobalObject)); + + auto* thisObject = castThisValue<JSClass>(lexicalGlobalObject, JSC::JSValue::decode(thisValue)); + if (UNLIKELY(!thisObject)) { + if constexpr (shouldThrow == CastedThisErrorBehavior::Throw) + return JSC::throwVMDOMAttributeSetterTypeError(&lexicalGlobalObject, throwScope, JSClass::info(), attributeName); + else + return false; + } + + RELEASE_AND_RETURN(throwScope, (setter(lexicalGlobalObject, *thisObject, JSC::JSValue::decode(encodedValue)))); + } + + // FIXME: FIXME: This can be merged with `set` if we replace the explicit setter function template parameter with a generic lambda. + template<SetterPassingPropertyName setter, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static bool setPassingPropertyName(JSC::JSGlobalObject& lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue encodedValue, JSC::PropertyName attributeName) + { + auto throwScope = DECLARE_THROW_SCOPE(JSC::getVM(&lexicalGlobalObject)); + + auto* thisObject = castThisValue<JSClass>(lexicalGlobalObject, JSC::JSValue::decode(thisValue)); + if (UNLIKELY(!thisObject)) { + if constexpr (shouldThrow == CastedThisErrorBehavior::Throw) + return JSC::throwVMDOMAttributeSetterTypeError(&lexicalGlobalObject, throwScope, JSClass::info(), attributeName); + else + return false; + } + + RELEASE_AND_RETURN(throwScope, (setter(lexicalGlobalObject, *thisObject, JSC::JSValue::decode(encodedValue), attributeName))); + } + + template<StaticSetter setter, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static bool setStatic(JSC::JSGlobalObject& lexicalGlobalObject, JSC::EncodedJSValue, JSC::EncodedJSValue encodedValue, JSC::PropertyName) + { + return setter(lexicalGlobalObject, JSC::JSValue::decode(encodedValue)); + } + + template<Getter getter, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static JSC::EncodedJSValue get(JSC::JSGlobalObject& lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName attributeName) + { + auto throwScope = DECLARE_THROW_SCOPE(JSC::getVM(&lexicalGlobalObject)); + + if constexpr (shouldThrow == CastedThisErrorBehavior::Assert) { + ASSERT(castThisValue<JSClass>(lexicalGlobalObject, JSC::JSValue::decode(thisValue))); + auto* thisObject = JSC::jsCast<JSClass*>(JSC::JSValue::decode(thisValue)); + RELEASE_AND_RETURN(throwScope, (JSC::JSValue::encode(getter(lexicalGlobalObject, *thisObject)))); + } else { + auto* thisObject = castThisValue<JSClass>(lexicalGlobalObject, JSC::JSValue::decode(thisValue)); + if (UNLIKELY(!thisObject)) { + if constexpr (shouldThrow == CastedThisErrorBehavior::Throw) + return JSC::throwVMDOMAttributeGetterTypeError(&lexicalGlobalObject, throwScope, JSClass::info(), attributeName); + else if constexpr (shouldThrow == CastedThisErrorBehavior::RejectPromise) + RELEASE_AND_RETURN(throwScope, rejectPromiseWithGetterTypeError(lexicalGlobalObject, JSClass::info(), attributeName)); + else + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + RELEASE_AND_RETURN(throwScope, (JSC::JSValue::encode(getter(lexicalGlobalObject, *thisObject)))); + } + } + + // FIXME: This can be merged with `get` if we replace the explicit setter function template parameter with a generic lambda. + template<GetterPassingPropertyName getter, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static JSC::EncodedJSValue getPassingPropertyName(JSC::JSGlobalObject& lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName attributeName) + { + auto throwScope = DECLARE_THROW_SCOPE(JSC::getVM(&lexicalGlobalObject)); + + if constexpr (shouldThrow == CastedThisErrorBehavior::Assert) { + ASSERT(castThisValue<JSClass>(lexicalGlobalObject, JSC::JSValue::decode(thisValue))); + auto* thisObject = JSC::jsCast<JSClass*>(JSC::JSValue::decode(thisValue)); + RELEASE_AND_RETURN(throwScope, (JSC::JSValue::encode(getter(lexicalGlobalObject, *thisObject, attributeName)))); + } else { + auto* thisObject = castThisValue<JSClass>(lexicalGlobalObject, JSC::JSValue::decode(thisValue)); + if (UNLIKELY(!thisObject)) { + if constexpr (shouldThrow == CastedThisErrorBehavior::Throw) + return JSC::throwVMDOMAttributeGetterTypeError(&lexicalGlobalObject, throwScope, JSClass::info(), attributeName); + else if constexpr (shouldThrow == CastedThisErrorBehavior::RejectPromise) + RELEASE_AND_RETURN(throwScope, rejectPromiseWithGetterTypeError(lexicalGlobalObject, JSClass::info(), attributeName)); + else + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + RELEASE_AND_RETURN(throwScope, (JSC::JSValue::encode(getter(lexicalGlobalObject, *thisObject, attributeName)))); + } + } + + template<StaticGetter getter, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static JSC::EncodedJSValue getStatic(JSC::JSGlobalObject& lexicalGlobalObject, JSC::EncodedJSValue, JSC::PropertyName) + { + return JSC::JSValue::encode(getter(lexicalGlobalObject)); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMBinding.h b/src/bun.js/bindings/webcore/JSDOMBinding.h new file mode 100644 index 000000000..cb9a3a1c6 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMBinding.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003-2006, 2008-2009, 2013, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * Copyright (C) 2012 Ericsson AB. All rights reserved. + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +// FIXME: Remove this header. + +#include "ExceptionOr.h" +#include "JSDOMWrapperCache.h" +#include <JavaScriptCore/AuxiliaryBarrierInlines.h> +#include <JavaScriptCore/HeapInlines.h> +#include <JavaScriptCore/JSArray.h> +#include <JavaScriptCore/JSCJSValueInlines.h> +#include <JavaScriptCore/JSCellInlines.h> +#include <JavaScriptCore/JSObjectInlines.h> +#include <JavaScriptCore/Lookup.h> +#include <JavaScriptCore/ObjectConstructor.h> +#include <JavaScriptCore/SlotVisitorInlines.h> +#include <JavaScriptCore/StructureInlines.h> +#include <JavaScriptCore/WriteBarrier.h> +#include <cstddef> +#include <wtf/Forward.h> +#include <wtf/GetPtr.h> +#include <wtf/Vector.h> diff --git a/src/bun.js/bindings/webcore/JSDOMBindingInternalsBuiltins.cpp b/src/bun.js/bindings/webcore/JSDOMBindingInternalsBuiltins.cpp new file mode 100644 index 000000000..2ae04a290 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMBindingInternalsBuiltins.cpp @@ -0,0 +1,79 @@ +// /* +// * Copyright (c) 2016 Apple Inc. All rights reserved. +// * Copyright (c) 2017 Apple Inc. +// * +// * 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. +// * +// */ + +// // DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for +// // builtins by the script: Source/JavaScriptCore/Scripts/generate-js-builtins.py + +// #include "config.h" +// #include "JSDOMBindingInternalsBuiltins.h" + +// #include "WebCoreJSClientData.h" +// #include "JavaScriptCore/HeapInlines.h" +// #include "JavaScriptCore/IdentifierInlines.h" +// #include "JavaScriptCore/Intrinsic.h" +// #include "JavaScriptCore/JSCJSValueInlines.h" +// #include "JavaScriptCore/JSCellInlines.h" +// #include "JavaScriptCore/StructureInlines.h" +// #include "JavaScriptCore/VM.h" + +// namespace WebCore { + +// const JSC::ConstructAbility s_jsDOMBindingInternalsForEachWrapperCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +// const JSC::ConstructorKind s_jsDOMBindingInternalsForEachWrapperCodeConstructorKind = JSC::ConstructorKind::None; +// const int s_jsDOMBindingInternalsForEachWrapperCodeLength = 170; +// static const JSC::Intrinsic s_jsDOMBindingInternalsForEachWrapperCodeIntrinsic = JSC::NoIntrinsic; +// const char* const s_jsDOMBindingInternalsForEachWrapperCode = +// "(function (mapLikeOrSetLike, callback)\n" \ +// "{\n" \ +// " \"use strict\";\n" \ +// " mapLikeOrSetLike.forEach((value, key, backingMapOrSet) => {\n" \ +// " callback(value, key, this);\n" \ +// " });\n" \ +// "})\n" \ +// ; + +// const JSC::ConstructAbility s_jsDOMBindingInternalsGetUserMediaShimCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; +// const JSC::ConstructorKind s_jsDOMBindingInternalsGetUserMediaShimCodeConstructorKind = JSC::ConstructorKind::None; +// const int s_jsDOMBindingInternalsGetUserMediaShimCodeLength = 147; +// static const JSC::Intrinsic s_jsDOMBindingInternalsGetUserMediaShimCodeIntrinsic = JSC::NoIntrinsic; +// const char* const s_jsDOMBindingInternalsGetUserMediaShimCode = +// "(function (constraints, successCallback, errorCallback)\n" \ +// "{\n" \ +// " this.mediaDevices.getUserMedia(constraints).then(successCallback, errorCallback);\n" \ +// "})\n" \ +// ; + +// #define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \ +// JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \ +// {\ +// JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \ +// return clientData->builtinFunctions().jsDOMBindingInternalsBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().jsDOMBindingInternalsBuiltins().codeName##Source(), std::nullopt, s_##codeName##Intrinsic); \ +// } +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR) +// #undef DEFINE_BUILTIN_GENERATOR + +// } // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMBindingInternalsBuiltins.h b/src/bun.js/bindings/webcore/JSDOMBindingInternalsBuiltins.h new file mode 100644 index 000000000..40b698c3a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMBindingInternalsBuiltins.h @@ -0,0 +1,159 @@ +// /* +// * Copyright (c) 2016 Apple Inc. All rights reserved. +// * Copyright (c) 2017 Apple Inc. +// * +// * 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. +// * +// */ + +// // DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for +// // builtins by the script: Source/JavaScriptCore/Scripts/generate-js-builtins.py + +// #pragma once + +// #include "JavaScriptCore/BuiltinUtils.h" +// #include "JavaScriptCore/Identifier.h" +// #include "JavaScriptCore/JSFunction.h" +// #include "JavaScriptCore/UnlinkedFunctionExecutable.h" + +// namespace JSC { +// class FunctionExecutable; +// } + +// namespace WebCore { + +// /* JSDOMBindingInternals */ +// extern const char* const s_jsDOMBindingInternalsForEachWrapperCode; +// extern const int s_jsDOMBindingInternalsForEachWrapperCodeLength; +// extern const JSC::ConstructAbility s_jsDOMBindingInternalsForEachWrapperCodeConstructAbility; +// extern const JSC::ConstructorKind s_jsDOMBindingInternalsForEachWrapperCodeConstructorKind; +// extern const char* const s_jsDOMBindingInternalsGetUserMediaShimCode; +// extern const int s_jsDOMBindingInternalsGetUserMediaShimCodeLength; +// extern const JSC::ConstructAbility s_jsDOMBindingInternalsGetUserMediaShimCodeConstructAbility; +// extern const JSC::ConstructorKind s_jsDOMBindingInternalsGetUserMediaShimCodeConstructorKind; + +// #define WEBCORE_BUILTIN_JSDOMBINDINGINTERNALS_FOREACHWRAPPER 0 +// #define WEBCORE_BUILTIN_JSDOMBINDINGINTERNALS_GETUSERMEDIASHIM 0 + +// #define WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(macro) \ +// macro(jsDOMBindingInternalsForEachWrapperCode, forEachWrapper, static_cast<const char*>(nullptr), s_jsDOMBindingInternalsForEachWrapperCodeLength) \ +// macro(jsDOMBindingInternalsGetUserMediaShimCode, getUserMediaShim, static_cast<const char*>(nullptr), s_jsDOMBindingInternalsGetUserMediaShimCodeLength) + +// #define DECLARE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \ +// JSC::FunctionExecutable* codeName##Generator(JSC::VM&); + +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR) +// #undef DECLARE_BUILTIN_GENERATOR + +// class JSDOMBindingInternalsBuiltinsWrapper : private JSC::WeakHandleOwner { +// public: +// explicit JSDOMBindingInternalsBuiltinsWrapper(JSC::VM& vm) +// : m_vm(vm) +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_FUNCTION_NAME(INITIALIZE_BUILTIN_NAMES) +// #define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, overriddenName, length) , m_##name##Source(JSC::makeSource(StringImpl::createFromLiteral(s_##name, length), {})) +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(INITIALIZE_BUILTIN_SOURCE_MEMBERS) +// #undef INITIALIZE_BUILTIN_SOURCE_MEMBERS +// { +// } + +// #define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, overriddenName, length) \ +// JSC::UnlinkedFunctionExecutable* name##Executable(); \ +// const JSC::SourceCode& name##Source() const { return m_##name##Source; } +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES) +// #undef EXPOSE_BUILTIN_EXECUTABLES + +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR) + +// void exportNames(); + +// private: +// JSC::VM& m_vm; + +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES) + +// #define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, overriddenName, length) \ +// JSC::SourceCode m_##name##Source; \ +// JSC::Weak<JSC::UnlinkedFunctionExecutable> m_##name##Executable; +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS) +// #undef DECLARE_BUILTIN_SOURCE_MEMBERS +// }; + +// #define DEFINE_BUILTIN_EXECUTABLES(name, functionName, overriddenName, length) \ +// inline JSC::UnlinkedFunctionExecutable* JSDOMBindingInternalsBuiltinsWrapper::name##Executable() \ +// { \ +// if (!m_##name##Executable) { \ +// JSC::Identifier executableName = functionName##PublicName(); \ +// if (overriddenName) \ +// executableName = JSC::Identifier::fromString(m_vm, overriddenName); \ +// m_##name##Executable = JSC::Weak<JSC::UnlinkedFunctionExecutable>(JSC::createBuiltinExecutable(m_vm, m_##name##Source, executableName, s_##name##ConstructorKind, s_##name##ConstructAbility), this, &m_##name##Executable); \ +// } \ +// return m_##name##Executable.get(); \ +// } +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(DEFINE_BUILTIN_EXECUTABLES) +// #undef DEFINE_BUILTIN_EXECUTABLES + +// inline void JSDOMBindingInternalsBuiltinsWrapper::exportNames() +// { +// #define EXPORT_FUNCTION_NAME(name) m_vm.propertyNames->appendExternalName(name##PublicName(), name##PrivateName()); +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_FUNCTION_NAME(EXPORT_FUNCTION_NAME) +// #undef EXPORT_FUNCTION_NAME +// } + +// class JSDOMBindingInternalsBuiltinFunctions { +// public: +// explicit JSDOMBindingInternalsBuiltinFunctions(JSC::VM& vm) +// : m_vm(vm) +// { +// } + +// void init(JSC::JSGlobalObject&); +// template<typename Visitor> void visit(Visitor&); + +// public: +// JSC::VM& m_vm; + +// #define DECLARE_BUILTIN_SOURCE_MEMBERS(functionName) \ +// JSC::WriteBarrier<JSC::JSFunction> m_##functionName##Function; +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_SOURCE_MEMBERS) +// #undef DECLARE_BUILTIN_SOURCE_MEMBERS +// }; + +// inline void JSDOMBindingInternalsBuiltinFunctions::init(JSC::JSGlobalObject& globalObject) +// { +// #define EXPORT_FUNCTION(codeName, functionName, overriddenName, length) \ +// m_##functionName##Function.set(m_vm, &globalObject, JSC::JSFunction::create(m_vm, codeName##Generator(m_vm), &globalObject)); +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_CODE(EXPORT_FUNCTION) +// #undef EXPORT_FUNCTION +// } + +// template<typename Visitor> +// inline void JSDOMBindingInternalsBuiltinFunctions::visit(Visitor& visitor) +// { +// #define VISIT_FUNCTION(name) visitor.append(m_##name##Function); +// WEBCORE_FOREACH_JSDOMBINDINGINTERNALS_BUILTIN_FUNCTION_NAME(VISIT_FUNCTION) +// #undef VISIT_FUNCTION +// } + +// template void JSDOMBindingInternalsBuiltinFunctions::visit(JSC::AbstractSlotVisitor&); +// template void JSDOMBindingInternalsBuiltinFunctions::visit(JSC::SlotVisitor&); + +// } // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMBuiltinConstructor.h b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructor.h new file mode 100644 index 000000000..733a880f3 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructor.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015, 2016 Canon Inc. All rights reserved. + * Copyright (C) 2016-2021 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMBuiltinConstructorBase.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMWrapperCache.h" + +namespace WebCore { + +template<typename JSClass> class JSDOMBuiltinConstructor final : public JSDOMBuiltinConstructorBase { +public: + using Base = JSDOMBuiltinConstructorBase; + + static JSDOMBuiltinConstructor* create(JSC::VM&, JSC::Structure*, JSDOMGlobalObject&); + static JSC::Structure* createStructure(JSC::VM&, JSC::JSGlobalObject&, JSC::JSValue prototype); + + DECLARE_INFO; + + // Usually defined for each specialization class. + static JSC::JSValue prototypeForStructure(JSC::VM&, const JSDOMGlobalObject&); + + static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); + +private: + JSDOMBuiltinConstructor(JSC::VM& vm, JSC::Structure* structure) + : Base(vm, structure, construct) + { + } + + void finishCreation(JSC::VM&, JSDOMGlobalObject&); + + JSC::Structure* getDOMStructureForJSObject(JSC::JSGlobalObject*, JSC::JSObject* newTarget); + + // Usually defined for each specialization class. + void initializeProperties(JSC::VM&, JSDOMGlobalObject&) {} + // Must be defined for each specialization class. + JSC::FunctionExecutable* initializeExecutable(JSC::VM&); +}; + +template<typename JSClass> inline JSDOMBuiltinConstructor<JSClass>* JSDOMBuiltinConstructor<JSClass>::create(JSC::VM& vm, JSC::Structure* structure, JSDOMGlobalObject& globalObject) +{ + JSDOMBuiltinConstructor* constructor = new (NotNull, JSC::allocateCell<JSDOMBuiltinConstructor>(vm)) JSDOMBuiltinConstructor(vm, structure); + constructor->finishCreation(vm, globalObject); + return constructor; +} + +template<typename JSClass> inline JSC::Structure* JSDOMBuiltinConstructor<JSClass>::createStructure(JSC::VM& vm, JSC::JSGlobalObject& globalObject, JSC::JSValue prototype) +{ + return JSC::Structure::create(vm, &globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); +} + +template<typename JSClass> inline void JSDOMBuiltinConstructor<JSClass>::finishCreation(JSC::VM& vm, JSDOMGlobalObject& globalObject) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + setInitializeFunction(vm, *JSC::JSFunction::create(vm, initializeExecutable(vm), &globalObject)); + initializeProperties(vm, globalObject); +} + +template<typename JSClass> inline JSC::Structure* JSDOMBuiltinConstructor<JSClass>::getDOMStructureForJSObject(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSObject* newTarget) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + + if (LIKELY(newTarget == this)) + return getDOMStructure<JSClass>(vm, *globalObject()); + + auto scope = DECLARE_THROW_SCOPE(vm); + auto* newTargetGlobalObject = JSC::getFunctionRealm(lexicalGlobalObject, newTarget); + RETURN_IF_EXCEPTION(scope, nullptr); + auto* baseStructure = getDOMStructure<JSClass>(vm, *JSC::jsCast<JSDOMGlobalObject*>(newTargetGlobalObject)); + RELEASE_AND_RETURN(scope, JSC::InternalFunction::createSubclassStructure(lexicalGlobalObject, newTarget, baseStructure)); +} + +template<typename JSClass> inline JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSDOMBuiltinConstructor<JSClass>::construct(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) +{ + ASSERT(callFrame); + auto* castedThis = JSC::jsCast<JSDOMBuiltinConstructor*>(callFrame->jsCallee()); + auto* structure = castedThis->getDOMStructureForJSObject(lexicalGlobalObject, asObject(callFrame->newTarget())); + if (UNLIKELY(!structure)) + return {}; + + auto* jsObject = JSClass::create(structure, castedThis->globalObject()); + JSC::call(lexicalGlobalObject, castedThis->initializeFunction(), jsObject, JSC::ArgList(callFrame), "This error should never occur: initialize function is guaranteed to be callable."_s); + return JSC::JSValue::encode(jsObject); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.cpp b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.cpp new file mode 100644 index 000000000..98058f5f4 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004-2022 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSDOMBuiltinConstructorBase.h" + +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/JSCInlines.h> + +namespace WebCore { +using namespace JSC; + +template<typename Visitor> +void JSDOMBuiltinConstructorBase::visitChildrenImpl(JSC::JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSDOMBuiltinConstructorBase*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + visitor.append(thisObject->m_initializeFunction); +} + +DEFINE_VISIT_CHILDREN(JSDOMBuiltinConstructorBase); + +JSC::GCClient::IsoSubspace* JSDOMBuiltinConstructorBase::subspaceForImpl(JSC::VM& vm) +{ + return &static_cast<JSVMClientData*>(vm.clientData)->domBuiltinConstructorSpace(); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.h b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.h new file mode 100644 index 000000000..9593d99c1 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015, 2016 Canon Inc. All rights reserved. + * Copyright (C) 2016-2022 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMConstructorBase.h" + +namespace WebCore { + +class JSDOMBuiltinConstructorBase : public JSDOMConstructorBase { +public: + using Base = JSDOMConstructorBase; + + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + static_assert(sizeof(CellType) == sizeof(JSDOMBuiltinConstructorBase)); + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(CellType, JSDOMBuiltinConstructorBase); + static_assert(CellType::destroy == JSC::JSCell::destroy, "JSDOMBuiltinConstructor<JSClass> is not destructible actually"); + return subspaceForImpl(vm); + } + +protected: + JSDOMBuiltinConstructorBase(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction functionForConstruct) + : Base(vm, structure, functionForConstruct) + { + } + + DECLARE_VISIT_CHILDREN; + + JSC::JSFunction* initializeFunction(); + void setInitializeFunction(JSC::VM&, JSC::JSFunction&); + +private: + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM&); + + JSC::WriteBarrier<JSC::JSFunction> m_initializeFunction; +}; + +inline JSC::JSFunction* JSDOMBuiltinConstructorBase::initializeFunction() +{ + return m_initializeFunction.get(); +} + +inline void JSDOMBuiltinConstructorBase::setInitializeFunction(JSC::VM& vm, JSC::JSFunction& function) +{ + m_initializeFunction.set(vm, this, &function); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMCastThisValue.h b/src/bun.js/bindings/webcore/JSDOMCastThisValue.h new file mode 100644 index 000000000..d7028c4b5 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMCastThisValue.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003-2006, 2008-2009, 2013, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * Copyright (C) 2012 Ericsson AB. All rights reserved. + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * 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 "JSDOMGlobalObject.h" + +namespace WebCore { + +enum class CastedThisErrorBehavior : uint8_t { + Throw, + ReturnEarly, + RejectPromise, + Assert, +}; + +template<class JSClass> +JSClass* castThisValue(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue thisValue) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + if constexpr (std::is_base_of_v<JSDOMGlobalObject, JSClass>) + return toJSDOMGlobalObject<JSClass>(vm, thisValue.isUndefinedOrNull() ? JSC::JSValue(&lexicalGlobalObject) : thisValue); + else + return JSC::jsDynamicCast<JSClass*>(thisValue); +} + +} diff --git a/src/bun.js/bindings/webcore/JSDOMConstructor.h b/src/bun.js/bindings/webcore/JSDOMConstructor.h new file mode 100644 index 000000000..680d71a4e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConstructor.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015, 2016 Canon Inc. All rights reserved. + * Copyright (C) 2016-2021 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMConstructorBase.h" + +namespace WebCore { + +template<typename JSClass> class JSDOMConstructor final : public JSDOMConstructorBase { +public: + using Base = JSDOMConstructorBase; + + static JSDOMConstructor* create(JSC::VM&, JSC::Structure*, JSDOMGlobalObject&); + static JSC::Structure* createStructure(JSC::VM&, JSC::JSGlobalObject&, JSC::JSValue prototype); + + DECLARE_INFO; + + // Must be defined for each specialization class. + static JSC::JSValue prototypeForStructure(JSC::VM&, const JSDOMGlobalObject&); + + // Must be defined for each specialization class. + static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); + +private: + JSDOMConstructor(JSC::VM& vm, JSC::Structure* structure) + : Base(vm, structure, construct) + { + } + + void finishCreation(JSC::VM&, JSDOMGlobalObject&); + + // Usually defined for each specialization class. + void initializeProperties(JSC::VM&, JSDOMGlobalObject&) {} +}; + +template<typename JSClass> inline JSDOMConstructor<JSClass>* JSDOMConstructor<JSClass>::create(JSC::VM& vm, JSC::Structure* structure, JSDOMGlobalObject& globalObject) +{ + JSDOMConstructor* constructor = new (NotNull, JSC::allocateCell<JSDOMConstructor>(vm)) JSDOMConstructor(vm, structure); + constructor->finishCreation(vm, globalObject); + return constructor; +} + +template<typename JSClass> inline JSC::Structure* JSDOMConstructor<JSClass>::createStructure(JSC::VM& vm, JSC::JSGlobalObject& globalObject, JSC::JSValue prototype) +{ + return JSC::Structure::create(vm, &globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); +} + +template<typename JSClass> inline void JSDOMConstructor<JSClass>::finishCreation(JSC::VM& vm, JSDOMGlobalObject& globalObject) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + initializeProperties(vm, globalObject); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConstructorBase.cpp b/src/bun.js/bindings/webcore/JSDOMConstructorBase.cpp new file mode 100644 index 000000000..76e5bed57 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConstructorBase.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004-2022 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSDOMConstructor.h" + +#include "WebCoreJSClientData.h" + +namespace WebCore { +using namespace JSC; + +STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSDOMConstructorBase); + +JSC_DEFINE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructor, (JSGlobalObject * globalObject, CallFrame*)) +{ + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + throwTypeError(globalObject, scope, "Constructor requires 'new' operator"_s); + return JSValue::encode(jsNull()); +} + +JSC_DEFINE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructorNotConstructable, (JSC::JSGlobalObject * globalObject, JSC::CallFrame*)) +{ + JSC::VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSC::throwTypeError(globalObject, scope, "Illegal constructor"_s); + return JSC::JSValue::encode(JSC::jsNull()); +} + +JSC::GCClient::IsoSubspace* JSDOMConstructorBase::subspaceForImpl(JSC::VM& vm) +{ + return &static_cast<JSVMClientData*>(vm.clientData)->domConstructorSpace(); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConstructorBase.h b/src/bun.js/bindings/webcore/JSDOMConstructorBase.h new file mode 100644 index 000000000..335c112d3 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConstructorBase.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015, 2016 Canon Inc. All rights reserved. + * Copyright (C) 2016-2022 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMGlobalObject.h" +#include "JavaScriptCore/InternalFunction.h" + +#include "ZigGlobalObject.h" + +namespace WebCore { + +JSC_DECLARE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructor); +JSC_DECLARE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructorNotConstructable); + +// Base class for all callable constructor objects in the JSC bindings. +class JSDOMConstructorBase : public JSC::InternalFunction { +public: + using Base = InternalFunction; + + static constexpr unsigned StructureFlags = Base::StructureFlags; + static constexpr bool needsDestruction = false; + + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + static_assert(sizeof(CellType) == sizeof(JSDOMConstructorBase)); + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(CellType, JSDOMConstructorBase); + static_assert(CellType::destroy == JSC::JSCell::destroy, "JSDOMConstructor<JSClass> is not destructible actually"); + return subspaceForImpl(vm); + } + + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM&); + + JSDOMGlobalObject* globalObject() const { return JSC::jsCast<JSDOMGlobalObject*>(Base::globalObject()); } + ScriptExecutionContext* scriptExecutionContext() const { return globalObject()->scriptExecutionContext(); } + +protected: + JSDOMConstructorBase(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction functionForConstruct) + : Base(vm, structure, + functionForConstruct ? callThrowTypeErrorForJSDOMConstructor : callThrowTypeErrorForJSDOMConstructorNotConstructable, + functionForConstruct ? functionForConstruct : callThrowTypeErrorForJSDOMConstructorNotConstructable) + { + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConstructorNotCallable.h b/src/bun.js/bindings/webcore/JSDOMConstructorNotCallable.h new file mode 100644 index 000000000..779bf8876 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConstructorNotCallable.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2021 Alexey Shvayka <shvaikalesh@gmail.com> + * Copyright (C) 2021-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 + * 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 "JSDOMWrapper.h" +#include "WebCoreJSClientData.h" + +namespace WebCore { + +template<typename JSClass> class JSDOMConstructorNotCallable : public JSDOMObject { +public: + using Base = JSDOMObject; + + static constexpr unsigned StructureFlags = Base::StructureFlags; + static constexpr bool needsDestruction = false; + static JSDOMConstructorNotCallable* create(JSC::VM&, JSC::Structure*, JSDOMGlobalObject&); + static JSC::Structure* createStructure(JSC::VM&, JSC::JSGlobalObject&, JSC::JSValue prototype); + + DECLARE_INFO; + + static JSC::JSValue prototypeForStructure(JSC::VM&, const JSDOMGlobalObject&); + + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + static_assert(sizeof(CellType) == sizeof(JSDOMConstructorNotCallable)); + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(CellType, JSDOMConstructorNotCallable); + static_assert(CellType::destroy == JSC::JSCell::destroy, "JSDOMConstructorNotCallable<JSClass> is not destructible actually"); + return &static_cast<JSVMClientData*>(vm.clientData)->domNamespaceObjectSpace(); + } + +private: + JSDOMConstructorNotCallable(JSC::Structure* structure, JSDOMGlobalObject& globalObject) + : Base(structure, globalObject) + { + } + + void finishCreation(JSC::VM&, JSDOMGlobalObject&); + void initializeProperties(JSC::VM&, JSDOMGlobalObject&) {} +}; + +template<typename JSClass> inline JSDOMConstructorNotCallable<JSClass>* JSDOMConstructorNotCallable<JSClass>::create(JSC::VM& vm, JSC::Structure* structure, JSDOMGlobalObject& globalObject) +{ + JSDOMConstructorNotCallable* constructor = new (NotNull, JSC::allocateCell<JSDOMConstructorNotCallable>(vm)) JSDOMConstructorNotCallable(structure, globalObject); + constructor->finishCreation(vm, globalObject); + return constructor; +} + +template<typename JSClass> inline JSC::Structure* JSDOMConstructorNotCallable<JSClass>::createStructure(JSC::VM& vm, JSC::JSGlobalObject& globalObject, JSC::JSValue prototype) +{ + return JSC::Structure::create(vm, &globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); +} + +template<typename JSClass> inline void JSDOMConstructorNotCallable<JSClass>::finishCreation(JSC::VM& vm, JSDOMGlobalObject& globalObject) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + initializeProperties(vm, globalObject); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConstructorNotConstructable.h b/src/bun.js/bindings/webcore/JSDOMConstructorNotConstructable.h new file mode 100644 index 000000000..ac173d0fe --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConstructorNotConstructable.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015, 2016 Canon Inc. All rights reserved. + * Copyright (C) 2016-2021 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMConstructorBase.h" + +namespace WebCore { + +template<typename JSClass> class JSDOMConstructorNotConstructable final : public JSDOMConstructorBase { +public: + using Base = JSDOMConstructorBase; + + static JSDOMConstructorNotConstructable* create(JSC::VM&, JSC::Structure*, JSDOMGlobalObject&); + static JSC::Structure* createStructure(JSC::VM&, JSC::JSGlobalObject&, JSC::JSValue prototype); + + DECLARE_INFO; + + // Must be defined for each specialization class. + static JSC::JSValue prototypeForStructure(JSC::VM&, const JSDOMGlobalObject&); + +private: + JSDOMConstructorNotConstructable(JSC::VM& vm, JSC::Structure* structure) + : Base(vm, structure, nullptr) + { + } + + void finishCreation(JSC::VM&, JSDOMGlobalObject&); + + // Usually defined for each specialization class. + void initializeProperties(JSC::VM&, JSDOMGlobalObject&) {} +}; + +template<typename JSClass> inline JSDOMConstructorNotConstructable<JSClass>* JSDOMConstructorNotConstructable<JSClass>::create(JSC::VM& vm, JSC::Structure* structure, JSDOMGlobalObject& globalObject) +{ + JSDOMConstructorNotConstructable* constructor = new (NotNull, JSC::allocateCell<JSDOMConstructorNotConstructable>(vm)) JSDOMConstructorNotConstructable(vm, structure); + constructor->finishCreation(vm, globalObject); + return constructor; +} + +template<typename JSClass> inline JSC::Structure* JSDOMConstructorNotConstructable<JSClass>::createStructure(JSC::VM& vm, JSC::JSGlobalObject& globalObject, JSC::JSValue prototype) +{ + return JSC::Structure::create(vm, &globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); +} + +template<typename JSClass> inline void JSDOMConstructorNotConstructable<JSClass>::finishCreation(JSC::VM& vm, JSDOMGlobalObject& globalObject) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + initializeProperties(vm, globalObject); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvert.h b/src/bun.js/bindings/webcore/JSDOMConvert.h new file mode 100644 index 000000000..f5c32823d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvert.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 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 "JSDOMConvertAny.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertBufferSource.h" +#include "JSDOMConvertCallbacks.h" +#include "JSDOMConvertDate.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMConvertEnumeration.h" +#include "JSDOMConvertEventListener.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertJSON.h" +#include "JSDOMConvertNull.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertObject.h" +#include "JSDOMConvertRecord.h" +#include "JSDOMConvertSequences.h" +#include "JSDOMConvertSerializedScriptValue.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMConvertUnion.h" +#include "JSDOMConvertWebGL.h" + +#include "JSDOMConvertBufferSource+JSBuffer.h"
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSDOMConvertAny.h b/src/bun.js/bindings/webcore/JSDOMConvertAny.h new file mode 100644 index 000000000..b744bbb89 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertAny.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSValueInWrappedObject.h" + +namespace WebCore { + +template<> struct Converter<IDLAny> : DefaultConverter<IDLAny> { + using ReturnType = JSC::JSValue; + + static constexpr bool conversionHasSideEffects = false; + + static JSC::JSValue convert(JSC::JSGlobalObject&, JSC::JSValue value) + { + return value; + } + + static JSC::JSValue convert(const JSC::Strong<JSC::Unknown>& value) + { + return value.get(); + } +}; + +template<> struct JSConverter<IDLAny> { + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(const JSC::JSValue& value) + { + return value; + } + + static JSC::JSValue convert(const JSC::Strong<JSC::Unknown>& value) + { + return value.get(); + } + + static JSC::JSValue convert(const JSValueInWrappedObject& value) + { + return value.getValue(); + } +}; + +template<> struct VariadicConverter<IDLAny> { + using Item = typename IDLAny::ImplementationType; + + static std::optional<Item> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto result = Converter<IDLAny>::convert(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(scope, std::nullopt); + + return Item { vm, result }; + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertBase.h b/src/bun.js/bindings/webcore/JSDOMConvertBase.h new file mode 100644 index 000000000..8cab2e7d8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertBase.h @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2016 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 "root.h" +#include "ZigGlobalObject.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMExceptionHandling.h" +#include <JavaScriptCore/Error.h> + +namespace WebCore { + +// Conversion from JSValue -> Implementation +template<typename T> struct Converter; + +namespace Detail { + +template<typename T> inline T* getPtrOrRef(const T* p) { return const_cast<T*>(p); } +template<typename T> inline T& getPtrOrRef(const T& p) { return const_cast<T&>(p); } +template<typename T> inline T* getPtrOrRef(const RefPtr<T>& p) { return p.get(); } +template<typename T> inline T& getPtrOrRef(const Ref<T>& p) { return p.get(); } + +} + +struct DefaultExceptionThrower { + void operator()(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) + { + throwTypeError(&lexicalGlobalObject, scope); + } +}; + +template<typename T> typename Converter<T>::ReturnType convert(JSC::JSGlobalObject&, JSC::JSValue); +template<typename T> typename Converter<T>::ReturnType convert(JSC::JSGlobalObject&, JSC::JSValue, JSC::JSObject&); +template<typename T> typename Converter<T>::ReturnType convert(JSC::JSGlobalObject&, JSC::JSValue, JSDOMGlobalObject&); +template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::JSGlobalObject&, JSC::JSValue, ExceptionThrower&&); +template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::JSGlobalObject&, JSC::JSValue, JSC::JSObject&, ExceptionThrower&&); +template<typename T, typename ExceptionThrower> typename Converter<T>::ReturnType convert(JSC::JSGlobalObject&, JSC::JSValue, JSDOMGlobalObject&, ExceptionThrower&&); + +template<typename T> inline typename Converter<T>::ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return Converter<T>::convert(lexicalGlobalObject, value); +} + +template<typename T> inline typename Converter<T>::ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSC::JSObject& thisObject) +{ + return Converter<T>::convert(lexicalGlobalObject, value, thisObject); +} + +template<typename T> inline typename Converter<T>::ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSDOMGlobalObject& globalObject) +{ + return Converter<T>::convert(lexicalGlobalObject, value, globalObject); +} + +template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower) +{ + return Converter<T>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); +} + +template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower) +{ + return Converter<T>::convert(lexicalGlobalObject, value, thisObject, std::forward<ExceptionThrower>(exceptionThrower)); +} + +template<typename T, typename ExceptionThrower> inline typename Converter<T>::ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower) +{ + return Converter<T>::convert(lexicalGlobalObject, value, globalObject, std::forward<ExceptionThrower>(exceptionThrower)); +} + +// Conversion from Implementation -> JSValue +template<typename T> struct JSConverter; + +template<typename T, typename U> inline JSC::JSValue toJS(U&&); +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject&, U&&); +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, U&&); +template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject&, JSDOMGlobalObject&, U&&); + +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject&, JSC::ThrowScope&, U&& valueOrFunctor); +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, JSC::ThrowScope&, U&& valueOrFunctor); +template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject&, JSDOMGlobalObject&, JSC::ThrowScope&, U&& valueOrFunctor); + +template<typename T, bool needsState = JSConverter<T>::needsState, bool needsGlobalObject = JSConverter<T>::needsGlobalObject> +struct JSConverterOverloader; + +template<typename T> +struct JSConverterOverloader<T, true, true> { + template<typename U> static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, globalObject, std::forward<U>(value)); + } +}; + +template<typename T> +struct JSConverterOverloader<T, true, false> { + template<typename U> static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, U&& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, std::forward<U>(value)); + } + + template<typename U> static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject&, U&& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, std::forward<U>(value)); + } +}; + +template<typename T> +struct JSConverterOverloader<T, false, false> { + template<typename U> static JSC::JSValue convert(JSC::JSGlobalObject&, U&& value) + { + return JSConverter<T>::convert(std::forward<U>(value)); + } + + template<typename U> static JSC::JSValue convert(JSC::JSGlobalObject&, JSDOMGlobalObject&, U&& value) + { + return JSConverter<T>::convert(std::forward<U>(value)); + } +}; + +template<typename T, typename U> inline JSC::JSValue toJS(U&& value) +{ + return JSConverter<T>::convert(std::forward<U>(value)); +} + +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject& lexicalGlobalObject, U&& value) +{ + return JSConverterOverloader<T>::convert(lexicalGlobalObject, std::forward<U>(value)); +} + +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) +{ + return JSConverterOverloader<T>::convert(lexicalGlobalObject, globalObject, std::forward<U>(value)); +} + +template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) +{ + return JSConverter<T>::convertNewlyCreated(lexicalGlobalObject, globalObject, std::forward<U>(value)); +} + +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& throwScope, U&& valueOrFunctor) +{ + if constexpr (std::is_invocable_v<U>) { + using FunctorReturnType = std::invoke_result_t<U>; + + if constexpr (std::is_same_v<void, FunctorReturnType>) { + valueOrFunctor(); + return JSC::jsUndefined(); + } else if constexpr (std::is_same_v<ExceptionOr<void>, FunctorReturnType>) { + auto result = valueOrFunctor(); + if (UNLIKELY(result.hasException())) { + propagateException(lexicalGlobalObject, throwScope, result.releaseException()); + return {}; + } + return JSC::jsUndefined(); + } else + return toJS<T>(lexicalGlobalObject, throwScope, valueOrFunctor()); + } else { + if constexpr (IsExceptionOr<U>) { + if (UNLIKELY(valueOrFunctor.hasException())) { + propagateException(lexicalGlobalObject, throwScope, valueOrFunctor.releaseException()); + return {}; + } + + return toJS<T>(lexicalGlobalObject, valueOrFunctor.releaseReturnValue()); + } else + return toJS<T>(lexicalGlobalObject, std::forward<U>(valueOrFunctor)); + } +} + +template<typename T, typename U> inline JSC::JSValue toJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, JSC::ThrowScope& throwScope, U&& valueOrFunctor) +{ + if constexpr (std::is_invocable_v<U>) { + using FunctorReturnType = std::invoke_result_t<U>; + + if constexpr (std::is_same_v<void, FunctorReturnType>) { + valueOrFunctor(); + return JSC::jsUndefined(); + } else if constexpr (std::is_same_v<ExceptionOr<void>, FunctorReturnType>) { + auto result = valueOrFunctor(); + if (UNLIKELY(result.hasException())) { + propagateException(lexicalGlobalObject, throwScope, result.releaseException()); + return {}; + } + return JSC::jsUndefined(); + } else + return toJS<T>(lexicalGlobalObject, globalObject, throwScope, valueOrFunctor()); + } else { + if constexpr (IsExceptionOr<U>) { + if (UNLIKELY(valueOrFunctor.hasException())) { + propagateException(lexicalGlobalObject, throwScope, valueOrFunctor.releaseException()); + return {}; + } + + return toJS<T>(lexicalGlobalObject, globalObject, valueOrFunctor.releaseReturnValue()); + } else + return toJS<T>(lexicalGlobalObject, globalObject, std::forward<U>(valueOrFunctor)); + } +} + +template<typename T, typename U> inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, JSC::ThrowScope& throwScope, U&& valueOrFunctor) +{ + if constexpr (std::is_invocable_v<U>) { + using FunctorReturnType = std::invoke_result_t<U>; + + if constexpr (std::is_same_v<void, FunctorReturnType>) { + valueOrFunctor(); + return JSC::jsUndefined(); + } else if constexpr (std::is_same_v<ExceptionOr<void>, FunctorReturnType>) { + auto result = valueOrFunctor(); + if (UNLIKELY(result.hasException())) { + propagateException(lexicalGlobalObject, throwScope, result.releaseException()); + return {}; + } + return JSC::jsUndefined(); + } else + return toJSNewlyCreated<T>(lexicalGlobalObject, globalObject, throwScope, valueOrFunctor()); + + } else { + if constexpr (IsExceptionOr<U>) { + if (UNLIKELY(valueOrFunctor.hasException())) { + propagateException(lexicalGlobalObject, throwScope, valueOrFunctor.releaseException()); + return {}; + } + + return toJSNewlyCreated<T>(lexicalGlobalObject, globalObject, valueOrFunctor.releaseReturnValue()); + } else + return toJSNewlyCreated<T>(lexicalGlobalObject, globalObject, std::forward<U>(valueOrFunctor)); + } +} + +template<typename T> struct DefaultConverter { + using ReturnType = typename T::ImplementationType; + + // We assume the worst, subtypes can override to be less pessimistic. + // An example of something that can have side effects + // is having a converter that does JSC::JSValue::toNumber. + // toNumber() in JavaScript can call arbitrary JS functions. + // + // An example of something that does not have side effects + // is something having a converter that does JSC::JSValue::toBoolean. + // toBoolean() in JS can't call arbitrary functions. + static constexpr bool conversionHasSideEffects = true; +}; + +// Conversion from JSValue -> Implementation for variadic arguments +template<typename IDLType> struct VariadicConverter; + +} // namespace WebCore
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSDOMConvertBoolean.h b/src/bun.js/bindings/webcore/JSDOMConvertBoolean.h new file mode 100644 index 000000000..ed8ea5211 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertBoolean.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" + +namespace WebCore { + +template<> struct Converter<IDLBoolean> : DefaultConverter<IDLBoolean> { + + static constexpr bool conversionHasSideEffects = false; + + static bool convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return value.toBoolean(&lexicalGlobalObject); + } +}; + +template<> struct JSConverter<IDLBoolean> { + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(bool value) + { + return JSC::jsBoolean(value); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertBufferSource.h b/src/bun.js/bindings/webcore/JSDOMConvertBufferSource.h new file mode 100644 index 000000000..bab958a4f --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertBufferSource.h @@ -0,0 +1,481 @@ +/* + * Copyright (C) 2016 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 "BufferSource.h" +#include "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSDOMWrapperCache.h" +#include "JavaScriptCore/JSTypedArrays.h" + +namespace WebCore { + +struct IDLInt8Array : IDLTypedArray<JSC::Int8Array> { +}; +struct IDLInt16Array : IDLTypedArray<JSC::Int16Array> { +}; +struct IDLInt32Array : IDLTypedArray<JSC::Int32Array> { +}; +struct IDLUint8Array : IDLTypedArray<JSC::Uint8Array> { +}; +struct IDLUint16Array : IDLTypedArray<JSC::Uint16Array> { +}; +struct IDLUint32Array : IDLTypedArray<JSC::Uint32Array> { +}; +struct IDLUint8ClampedArray : IDLTypedArray<JSC::Uint8ClampedArray> { +}; +struct IDLFloat32Array : IDLTypedArray<JSC::Float32Array> { +}; +struct IDLFloat64Array : IDLTypedArray<JSC::Float64Array> { +}; +struct IDLBigInt64Array : IDLTypedArray<JSC::BigInt64Array> { +}; +struct IDLBigUint64Array : IDLTypedArray<JSC::BigUint64Array> { +}; + +inline RefPtr<JSC::Int8Array> toPossiblySharedInt8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int8Adaptor>(vm, value); } +inline RefPtr<JSC::Int16Array> toPossiblySharedInt16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int16Adaptor>(vm, value); } +inline RefPtr<JSC::Int32Array> toPossiblySharedInt32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Int32Adaptor>(vm, value); } +inline RefPtr<JSC::Uint8Array> toPossiblySharedUint8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint8Adaptor>(vm, value); } +inline RefPtr<JSC::Uint8ClampedArray> toPossiblySharedUint8ClampedArray(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint8ClampedAdaptor>(vm, value); } +inline RefPtr<JSC::Uint16Array> toPossiblySharedUint16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint16Adaptor>(vm, value); } +inline RefPtr<JSC::Uint32Array> toPossiblySharedUint32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Uint32Adaptor>(vm, value); } +inline RefPtr<JSC::Float32Array> toPossiblySharedFloat32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Float32Adaptor>(vm, value); } +inline RefPtr<JSC::Float64Array> toPossiblySharedFloat64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::Float64Adaptor>(vm, value); } +inline RefPtr<JSC::BigInt64Array> toPossiblySharedBigInt64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::BigInt64Adaptor>(vm, value); } +inline RefPtr<JSC::BigUint64Array> toPossiblySharedBigUint64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toPossiblySharedNativeTypedView<JSC::BigUint64Adaptor>(vm, value); } + +inline RefPtr<JSC::Int8Array> toUnsharedInt8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int8Adaptor>(vm, value); } +inline RefPtr<JSC::Int16Array> toUnsharedInt16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int16Adaptor>(vm, value); } +inline RefPtr<JSC::Int32Array> toUnsharedInt32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Int32Adaptor>(vm, value); } +inline RefPtr<JSC::Uint8Array> toUnsharedUint8Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint8Adaptor>(vm, value); } +inline RefPtr<JSC::Uint8ClampedArray> toUnsharedUint8ClampedArray(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint8ClampedAdaptor>(vm, value); } +inline RefPtr<JSC::Uint16Array> toUnsharedUint16Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint16Adaptor>(vm, value); } +inline RefPtr<JSC::Uint32Array> toUnsharedUint32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Uint32Adaptor>(vm, value); } +inline RefPtr<JSC::Float32Array> toUnsharedFloat32Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Float32Adaptor>(vm, value); } +inline RefPtr<JSC::Float64Array> toUnsharedFloat64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::Float64Adaptor>(vm, value); } +inline RefPtr<JSC::BigInt64Array> toUnsharedBigInt64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::BigInt64Adaptor>(vm, value); } +inline RefPtr<JSC::BigUint64Array> toUnsharedBigUint64Array(JSC::VM& vm, JSC::JSValue value) { return JSC::toUnsharedNativeTypedView<JSC::BigUint64Adaptor>(vm, value); } + +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, JSC::ArrayBuffer& buffer) +{ + if (auto result = getCachedWrapper(globalObject->world(), buffer)) + return result; + + // The JSArrayBuffer::create function will register the wrapper in finishCreation. + return JSC::JSArrayBuffer::create(JSC::getVM(lexicalGlobalObject), globalObject->arrayBufferStructure(buffer.sharingMode()), &buffer); +} + +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSGlobalObject* globalObject, JSC::ArrayBufferView& view) +{ + return view.wrap(lexicalGlobalObject, globalObject); +} + +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, JSC::ArrayBuffer* buffer) +{ + if (!buffer) + return JSC::jsNull(); + return toJS(lexicalGlobalObject, globalObject, *buffer); +} + +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSGlobalObject* globalObject, JSC::ArrayBufferView* view) +{ + if (!view) + return JSC::jsNull(); + return toJS(lexicalGlobalObject, globalObject, *view); +} + +inline RefPtr<JSC::ArrayBufferView> toPossiblySharedArrayBufferView(JSC::VM& vm, JSC::JSValue value) +{ + auto* wrapper = JSC::jsDynamicCast<JSC::JSArrayBufferView*>(value); + if (!wrapper) + return nullptr; + return wrapper->possiblySharedImpl(); +} + +inline RefPtr<JSC::ArrayBufferView> toUnsharedArrayBufferView(JSC::VM& vm, JSC::JSValue value) +{ + auto result = toPossiblySharedArrayBufferView(vm, value); + if (!result || result->isShared()) + return nullptr; + return result; +} + +namespace Detail { + +enum class BufferSourceConverterAllowSharedMode { Allow, + Disallow }; +template<typename BufferSourceType, BufferSourceConverterAllowSharedMode mode> +struct BufferSourceConverter { + using WrapperType = typename Converter<BufferSourceType>::WrapperType; + using ReturnType = typename Converter<BufferSourceType>::ReturnType; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + ReturnType object {}; + if constexpr (mode == BufferSourceConverterAllowSharedMode::Allow) + object = WrapperType::toWrappedAllowShared(vm, value); + else + object = WrapperType::toWrapped(vm, value); + if (UNLIKELY(!object)) + exceptionThrower(lexicalGlobalObject, scope); + return object; + } +}; + +} + +template<> struct Converter<IDLArrayBuffer> : DefaultConverter<IDLArrayBuffer> { + using WrapperType = JSC::JSArrayBuffer; + using ReturnType = JSC::ArrayBuffer*; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLArrayBuffer, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLArrayBuffer> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLDataView> : DefaultConverter<IDLDataView> { + using WrapperType = JSC::JSDataView; + using ReturnType = RefPtr<JSC::DataView>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLDataView, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLDataView> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLInt8Array> : DefaultConverter<IDLInt8Array> { + using WrapperType = JSC::JSInt8Array; + using ReturnType = RefPtr<JSC::Int8Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLInt8Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLInt8Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLInt16Array> : DefaultConverter<IDLInt16Array> { + using WrapperType = JSC::JSInt16Array; + using ReturnType = RefPtr<JSC::Int16Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLInt16Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLInt16Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLInt32Array> : DefaultConverter<IDLInt32Array> { + using WrapperType = JSC::JSInt32Array; + using ReturnType = RefPtr<JSC::Int32Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLInt32Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLInt32Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLUint8Array> : DefaultConverter<IDLUint8Array> { + using WrapperType = JSC::JSUint8Array; + using ReturnType = RefPtr<JSC::Uint8Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLUint8Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLUint8Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } + + template<typename U> + static JSC::JSValue convertNewlyCreated(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) + { + return convert(lexicalGlobalObject, globalObject, std::forward<U>(value)); + } +}; + +template<> struct Converter<IDLUint16Array> : DefaultConverter<IDLUint16Array> { + using WrapperType = JSC::JSUint16Array; + using ReturnType = RefPtr<JSC::Uint16Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLUint16Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLUint16Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLUint32Array> : DefaultConverter<IDLUint32Array> { + using WrapperType = JSC::JSUint32Array; + using ReturnType = RefPtr<JSC::Uint32Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLUint32Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLUint32Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLUint8ClampedArray> : DefaultConverter<IDLUint8ClampedArray> { + using WrapperType = JSC::JSUint8ClampedArray; + using ReturnType = RefPtr<JSC::Uint8ClampedArray>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLUint8ClampedArray, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLUint8ClampedArray> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLFloat32Array> : DefaultConverter<IDLFloat32Array> { + using WrapperType = JSC::JSFloat32Array; + using ReturnType = RefPtr<JSC::Float32Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLFloat32Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLFloat32Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLFloat64Array> : DefaultConverter<IDLFloat64Array> { + using WrapperType = JSC::JSFloat64Array; + using ReturnType = RefPtr<JSC::Float64Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLFloat64Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLFloat64Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLBigInt64Array> : DefaultConverter<IDLBigInt64Array> { + using WrapperType = JSC::JSBigInt64Array; + using ReturnType = RefPtr<JSC::BigInt64Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLBigInt64Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLBigInt64Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLBigUint64Array> : DefaultConverter<IDLBigUint64Array> { + using WrapperType = JSC::JSBigUint64Array; + using ReturnType = RefPtr<JSC::BigUint64Array>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLBigUint64Array, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLBigUint64Array> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<> struct Converter<IDLArrayBufferView> : DefaultConverter<IDLArrayBufferView> { + using WrapperType = JSC::JSArrayBufferView; + using ReturnType = RefPtr<JSC::ArrayBufferView>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<IDLArrayBufferView, Detail::BufferSourceConverterAllowSharedMode::Disallow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<> struct JSConverter<IDLArrayBufferView> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } +}; + +template<typename T> +struct Converter<IDLAllowSharedAdaptor<T>> : DefaultConverter<T> { + using ConverterType = Converter<T>; + using WrapperType = typename ConverterType::WrapperType; + using ReturnType = typename ConverterType::ReturnType; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + return Detail::BufferSourceConverter<T, Detail::BufferSourceConverterAllowSharedMode::Allow>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertCallbacks.h b/src/bun.js/bindings/webcore/JSDOMConvertCallbacks.h new file mode 100644 index 000000000..c98ad316b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertCallbacks.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSDOMGlobalObject.h" + +namespace WebCore { + +template<typename T> struct Converter<IDLCallbackFunction<T>> : DefaultConverter<IDLCallbackFunction<T>> { + + static constexpr bool conversionHasSideEffects = false; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static RefPtr<T> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (!value.isCallable()) { + exceptionThrower(lexicalGlobalObject, scope); + return nullptr; + } + + return T::create(vm, JSC::asObject(value)); + } +}; + +template<typename T> struct JSConverter<IDLCallbackFunction<T>> { + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + template<typename U> + static JSC::JSValue convert(const U& value) + { + return toJS(Detail::getPtrOrRef(value)); + } + + template<typename U> + static JSC::JSValue convertNewlyCreated(U&& value) + { + return toJSNewlyCreated(std::forward<U>(value)); + } +}; + +template<typename T> struct Converter<IDLCallbackInterface<T>> : DefaultConverter<IDLCallbackInterface<T>> { + template<typename ExceptionThrower = DefaultExceptionThrower> + static RefPtr<T> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (!value.isObject()) { + exceptionThrower(lexicalGlobalObject, scope); + return nullptr; + } + + return T::create(vm, JSC::asObject(value)); + } +}; + +template<typename T> struct JSConverter<IDLCallbackInterface<T>> { + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + template<typename U> + static JSC::JSValue convert(const U& value) + { + return toJS(Detail::getPtrOrRef(value)); + } + + template<typename U> + static JSC::JSValue convertNewlyCreated(U&& value) + { + return toJSNewlyCreated(std::forward<U>(value)); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertDate.cpp b/src/bun.js/bindings/webcore/JSDOMConvertDate.cpp new file mode 100644 index 000000000..c624bd25b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertDate.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004-2011, 2013, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSDOMConvertDate.h" + +#include "JavaScriptCore/DateInstance.h" +#include "JavaScriptCore/HeapInlines.h" +#include "JavaScriptCore/JSCJSValueInlines.h" +#include "JavaScriptCore/JSGlobalObject.h" + +namespace WebCore { +using namespace JSC; + +JSValue jsDate(JSGlobalObject& lexicalGlobalObject, WallTime value) +{ + return DateInstance::create(lexicalGlobalObject.vm(), lexicalGlobalObject.dateStructure(), value.secondsSinceEpoch().milliseconds()); +} + +WallTime valueToDate(JSC::JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + double milliseconds = std::numeric_limits<double>::quiet_NaN(); + + auto& vm = lexicalGlobalObject.vm(); + if (value.inherits<DateInstance>()) + milliseconds = jsCast<DateInstance*>(value)->internalNumber(); + else if (value.isNumber()) + milliseconds = value.asNumber(); + else if (value.isString()) + milliseconds = vm.dateCache.parseDate(&lexicalGlobalObject, vm, value.getString(&lexicalGlobalObject)); + + return WallTime::fromRawSeconds(Seconds::fromMilliseconds(milliseconds).value()); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertDate.h b/src/bun.js/bindings/webcore/JSDOMConvertDate.h new file mode 100644 index 000000000..de0a9f770 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertDate.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JavaScriptCore/JSGlobalObject.h" +#include "wtf/WallTime.h" + +namespace WebCore { + +JSC::JSValue jsDate(JSC::JSGlobalObject&, WallTime value); +WallTime valueToDate(JSC::JSGlobalObject&, JSC::JSValue); // NaN if the value can't be converted to a date. + +template<> struct Converter<IDLDate> : DefaultConverter<IDLDate> { + static WallTime convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return valueToDate(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLDate> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + // FIXME: This should be taking a JSDOMGlobalObject and passing it to jsDate. + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, WallTime value) + { + return jsDate(lexicalGlobalObject, value); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertDictionary.h b/src/bun.js/bindings/webcore/JSDOMConvertDictionary.h new file mode 100644 index 000000000..94173b16f --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertDictionary.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" + +namespace WebCore { + +// Specialized by generated code for IDL dictionary conversion. +template<typename T> T convertDictionary(JSC::JSGlobalObject&, JSC::JSValue); + + +template<typename T> struct Converter<IDLDictionary<T>> : DefaultConverter<IDLDictionary<T>> { + using ReturnType = T; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertDictionary<T>(lexicalGlobalObject, value); + } +}; + +template<typename T> struct JSConverter<IDLDictionary<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const T& dictionary) + { + return convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertEnumeration.h b/src/bun.js/bindings/webcore/JSDOMConvertEnumeration.h new file mode 100644 index 000000000..d458e4aa8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertEnumeration.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSDOMGlobalObject.h" + +namespace WebCore { + +// Specialized by generated code for IDL enumeration conversion. +template<typename T> std::optional<T> parseEnumeration(JSC::JSGlobalObject&, JSC::JSValue); +template<typename T> const char* expectedEnumerationValues(); + +// Specialized by generated code for IDL enumeration conversion. +template<typename T> JSC::JSString* convertEnumerationToJS(JSC::JSGlobalObject&, T); + + +template<typename T> struct Converter<IDLEnumeration<T>> : DefaultConverter<IDLEnumeration<T>> { + template<typename ExceptionThrower = DefaultExceptionThrower> + static T convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + + auto result = parseEnumeration<T>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, { }); + + if (UNLIKELY(!result)) { + exceptionThrower(lexicalGlobalObject, throwScope); + return { }; + } + return result.value(); + } +}; + +template<typename T> struct JSConverter<IDLEnumeration<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, T value) + { + return convertEnumerationToJS(lexicalGlobalObject, value); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertEventListener.h b/src/bun.js/bindings/webcore/JSDOMConvertEventListener.h new file mode 100644 index 000000000..09d0cbb6e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertEventListener.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" + +namespace WebCore { + +template<typename T> struct Converter<IDLEventListener<T>> : DefaultConverter<IDLEventListener<T>> { + using ReturnType = RefPtr<T>; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + auto scope = DECLARE_THROW_SCOPE(JSC::getVM(&lexicalGlobalObject)); + + if (UNLIKELY(!value.isObject())) { + exceptionThrower(lexicalGlobalObject, scope); + return nullptr; + } + + bool isAttribute = false; + return T::create(*asObject(value), thisObject, isAttribute, currentWorld(lexicalGlobalObject)); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertInterface.h b/src/bun.js/bindings/webcore/JSDOMConvertInterface.h new file mode 100644 index 000000000..349276467 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertInterface.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 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 "root.h" + +#include "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JavaScriptCore/Error.h" + +namespace WebCore { + +template<typename ImplementationClass> struct JSDOMWrapperConverterTraits; + +template<typename T, typename Enable = void> +struct JSToWrappedOverloader { + using ReturnType = typename JSDOMWrapperConverterTraits<T>::ToWrappedReturnType; + using WrapperType = typename JSDOMWrapperConverterTraits<T>::WrapperClass; + + static ReturnType toWrapped(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return WrapperType::toWrapped(JSC::getVM(&lexicalGlobalObject), value); + } +}; + +template<typename T> +struct JSToWrappedOverloader<T, typename std::enable_if<JSDOMWrapperConverterTraits<T>::needsState>::type> { + using ReturnType = typename JSDOMWrapperConverterTraits<T>::ToWrappedReturnType; + using WrapperType = typename JSDOMWrapperConverterTraits<T>::WrapperClass; + + static ReturnType toWrapped(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return WrapperType::toWrapped(lexicalGlobalObject, value); + } +}; + +template<typename T> struct Converter<IDLInterface<T>> : DefaultConverter<IDLInterface<T>> { + using ReturnType = typename JSDOMWrapperConverterTraits<T>::ToWrappedReturnType; + using WrapperType = typename JSDOMWrapperConverterTraits<T>::WrapperClass; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + ReturnType object = JSToWrappedOverloader<T>::toWrapped(lexicalGlobalObject, value); + if (UNLIKELY(!object)) + exceptionThrower(lexicalGlobalObject, scope); + return object; + } +}; + +template<typename T> struct JSConverter<IDLInterface<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const U& value) + { + return toJS(&lexicalGlobalObject, &globalObject, Detail::getPtrOrRef(value)); + } + + template<typename U> + static JSC::JSValue convertNewlyCreated(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) + { + return toJSNewlyCreated(&lexicalGlobalObject, &globalObject, std::forward<U>(value)); + } +}; + +template<typename T> struct VariadicConverter<IDLInterface<T>> { + using Item = std::reference_wrapper<T>; + + static std::optional<Item> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + auto* result = Converter<IDLInterface<T>>::convert(lexicalGlobalObject, value); + if (!result) + return std::nullopt; + return std::optional<Item> { *result }; + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertJSON.h b/src/bun.js/bindings/webcore/JSDOMConvertJSON.h new file mode 100644 index 000000000..9a289ef6c --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertJSON.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JavaScriptCore/JSONObject.h" + +namespace WebCore { + +template<> struct Converter<IDLJSON> : DefaultConverter<IDLJSON> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return JSC::JSONStringify(&lexicalGlobalObject, value, 0); + } +}; + +template<> struct JSConverter<IDLJSON> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const String& value) + { + return JSC::JSONParse(&lexicalGlobalObject, value); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertNull.h b/src/bun.js/bindings/webcore/JSDOMConvertNull.h new file mode 100644 index 000000000..b132825d2 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertNull.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" + +namespace WebCore { + +template<> struct Converter<IDLNull> : DefaultConverter<IDLNull> { + static std::nullptr_t convert(JSC::JSGlobalObject&, JSC::JSValue) + { + return nullptr; + } +}; + +template<> struct JSConverter<IDLNull> { + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(std::nullptr_t) + { + return JSC::jsNull(); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertNullable.h b/src/bun.js/bindings/webcore/JSDOMConvertNullable.h new file mode 100644 index 000000000..a3e4b5cc4 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertNullable.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertStrings.h" + +namespace WebCore { + +namespace Detail { + +template<typename IDLType> +struct NullableConversionType; + +template<typename IDLType> +struct NullableConversionType { + using Type = typename IDLNullable<IDLType>::ImplementationType; +}; + +template<typename T> +struct NullableConversionType<IDLInterface<T>> { + using Type = typename Converter<IDLInterface<T>>::ReturnType; +}; + +template<> +struct NullableConversionType<IDLAny> { + using Type = typename Converter<IDLAny>::ReturnType; +}; + +} + +template<typename T> struct Converter<IDLNullable<T>> : DefaultConverter<IDLNullable<T>> { + using ReturnType = typename Detail::NullableConversionType<T>::Type; + + // 1. If Type(V) is not Object, and the conversion to an IDL value is being performed + // due to V being assigned to an attribute whose type is a nullable callback function + // that is annotated with [LegacyTreatNonObjectAsNull], then return the IDL nullable + // type T? value null. + // + // NOTE: Handled elsewhere. + // + // 2. Otherwise, if V is null or undefined, then return the IDL nullable type T? value null. + // 3. Otherwise, return the result of converting V using the rules for the inner IDL type T. + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + if (value.isUndefinedOrNull()) + return T::nullValue(); + return Converter<T>::convert(lexicalGlobalObject, value); + } + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSC::JSObject& thisObject) + { + if (value.isUndefinedOrNull()) + return T::nullValue(); + return Converter<T>::convert(lexicalGlobalObject, value, thisObject); + } + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSDOMGlobalObject& globalObject) + { + if (value.isUndefinedOrNull()) + return T::nullValue(); + return Converter<T>::convert(lexicalGlobalObject, value, globalObject); + } + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower) + { + if (value.isUndefinedOrNull()) + return T::nullValue(); + return Converter<T>::convert(lexicalGlobalObject, value, std::forward<ExceptionThrower>(exceptionThrower)); + } + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSC::JSObject& thisObject, ExceptionThrower&& exceptionThrower) + { + if (value.isUndefinedOrNull()) + return T::nullValue(); + return Converter<T>::convert(lexicalGlobalObject, value, thisObject, std::forward<ExceptionThrower>(exceptionThrower)); + } + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSDOMGlobalObject& globalObject, ExceptionThrower&& exceptionThrower) + { + if (value.isUndefinedOrNull()) + return T::nullValue(); + return Converter<T>::convert(lexicalGlobalObject, value, globalObject, std::forward<ExceptionThrower>(exceptionThrower)); + } +}; + +template<typename T> struct JSConverter<IDLNullable<T>> { + using ImplementationType = typename IDLNullable<T>::ImplementationType; + + static constexpr bool needsState = JSConverter<T>::needsState; + static constexpr bool needsGlobalObject = JSConverter<T>::needsGlobalObject; + + template<typename U> + static JSC::JSValue convert(U&& value) + { + if (T::isNullValue(value)) + return JSC::jsNull(); + return JSConverter<T>::convert(T::extractValueFromNullable(value)); + } + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, U&& value) + { + if (T::isNullValue(value)) + return JSC::jsNull(); + return JSConverter<T>::convert(lexicalGlobalObject, T::extractValueFromNullable(value)); + } + template<typename U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) + { + if (T::isNullValue(value)) + return JSC::jsNull(); + return JSConverter<T>::convert(lexicalGlobalObject, globalObject, T::extractValueFromNullable(value)); + } + + template<typename U> + static JSC::JSValue convertNewlyCreated(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U&& value) + { + if (T::isNullValue(value)) + return JSC::jsNull(); + return JSConverter<T>::convert(lexicalGlobalObject, globalObject, T::extractValueFromNullable(value)); + } +}; + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertNumbers.cpp b/src/bun.js/bindings/webcore/JSDOMConvertNumbers.cpp new file mode 100644 index 000000000..438d32723 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertNumbers.cpp @@ -0,0 +1,379 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004-2011, 2013, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSDOMConvertNumbers.h" + +#include "JSDOMExceptionHandling.h" +#include "JavaScriptCore/HeapInlines.h" +#include "JavaScriptCore/JSCJSValueInlines.h" +#include "wtf/MathExtras.h" +#include "wtf/text/StringConcatenateNumbers.h" +#include "wtf/text/WTFString.h" + +namespace WebCore { +using namespace JSC; + +enum class IntegerConversionConfiguration { Normal, + EnforceRange, + Clamp }; + +static const int32_t kMaxInt32 = 0x7fffffff; +static const int32_t kMinInt32 = -kMaxInt32 - 1; +static const uint32_t kMaxUInt32 = 0xffffffffU; +static const int64_t kJSMaxInteger = 0x20000000000000LL - 1; // 2^53 - 1, largest integer exactly representable in ECMAScript. + +static String rangeErrorString(double value, double min, double max) +{ + return makeString("Value ", value, " is outside the range [", min, ", ", max, ']'); +} + +static double enforceRange(JSGlobalObject& lexicalGlobalObject, double x, double minimum, double maximum) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (std::isnan(x) || std::isinf(x)) { + throwTypeError(&lexicalGlobalObject, scope, rangeErrorString(x, minimum, maximum)); + return 0; + } + x = trunc(x); + if (x < minimum || x > maximum) { + throwTypeError(&lexicalGlobalObject, scope, rangeErrorString(x, minimum, maximum)); + return 0; + } + return x; +} + +namespace { + +template<typename T> +struct IntTypeLimits { +}; + +template<> +struct IntTypeLimits<int8_t> { + static const int8_t minValue = -128; + static const int8_t maxValue = 127; + static const unsigned numberOfValues = 256; // 2^8 +}; + +template<> +struct IntTypeLimits<uint8_t> { + static const uint8_t maxValue = 255; + static const unsigned numberOfValues = 256; // 2^8 +}; + +template<> +struct IntTypeLimits<int16_t> { + static const short minValue = -32768; + static const short maxValue = 32767; + static const unsigned numberOfValues = 65536; // 2^16 +}; + +template<> +struct IntTypeLimits<uint16_t> { + static const unsigned short maxValue = 65535; + static const unsigned numberOfValues = 65536; // 2^16 +}; + +} + +template<typename T, IntegerConversionConfiguration configuration> +static inline T toSmallerInt(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + static_assert(std::is_signed<T>::value && std::is_integral<T>::value, "Should only be used for signed integral types"); + + typedef IntTypeLimits<T> LimitsTrait; + // Fast path if the value is already a 32-bit signed integer in the right range. + if (value.isInt32()) { + int32_t d = value.asInt32(); + if (d >= LimitsTrait::minValue && d <= LimitsTrait::maxValue) + return static_cast<T>(d); + switch (configuration) { + case IntegerConversionConfiguration::Normal: + break; + case IntegerConversionConfiguration::EnforceRange: + throwTypeError(&lexicalGlobalObject, scope); + return 0; + case IntegerConversionConfiguration::Clamp: + return d < LimitsTrait::minValue ? LimitsTrait::minValue : LimitsTrait::maxValue; + } + d %= LimitsTrait::numberOfValues; + return static_cast<T>(d > LimitsTrait::maxValue ? d - LimitsTrait::numberOfValues : d); + } + + double x = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0); + + switch (configuration) { + case IntegerConversionConfiguration::Normal: + break; + case IntegerConversionConfiguration::EnforceRange: + return enforceRange(lexicalGlobalObject, x, LimitsTrait::minValue, LimitsTrait::maxValue); + case IntegerConversionConfiguration::Clamp: + return std::isnan(x) ? 0 : clampTo<T>(x); + } + + if (std::isnan(x) || std::isinf(x) || !x) + return 0; + + x = x < 0 ? -floor(fabs(x)) : floor(fabs(x)); + x = fmod(x, LimitsTrait::numberOfValues); + + return static_cast<T>(x > LimitsTrait::maxValue ? x - LimitsTrait::numberOfValues : x); +} + +template<typename T, IntegerConversionConfiguration configuration> +static inline T toSmallerUInt(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + static_assert(std::is_unsigned<T>::value && std::is_integral<T>::value, "Should only be used for unsigned integral types"); + + typedef IntTypeLimits<T> LimitsTrait; + // Fast path if the value is already a 32-bit unsigned integer in the right range. + if (value.isUInt32()) { + uint32_t d = value.asUInt32(); + if (d <= LimitsTrait::maxValue) + return static_cast<T>(d); + switch (configuration) { + case IntegerConversionConfiguration::Normal: + return static_cast<T>(d); + case IntegerConversionConfiguration::EnforceRange: + throwTypeError(&lexicalGlobalObject, scope); + return 0; + case IntegerConversionConfiguration::Clamp: + return LimitsTrait::maxValue; + } + } + + double x = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0); + + switch (configuration) { + case IntegerConversionConfiguration::Normal: + break; + case IntegerConversionConfiguration::EnforceRange: + return enforceRange(lexicalGlobalObject, x, 0, LimitsTrait::maxValue); + case IntegerConversionConfiguration::Clamp: + return std::isnan(x) ? 0 : clampTo<T>(x); + } + + if (std::isnan(x) || std::isinf(x) || !x) + return 0; + + x = x < 0 ? -floor(fabs(x)) : floor(fabs(x)); + x = fmod(x, LimitsTrait::numberOfValues); + if (x < 0) + x += LimitsTrait::numberOfValues; + return static_cast<T>(x); +} + +template<> int8_t convertToIntegerEnforceRange<int8_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerInt<int8_t, IntegerConversionConfiguration::EnforceRange>(lexicalGlobalObject, value); +} + +template<> uint8_t convertToIntegerEnforceRange<uint8_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerUInt<uint8_t, IntegerConversionConfiguration::EnforceRange>(lexicalGlobalObject, value); +} + +template<> int8_t convertToIntegerClamp<int8_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerInt<int8_t, IntegerConversionConfiguration::Clamp>(lexicalGlobalObject, value); +} + +template<> uint8_t convertToIntegerClamp<uint8_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerUInt<uint8_t, IntegerConversionConfiguration::Clamp>(lexicalGlobalObject, value); +} + +template<> int8_t convertToInteger<int8_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerInt<int8_t, IntegerConversionConfiguration::Normal>(lexicalGlobalObject, value); +} + +template<> uint8_t convertToInteger<uint8_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerUInt<uint8_t, IntegerConversionConfiguration::Normal>(lexicalGlobalObject, value); +} + +template<> int16_t convertToIntegerEnforceRange<int16_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerInt<int16_t, IntegerConversionConfiguration::EnforceRange>(lexicalGlobalObject, value); +} + +template<> uint16_t convertToIntegerEnforceRange<uint16_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerUInt<uint16_t, IntegerConversionConfiguration::EnforceRange>(lexicalGlobalObject, value); +} + +template<> int16_t convertToIntegerClamp<int16_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerInt<int16_t, IntegerConversionConfiguration::Clamp>(lexicalGlobalObject, value); +} + +template<> uint16_t convertToIntegerClamp<uint16_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerUInt<uint16_t, IntegerConversionConfiguration::Clamp>(lexicalGlobalObject, value); +} + +template<> int16_t convertToInteger<int16_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerInt<int16_t, IntegerConversionConfiguration::Normal>(lexicalGlobalObject, value); +} + +template<> uint16_t convertToInteger<uint16_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return toSmallerUInt<uint16_t, IntegerConversionConfiguration::Normal>(lexicalGlobalObject, value); +} + +template<> int32_t convertToIntegerEnforceRange<int32_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isInt32()) + return value.asInt32(); + + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + double x = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0); + return enforceRange(lexicalGlobalObject, x, kMinInt32, kMaxInt32); +} + +template<> uint32_t convertToIntegerEnforceRange<uint32_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isUInt32()) + return value.asUInt32(); + + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + double x = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0); + return enforceRange(lexicalGlobalObject, x, 0, kMaxUInt32); +} + +template<> int32_t convertToIntegerClamp<int32_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isInt32()) + return value.asInt32(); + + double x = value.toNumber(&lexicalGlobalObject); + return std::isnan(x) ? 0 : clampTo<int32_t>(x); +} + +template<> uint32_t convertToIntegerClamp<uint32_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isUInt32()) + return value.asUInt32(); + + double x = value.toNumber(&lexicalGlobalObject); + return std::isnan(x) ? 0 : clampTo<uint32_t>(x); +} + +template<> int32_t convertToInteger<int32_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return value.toInt32(&lexicalGlobalObject); +} + +template<> uint32_t convertToInteger<uint32_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + return value.toUInt32(&lexicalGlobalObject); +} + +template<> int64_t convertToIntegerEnforceRange<int64_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isInt32()) + return value.asInt32(); + + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + double x = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0); + return enforceRange(lexicalGlobalObject, x, -kJSMaxInteger, kJSMaxInteger); +} + +template<> uint64_t convertToIntegerEnforceRange<uint64_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isUInt32()) + return value.asUInt32(); + + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + double x = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0); + return enforceRange(lexicalGlobalObject, x, 0, kJSMaxInteger); +} + +template<> int64_t convertToIntegerClamp<int64_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isInt32()) + return value.asInt32(); + + double x = value.toNumber(&lexicalGlobalObject); + return std::isnan(x) ? 0 : static_cast<int64_t>(std::min<double>(std::max<double>(x, -kJSMaxInteger), kJSMaxInteger)); +} + +template<> uint64_t convertToIntegerClamp<uint64_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isUInt32()) + return value.asUInt32(); + + double x = value.toNumber(&lexicalGlobalObject); + return std::isnan(x) ? 0 : static_cast<uint64_t>(std::min<double>(std::max<double>(x, 0), kJSMaxInteger)); +} + +template<> int64_t convertToInteger<int64_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isInt32()) + return value.asInt32(); + + double x = value.toNumber(&lexicalGlobalObject); + + // Map NaNs and +/-Infinity to 0; convert finite values modulo 2^64. + unsigned long long n; + doubleToInteger(x, n); + return n; +} + +template<> uint64_t convertToInteger<uint64_t>(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + if (value.isUInt32()) + return value.asUInt32(); + + double x = value.toNumber(&lexicalGlobalObject); + + // Map NaNs and +/-Infinity to 0; convert finite values modulo 2^64. + unsigned long long n; + doubleToInteger(x, n); + return n; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertNumbers.h b/src/bun.js/bindings/webcore/JSDOMConvertNumbers.h new file mode 100644 index 000000000..29413d8d9 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertNumbers.h @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSDOMExceptionHandling.h" +#include <JavaScriptCore/JSCJSValueInlines.h> +#include <JavaScriptCore/PureNaN.h> + +namespace WebCore { + +// The following functions convert values to integers as per the WebIDL specification. +// The conversion fails if the value cannot be converted to a number or, if EnforceRange is specified, +// the value is outside the range of the destination integer type. + +template<typename T> T convertToInteger(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int8_t convertToInteger<int8_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint8_t convertToInteger<uint8_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int16_t convertToInteger<int16_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint16_t convertToInteger<uint16_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int32_t convertToInteger<int32_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint32_t convertToInteger<uint32_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int64_t convertToInteger<int64_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint64_t convertToInteger<uint64_t>(JSC::JSGlobalObject&, JSC::JSValue); + +template<typename T> T convertToIntegerEnforceRange(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int8_t convertToIntegerEnforceRange<int8_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint8_t convertToIntegerEnforceRange<uint8_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int16_t convertToIntegerEnforceRange<int16_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint16_t convertToIntegerEnforceRange<uint16_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int32_t convertToIntegerEnforceRange<int32_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint32_t convertToIntegerEnforceRange<uint32_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int64_t convertToIntegerEnforceRange<int64_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint64_t convertToIntegerEnforceRange<uint64_t>(JSC::JSGlobalObject&, JSC::JSValue); + +template<typename T> T convertToIntegerClamp(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int8_t convertToIntegerClamp<int8_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint8_t convertToIntegerClamp<uint8_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int16_t convertToIntegerClamp<int16_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint16_t convertToIntegerClamp<uint16_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int32_t convertToIntegerClamp<int32_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint32_t convertToIntegerClamp<uint32_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT int64_t convertToIntegerClamp<int64_t>(JSC::JSGlobalObject&, JSC::JSValue); +template<> WEBCORE_EXPORT uint64_t convertToIntegerClamp<uint64_t>(JSC::JSGlobalObject&, JSC::JSValue); + +// MARK: - +// MARK: Integer types + +template<> struct Converter<IDLByte> : DefaultConverter<IDLByte> { + static int8_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<int8_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLByte> { + using Type = typename IDLByte::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLOctet> : DefaultConverter<IDLOctet> { + static uint8_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<uint8_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLOctet> { + using Type = typename IDLOctet::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLShort> : DefaultConverter<IDLShort> { + static int16_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<int16_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLShort> { + using Type = typename IDLShort::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLUnsignedShort> : DefaultConverter<IDLUnsignedShort> { + static uint16_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<uint16_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLUnsignedShort> { + using Type = typename IDLUnsignedShort::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLLong> : DefaultConverter<IDLLong> { + static inline int32_t convert(JSC::JSGlobalObject&, JSC::ThrowScope&, double number) + { + return JSC::toInt32(number); + } + + static int32_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<int32_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLLong> { + using Type = typename IDLLong::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLUnsignedLong> : DefaultConverter<IDLUnsignedLong> { + static uint32_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<uint32_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLUnsignedLong> { + using Type = typename IDLUnsignedLong::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLLongLong> : DefaultConverter<IDLLongLong> { + static int64_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<int64_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLLongLong> { + using Type = typename IDLLongLong::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLUnsignedLongLong> : DefaultConverter<IDLUnsignedLongLong> { + static uint64_t convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToInteger<uint64_t>(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLUnsignedLongLong> { + using Type = typename IDLUnsignedLongLong::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +// MARK: - +// MARK: Annotated Integer types + +template<typename T> struct Converter<IDLClampAdaptor<T>> : DefaultConverter<IDLClampAdaptor<T>> { + using ReturnType = typename IDLClampAdaptor<T>::ImplementationType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToIntegerClamp<ReturnType>(lexicalGlobalObject, value); + } +}; + +template<typename T> struct JSConverter<IDLClampAdaptor<T>> { + using Type = typename IDLClampAdaptor<T>::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSConverter<T>::convert(value); + } +}; + + +template<typename T> struct Converter<IDLEnforceRangeAdaptor<T>> : DefaultConverter<IDLEnforceRangeAdaptor<T>> { + using ReturnType = typename IDLEnforceRangeAdaptor<T>::ImplementationType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertToIntegerEnforceRange<ReturnType>(lexicalGlobalObject, value); + } +}; + +template<typename T> struct JSConverter<IDLEnforceRangeAdaptor<T>> { + using Type = typename IDLEnforceRangeAdaptor<T>::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSConverter<T>::convert(value); + } +}; + + +// MARK: - +// MARK: Floating point types + +template<> struct Converter<IDLFloat> : DefaultConverter<IDLFloat> { + + static inline float convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, double number) + { + if (UNLIKELY(!std::isfinite(number))) + throwNonFiniteTypeError(lexicalGlobalObject, scope); + return static_cast<float>(number); + } + + static float convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + double number = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0.0); + if (UNLIKELY(number < std::numeric_limits<float>::lowest() || number > std::numeric_limits<float>::max())) + throwTypeError(&lexicalGlobalObject, scope, "The provided value is outside the range of a float"_s); + if (UNLIKELY(!std::isfinite(number))) + throwNonFiniteTypeError(lexicalGlobalObject, scope); + return static_cast<float>(number); + } +}; + +template<> struct JSConverter<IDLFloat> { + using Type = typename IDLFloat::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLUnrestrictedFloat> : DefaultConverter<IDLUnrestrictedFloat> { + static inline float convert(JSC::JSGlobalObject&, JSC::ThrowScope&, double number) + { + return static_cast<float>(number); + } + + static float convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + double number = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0.0); + + if (UNLIKELY(number < std::numeric_limits<float>::lowest())) + return -std::numeric_limits<float>::infinity(); + if (UNLIKELY(number > std::numeric_limits<float>::max())) + return std::numeric_limits<float>::infinity(); + return static_cast<float>(number); + } +}; + +template<> struct JSConverter<IDLUnrestrictedFloat> { + using Type = typename IDLUnrestrictedFloat::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLDouble> : DefaultConverter<IDLDouble> { + static inline double convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, double number) + { + if (UNLIKELY(!std::isfinite(number))) + throwNonFiniteTypeError(lexicalGlobalObject, scope); + return number; + } + + static double convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + double number = value.toNumber(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, 0.0); + if (UNLIKELY(!std::isfinite(number))) + throwNonFiniteTypeError(lexicalGlobalObject, scope); + return number; + } +}; + +template<> struct JSConverter<IDLDouble> { + using Type = typename IDLDouble::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + ASSERT(!std::isnan(value)); + return JSC::jsNumber(value); + } +}; + +template<> struct Converter<IDLUnrestrictedDouble> : DefaultConverter<IDLUnrestrictedDouble> { + static inline double convert(JSC::JSGlobalObject&, JSC::ThrowScope&, double number) + { + return number; + } + + static double convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return value.toNumber(&lexicalGlobalObject); + } +}; + +template<> struct JSConverter<IDLUnrestrictedDouble> { + using Type = typename IDLUnrestrictedDouble::ImplementationType; + + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(Type value) + { + return JSC::jsNumber(JSC::purifyNaN(value)); + } + + // Add overload for MediaTime. + static JSC::JSValue convert(const MediaTime& value) + { + return JSC::jsNumber(JSC::purifyNaN(value.toDouble())); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertObject.h b/src/bun.js/bindings/webcore/JSDOMConvertObject.h new file mode 100644 index 000000000..24dacac9e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertObject.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JavaScriptCore/StrongInlines.h" + +namespace WebCore { + +template<> struct Converter<IDLObject> : DefaultConverter<IDLObject> { + + static constexpr bool conversionHasSideEffects = false; + + template<typename ExceptionThrower = DefaultExceptionThrower> + static JSC::Strong<JSC::JSObject> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (!value.isObject()) { + exceptionThrower(lexicalGlobalObject, scope); + return {}; + } + + return { vm, JSC::asObject(value) }; + } +}; + +template<> struct JSConverter<IDLObject> { + static constexpr bool needsState = false; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(const JSC::Strong<JSC::JSObject>& value) + { + return value.get(); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertPromise.h b/src/bun.js/bindings/webcore/JSDOMConvertPromise.h new file mode 100644 index 000000000..e01a99884 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertPromise.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>. + * + * 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSDOMPromise.h" +// #include "WorkerGlobalScope.h" + +namespace WebCore { + +template<typename T> struct Converter<IDLPromise<T>> : DefaultConverter<IDLPromise<T>> { + using ReturnType = RefPtr<DOMPromise>; + + // https://webidl.spec.whatwg.org/#es-promise + template<typename ExceptionThrower = DefaultExceptionThrower> + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + auto* globalObject = JSC::jsDynamicCast<JSDOMGlobalObject*>(&lexicalGlobalObject); + if (!globalObject) + return nullptr; + + // 1. Let resolve be the original value of %Promise%.resolve. + // 2. Let promise be the result of calling resolve with %Promise% as the this value and V as the single argument value. + auto* promise = JSC::JSPromise::resolvedPromise(globalObject, value); + if (scope.exception()) { + auto* scriptExecutionContext = globalObject->scriptExecutionContext(); + // if (is<WorkerGlobalScope>(scriptExecutionContext)) { + // auto* scriptController = downcast<WorkerGlobalScope>(*scriptExecutionContext).script(); + // bool terminatorCausedException = vm.isTerminationException(scope.exception()); + // if (terminatorCausedException || (scriptController && scriptController->isTerminatingExecution())) { + // scriptController->forbidExecution(); + // return nullptr; + // } + // } + exceptionThrower(lexicalGlobalObject, scope); + return nullptr; + } + ASSERT(promise); + + // 3. Return the IDL promise type value that is a reference to the same object as promise. + return DOMPromise::create(*globalObject, *promise); + } +}; + +template<typename T> struct JSConverter<IDLPromise<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + static JSC::JSValue convert(JSC::JSGlobalObject&, JSDOMGlobalObject&, DOMPromise& promise) + { + return promise.promise(); + } + + template<template<typename> class U> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, U<T>& promiseProxy) + { + return promiseProxy.promise(lexicalGlobalObject, globalObject); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertRecord.h b/src/bun.js/bindings/webcore/JSDOMConvertRecord.h new file mode 100644 index 000000000..0f4c84eff --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertRecord.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2016-2019 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 "IDLTypes.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMGlobalObject.h" +#include "JavaScriptCore/ObjectConstructor.h" + +namespace WebCore { + +namespace Detail { + +template<typename IDLStringType> +struct IdentifierConverter; + +template<> struct IdentifierConverter<IDLDOMString> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::Identifier& identifier) + { + return identifierToString(lexicalGlobalObject, identifier); + } +}; + +template<> struct IdentifierConverter<IDLByteString> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::Identifier& identifier) + { + return identifierToByteString(lexicalGlobalObject, identifier); + } +}; + +template<> struct IdentifierConverter<IDLUSVString> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::Identifier& identifier) + { + return identifierToUSVString(lexicalGlobalObject, identifier); + } +}; + +} + +template<typename K, typename V> struct Converter<IDLRecord<K, V>> : DefaultConverter<IDLRecord<K, V>> { + using ReturnType = typename IDLRecord<K, V>::ImplementationType; + using KeyType = typename K::ImplementationType; + using ValueType = typename V::ImplementationType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSDOMGlobalObject& globalObject) + { + return convertRecord<JSDOMGlobalObject&>(lexicalGlobalObject, value, globalObject); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return convertRecord(lexicalGlobalObject, value); + } + +private: + template<class... Args> + static ReturnType convertRecord(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, Args... args) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + // 1. Let result be a new empty instance of record<K, V>. + // 2. If Type(O) is Undefined or Null, return result. + if (value.isUndefinedOrNull()) + return {}; + + // 3. If Type(O) is not Object, throw a TypeError. + if (!value.isObject()) { + throwTypeError(&lexicalGlobalObject, scope); + return {}; + } + + JSC::JSObject* object = JSC::asObject(value); + + ReturnType result; + HashMap<KeyType, size_t> resultMap; + + // 4. Let keys be ? O.[[OwnPropertyKeys]](). + JSC::PropertyNameArray keys(vm, JSC::PropertyNameMode::StringsAndSymbols, JSC::PrivateSymbolMode::Exclude); + object->methodTable()->getOwnPropertyNames(object, &lexicalGlobalObject, keys, JSC::DontEnumPropertiesMode::Include); + RETURN_IF_EXCEPTION(scope, {}); + + // 5. Repeat, for each element key of keys in List order: + for (auto& key : keys) { + // 1. Let desc be ? O.[[GetOwnProperty]](key). + JSC::PropertySlot slot(object, JSC::PropertySlot::InternalMethodType::GetOwnProperty); + bool hasProperty = object->methodTable()->getOwnPropertySlot(object, &lexicalGlobalObject, key, slot); + RETURN_IF_EXCEPTION(scope, {}); + + // 2. If desc is not undefined and desc.[[Enumerable]] is true: + + // It's necessary to filter enumerable here rather than using DontEnumPropertiesMode::Exclude, + // to prevent an observable extra [[GetOwnProperty]] operation in the case of ProxyObject records. + if (hasProperty && !(slot.attributes() & JSC::PropertyAttribute::DontEnum)) { + // 1. Let typedKey be key converted to an IDL value of type K. + auto typedKey = Detail::IdentifierConverter<K>::convert(lexicalGlobalObject, key); + RETURN_IF_EXCEPTION(scope, {}); + + // 2. Let value be ? Get(O, key). + JSC::JSValue subValue; + if (LIKELY(!slot.isTaintedByOpaqueObject())) + subValue = slot.getValue(&lexicalGlobalObject, key); + else + subValue = object->get(&lexicalGlobalObject, key); + RETURN_IF_EXCEPTION(scope, {}); + + // 3. Let typedValue be value converted to an IDL value of type V. + auto typedValue = Converter<V>::convert(lexicalGlobalObject, subValue, args...); + RETURN_IF_EXCEPTION(scope, {}); + + // 4. Set result[typedKey] to typedValue. + // Note: It's possible that typedKey is already in result if K is USVString and key contains unpaired surrogates. + if constexpr (std::is_same_v<K, IDLUSVString>) { + if (!typedKey.is8Bit()) { + auto addResult = resultMap.add(typedKey, result.size()); + if (!addResult.isNewEntry) { + ASSERT(result[addResult.iterator->value].key == typedKey); + result[addResult.iterator->value].value = WTFMove(typedValue); + continue; + } + } + } else + UNUSED_VARIABLE(resultMap); + + // 5. Otherwise, append to result a mapping (typedKey, typedValue). + result.append({ WTFMove(typedKey), WTFMove(typedValue) }); + } + } + + // 6. Return result. + return result; + } +}; + +template<typename K, typename V> struct JSConverter<IDLRecord<K, V>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename MapType> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const MapType& map) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + + // 1. Let result be ! ObjectCreate(%ObjectPrototype%). + auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype()); + + // 2. Repeat, for each mapping (key, value) in D: + for (const auto& keyValuePair : map) { + // 1. Let esKey be key converted to an ECMAScript value. + // Note, this step is not required, as we need the key to be + // an Identifier, not a JSValue. + + // 2. Let esValue be value converted to an ECMAScript value. + auto esValue = toJS<V>(lexicalGlobalObject, globalObject, keyValuePair.value); + + // 3. Let created be ! CreateDataProperty(result, esKey, esValue). + bool created = result->putDirect(vm, JSC::Identifier::fromString(vm, keyValuePair.key), esValue); + + // 4. Assert: created is true. + ASSERT_UNUSED(created, created); + } + + // 3. Return result. + return result; + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertScheduledAction.h b/src/bun.js/bindings/webcore/JSDOMConvertScheduledAction.h new file mode 100644 index 000000000..72fb8450d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertScheduledAction.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertStrings.h" +#include "ScheduledAction.h" + +namespace WebCore { + +template<> struct Converter<IDLScheduledAction> : DefaultConverter<IDLScheduledAction> { + static std::unique_ptr<ScheduledAction> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, JSDOMGlobalObject& globalObject) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (!value.isCallable()) { + auto code = Converter<IDLDOMString>::convert(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(scope, nullptr); + return ScheduledAction::create(globalObject.world(), WTFMove(code)); + } + + // The value must be an object at this point because no non-object values are callable. + ASSERT(value.isObject()); + return ScheduledAction::create(globalObject.world(), JSC::Strong<JSC::Unknown> { vm, JSC::asObject(value) }); + } +}; + +} diff --git a/src/bun.js/bindings/webcore/JSDOMConvertSequences.h b/src/bun.js/bindings/webcore/JSDOMConvertSequences.h new file mode 100644 index 000000000..a08336f64 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertSequences.h @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2016-2017 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMGlobalObject.h" +#include "JavaScriptCore/IteratorOperations.h" +#include "JavaScriptCore/JSArray.h" +#include "JavaScriptCore/JSGlobalObjectInlines.h" +#include "JavaScriptCore/ObjectConstructor.h" + +namespace WebCore { + +namespace Detail { + +template<typename IDLType> +struct GenericSequenceConverter { + using ReturnType = Vector<typename IDLType::SequenceStorageType>; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object) + { + return convert(lexicalGlobalObject, object, ReturnType()); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, ReturnType&& result) + { + forEachInIterable(&lexicalGlobalObject, object, [&result](JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSValue nextValue) { + auto scope = DECLARE_THROW_SCOPE(vm); + + auto convertedValue = Converter<IDLType>::convert(*lexicalGlobalObject, nextValue); + if (UNLIKELY(scope.exception())) + return; + result.append(WTFMove(convertedValue)); + }); + return WTFMove(result); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return convert(lexicalGlobalObject, object, method, ReturnType()); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method, ReturnType&& result) + { + forEachInIterable(lexicalGlobalObject, object, method, [&result](JSC::VM& vm, JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue nextValue) { + auto scope = DECLARE_THROW_SCOPE(vm); + + auto convertedValue = Converter<IDLType>::convert(lexicalGlobalObject, nextValue); + if (UNLIKELY(scope.exception())) + return; + result.append(WTFMove(convertedValue)); + }); + return WTFMove(result); + } +}; + +// Specialization for numeric types +// FIXME: This is only implemented for the IDLFloatingPointTypes and IDLLong. To add +// support for more numeric types, add an overload of Converter<IDLType>::convert that +// takes a JSGlobalObject, ThrowScope and double as its arguments. +template<typename IDLType> +struct NumericSequenceConverter { + using GenericConverter = GenericSequenceConverter<IDLType>; + using ReturnType = typename GenericConverter::ReturnType; + + static ReturnType convertArray(JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, JSC::JSArray* array, unsigned length, JSC::IndexingType indexingType, ReturnType&& result) + { + if (indexingType == JSC::Int32Shape) { + for (unsigned i = 0; i < length; i++) { + auto indexValue = array->butterfly()->contiguousInt32().at(array, i).get(); + ASSERT(!indexValue || indexValue.isInt32()); + if (!indexValue) + result.uncheckedAppend(0); + else + result.uncheckedAppend(indexValue.asInt32()); + } + return WTFMove(result); + } + + ASSERT(indexingType == JSC::DoubleShape); + for (unsigned i = 0; i < length; i++) { + double doubleValue = array->butterfly()->contiguousDouble().at(array, i); + if (std::isnan(doubleValue)) + result.uncheckedAppend(0); + else { + auto convertedValue = Converter<IDLType>::convert(lexicalGlobalObject, scope, doubleValue); + RETURN_IF_EXCEPTION(scope, {}); + + result.uncheckedAppend(convertedValue); + } + } + return WTFMove(result); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (!value.isObject()) { + throwSequenceTypeError(lexicalGlobalObject, scope); + return {}; + } + + JSC::JSObject* object = JSC::asObject(value); + if (!JSC::isJSArray(object)) + RELEASE_AND_RETURN(scope, GenericConverter::convert(lexicalGlobalObject, object)); + + JSC::JSArray* array = JSC::asArray(object); + if (!array->isIteratorProtocolFastAndNonObservable()) + RELEASE_AND_RETURN(scope, GenericConverter::convert(lexicalGlobalObject, object)); + + unsigned length = array->length(); + ReturnType result; + // If we're not an int32/double array, it's possible that converting a + // JSValue to a number could cause the iterator protocol to change, hence, + // we may need more capacity, or less. In such cases, we use the length + // as a proxy for the capacity we will most likely need (it's unlikely that + // a program is written with a valueOf that will augment the iterator protocol). + // If we are an int32/double array, then length is precisely the capacity we need. + if (!result.tryReserveCapacity(length)) { + // FIXME: Is the right exception to throw? + throwTypeError(&lexicalGlobalObject, scope); + return {}; + } + + JSC::IndexingType indexingType = array->indexingType() & JSC::IndexingShapeMask; + if (indexingType != JSC::Int32Shape && indexingType != JSC::DoubleShape) + RELEASE_AND_RETURN(scope, GenericConverter::convert(lexicalGlobalObject, object, WTFMove(result))); + + return convertArray(lexicalGlobalObject, scope, array, length, indexingType, WTFMove(result)); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (!JSC::isJSArray(object)) + RELEASE_AND_RETURN(scope, GenericConverter::convert(lexicalGlobalObject, object, method)); + + JSC::JSArray* array = JSC::asArray(object); + if (!array->isIteratorProtocolFastAndNonObservable()) + RELEASE_AND_RETURN(scope, GenericConverter::convert(lexicalGlobalObject, object, method)); + + unsigned length = array->length(); + ReturnType result; + // If we're not an int32/double array, it's possible that converting a + // JSValue to a number could cause the iterator protocol to change, hence, + // we may need more capacity, or less. In such cases, we use the length + // as a proxy for the capacity we will most likely need (it's unlikely that + // a program is written with a valueOf that will augment the iterator protocol). + // If we are an int32/double array, then length is precisely the capacity we need. + if (!result.tryReserveCapacity(length)) { + // FIXME: Is the right exception to throw? + throwTypeError(&lexicalGlobalObject, scope); + return {}; + } + + JSC::IndexingType indexingType = array->indexingType() & JSC::IndexingShapeMask; + if (indexingType != JSC::Int32Shape && indexingType != JSC::DoubleShape) + RELEASE_AND_RETURN(scope, GenericConverter::convert(lexicalGlobalObject, object, method, WTFMove(result))); + + return convertArray(lexicalGlobalObject, scope, array, length, indexingType, WTFMove(result)); + } +}; + +template<typename IDLType> +struct SequenceConverter { + using GenericConverter = GenericSequenceConverter<IDLType>; + using ReturnType = typename GenericConverter::ReturnType; + + static ReturnType convertArray(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSArray* array) + { + auto& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + unsigned length = array->length(); + + ReturnType result; + if (!result.tryReserveCapacity(length)) { + // FIXME: Is the right exception to throw? + throwTypeError(&lexicalGlobalObject, scope); + return {}; + } + + JSC::IndexingType indexingType = array->indexingType() & JSC::IndexingShapeMask; + + if (indexingType == JSC::ContiguousShape) { + for (unsigned i = 0; i < length; i++) { + auto indexValue = array->butterfly()->contiguous().at(array, i).get(); + if (!indexValue) + indexValue = JSC::jsUndefined(); + + auto convertedValue = Converter<IDLType>::convert(lexicalGlobalObject, indexValue); + RETURN_IF_EXCEPTION(scope, {}); + + result.uncheckedAppend(convertedValue); + } + return result; + } + + for (unsigned i = 0; i < length; i++) { + auto indexValue = array->getDirectIndex(&lexicalGlobalObject, i); + RETURN_IF_EXCEPTION(scope, {}); + + if (!indexValue) + indexValue = JSC::jsUndefined(); + + auto convertedValue = Converter<IDLType>::convert(lexicalGlobalObject, indexValue); + RETURN_IF_EXCEPTION(scope, {}); + + result.uncheckedAppend(convertedValue); + } + return result; + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + if (!value.isObject()) { + throwSequenceTypeError(lexicalGlobalObject, scope); + return {}; + } + + JSC::JSObject* object = JSC::asObject(value); + if (Converter<IDLType>::conversionHasSideEffects) + RELEASE_AND_RETURN(scope, (GenericConverter::convert(lexicalGlobalObject, object))); + + if (!JSC::isJSArray(object)) + RELEASE_AND_RETURN(scope, (GenericConverter::convert(lexicalGlobalObject, object))); + + JSC::JSArray* array = JSC::asArray(object); + if (!array->isIteratorProtocolFastAndNonObservable()) + RELEASE_AND_RETURN(scope, (GenericConverter::convert(lexicalGlobalObject, object))); + + RELEASE_AND_RETURN(scope, (convertArray(lexicalGlobalObject, array))); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + if (Converter<IDLType>::conversionHasSideEffects) + return GenericConverter::convert(lexicalGlobalObject, object, method); + + if (!JSC::isJSArray(object)) + return GenericConverter::convert(lexicalGlobalObject, object, method); + + JSC::JSArray* array = JSC::asArray(object); + if (!array->isIteratorProtocolFastAndNonObservable()) + return GenericConverter::convert(lexicalGlobalObject, object, method); + + return convertArray(lexicalGlobalObject, array); + } +}; + +template<> +struct SequenceConverter<IDLLong> { + using ReturnType = typename GenericSequenceConverter<IDLLong>::ReturnType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return NumericSequenceConverter<IDLLong>::convert(lexicalGlobalObject, value); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return NumericSequenceConverter<IDLLong>::convert(lexicalGlobalObject, object, method); + } +}; + +template<> +struct SequenceConverter<IDLFloat> { + using ReturnType = typename GenericSequenceConverter<IDLFloat>::ReturnType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return NumericSequenceConverter<IDLFloat>::convert(lexicalGlobalObject, value); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return NumericSequenceConverter<IDLFloat>::convert(lexicalGlobalObject, object, method); + } +}; + +template<> +struct SequenceConverter<IDLUnrestrictedFloat> { + using ReturnType = typename GenericSequenceConverter<IDLUnrestrictedFloat>::ReturnType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return NumericSequenceConverter<IDLUnrestrictedFloat>::convert(lexicalGlobalObject, value); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return NumericSequenceConverter<IDLUnrestrictedFloat>::convert(lexicalGlobalObject, object, method); + } +}; + +template<> +struct SequenceConverter<IDLDouble> { + using ReturnType = typename GenericSequenceConverter<IDLDouble>::ReturnType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return NumericSequenceConverter<IDLDouble>::convert(lexicalGlobalObject, value); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return NumericSequenceConverter<IDLDouble>::convert(lexicalGlobalObject, object, method); + } +}; + +template<> +struct SequenceConverter<IDLUnrestrictedDouble> { + using ReturnType = typename GenericSequenceConverter<IDLUnrestrictedDouble>::ReturnType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return NumericSequenceConverter<IDLUnrestrictedDouble>::convert(lexicalGlobalObject, value); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return NumericSequenceConverter<IDLUnrestrictedDouble>::convert(lexicalGlobalObject, object, method); + } +}; + +} + +template<typename T> struct Converter<IDLSequence<T>> : DefaultConverter<IDLSequence<T>> { + using ReturnType = typename Detail::SequenceConverter<T>::ReturnType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return Detail::SequenceConverter<T>::convert(lexicalGlobalObject, value); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return Detail::SequenceConverter<T>::convert(lexicalGlobalObject, object, method); + } +}; + +template<typename T> struct JSConverter<IDLSequence<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U, size_t inlineCapacity> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const Vector<U, inlineCapacity>& vector) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + JSC::MarkedArgumentBuffer list; + for (auto& element : vector) { + auto jsValue = toJS<T>(lexicalGlobalObject, globalObject, element); + RETURN_IF_EXCEPTION(scope, {}); + list.append(jsValue); + } + if (UNLIKELY(list.hasOverflowed())) { + throwOutOfMemoryError(&lexicalGlobalObject, scope); + return {}; + } + RELEASE_AND_RETURN(scope, JSC::constructArray(&globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), list)); + } +}; + +template<typename T> struct Converter<IDLFrozenArray<T>> : DefaultConverter<IDLFrozenArray<T>> { + using ReturnType = typename Detail::SequenceConverter<T>::ReturnType; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return Detail::SequenceConverter<T>::convert(lexicalGlobalObject, value); + } + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return Detail::SequenceConverter<T>::convert(lexicalGlobalObject, object, method); + } +}; + +template<typename T> struct JSConverter<IDLFrozenArray<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template<typename U, size_t inlineCapacity> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const Vector<U, inlineCapacity>& vector) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + JSC::MarkedArgumentBuffer list; + for (auto& element : vector) { + auto jsValue = toJS<T>(lexicalGlobalObject, globalObject, element); + RETURN_IF_EXCEPTION(scope, {}); + list.append(jsValue); + } + if (UNLIKELY(list.hasOverflowed())) { + throwOutOfMemoryError(&lexicalGlobalObject, scope); + return {}; + } + auto* array = JSC::constructArray(&globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), list); + RETURN_IF_EXCEPTION(scope, {}); + RELEASE_AND_RETURN(scope, JSC::objectConstructorFreeze(&lexicalGlobalObject, array)); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertSerializedScriptValue.h b/src/bun.js/bindings/webcore/JSDOMConvertSerializedScriptValue.h new file mode 100644 index 000000000..ba714ff67 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertSerializedScriptValue.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertStrings.h" + +namespace WebCore { + +template<typename T> struct Converter<IDLSerializedScriptValue<T>> : DefaultConverter<IDLSerializedScriptValue<T>> { + static RefPtr<T> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return T::create(lexicalGlobalObject, value); + } +}; + +template<typename T> struct JSConverter<IDLSerializedScriptValue<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, RefPtr<T> value) + { + return value ? value->deserialize(lexicalGlobalObject, &globalObject) : JSC::jsNull(); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertStrings.cpp b/src/bun.js/bindings/webcore/JSDOMConvertStrings.cpp new file mode 100644 index 000000000..00f385e07 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertStrings.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2004-2011, 2013, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSDOMConvertStrings.h" + +#include "JSDOMExceptionHandling.h" +#include <JavaScriptCore/HeapInlines.h> +#include <JavaScriptCore/JSCJSValueInlines.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/unicode/CharacterNames.h> + +namespace WebCore { +using namespace JSC; + +String identifierToString(JSGlobalObject& lexicalGlobalObject, const Identifier& identifier) +{ + if (UNLIKELY(identifier.isSymbol())) { + auto scope = DECLARE_THROW_SCOPE(lexicalGlobalObject.vm()); + throwTypeError(&lexicalGlobalObject, scope, SymbolCoercionError); + return {}; + } + + return identifier.string(); +} + +static inline bool throwIfInvalidByteString(JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope, const String& string) +{ + if (UNLIKELY(!string.isAllLatin1())) { + throwTypeError(&lexicalGlobalObject, scope); + return true; + } + return false; +} + +String identifierToByteString(JSGlobalObject& lexicalGlobalObject, const Identifier& identifier) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto string = identifierToString(lexicalGlobalObject, identifier); + RETURN_IF_EXCEPTION(scope, {}); + if (UNLIKELY(throwIfInvalidByteString(lexicalGlobalObject, scope, string))) + return {}; + return string; +} + +String valueToByteString(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto string = value.toWTFString(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); + + if (UNLIKELY(throwIfInvalidByteString(lexicalGlobalObject, scope, string))) + return {}; + return string; +} + +AtomString valueToByteAtomString(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto string = value.toString(&lexicalGlobalObject)->toAtomString(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); + + if (UNLIKELY(throwIfInvalidByteString(lexicalGlobalObject, scope, string.string()))) + return nullAtom(); + + return string; +} + +String identifierToUSVString(JSGlobalObject& lexicalGlobalObject, const Identifier& identifier) +{ + return replaceUnpairedSurrogatesWithReplacementCharacter(identifierToString(lexicalGlobalObject, identifier)); +} + +String valueToUSVString(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto string = value.toWTFString(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); + + return replaceUnpairedSurrogatesWithReplacementCharacter(WTFMove(string)); +} + +AtomString valueToUSVAtomString(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto string = value.toString(&lexicalGlobalObject)->toAtomString(&lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); + + return replaceUnpairedSurrogatesWithReplacementCharacter(WTFMove(string)); +} + +} // namespace WebCore
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSDOMConvertStrings.h b/src/bun.js/bindings/webcore/JSDOMConvertStrings.h new file mode 100644 index 000000000..450caf7e9 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertStrings.h @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2016-2019 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "StringAdaptors.h" + +namespace WebCore { + +WEBCORE_EXPORT String identifierToString(JSC::JSGlobalObject&, const JSC::Identifier&); +WEBCORE_EXPORT String identifierToByteString(JSC::JSGlobalObject&, const JSC::Identifier&); +WEBCORE_EXPORT String valueToByteString(JSC::JSGlobalObject&, JSC::JSValue); +WEBCORE_EXPORT AtomString valueToByteAtomString(JSC::JSGlobalObject&, JSC::JSValue); +WEBCORE_EXPORT String identifierToUSVString(JSC::JSGlobalObject&, const JSC::Identifier&); +WEBCORE_EXPORT String valueToUSVString(JSC::JSGlobalObject&, JSC::JSValue); +WEBCORE_EXPORT AtomString valueToUSVAtomString(JSC::JSGlobalObject&, JSC::JSValue); + +inline AtomString propertyNameToString(JSC::PropertyName propertyName) +{ + ASSERT(!propertyName.isSymbol()); + return propertyName.uid() ? propertyName.uid() : propertyName.publicName(); +} + +inline AtomString propertyNameToAtomString(JSC::PropertyName propertyName) +{ + return AtomString(propertyName.uid() ? propertyName.uid() : propertyName.publicName()); +} + +// MARK: - +// MARK: String types + +template<> struct Converter<IDLDOMString> : DefaultConverter<IDLDOMString> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return value.toWTFString(&lexicalGlobalObject); + } +}; + +template<> struct JSConverter<IDLDOMString> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const String& value) + { + return JSC::jsStringWithCache(JSC::getVM(&lexicalGlobalObject), value); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const UncachedString& value) + { + return JSC::jsString(JSC::getVM(&lexicalGlobalObject), value.string); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const OwnedString& value) + { + return JSC::jsOwnedString(JSC::getVM(&lexicalGlobalObject), value.string); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const URL& value) + { + return JSC::jsOwnedString(JSC::getVM(&lexicalGlobalObject), value.string()); + } +}; + +template<> struct Converter<IDLByteString> : DefaultConverter<IDLByteString> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return valueToByteString(lexicalGlobalObject, value); + } +}; + +template<> struct JSConverter<IDLByteString> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const String& value) + { + return JSC::jsStringWithCache(JSC::getVM(&lexicalGlobalObject), value); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const UncachedString& value) + { + return JSC::jsString(JSC::getVM(&lexicalGlobalObject), value.string); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const OwnedString& value) + { + return JSC::jsOwnedString(JSC::getVM(&lexicalGlobalObject), value.string); + } +}; + +template<> struct Converter<IDLUSVString> : DefaultConverter<IDLUSVString> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return valueToUSVString(lexicalGlobalObject, value); + } + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const URL& value) + { + return JSC::jsOwnedString(JSC::getVM(&lexicalGlobalObject), value.string()); + } +}; + +template<> struct JSConverter<IDLUSVString> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const String& value) + { + return JSC::jsStringWithCache(JSC::getVM(&lexicalGlobalObject), value); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const UncachedString& value) + { + return JSC::jsString(JSC::getVM(&lexicalGlobalObject), value.string); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const OwnedString& value) + { + return JSC::jsOwnedString(JSC::getVM(&lexicalGlobalObject), value.string); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const URL& value) + { + return JSC::jsOwnedString(JSC::getVM(&lexicalGlobalObject), value.string()); + } +}; + +// MARK: - +// MARK: String type adaptors + +template<typename T> struct Converter<IDLLegacyNullToEmptyStringAdaptor<T>> : DefaultConverter<IDLLegacyNullToEmptyStringAdaptor<T>> { + static String convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + if (value.isNull()) + return emptyString(); + return Converter<T>::convert(lexicalGlobalObject, value); + } +}; + +template<typename T> struct JSConverter<IDLLegacyNullToEmptyStringAdaptor<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const String& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, value); + } +}; + +template<typename T> struct Converter<IDLLegacyNullToEmptyAtomStringAdaptor<T>> : DefaultConverter<IDLLegacyNullToEmptyAtomStringAdaptor<T>> { + static AtomString convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + if (value.isNull()) + return emptyAtom(); + return Converter<IDLAtomStringAdaptor<T>>::convert(lexicalGlobalObject, value); + } +}; + +template<typename T> struct JSConverter<IDLLegacyNullToEmptyAtomStringAdaptor<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const AtomString& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, value); + } +}; + +template<typename T> struct Converter<IDLAtomStringAdaptor<T>> : DefaultConverter<IDLAtomStringAdaptor<T>> { + static AtomString convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + static_assert(std::is_same<T, IDLDOMString>::value, "This adaptor is only supported for IDLDOMString at the moment."); + + return value.toString(&lexicalGlobalObject)->toAtomString(&lexicalGlobalObject); + } +}; + +template<> struct Converter<IDLAtomStringAdaptor<IDLUSVString>> : DefaultConverter<IDLAtomStringAdaptor<IDLUSVString>> { + static AtomString convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return valueToUSVAtomString(lexicalGlobalObject, value); + } +}; + +template<> struct Converter<IDLAtomStringAdaptor<IDLByteString>> : DefaultConverter<IDLAtomStringAdaptor<IDLByteString>> { + static AtomString convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return valueToByteAtomString(lexicalGlobalObject, value); + } +}; + +template<typename T> struct JSConverter<IDLAtomStringAdaptor<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const AtomString& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, value); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const String& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, value); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const URL& value) + { + return JSConverter<T>::convert(lexicalGlobalObject, value.string()); + } +}; + +template<> struct JSConverter<IDLAtomStringAdaptor<IDLUSVString>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const AtomString& value) + { + return JSConverter<IDLUSVString>::convert(lexicalGlobalObject, value.string()); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const String& value) + { + return JSConverter<IDLUSVString>::convert(lexicalGlobalObject, value); + } + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const URL& value) + { + return JSConverter<IDLUSVString>::convert(lexicalGlobalObject, value.string()); + } +}; + +template<> struct JSConverter<IDLAtomStringAdaptor<IDLByteString>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const AtomString& value) + { + return JSConverter<IDLByteString>::convert(lexicalGlobalObject, value.string()); + } +}; + +template<typename T> struct Converter<IDLRequiresExistingAtomStringAdaptor<T>> : DefaultConverter<IDLRequiresExistingAtomStringAdaptor<T>> { + static AtomString convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + static_assert(std::is_same<T, IDLDOMString>::value, "This adaptor is only supported for IDLDOMString at the moment."); + + return value.toString(&lexicalGlobalObject)->toExistingAtomString(&lexicalGlobalObject); + } +}; + +template<typename T> struct JSConverter<IDLRequiresExistingAtomStringAdaptor<T>> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = false; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, const AtomString& value) + { + static_assert(std::is_same<T, IDLDOMString>::value, "This adaptor is only supported for IDLDOMString at the moment."); + + return JSConverter<T>::convert(lexicalGlobalObject, value); + } +}; + +} // namespace WebCore
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSDOMConvertUnion.h b/src/bun.js/bindings/webcore/JSDOMConvertUnion.h new file mode 100644 index 000000000..75ce6f86a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertUnion.h @@ -0,0 +1,417 @@ +/* + * Copyright (C) 2016-2020 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 "IDLTypes.h" +#include "JSDOMBinding.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBufferSource.h" +#include "JSDOMConvertBufferSource+JSBuffer.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNull.h" +#include "JavaScriptCore/IteratorOperations.h" +#include <variant> + +namespace WebCore { + +template<typename ReturnType, bool enabled> +struct ConditionalReturner; + +template<typename ReturnType> +struct ConditionalReturner<ReturnType, true> { + template<typename T> + static std::optional<ReturnType> get(T&& value) + { + return ReturnType(std::forward<T>(value)); + } +}; + +template<typename ReturnType> +struct ConditionalReturner<ReturnType, false> { + template<typename T> + static std::optional<ReturnType> get(T&&) + { + return std::nullopt; + } +}; + +template<typename ReturnType, typename T, bool enabled> +struct ConditionalConverter; + +template<typename ReturnType, typename T> +struct ConditionalConverter<ReturnType, T, true> { + static std::optional<ReturnType> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + return ReturnType(Converter<T>::convert(lexicalGlobalObject, value)); + } +}; + +template<typename ReturnType, typename T> +struct ConditionalConverter<ReturnType, T, false> { + static std::optional<ReturnType> convert(JSC::JSGlobalObject&, JSC::JSValue) + { + return std::nullopt; + } +}; + +template<typename ReturnType, typename T, bool enabled> +struct ConditionalSequenceConverter; + +template<typename ReturnType, typename T> +struct ConditionalSequenceConverter<ReturnType, T, true> { + static std::optional<ReturnType> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject* object, JSC::JSValue method) + { + return ReturnType(Converter<T>::convert(lexicalGlobalObject, object, method)); + } +}; + +template<typename ReturnType, typename T> +struct ConditionalSequenceConverter<ReturnType, T, false> { + static std::optional<ReturnType> convert(JSC::JSGlobalObject&, JSC::JSObject*, JSC::JSValue) + { + return std::nullopt; + } +}; + +namespace Detail { + +template<typename List, bool condition> +struct ConditionalFront; + +template<typename List> +struct ConditionalFront<List, true> { + using type = brigand::front<List>; +}; + +template<typename List> +struct ConditionalFront<List, false> { + using type = void; +}; + +} + +template<typename List, bool condition> +using ConditionalFront = typename Detail::ConditionalFront<List, condition>::type; + +template<typename... T> struct Converter<IDLUnion<T...>> : DefaultConverter<IDLUnion<T...>> { + using Type = IDLUnion<T...>; + using TypeList = typename Type::TypeList; + using ReturnType = typename Type::ImplementationType; + + using NumericTypeList = brigand::filter<TypeList, IsIDLNumber<brigand::_1>>; + static constexpr size_t numberOfNumericTypes = brigand::size<NumericTypeList>::value; + static_assert(numberOfNumericTypes == 0 || numberOfNumericTypes == 1, "There can be 0 or 1 numeric types in an IDLUnion."); + using NumericType = ConditionalFront<NumericTypeList, numberOfNumericTypes != 0>; + + using StringTypeList = brigand::filter<TypeList, IsIDLStringOrEnumeration<brigand::_1>>; + static constexpr size_t numberOfStringTypes = brigand::size<StringTypeList>::value; + static_assert(numberOfStringTypes == 0 || numberOfStringTypes == 1, "There can be 0 or 1 string types in an IDLUnion."); + using StringType = ConditionalFront<StringTypeList, numberOfStringTypes != 0>; + + using SequenceTypeList = brigand::filter<TypeList, IsIDLSequence<brigand::_1>>; + static constexpr size_t numberOfSequenceTypes = brigand::size<SequenceTypeList>::value; + static_assert(numberOfSequenceTypes == 0 || numberOfSequenceTypes == 1, "There can be 0 or 1 sequence types in an IDLUnion."); + using SequenceType = ConditionalFront<SequenceTypeList, numberOfSequenceTypes != 0>; + + using FrozenArrayTypeList = brigand::filter<TypeList, IsIDLFrozenArray<brigand::_1>>; + static constexpr size_t numberOfFrozenArrayTypes = brigand::size<FrozenArrayTypeList>::value; + static_assert(numberOfFrozenArrayTypes == 0 || numberOfFrozenArrayTypes == 1, "There can be 0 or 1 FrozenArray types in an IDLUnion."); + using FrozenArrayType = ConditionalFront<FrozenArrayTypeList, numberOfFrozenArrayTypes != 0>; + + using DictionaryTypeList = brigand::filter<TypeList, IsIDLDictionary<brigand::_1>>; + static constexpr size_t numberOfDictionaryTypes = brigand::size<DictionaryTypeList>::value; + static_assert(numberOfDictionaryTypes == 0 || numberOfDictionaryTypes == 1, "There can be 0 or 1 dictionary types in an IDLUnion."); + static constexpr bool hasDictionaryType = numberOfDictionaryTypes != 0; + using DictionaryType = ConditionalFront<DictionaryTypeList, hasDictionaryType>; + + using RecordTypeList = brigand::filter<TypeList, IsIDLRecord<brigand::_1>>; + static constexpr size_t numberOfRecordTypes = brigand::size<RecordTypeList>::value; + static_assert(numberOfRecordTypes == 0 || numberOfRecordTypes == 1, "There can be 0 or 1 record types in an IDLUnion."); + static constexpr bool hasRecordType = numberOfRecordTypes != 0; + using RecordType = ConditionalFront<RecordTypeList, hasRecordType>; + + using ObjectTypeList = brigand::filter<TypeList, std::is_same<IDLObject, brigand::_1>>; + static constexpr size_t numberOfObjectTypes = brigand::size<ObjectTypeList>::value; + static_assert(numberOfObjectTypes == 0 || numberOfObjectTypes == 1, "There can be 0 or 1 object types in an IDLUnion."); + static constexpr bool hasObjectType = numberOfObjectTypes != 0; + using ObjectType = ConditionalFront<ObjectTypeList, hasObjectType>; + + static constexpr bool hasAnyObjectType = (numberOfSequenceTypes + numberOfFrozenArrayTypes + numberOfDictionaryTypes + numberOfRecordTypes + numberOfObjectTypes) > 0; + + using InterfaceTypeList = brigand::filter<TypeList, IsIDLInterface<brigand::_1>>; + using TypedArrayTypeList = brigand::filter<TypeList, IsIDLTypedArray<brigand::_1>>; + + static ReturnType convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + // 1. If the union type includes a nullable type and V is null or undefined, then return the IDL value null. + constexpr bool hasNullType = brigand::any<TypeList, std::is_same<IDLNull, brigand::_1>>::value; + if (hasNullType) { + if (value.isUndefinedOrNull()) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, IDLNull, hasNullType>::convert(lexicalGlobalObject, value).value())); + } + + // 2. Let types be the flattened member types of the union type. + // NOTE: Union is expected to be pre-flattented. + + // 3. If V is null or undefined then: + if (hasDictionaryType) { + if (value.isUndefinedOrNull()) { + // 1. If types includes a dictionary type, then return the result of converting V to that dictionary type. + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::convert(lexicalGlobalObject, value).value())); + } + } + + // 4. If V is a platform object, then: + // 1. If types includes an interface type that V implements, then return the IDL value that is a reference to the object V. + // 2. If types includes object, then return the IDL value that is a reference to the object V. + // (FIXME: Add support for object and step 4.2) + if (brigand::any<TypeList, IsIDLInterface<brigand::_1>>::value) { + std::optional<ReturnType> returnValue; + brigand::for_each<InterfaceTypeList>([&](auto&& type) { + if (returnValue) + return; + + using Type = typename WTF::RemoveCVAndReference<decltype(type)>::type::type; + using ImplementationType = typename Type::ImplementationType; + using RawType = typename Type::RawType; + + auto castedValue = JSToWrappedOverloader<RawType>::toWrapped(lexicalGlobalObject, value); + if (!castedValue) + return; + + returnValue = ReturnType(ImplementationType(castedValue)); + }); + + if (returnValue) + return WTFMove(returnValue.value()); + } + + // FIXME: Add support for steps 5 & 6. + // + // 5. If V is a DOMException platform object, then: + // 1. If types includes DOMException or Error, then return the result of converting V to that type. + // 2 If types includes object, then return the IDL value that is a reference to the object V. + // + // 6. If Type(V) is Object and V has an [[ErrorData]] internal slot), then: + // 1. If types includes Error, then return the result of converting V to Error. + // 2. If types includes object, then return the IDL value that is a reference to the object V. + + // 7. If Type(V) is Object and V has an [[ArrayBufferData]] internal slot, then: + // 1. If types includes ArrayBuffer, then return the result of converting V to ArrayBuffer. + // 2. If types includes object, then return the IDL value that is a reference to the object V. + constexpr bool hasArrayBufferType = brigand::any<TypeList, IsIDLArrayBuffer<brigand::_1>>::value; + if (hasArrayBufferType || hasObjectType) { + auto arrayBuffer = (brigand::any<TypeList, IsIDLArrayBufferAllowShared<brigand::_1>>::value) ? JSC::JSArrayBuffer::toWrappedAllowShared(vm, value) : JSC::JSArrayBuffer::toWrapped(vm, value); + if (arrayBuffer) { + if (hasArrayBufferType) + return ConditionalReturner<ReturnType, hasArrayBufferType>::get(WTFMove(arrayBuffer)).value(); + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, ObjectType, hasObjectType>::convert(lexicalGlobalObject, value).value())); + } + } + + constexpr bool hasArrayBufferViewType = brigand::any<TypeList, IsIDLArrayBufferView<brigand::_1>>::value; + if (hasArrayBufferViewType || hasObjectType) { + auto arrayBufferView = (brigand::any<TypeList, IsIDLArrayBufferViewAllowShared<brigand::_1>>::value) ? JSC::JSArrayBufferView::toWrappedAllowShared(vm, value) : JSC::JSArrayBufferView::toWrapped(vm, value); + if (arrayBufferView) { + if (hasArrayBufferViewType) + return ConditionalReturner<ReturnType, hasArrayBufferViewType>::get(WTFMove(arrayBufferView)).value(); + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, ObjectType, hasObjectType>::convert(lexicalGlobalObject, value).value())); + } + } + + // 8. If Type(V) is Object and V has a [[DataView]] internal slot, then: + // 1. If types includes DataView, then return the result of converting V to DataView. + // 2. If types includes object, then return the IDL value that is a reference to the object V. + constexpr bool hasDataViewType = brigand::any<TypeList, std::is_same<IDLDataView, brigand::_1>>::value; + if (hasDataViewType || hasObjectType) { + auto dataView = JSC::JSDataView::toWrapped(vm, value); + if (dataView) { + if (hasDataViewType) + return ConditionalReturner<ReturnType, hasDataViewType>::get(WTFMove(dataView)).value(); + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, ObjectType, hasObjectType>::convert(lexicalGlobalObject, value).value())); + } + } + + // 9. If Type(V) is Object and V has a [[TypedArrayName]] internal slot, then: + // 1. If types includes a typed array type whose name is the value of V’s [[TypedArrayName]] internal slot, then return the result of converting V to that type. + // 2. If types includes object, then return the IDL value that is a reference to the object V. + // (FIXME: Add support for object and step 9.2) + constexpr bool hasTypedArrayType = brigand::any<TypeList, IsIDLTypedArray<brigand::_1>>::value; + if (hasTypedArrayType) { + std::optional<ReturnType> returnValue; + brigand::for_each<TypedArrayTypeList>([&](auto&& type) { + if (returnValue) + return; + + using Type = typename WTF::RemoveCVAndReference<decltype(type)>::type::type; + using ImplementationType = typename Type::ImplementationType; + using WrapperType = typename Converter<Type>::WrapperType; + + auto castedValue = (brigand::any<TypeList, IsIDLTypedArrayAllowShared<brigand::_1>>::value) ? WrapperType::toWrappedAllowShared(vm, value) : WrapperType::toWrapped(vm, value); + if (!castedValue) + return; + + returnValue = ReturnType(ImplementationType(castedValue)); + }); + + if (returnValue) + return WTFMove(returnValue.value()); + } + + // FIXME: Add support for step 10. + // + // 10. If IsCallable(V) is true, then: + // 1. If types includes a callback function type, then return the result of converting V to that callback function type. + // 2. If types includes object, then return the IDL value that is a reference to the object V. + + // 11. If V is any kind of object, then: + if (hasAnyObjectType) { + if (value.isCell()) { + JSC::JSCell* cell = value.asCell(); + if (cell->isObject()) { + auto object = asObject(value); + + // 1. If types includes a sequence type, then: + // 1. Let method be the result of GetMethod(V, @@iterator). + // 2. ReturnIfAbrupt(method). + // 3. If method is not undefined, return the result of creating a + // sequence of that type from V and method. + constexpr bool hasSequenceType = numberOfSequenceTypes != 0; + if (hasSequenceType) { + auto method = JSC::iteratorMethod(&lexicalGlobalObject, object); + RETURN_IF_EXCEPTION(scope, ReturnType()); + if (!method.isUndefined()) + RELEASE_AND_RETURN(scope, (ConditionalSequenceConverter<ReturnType, SequenceType, hasSequenceType>::convert(lexicalGlobalObject, object, method).value())); + } + + // 2. If types includes a frozen array type, then: + // 1. Let method be the result of GetMethod(V, @@iterator). + // 2. ReturnIfAbrupt(method). + // 3. If method is not undefined, return the result of creating a + // frozen array of that type from V and method. + constexpr bool hasFrozenArrayType = numberOfFrozenArrayTypes != 0; + if (hasFrozenArrayType) { + auto method = JSC::iteratorMethod(&lexicalGlobalObject, object); + RETURN_IF_EXCEPTION(scope, ReturnType()); + if (!method.isUndefined()) + RELEASE_AND_RETURN(scope, (ConditionalSequenceConverter<ReturnType, FrozenArrayType, hasFrozenArrayType>::convert(lexicalGlobalObject, object, method).value())); + } + + // 3. If types includes a dictionary type, then return the result of + // converting V to that dictionary type. + if (hasDictionaryType) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, DictionaryType, hasDictionaryType>::convert(lexicalGlobalObject, value).value())); + + // 4. If types includes a record type, then return the result of converting V to that record type. + if (hasRecordType) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, RecordType, hasRecordType>::convert(lexicalGlobalObject, value).value())); + + // 5. If types includes a callback interface type, then return the result of converting V to that interface type. + // (FIXME: Add support for callback interface type and step 12.5) + + // 6. If types includes object, then return the IDL value that is a reference to the object V. + if (hasObjectType) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, ObjectType, hasObjectType>::convert(lexicalGlobalObject, value).value())); + } + } + } + + // 12. If V is a Boolean value, then: + // 1. If types includes a boolean, then return the result of converting V to boolean. + constexpr bool hasBooleanType = brigand::any<TypeList, std::is_same<IDLBoolean, brigand::_1>>::value; + if (hasBooleanType) { + if (value.isBoolean()) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, IDLBoolean, hasBooleanType>::convert(lexicalGlobalObject, value).value())); + } + + // 13. If V is a Number value, then: + // 1. If types includes a numeric type, then return the result of converting V to that numeric type. + constexpr bool hasNumericType = brigand::size<NumericTypeList>::value != 0; + if (hasNumericType) { + if (value.isNumber()) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, NumericType, hasNumericType>::convert(lexicalGlobalObject, value).value())); + } + + // 14. If types includes a string type, then return the result of converting V to that type. + constexpr bool hasStringType = brigand::size<StringTypeList>::value != 0; + if (hasStringType) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, StringType, hasStringType>::convert(lexicalGlobalObject, value).value())); + + // 15. If types includes a numeric type, then return the result of converting V to that numeric type. + if (hasNumericType) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, NumericType, hasNumericType>::convert(lexicalGlobalObject, value).value())); + + // 16. If types includes a boolean, then return the result of converting V to boolean. + if (hasBooleanType) + RELEASE_AND_RETURN(scope, (ConditionalConverter<ReturnType, IDLBoolean, hasBooleanType>::convert(lexicalGlobalObject, value).value())); + + // 17. Throw a TypeError. + throwTypeError(&lexicalGlobalObject, scope); + return ReturnType(); + } +}; + +template<typename... T> struct JSConverter<IDLUnion<T...>> { + using Type = IDLUnion<T...>; + using TypeList = typename Type::TypeList; + using ImplementationType = typename Type::ImplementationType; + + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + using Sequence = brigand::make_sequence<brigand::ptrdiff_t<0>, std::variant_size<ImplementationType>::value>; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const ImplementationType& variant) + { + auto index = variant.index(); + + std::optional<JSC::JSValue> returnValue; + brigand::for_each<Sequence>([&](auto&& type) { + using I = typename WTF::RemoveCVAndReference<decltype(type)>::type::type; + if (I::value == index) { + ASSERT(!returnValue); + returnValue = toJS<brigand::at<TypeList, I>>(lexicalGlobalObject, globalObject, std::get<I::value>(variant)); + } + }); + + ASSERT(returnValue); + return returnValue.value(); + } +}; + +// BufferSource specialization. In WebKit, BufferSource is defined as IDLUnion<IDLArrayBufferView, IDLArrayBuffer> as a hack, and it is not compatible to +// annotation described in WebIDL. +template<> struct Converter<IDLAllowSharedAdaptor<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>> : DefaultConverter<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>> { + static auto convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) -> decltype(auto) + { + return Converter<IDLUnion<IDLAllowSharedAdaptor<IDLArrayBufferView>, IDLAllowSharedAdaptor<IDLArrayBuffer>>>::convert(lexicalGlobalObject, value); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertVariadic.h b/src/bun.js/bindings/webcore/JSDOMConvertVariadic.h new file mode 100644 index 000000000..dd16b1d66 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertVariadic.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016-2021 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" +#include "wtf/FixedVector.h" + +namespace WebCore { + +template<typename IDLType> +struct VariadicConverter { + using Item = typename IDLType::ImplementationType; + + static std::optional<Item> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto result = Converter<IDLType>::convert(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(scope, std::nullopt); + + return result; + } +}; + +template<typename IDLType> FixedVector<typename VariadicConverter<IDLType>::Item> convertVariadicArguments(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, size_t startIndex) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + + size_t length = callFrame.argumentCount(); + if (startIndex >= length) + return {}; + + FixedVector<typename VariadicConverter<IDLType>::Item> result(length - startIndex); + + size_t resultIndex = 0; + for (size_t i = startIndex; i < length; ++i) { + auto value = VariadicConverter<IDLType>::convert(lexicalGlobalObject, callFrame.uncheckedArgument(i)); + EXCEPTION_ASSERT_UNUSED(scope, !!scope.exception() == !value); + if (!value) + return {}; + result[resultIndex] = WTFMove(*value); + resultIndex++; + } + + return result; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMConvertWebGL.cpp b/src/bun.js/bindings/webcore/JSDOMConvertWebGL.cpp new file mode 100644 index 000000000..7d4576661 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertWebGL.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config.h" +#include "JSDOMConvertWebGL.h" + +#if ENABLE(WEBGL) + +#include "JSANGLEInstancedArrays.h" +#include "JSDOMConvertBufferSource.h" +#include "JSEXTBlendMinMax.h" +#include "JSEXTColorBufferFloat.h" +#include "JSEXTColorBufferHalfFloat.h" +#include "JSEXTFloatBlend.h" +#include "JSEXTFragDepth.h" +#include "JSEXTShaderTextureLOD.h" +#include "JSEXTTextureCompressionRGTC.h" +#include "JSEXTTextureFilterAnisotropic.h" +#include "JSEXTsRGB.h" +#include "JSKHRParallelShaderCompile.h" +#include "JSOESElementIndexUint.h" +#include "JSOESFBORenderMipmap.h" +#include "JSOESStandardDerivatives.h" +#include "JSOESTextureFloat.h" +#include "JSOESTextureFloatLinear.h" +#include "JSOESTextureHalfFloat.h" +#include "JSOESTextureHalfFloatLinear.h" +#include "JSOESVertexArrayObject.h" +#include "JSWebGLBuffer.h" +#include "JSWebGLColorBufferFloat.h" +#include "JSWebGLCompressedTextureASTC.h" +#include "JSWebGLCompressedTextureATC.h" +#include "JSWebGLCompressedTextureETC.h" +#include "JSWebGLCompressedTextureETC1.h" +#include "JSWebGLCompressedTexturePVRTC.h" +#include "JSWebGLCompressedTextureS3TC.h" +#include "JSWebGLCompressedTextureS3TCsRGB.h" +#include "JSWebGLDebugRendererInfo.h" +#include "JSWebGLDebugShaders.h" +#include "JSWebGLDepthTexture.h" +#include "JSWebGLDrawBuffers.h" +#include "JSWebGLFramebuffer.h" +#include "JSWebGLLoseContext.h" +#include "JSWebGLMultiDraw.h" +#include "JSWebGLProgram.h" +#include "JSWebGLRenderbuffer.h" +#include "JSWebGLSampler.h" +#include "JSWebGLTexture.h" +#include "JSWebGLTransformFeedback.h" +#include "JSWebGLVertexArrayObject.h" +#include "JSWebGLVertexArrayObjectOES.h" + +namespace WebCore { +using namespace JSC; + +// FIXME: This should use the IDLUnion JSConverter. +JSValue convertToJSValue(JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const WebGLAny& any) +{ + return WTF::switchOn( + any, + [](std::nullptr_t) -> JSValue { + return jsNull(); + }, + [](bool value) -> JSValue { + return jsBoolean(value); + }, + [](int value) -> JSValue { + return jsNumber(value); + }, + [](unsigned value) -> JSValue { + return jsNumber(value); + }, + [](long long value) -> JSValue { + return jsNumber(value); + }, + [](float value) -> JSValue { + return jsNumber(value); + }, + [&](const String& value) -> JSValue { + return jsStringWithCache(lexicalGlobalObject.vm(), value); + }, + [&](const Vector<bool>& values) -> JSValue { + MarkedArgumentBuffer list; + for (auto& value : values) + list.append(jsBoolean(value)); + RELEASE_ASSERT(!list.hasOverflowed()); + return constructArray(&globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), list); + }, + [&](const Vector<int>& values) -> JSValue { + MarkedArgumentBuffer list; + for (auto& value : values) + list.append(jsNumber(value)); + RELEASE_ASSERT(!list.hasOverflowed()); + return constructArray(&globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), list); + }, + [&](const Vector<unsigned>& values) -> JSValue { + MarkedArgumentBuffer list; + for (auto& value : values) + list.append(jsNumber(value)); + RELEASE_ASSERT(!list.hasOverflowed()); + return constructArray(&globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), list); + }, + [&](const RefPtr<Float32Array>& array) { + return toJS(&lexicalGlobalObject, &globalObject, array.get()); + }, + [&](const RefPtr<Int32Array>& array) { + return toJS(&lexicalGlobalObject, &globalObject, array.get()); + }, + [&](const RefPtr<Uint8Array>& array) { + return toJS(&lexicalGlobalObject, &globalObject, array.get()); + }, + [&](const RefPtr<Uint32Array>& array) { + return toJS(&lexicalGlobalObject, &globalObject, array.get()); + }, + [&](const RefPtr<WebGLBuffer>& buffer) { + return toJS(&lexicalGlobalObject, &globalObject, buffer.get()); + }, + [&](const RefPtr<WebGLFramebuffer>& buffer) { + return toJS(&lexicalGlobalObject, &globalObject, buffer.get()); + }, + [&](const RefPtr<WebGLProgram>& program) { + return toJS(&lexicalGlobalObject, &globalObject, program.get()); + }, + [&](const RefPtr<WebGLRenderbuffer>& buffer) { + return toJS(&lexicalGlobalObject, &globalObject, buffer.get()); + }, + [&](const RefPtr<WebGLTexture>& texture) { + return toJS(&lexicalGlobalObject, &globalObject, texture.get()); + }, + [&](const RefPtr<WebGLVertexArrayObjectOES>& array) { + return toJS(&lexicalGlobalObject, &globalObject, array.get()); + } +#if ENABLE(WEBGL2) + , + [&](const RefPtr<WebGLSampler>& sampler) { + return toJS(&lexicalGlobalObject, &globalObject, sampler.get()); + }, + [&](const RefPtr<WebGLTransformFeedback>& transformFeedback) { + return toJS(&lexicalGlobalObject, &globalObject, transformFeedback.get()); + }, + [&](const RefPtr<WebGLVertexArrayObject>& array) { + return toJS(&lexicalGlobalObject, &globalObject, array.get()); + } +#endif + ); +} + +JSValue convertToJSValue(JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, WebGLExtension& extension) +{ + switch (extension.getName()) { + case WebGLExtension::WebGLLoseContextName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLLoseContext&>(extension)); + case WebGLExtension::EXTShaderTextureLODName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTShaderTextureLOD&>(extension)); + case WebGLExtension::EXTTextureCompressionRGTCName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTTextureCompressionRGTC&>(extension)); + case WebGLExtension::EXTTextureFilterAnisotropicName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTTextureFilterAnisotropic&>(extension)); + case WebGLExtension::EXTsRGBName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTsRGB&>(extension)); + case WebGLExtension::EXTFragDepthName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTFragDepth&>(extension)); + case WebGLExtension::EXTBlendMinMaxName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTBlendMinMax&>(extension)); + case WebGLExtension::KHRParallelShaderCompileName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<KHRParallelShaderCompile&>(extension)); + case WebGLExtension::OESStandardDerivativesName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESStandardDerivatives&>(extension)); + case WebGLExtension::OESTextureFloatName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESTextureFloat&>(extension)); + case WebGLExtension::OESTextureFloatLinearName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESTextureFloatLinear&>(extension)); + case WebGLExtension::OESTextureHalfFloatName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESTextureHalfFloat&>(extension)); + case WebGLExtension::OESTextureHalfFloatLinearName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESTextureHalfFloatLinear&>(extension)); + case WebGLExtension::OESVertexArrayObjectName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESVertexArrayObject&>(extension)); + case WebGLExtension::OESElementIndexUintName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESElementIndexUint&>(extension)); + case WebGLExtension::OESFBORenderMipmapName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<OESFBORenderMipmap&>(extension)); + case WebGLExtension::WebGLDebugRendererInfoName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLDebugRendererInfo&>(extension)); + case WebGLExtension::WebGLDebugShadersName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLDebugShaders&>(extension)); + case WebGLExtension::WebGLCompressedTextureATCName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLCompressedTextureATC&>(extension)); + case WebGLExtension::WebGLCompressedTextureETCName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLCompressedTextureETC&>(extension)); + case WebGLExtension::WebGLCompressedTextureETC1Name: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLCompressedTextureETC1&>(extension)); + case WebGLExtension::WebGLCompressedTexturePVRTCName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLCompressedTexturePVRTC&>(extension)); + case WebGLExtension::WebGLCompressedTextureS3TCName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLCompressedTextureS3TC&>(extension)); + case WebGLExtension::WebGLCompressedTextureS3TCsRGBName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLCompressedTextureS3TCsRGB&>(extension)); + case WebGLExtension::WebGLCompressedTextureASTCName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLCompressedTextureASTC&>(extension)); + case WebGLExtension::WebGLDepthTextureName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLDepthTexture&>(extension)); + case WebGLExtension::WebGLDrawBuffersName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLDrawBuffers&>(extension)); + case WebGLExtension::ANGLEInstancedArraysName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<ANGLEInstancedArrays&>(extension)); + case WebGLExtension::EXTColorBufferHalfFloatName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTColorBufferHalfFloat&>(extension)); + case WebGLExtension::EXTFloatBlendName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTFloatBlend&>(extension)); + case WebGLExtension::WebGLColorBufferFloatName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLColorBufferFloat&>(extension)); + case WebGLExtension::EXTColorBufferFloatName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<EXTColorBufferFloat&>(extension)); + case WebGLExtension::WebGLMultiDrawName: + return toJS(&lexicalGlobalObject, &globalObject, static_cast<WebGLMultiDraw&>(extension)); + } + ASSERT_NOT_REACHED(); + return jsNull(); +} + +} + +#endif diff --git a/src/bun.js/bindings/webcore/JSDOMConvertWebGL.h b/src/bun.js/bindings/webcore/JSDOMConvertWebGL.h new file mode 100644 index 000000000..ae8f7e688 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertWebGL.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 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 + +#if ENABLE(WEBGL) + +#include "IDLTypes.h" +#include "JSDOMConvertBase.h" + +namespace WebCore { + +JSC::JSValue convertToJSValue(JSC::JSGlobalObject&, JSDOMGlobalObject&, const WebGLAny&); +JSC::JSValue convertToJSValue(JSC::JSGlobalObject&, JSDOMGlobalObject&, WebGLExtension&); + +inline JSC::JSValue convertToJSValue(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, WebGLExtension* extension) +{ + if (!extension) + return JSC::jsNull(); + return convertToJSValue(lexicalGlobalObject, globalObject, *extension); +} + +template<> struct JSConverter<IDLWebGLAny> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const WebGLAny& value) + { + return convertToJSValue(lexicalGlobalObject, globalObject, value); + } +}; + +template<> struct JSConverter<IDLWebGLExtension> { + static constexpr bool needsState = true; + static constexpr bool needsGlobalObject = true; + + template <typename T> + static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const T& value) + { + return convertToJSValue(lexicalGlobalObject, globalObject, Detail::getPtrOrRef(value)); + } +}; + +} // namespace WebCore + +#endif diff --git a/src/bun.js/bindings/webcore/JSDOMConvertXPathNSResolver.h b/src/bun.js/bindings/webcore/JSDOMConvertXPathNSResolver.h new file mode 100644 index 000000000..6c48a072a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMConvertXPathNSResolver.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 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 "IDLTypes.h" +#include "JSDOMConvertBase.h" + +#include "JSCustomXPathNSResolver.h" +#include "JSXPathNSResolver.h" + +namespace WebCore { + +template<> struct Converter<IDLInterface<XPathNSResolver>> : DefaultConverter<IDLInterface<XPathNSResolver>> { + template<typename ExceptionThrower = DefaultExceptionThrower> + static RefPtr<XPathNSResolver> convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower()) + { + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + if (!value.isObject()) { + exceptionThrower(lexicalGlobalObject, scope); + return nullptr; + } + + auto object = asObject(value); + if (object->inherits<JSXPathNSResolver>()) + return &JSC::jsCast<JSXPathNSResolver*>(object)->wrapped(); + + return JSCustomXPathNSResolver::create(vm, object); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMException.cpp b/src/bun.js/bindings/webcore/JSDOMException.cpp new file mode 100644 index 000000000..5dde2de4e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMException.cpp @@ -0,0 +1,381 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "root.h" + +#include "JSDOMException.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include "JavaScriptCore/FunctionPrototype.h" +#include "JavaScriptCore/HeapAnalyzer.h" + +#include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" +#include "JavaScriptCore/SlotVisitorMacros.h" +#include "JavaScriptCore/SubspaceInlines.h" +#include "wtf/GetPtr.h" +#include "wtf/PointerPreparations.h" +#include "wtf/URL.h" + +namespace WebCore { +using namespace JSC; + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsDOMExceptionConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMException_code); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMException_name); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMException_message); + +class JSDOMExceptionPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSDOMExceptionPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSDOMExceptionPrototype* ptr = new (NotNull, JSC::allocateCell<JSDOMExceptionPrototype>(vm)) JSDOMExceptionPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDOMExceptionPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSDOMExceptionPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDOMExceptionPrototype, JSDOMExceptionPrototype::Base); + +using JSDOMExceptionDOMConstructor = JSDOMConstructor<JSDOMException>; + +/* Hash table for constructor */ + +static const HashTableValue JSDOMExceptionConstructorTableValues[] = { + { "INDEX_SIZE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } }, + { "DOMSTRING_SIZE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } }, + { "HIERARCHY_REQUEST_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } }, + { "WRONG_DOCUMENT_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(4) } }, + { "INVALID_CHARACTER_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(5) } }, + { "NO_DATA_ALLOWED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(6) } }, + { "NO_MODIFICATION_ALLOWED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(7) } }, + { "NOT_FOUND_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(8) } }, + { "NOT_SUPPORTED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(9) } }, + { "INUSE_ATTRIBUTE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(10) } }, + { "INVALID_STATE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(11) } }, + { "SYNTAX_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(12) } }, + { "INVALID_MODIFICATION_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(13) } }, + { "NAMESPACE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(14) } }, + { "INVALID_ACCESS_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(15) } }, + { "VALIDATION_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(16) } }, + { "TYPE_MISMATCH_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(17) } }, + { "SECURITY_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(18) } }, + { "NETWORK_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(19) } }, + { "ABORT_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(20) } }, + { "URL_MISMATCH_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(21) } }, + { "QUOTA_EXCEEDED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(22) } }, + { "TIMEOUT_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(23) } }, + { "INVALID_NODE_TYPE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(24) } }, + { "DATA_CLONE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(25) } }, +}; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSDOMExceptionDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSDOMExceptionDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->argument(0); + auto message = argument0.value().isUndefined() ? emptyString() : convert<IDLDOMString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto name = argument1.value().isUndefined() ? "Error"_s : convert<IDLDOMString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = DOMException::create(WTFMove(message), WTFMove(name)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<DOMException>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<DOMException>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSDOMExceptionDOMConstructorConstruct, JSDOMExceptionDOMConstructor::construct); + +template<> const ClassInfo JSDOMExceptionDOMConstructor::s_info = { "DOMException"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMExceptionDOMConstructor) }; + +template<> JSValue JSDOMExceptionDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSDOMExceptionDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "DOMException"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSDOMException::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); + reifyStaticProperties(vm, JSDOMException::info(), JSDOMExceptionConstructorTableValues, *this); +} + +/* Hash table for prototype */ + +static const HashTableValue JSDOMExceptionPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMExceptionConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "code"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMException_code), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "name"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMException_name), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "message"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMException_message), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "INDEX_SIZE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } }, + { "DOMSTRING_SIZE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } }, + { "HIERARCHY_REQUEST_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } }, + { "WRONG_DOCUMENT_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(4) } }, + { "INVALID_CHARACTER_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(5) } }, + { "NO_DATA_ALLOWED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(6) } }, + { "NO_MODIFICATION_ALLOWED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(7) } }, + { "NOT_FOUND_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(8) } }, + { "NOT_SUPPORTED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(9) } }, + { "INUSE_ATTRIBUTE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(10) } }, + { "INVALID_STATE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(11) } }, + { "SYNTAX_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(12) } }, + { "INVALID_MODIFICATION_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(13) } }, + { "NAMESPACE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(14) } }, + { "INVALID_ACCESS_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(15) } }, + { "VALIDATION_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(16) } }, + { "TYPE_MISMATCH_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(17) } }, + { "SECURITY_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(18) } }, + { "NETWORK_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(19) } }, + { "ABORT_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(20) } }, + { "URL_MISMATCH_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(21) } }, + { "QUOTA_EXCEEDED_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(22) } }, + { "TIMEOUT_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(23) } }, + { "INVALID_NODE_TYPE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(24) } }, + { "DATA_CLONE_ERR"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(25) } }, +}; + +const ClassInfo JSDOMExceptionPrototype::s_info = { "DOMException"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMExceptionPrototype) }; + +void JSDOMExceptionPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSDOMException::info(), JSDOMExceptionPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSDOMException::s_info = { "DOMException"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMException) }; + +JSDOMException::JSDOMException(Structure* structure, JSDOMGlobalObject& globalObject, Ref<DOMException>&& impl) + : JSDOMWrapper<DOMException>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSDOMException::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, DOMException>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSDOMException::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSDOMExceptionPrototype::create(vm, &globalObject, JSDOMExceptionPrototype::createStructure(vm, &globalObject, globalObject.errorPrototype())); +} + +JSObject* JSDOMException::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSDOMException>(vm, globalObject); +} + +JSValue JSDOMException::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSDOMExceptionDOMConstructor, DOMConstructorID::DOMException>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSDOMException::destroy(JSC::JSCell* cell) +{ + JSDOMException* thisObject = static_cast<JSDOMException*>(cell); + thisObject->JSDOMException::~JSDOMException(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMExceptionConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSDOMExceptionPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSDOMException::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsDOMException_codeGetter(JSGlobalObject& lexicalGlobalObject, JSDOMException& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedShort>(lexicalGlobalObject, throwScope, impl.legacyCode()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMException_code, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMException>::get<jsDOMException_codeGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsDOMException_nameGetter(JSGlobalObject& lexicalGlobalObject, JSDOMException& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.name()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMException_name, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMException>::get<jsDOMException_nameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsDOMException_messageGetter(JSGlobalObject& lexicalGlobalObject, JSDOMException& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.message()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMException_message, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMException>::get<jsDOMException_messageGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +JSC::GCClient::IsoSubspace* JSDOMException::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSDOMException, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForDOMException.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForDOMException = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForDOMException.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForDOMException = WTFMove(space); }); +} + +void JSDOMException::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSDOMException*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + // if (thisObject->scriptExecutionContext()) + // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSDOMExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSDOMExceptionOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsDOMException = static_cast<JSDOMException*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsDOMException->wrapped(), jsDOMException); +} + +// #if ENABLE(BINDING_INTEGRITY) +// #if PLATFORM(WIN) +// #pragma warning(disable : 4483) +// extern "C" { +// extern void (*const __identifier("??_7DOMException@WebCore@@6B@")[])(); +// } +// #else +// extern "C" { +// extern void* _ZTVN7WebCore12DOMExceptionE[]; +// } +// #endif +// #endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<DOMException>&& impl) +{ + + // if constexpr (std::is_polymorphic_v<DOMException>) { + // #if ENABLE(BINDING_INTEGRITY) + // const void* actualVTablePointer = getVTablePointer(impl.ptr()); + // #if PLATFORM(WIN) + // void* expectedVTablePointer = __identifier("??_7DOMException@WebCore@@6B@"); + // #else + // void* expectedVTablePointer = &_ZTVN7WebCore12DOMExceptionE[2]; + // #endif + + // // If you hit this assertion you either have a use after free bug, or + // // DOMException has subclasses. If DOMException has subclasses that get passed + // // to toJS() we currently require DOMException you to opt out of binding hardening + // // by adding the SkipVTableValidation attribute to the interface IDL definition + // RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); + // #endif + // } + return createWrapper<DOMException>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, DOMException& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +DOMException* JSDOMException::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSDOMException*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, DOMException*) +{ + static NeverDestroyed<JSDOMExceptionOwner> owner; + return &owner.get(); +} + +} diff --git a/src/bun.js/bindings/webcore/JSDOMException.h b/src/bun.js/bindings/webcore/JSDOMException.h new file mode 100644 index 000000000..7c20a5745 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMException.h @@ -0,0 +1,93 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "root.h" + +#include "DOMException.h" +#include "JSDOMWrapper.h" +#include "JavaScriptCore/ErrorPrototype.h" +#include "wtf/NeverDestroyed.h" + +namespace WebCore { + +class JSDOMException : public JSDOMWrapper<DOMException> { +public: + using Base = JSDOMWrapper<DOMException>; + static JSDOMException* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<DOMException>&& impl) + { + JSDOMException* ptr = new (NotNull, JSC::allocateCell<JSDOMException>(globalObject->vm())) JSDOMException(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static DOMException* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +protected: + JSDOMException(JSC::Structure*, JSDOMGlobalObject&, Ref<DOMException>&&); + + void finishCreation(JSC::VM&); +}; + +class JSDOMExceptionOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, DOMException*); + +inline void* wrapperKey(DOMException* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, DOMException&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, DOMException* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<DOMException>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<DOMException>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<DOMException> { + using WrapperClass = JSDOMException; + using ToWrappedReturnType = DOMException*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMGlobalObjectInlines.h b/src/bun.js/bindings/webcore/JSDOMGlobalObjectInlines.h new file mode 100644 index 000000000..313b14aa2 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMGlobalObjectInlines.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 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. + * + */ + +#pragma once + +#include "DOMConstructors.h" +#include "JSDOMGlobalObject.h" + +namespace WebCore { + +template<class ConstructorClass, DOMConstructorID constructorID> +inline JSC::JSObject* getDOMConstructor(JSC::VM& vm, const Zig::GlobalObject& globalObject) +{ + // No locking is necessary unless we need to add a new constructor to Zig::GlobalObject::constructors(). + if (JSC::JSObject* constructor = globalObject.constructors().array()[static_cast<unsigned>(constructorID)].get()) + return constructor; + JSC::JSObject* constructor = ConstructorClass::create(vm, ConstructorClass::createStructure(vm, const_cast<Zig::GlobalObject&>(globalObject), ConstructorClass::prototypeForStructure(vm, globalObject)), const_cast<Zig::GlobalObject&>(globalObject)); + ASSERT(!globalObject.constructors().array()[static_cast<unsigned>(constructorID)].get()); + Zig::GlobalObject& mutableGlobalObject = const_cast<Zig::GlobalObject&>(globalObject); + mutableGlobalObject.constructors().array()[static_cast<unsigned>(constructorID)].set(vm, &globalObject, constructor); + return constructor; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMGuardedObject.cpp b/src/bun.js/bindings/webcore/JSDOMGuardedObject.cpp new file mode 100644 index 000000000..76fc86415 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMGuardedObject.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017-2021 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. + */ + +#include "config.h" +#include "JSDOMGuardedObject.h" + + +namespace WebCore { +using namespace JSC; + +DOMGuardedObject::DOMGuardedObject(JSDOMGlobalObject& globalObject, JSCell& guarded) + : ActiveDOMCallback(globalObject.scriptExecutionContext()) + , m_guarded(&guarded) + , m_globalObject(&globalObject) +{ + globalObject.vm().writeBarrier(&globalObject, &guarded); + if (globalObject.vm().heap.mutatorShouldBeFenced()) { + Locker locker { globalObject.gcLock() }; + globalObject.guardedObjects().add(this); + return; + } + globalObject.guardedObjects(NoLockingNecessary).add(this); +} + +DOMGuardedObject::~DOMGuardedObject() +{ + clear(); +} + +void DOMGuardedObject::clear() +{ + ASSERT(!m_guarded || m_globalObject); + removeFromGlobalObject(); + m_guarded.clear(); + m_globalObject.clear(); +} + +void DOMGuardedObject::removeFromGlobalObject() +{ + if (!m_guarded || !m_globalObject) + return; + + if (m_globalObject->vm().heap.mutatorShouldBeFenced()) { + Locker locker { m_globalObject->gcLock() }; + m_globalObject->guardedObjects().remove(this); + } else + m_globalObject->guardedObjects(NoLockingNecessary).remove(this); +} + +void DOMGuardedObject::contextDestroyed() +{ + ActiveDOMCallback::contextDestroyed(); + clear(); +} + +} diff --git a/src/bun.js/bindings/webcore/JSDOMGuardedObject.h b/src/bun.js/bindings/webcore/JSDOMGuardedObject.h new file mode 100644 index 000000000..cf0887c32 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMGuardedObject.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017-2021 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 "ActiveDOMCallback.h" +#include "JSDOMGlobalObject.h" +#include <JavaScriptCore/HeapInlines.h> +#include <JavaScriptCore/JSCell.h> +#include <JavaScriptCore/SlotVisitorInlines.h> +#include <JavaScriptCore/StrongInlines.h> + +namespace WebCore { + +class WEBCORE_EXPORT DOMGuardedObject : public RefCounted<DOMGuardedObject>, public ActiveDOMCallback { +public: + ~DOMGuardedObject(); + + bool isSuspended() const { return !m_guarded || !canInvokeCallback(); } // The wrapper world has gone away or active DOM objects have been suspended. + + template<typename Visitor> void visitAggregate(Visitor& visitor) { visitor.append(m_guarded); } + + JSC::JSValue guardedObject() const { return m_guarded.get(); } + JSDOMGlobalObject* globalObject() const { return m_globalObject.get(); } + + void clear(); + +protected: + DOMGuardedObject(JSDOMGlobalObject&, JSC::JSCell&); + + void contextDestroyed(); + bool isEmpty() const { return !m_guarded; } + + JSC::Weak<JSC::JSCell> m_guarded; + JSC::Weak<JSDOMGlobalObject> m_globalObject; + +private: + void removeFromGlobalObject(); +}; + +template<typename T> class DOMGuarded : public DOMGuardedObject { +protected: + DOMGuarded(JSDOMGlobalObject& globalObject, T& guarded) + : DOMGuardedObject(globalObject, guarded) + { + } + T* guarded() const { return JSC::jsDynamicCast<T*>(guardedObject()); } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMIterator.cpp b/src/bun.js/bindings/webcore/JSDOMIterator.cpp new file mode 100644 index 000000000..0bc957e17 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMIterator.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 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 "JSDOMIterator.h" + +#include <JavaScriptCore/ArrayPrototype.h> +#include <JavaScriptCore/BuiltinNames.h> + +namespace WebCore { + +void addValueIterableMethods(JSC::JSGlobalObject& globalObject, JSC::JSObject& prototype) +{ + JSC::ArrayPrototype* arrayPrototype = globalObject.arrayPrototype(); + ASSERT(arrayPrototype); + + JSC::JSGlobalObject* lexicalGlobalObject = &globalObject; + ASSERT(lexicalGlobalObject); + JSC::VM& vm = lexicalGlobalObject->vm(); + + auto copyProperty = [&](const JSC::Identifier& arrayIdentifier, const JSC::Identifier& otherIdentifier, unsigned attributes = 0) { + JSC::JSValue value = arrayPrototype->getDirect(vm, arrayIdentifier); + ASSERT(value); + prototype.putDirect(vm, otherIdentifier, value, attributes); + }; + + copyProperty(vm.propertyNames->builtinNames().entriesPrivateName(), vm.propertyNames->builtinNames().entriesPublicName()); + copyProperty(vm.propertyNames->builtinNames().forEachPrivateName(), vm.propertyNames->builtinNames().forEachPublicName()); + copyProperty(vm.propertyNames->builtinNames().keysPrivateName(), vm.propertyNames->builtinNames().keysPublicName()); + copyProperty(vm.propertyNames->builtinNames().valuesPrivateName(), vm.propertyNames->builtinNames().valuesPublicName()); +} + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSDOMIterator.h b/src/bun.js/bindings/webcore/JSDOMIterator.h new file mode 100644 index 000000000..b9740d4f9 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMIterator.h @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2016 Canon, 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 + * 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 CANON 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 CANON 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. + */ + +#pragma once + +#include "JSDOMConvert.h" +#include <JavaScriptCore/IteratorPrototype.h> +#include <JavaScriptCore/PropertySlot.h> +#include <type_traits> + +namespace WebCore { + +void addValueIterableMethods(JSC::JSGlobalObject&, JSC::JSObject&); + +enum class JSDOMIteratorType { Set, + Map }; + +// struct IteratorTraits { +// static constexpr JSDOMIteratorType type = [Map|Set]; +// using KeyType = [IDLType|void]; +// using ValueType = [IDLType]; +// }; + +template<typename T, typename U = void> using EnableIfMap = typename std::enable_if<T::type == JSDOMIteratorType::Map, U>::type; +template<typename T, typename U = void> using EnableIfSet = typename std::enable_if<T::type == JSDOMIteratorType::Set, U>::type; + +template<typename JSWrapper, typename IteratorTraits> class JSDOMIteratorPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + using DOMWrapped = typename JSWrapper::DOMWrapped; + + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDOMIteratorPrototype, Base); + return &vm.plainObjectSpace(); + } + + static JSDOMIteratorPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDOMIteratorPrototype, JSDOMIteratorPrototype::Base); + JSDOMIteratorPrototype* prototype = new (NotNull, JSC::allocateCell<JSDOMIteratorPrototype>(vm)) JSDOMIteratorPrototype(vm, structure); + prototype->finishCreation(vm, globalObject); + return prototype; + } + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + + static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES next(JSC::JSGlobalObject*, JSC::CallFrame*); + +private: + JSDOMIteratorPrototype(JSC::VM& vm, JSC::Structure* structure) + : Base(vm, structure) + { + } + + void finishCreation(JSC::VM&, JSC::JSGlobalObject*); +}; + +using IterationKind = JSC::IterationKind; + +template<typename JSWrapper, typename IteratorTraits> class JSDOMIteratorBase : public JSDOMObject { +public: + using Base = JSDOMObject; + + using Wrapper = JSWrapper; + using Traits = IteratorTraits; + + using DOMWrapped = typename Wrapper::DOMWrapped; + using Prototype = JSDOMIteratorPrototype<Wrapper, Traits>; + + DECLARE_INFO; + + static Prototype* createPrototype(JSC::VM& vm, JSC::JSGlobalObject& globalObject) + { + return Prototype::create(vm, &globalObject, Prototype::createStructure(vm, &globalObject, globalObject.iteratorPrototype())); + } + + JSC::JSValue next(JSC::JSGlobalObject&); + + static void createStructure(JSC::VM&, JSC::JSGlobalObject*, JSC::JSValue); // Make use of createStructure for this compile-error. + +protected: + JSDOMIteratorBase(JSC::Structure* structure, JSWrapper& iteratedObject, IterationKind kind) + : Base(structure, *iteratedObject.globalObject()) + , m_iterator(iteratedObject.wrapped().createIterator()) + , m_kind(kind) + { + } + + template<typename IteratorValue, typename T = Traits> EnableIfMap<T, JSC::JSValue> asJS(JSC::JSGlobalObject&, IteratorValue&); + template<typename IteratorValue, typename T = Traits> EnableIfSet<T, JSC::JSValue> asJS(JSC::JSGlobalObject&, IteratorValue&); + + static void destroy(JSC::JSCell*); + + std::optional<typename DOMWrapped::Iterator> m_iterator; + IterationKind m_kind; +}; + +inline JSC::JSValue jsPair(JSC::JSGlobalObject&, JSDOMGlobalObject& globalObject, JSC::JSValue value1, JSC::JSValue value2) +{ + JSC::MarkedArgumentBuffer arguments; + arguments.append(value1); + arguments.append(value2); + ASSERT(!arguments.hasOverflowed()); + return constructArray(&globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), arguments); +} + +template<typename FirstType, typename SecondType, typename T, typename U> +inline JSC::JSValue jsPair(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const T& value1, const U& value2) +{ + return jsPair(lexicalGlobalObject, globalObject, toJS<FirstType>(lexicalGlobalObject, globalObject, value1), toJS<SecondType>(lexicalGlobalObject, globalObject, value2)); +} + +template<typename JSIterator> JSC::JSValue iteratorCreate(typename JSIterator::Wrapper&, IterationKind); +template<typename JSIterator> JSC::JSValue iteratorForEach(JSC::JSGlobalObject&, JSC::CallFrame&, typename JSIterator::Wrapper&); + +template<typename JSIterator> JSC::JSValue iteratorCreate(typename JSIterator::Wrapper& thisObject, IterationKind kind) +{ + ASSERT(thisObject.globalObject()); + JSDOMGlobalObject& globalObject = *thisObject.globalObject(); + return JSIterator::create(globalObject.vm(), getDOMStructure<JSIterator>(globalObject.vm(), globalObject), thisObject, kind); +} + +template<typename JSWrapper, typename IteratorTraits> +template<typename IteratorValue, typename T> inline EnableIfMap<T, JSC::JSValue> JSDOMIteratorBase<JSWrapper, IteratorTraits>::asJS(JSC::JSGlobalObject& lexicalGlobalObject, IteratorValue& value) +{ + ASSERT(value); + + switch (m_kind) { + case IterationKind::Keys: + return toJS<typename Traits::KeyType>(lexicalGlobalObject, *globalObject(), value->key); + case IterationKind::Values: + return toJS<typename Traits::ValueType>(lexicalGlobalObject, *globalObject(), value->value); + case IterationKind::Entries: + return jsPair<typename Traits::KeyType, typename Traits::ValueType>(lexicalGlobalObject, *globalObject(), value->key, value->value); + }; + + ASSERT_NOT_REACHED(); + return {}; +} + +template<typename JSWrapper, typename IteratorTraits> +template<typename IteratorValue, typename T> inline EnableIfSet<T, JSC::JSValue> JSDOMIteratorBase<JSWrapper, IteratorTraits>::asJS(JSC::JSGlobalObject& lexicalGlobalObject, IteratorValue& value) +{ + ASSERT(value); + + auto globalObject = this->globalObject(); + auto result = toJS<typename Traits::ValueType>(lexicalGlobalObject, *globalObject, value); + + switch (m_kind) { + case IterationKind::Keys: + case IterationKind::Values: + return result; + case IterationKind::Entries: + return jsPair(lexicalGlobalObject, *globalObject, result, result); + }; + + ASSERT_NOT_REACHED(); + return {}; +} + +template<typename JSIterator, typename IteratorValue> EnableIfMap<typename JSIterator::Traits> appendForEachArguments(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value) +{ + ASSERT(value); + arguments.append(toJS<typename JSIterator::Traits::ValueType>(lexicalGlobalObject, globalObject, value->value)); + arguments.append(toJS<typename JSIterator::Traits::KeyType>(lexicalGlobalObject, globalObject, value->key)); +} + +template<typename JSIterator, typename IteratorValue> EnableIfSet<typename JSIterator::Traits> appendForEachArguments(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, JSC::MarkedArgumentBuffer& arguments, IteratorValue& value) +{ + ASSERT(value); + auto argument = toJS<typename JSIterator::Traits::ValueType>(lexicalGlobalObject, globalObject, value); + arguments.append(argument); + arguments.append(argument); +} + +template<typename JSIterator> JSC::JSValue iteratorForEach(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, typename JSIterator::Wrapper& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + JSC::JSValue callback = callFrame.argument(0); + JSC::JSValue thisValue = callFrame.argument(1); + + auto callData = JSC::getCallData(callback); + if (callData.type == JSC::CallData::Type::None) + return throwTypeError(&lexicalGlobalObject, scope, "Cannot call callback"_s); + + auto iterator = thisObject.wrapped().createIterator(); + while (auto value = iterator.next()) { + JSC::MarkedArgumentBuffer arguments; + appendForEachArguments<JSIterator>(lexicalGlobalObject, *thisObject.globalObject(), arguments, value); + arguments.append(&thisObject); + if (UNLIKELY(arguments.hasOverflowed())) { + throwOutOfMemoryError(&lexicalGlobalObject, scope); + return {}; + } + JSC::call(&lexicalGlobalObject, callback, callData, thisValue, arguments); + if (UNLIKELY(scope.exception())) + break; + } + return JSC::jsUndefined(); +} + +template<typename JSWrapper, typename IteratorTraits> +void JSDOMIteratorBase<JSWrapper, IteratorTraits>::destroy(JSCell* cell) +{ + JSDOMIteratorBase<JSWrapper, IteratorTraits>* thisObject = static_cast<JSDOMIteratorBase<JSWrapper, IteratorTraits>*>(cell); + thisObject->JSDOMIteratorBase<JSWrapper, IteratorTraits>::~JSDOMIteratorBase(); +} + +template<typename JSWrapper, typename IteratorTraits> +JSC::JSValue JSDOMIteratorBase<JSWrapper, IteratorTraits>::next(JSC::JSGlobalObject& lexicalGlobalObject) +{ + if (m_iterator) { + auto iteratorValue = m_iterator->next(); + if (iteratorValue) + return createIteratorResultObject(&lexicalGlobalObject, asJS(lexicalGlobalObject, iteratorValue), false); + m_iterator = std::nullopt; + } + return createIteratorResultObject(&lexicalGlobalObject, JSC::jsUndefined(), true); +} + +template<typename JSWrapper, typename IteratorTraits> +JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSDOMIteratorPrototype<JSWrapper, IteratorTraits>::next(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) +{ + JSC::VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto iterator = JSC::jsDynamicCast<JSDOMIteratorBase<JSWrapper, IteratorTraits>*>(callFrame->thisValue()); + if (!iterator) + return JSC::JSValue::encode(throwTypeError(globalObject, scope, "Cannot call next() on a non-Iterator object"_s)); + + return JSC::JSValue::encode(iterator->next(*globalObject)); +} + +template<typename JSWrapper, typename IteratorTraits> +void JSDOMIteratorPrototype<JSWrapper, IteratorTraits>::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->next, next, 0, 0, JSC::NoIntrinsic); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSDOMOperation.h b/src/bun.js/bindings/webcore/JSDOMOperation.h new file mode 100644 index 000000000..c3f6d0451 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMOperation.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003-2020 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * Copyright (C) 2012 Ericsson AB. All rights reserved. + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMCastThisValue.h" +#include "JSDOMExceptionHandling.h" + +namespace WebCore { + +template<typename JSClass> +class IDLOperation { +public: + using ClassParameter = JSClass*; + using Operation = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*, ClassParameter); + using StaticOperation = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*); + + // FIXME: Remove this after FunctionCallResolveNode is fixed not to pass resolved scope as |this| value. + // https://bugs.webkit.org/show_bug.cgi?id=225397 + static JSClass* cast(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame) + { + if constexpr (std::is_base_of_v<JSDOMGlobalObject, JSClass>) + return castThisValue<JSClass>(lexicalGlobalObject, callFrame.thisValue().toThis(&lexicalGlobalObject, JSC::ECMAMode::strict())); + else + return castThisValue<JSClass>(lexicalGlobalObject, callFrame.thisValue()); + } + + template<Operation operation, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static JSC::EncodedJSValue call(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, const char* operationName) + { + auto throwScope = DECLARE_THROW_SCOPE(JSC::getVM(&lexicalGlobalObject)); + + auto* thisObject = cast(lexicalGlobalObject, callFrame); + if constexpr (shouldThrow != CastedThisErrorBehavior::Assert) { + if (UNLIKELY(!thisObject)) + return throwThisTypeError(lexicalGlobalObject, throwScope, JSClass::info()->className, operationName); + } else + ASSERT(thisObject); + + ASSERT_GC_OBJECT_INHERITS(thisObject, JSClass::info()); + + // FIXME: We should refactor the binding generated code to use references for lexicalGlobalObject and thisObject. + RELEASE_AND_RETURN(throwScope, (operation(&lexicalGlobalObject, &callFrame, thisObject))); + } + + template<StaticOperation operation, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::Throw> + static JSC::EncodedJSValue callStatic(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, const char*) + { + // FIXME: We should refactor the binding generated code to use references for lexicalGlobalObject. + return operation(&lexicalGlobalObject, &callFrame); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMOperationReturningPromise.h b/src/bun.js/bindings/webcore/JSDOMOperationReturningPromise.h new file mode 100644 index 000000000..c4d1513ad --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMOperationReturningPromise.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2003-2020 Apple Inc. All rights reserved. + * Copyright (C) 2007 Samuel Weinig <sam@webkit.org> + * Copyright (C) 2009 Google, Inc. All rights reserved. + * Copyright (C) 2012 Ericsson AB. All rights reserved. + * Copyright (C) 2013 Michael Pruett <michael@68k.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "JSDOMOperation.h" +#include "JSDOMPromiseDeferred.h" + +namespace WebCore { + +template<typename JSClass> +class IDLOperationReturningPromise { +public: + using ClassParameter = JSClass*; + using Operation = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*, ClassParameter, Ref<DeferredPromise>&&); + using StaticOperation = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*, Ref<DeferredPromise>&&); + + template<Operation operation, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::RejectPromise> + static JSC::EncodedJSValue call(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, const char* operationName) + { + return JSC::JSValue::encode(callPromiseFunction(lexicalGlobalObject, callFrame, [&operationName] (JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, Ref<DeferredPromise>&& promise) { + auto* thisObject = IDLOperation<JSClass>::cast(lexicalGlobalObject, callFrame); + if constexpr (shouldThrow != CastedThisErrorBehavior::Assert) { + if (UNLIKELY(!thisObject)) + return rejectPromiseWithThisTypeError(promise.get(), JSClass::info()->className, operationName); + } else + ASSERT(thisObject); + + ASSERT_GC_OBJECT_INHERITS(thisObject, JSClass::info()); + + // FIXME: We should refactor the binding generated code to use references for lexicalGlobalObject and thisObject. + return operation(&lexicalGlobalObject, &callFrame, thisObject, WTFMove(promise)); + })); + } + + // This function is a special case for custom operations want to handle the creation of the promise themselves. + // It is triggered via the extended attribute [ReturnsOwnPromise]. + template<typename IDLOperation<JSClass>::Operation operation, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::RejectPromise> + static JSC::EncodedJSValue callReturningOwnPromise(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, const char* operationName) + { + auto* thisObject = IDLOperation<JSClass>::cast(lexicalGlobalObject, callFrame); + if constexpr (shouldThrow != CastedThisErrorBehavior::Assert) { + if (UNLIKELY(!thisObject)) + return rejectPromiseWithThisTypeError(lexicalGlobalObject, JSClass::info()->className, operationName); + } else + ASSERT(thisObject); + + ASSERT_GC_OBJECT_INHERITS(thisObject, JSClass::info()); + + // FIXME: We should refactor the binding generated code to use references for lexicalGlobalObject and thisObject. + return operation(&lexicalGlobalObject, &callFrame, thisObject); + } + + template<StaticOperation operation, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::RejectPromise> + static JSC::EncodedJSValue callStatic(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, const char*) + { + return JSC::JSValue::encode(callPromiseFunction(lexicalGlobalObject, callFrame, [] (JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, Ref<DeferredPromise>&& promise) { + // FIXME: We should refactor the binding generated code to use references for lexicalGlobalObject. + return operation(&lexicalGlobalObject, &callFrame, WTFMove(promise)); + })); + } + + // This function is a special case for custom operations want to handle the creation of the promise themselves. + // It is triggered via the extended attribute [ReturnsOwnPromise]. + template<typename IDLOperation<JSClass>::StaticOperation operation, CastedThisErrorBehavior shouldThrow = CastedThisErrorBehavior::RejectPromise> + static JSC::EncodedJSValue callStaticReturningOwnPromise(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, const char*) + { + // FIXME: We should refactor the binding generated code to use references for lexicalGlobalObject. + return operation(&lexicalGlobalObject, &callFrame); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMPromise.cpp b/src/bun.js/bindings/webcore/JSDOMPromise.cpp new file mode 100644 index 000000000..db1597552 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMPromise.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017-2021 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. + */ + +#include "config.h" +#include "JSDOMPromise.h" + +// #include "DOMWindow.h" +// #include "JSDOMWindow.h" +#include <JavaScriptCore/BuiltinNames.h> +#include <JavaScriptCore/CatchScope.h> +#include <JavaScriptCore/Exception.h> +#include <JavaScriptCore/JSNativeStdFunction.h> +#include <JavaScriptCore/JSPromiseConstructor.h> + +using namespace JSC; + +namespace WebCore { + +auto DOMPromise::whenSettled(std::function<void()>&& callback) -> IsCallbackRegistered +{ + return whenPromiseIsSettled(globalObject(), promise(), WTFMove(callback)); +} + +auto DOMPromise::whenPromiseIsSettled(JSDOMGlobalObject* globalObject, JSC::JSObject* promise, Function<void()>&& callback) -> IsCallbackRegistered +{ + auto& lexicalGlobalObject = *globalObject; + auto& vm = lexicalGlobalObject.vm(); + JSLockHolder lock(vm); + auto* handler = JSC::JSNativeStdFunction::create(vm, globalObject, 1, String {}, [callback = WTFMove(callback)](JSGlobalObject*, CallFrame*) mutable { + callback(); + return JSC::JSValue::encode(JSC::jsUndefined()); + }); + + auto scope = DECLARE_THROW_SCOPE(vm); + const JSC::Identifier& privateName = vm.propertyNames->builtinNames().thenPrivateName(); + auto thenFunction = promise->get(&lexicalGlobalObject, privateName); + + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + if (scope.exception()) + return IsCallbackRegistered::No; + + ASSERT(thenFunction.isCallable()); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(handler); + arguments.append(handler); + + auto callData = JSC::getCallData(thenFunction); + ASSERT(callData.type != JSC::CallData::Type::None); + call(&lexicalGlobalObject, thenFunction, callData, promise, arguments); + + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + return scope.exception() ? IsCallbackRegistered::No : IsCallbackRegistered::Yes; +} + +JSC::JSValue DOMPromise::result() const +{ + return promise()->result(m_globalObject->vm()); +} + +DOMPromise::Status DOMPromise::status() const +{ + switch (promise()->status(m_globalObject->vm())) { + case JSC::JSPromise::Status::Pending: + return Status::Pending; + case JSC::JSPromise::Status::Fulfilled: + return Status::Fulfilled; + case JSC::JSPromise::Status::Rejected: + return Status::Rejected; + }; + ASSERT_NOT_REACHED(); + return Status::Rejected; +} + +} diff --git a/src/bun.js/bindings/webcore/JSDOMPromise.h b/src/bun.js/bindings/webcore/JSDOMPromise.h new file mode 100644 index 000000000..97ebafa74 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMPromise.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013-2017 Apple Inc. All rights reserved. + * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>. + * + * 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 "JSDOMGuardedObject.h" +#include <JavaScriptCore/JSPromise.h> + +namespace WebCore { + +class DOMPromise : public DOMGuarded<JSC::JSPromise> { +public: + static Ref<DOMPromise> create(JSDOMGlobalObject& globalObject, JSC::JSPromise& promise) + { + return adoptRef(*new DOMPromise(globalObject, promise)); + } + + JSC::JSPromise* promise() const + { + ASSERT(!isSuspended()); + return guarded(); + } + + enum class IsCallbackRegistered { No, Yes }; + IsCallbackRegistered whenSettled(std::function<void()>&&); + JSC::JSValue result() const; + + enum class Status { Pending, Fulfilled, Rejected }; + Status status() const; + + static IsCallbackRegistered whenPromiseIsSettled(JSDOMGlobalObject*, JSC::JSObject* promise, Function<void()>&&); + +private: + DOMPromise(JSDOMGlobalObject& globalObject, JSC::JSPromise& promise) + : DOMGuarded<JSC::JSPromise>(globalObject, promise) + { + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMPromiseDeferred.cpp b/src/bun.js/bindings/webcore/JSDOMPromiseDeferred.cpp new file mode 100644 index 000000000..0c9f83ef7 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMPromiseDeferred.cpp @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2013-2021 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. + */ + +#include "config.h" +#include "JSDOMPromiseDeferred.h" + +// #include "DOMWindow.h" +// #include "EventLoop.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMPromise.h" +// #include "JSDOMWindow.h" +// #include "ScriptController.h" +// #include "WorkerGlobalScope.h" +#include <JavaScriptCore/BuiltinNames.h> +#include <JavaScriptCore/Exception.h> +#include <JavaScriptCore/JSONObject.h> +#include <JavaScriptCore/JSPromiseConstructor.h> +#include <JavaScriptCore/Strong.h> + +namespace WebCore { +using namespace JSC; + +JSC::JSValue DeferredPromise::promise() const +{ + if (isEmpty()) + return jsUndefined(); + + ASSERT(deferred()); + return deferred(); +} + +void DeferredPromise::callFunction(JSGlobalObject& lexicalGlobalObject, ResolveMode mode, JSValue resolution) +{ + if (shouldIgnoreRequestToFulfill()) + return; + + // if (activeDOMObjectsAreSuspended()) { + // JSC::Strong<JSC::Unknown, ShouldStrongDestructorGrabLock::Yes> strongResolution(lexicalGlobalObject.vm(), resolution); + // ASSERT(scriptExecutionContext()->eventLoop().isSuspended()); + // scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = Ref { *this }, mode, strongResolution = WTFMove(strongResolution)]() mutable { + // if (shouldIgnoreRequestToFulfill()) + // return; + + // JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); + // JSC::JSLockHolder locker(lexicalGlobalObject); + // callFunction(*globalObject(), mode, strongResolution.get()); + // }); + // return; + // } + + // FIXME: We could have error since any JS call can throw stack-overflow errors. + // https://bugs.webkit.org/show_bug.cgi?id=203402 + switch (mode) { + case ResolveMode::Resolve: + deferred()->resolve(&lexicalGlobalObject, resolution); + break; + case ResolveMode::Reject: + deferred()->reject(&lexicalGlobalObject, resolution); + break; + case ResolveMode::RejectAsHandled: + deferred()->rejectAsHandled(&lexicalGlobalObject, resolution); + break; + } + + if (m_mode == Mode::ClearPromiseOnResolve) + clear(); +} + +void DeferredPromise::whenSettled(Function<void()>&& callback) +{ + if (shouldIgnoreRequestToFulfill()) + return; + + // if (activeDOMObjectsAreSuspended()) { + // scriptExecutionContext()->eventLoop().queueTask(TaskSource::Networking, [this, protectedThis = Ref { *this }, callback = WTFMove(callback)]() mutable { + // whenSettled(WTFMove(callback)); + // }); + // return; + // } + + DOMPromise::whenPromiseIsSettled(globalObject(), deferred(), WTFMove(callback)); +} + +void DeferredPromise::reject(RejectAsHandled rejectAsHandled) +{ + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(m_globalObject); + auto& lexicalGlobalObject = *m_globalObject; + JSC::JSLockHolder locker(&lexicalGlobalObject); + reject(lexicalGlobalObject, JSC::jsUndefined(), rejectAsHandled); +} + +void DeferredPromise::reject(JSC::JSValue value, RejectAsHandled rejectAsHandled) +{ + if (shouldIgnoreRequestToFulfill()) + return; + ASSERT(deferred()); + ASSERT(m_globalObject); + auto& lexicalGlobalObject = *m_globalObject; + JSC::JSLockHolder locker(&lexicalGlobalObject); + reject(lexicalGlobalObject, value, rejectAsHandled); +} + +void DeferredPromise::reject(std::nullptr_t, RejectAsHandled rejectAsHandled) +{ + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(m_globalObject); + auto& lexicalGlobalObject = *m_globalObject; + JSC::JSLockHolder locker(&lexicalGlobalObject); + reject(lexicalGlobalObject, JSC::jsNull(), rejectAsHandled); +} + +void DeferredPromise::reject(Exception exception, RejectAsHandled rejectAsHandled) +{ + if (shouldIgnoreRequestToFulfill()) + return; + + Ref protectedThis(*this); + ASSERT(deferred()); + ASSERT(m_globalObject); + auto& lexicalGlobalObject = *m_globalObject; + JSC::VM& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder locker(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + + if (exception.code() == ExistingExceptionError) { + EXCEPTION_ASSERT(scope.exception()); + auto error = scope.exception()->value(); + bool isTerminating = handleTerminationExceptionIfNeeded(scope, lexicalGlobalObject); + scope.clearException(); + + if (!isTerminating) + reject<IDLAny>(error, rejectAsHandled); + return; + } + + auto error = createDOMException(lexicalGlobalObject, WTFMove(exception)); + if (UNLIKELY(scope.exception())) { + handleUncaughtException(scope, lexicalGlobalObject); + return; + } + + reject(lexicalGlobalObject, error, rejectAsHandled); + if (UNLIKELY(scope.exception())) + handleUncaughtException(scope, lexicalGlobalObject); +} + +void DeferredPromise::reject(ExceptionCode ec, const String& message, RejectAsHandled rejectAsHandled) +{ + if (shouldIgnoreRequestToFulfill()) + return; + + Ref protectedThis(*this); + ASSERT(deferred()); + ASSERT(m_globalObject); + auto& lexicalGlobalObject = *m_globalObject; + JSC::VM& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder locker(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + + if (ec == ExistingExceptionError) { + EXCEPTION_ASSERT(scope.exception()); + auto error = scope.exception()->value(); + bool isTerminating = handleTerminationExceptionIfNeeded(scope, lexicalGlobalObject); + scope.clearException(); + + if (!isTerminating) + reject<IDLAny>(error, rejectAsHandled); + return; + } + + auto error = createDOMException(&lexicalGlobalObject, ec, message); + if (UNLIKELY(scope.exception())) { + handleUncaughtException(scope, lexicalGlobalObject); + return; + } + + reject(lexicalGlobalObject, error, rejectAsHandled); + if (UNLIKELY(scope.exception())) + handleUncaughtException(scope, lexicalGlobalObject); +} + +void DeferredPromise::reject(const JSC::PrivateName& privateName, RejectAsHandled rejectAsHandled) +{ + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(m_globalObject); + JSC::JSGlobalObject* lexicalGlobalObject = m_globalObject.get(); + JSC::JSLockHolder locker(lexicalGlobalObject); + reject(*lexicalGlobalObject, JSC::Symbol::create(lexicalGlobalObject->vm(), privateName.uid()), rejectAsHandled); +} + +void rejectPromiseWithExceptionIfAny(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, JSPromise& promise, JSC::CatchScope& catchScope) +{ + UNUSED_PARAM(lexicalGlobalObject); + if (LIKELY(!catchScope.exception())) + return; + + JSValue error = catchScope.exception()->value(); + catchScope.clearException(); + + DeferredPromise::create(globalObject, promise)->reject<IDLAny>(error); +} + +JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::JSGlobalObject& lexicalGlobalObject, const String& errorMessage, RejectedPromiseWithTypeErrorCause cause) +{ + auto& globalObject = lexicalGlobalObject; + auto& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto promiseConstructor = globalObject.promiseConstructor(); + auto rejectFunction = promiseConstructor->get(&lexicalGlobalObject, vm.propertyNames->builtinNames().rejectPrivateName()); + RETURN_IF_EXCEPTION(scope, {}); + auto* rejectionValue = static_cast<ErrorInstance*>(createTypeError(&lexicalGlobalObject, errorMessage)); + if (cause == RejectedPromiseWithTypeErrorCause::NativeGetter) + rejectionValue->setNativeGetterTypeError(); + + auto callData = JSC::getCallData(rejectFunction); + ASSERT(callData.type != CallData::Type::None); + + MarkedArgumentBuffer arguments; + arguments.append(rejectionValue); + ASSERT(!arguments.hasOverflowed()); + + RELEASE_AND_RETURN(scope, JSValue::encode(call(&lexicalGlobalObject, rejectFunction, callData, promiseConstructor, arguments))); +} + +static inline JSC::JSValue parseAsJSON(JSC::JSGlobalObject* lexicalGlobalObject, const String& data) +{ + JSC::JSLockHolder lock(lexicalGlobalObject); + return JSC::JSONParse(lexicalGlobalObject, data); +} + +void fulfillPromiseWithJSON(Ref<DeferredPromise>&& promise, const String& data) +{ + JSC::JSValue value = parseAsJSON(promise->globalObject(), data); + if (!value) + promise->reject(SyntaxError); + else + promise->resolve<IDLAny>(value); +} + +void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&& promise, ArrayBuffer* arrayBuffer) +{ + if (!arrayBuffer) { + promise->reject<IDLAny>(createOutOfMemoryError(promise->globalObject())); + return; + } + promise->resolve<IDLInterface<ArrayBuffer>>(*arrayBuffer); +} + +void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&& promise, const void* data, size_t length) +{ + fulfillPromiseWithArrayBuffer(WTFMove(promise), ArrayBuffer::tryCreate(data, length).get()); +} + +bool DeferredPromise::handleTerminationExceptionIfNeeded(CatchScope& scope, JSDOMGlobalObject& lexicalGlobalObject) +{ + auto* exception = scope.exception(); + VM& vm = scope.vm(); + + auto& scriptExecutionContext = *lexicalGlobalObject.scriptExecutionContext(); + // if (is<WorkerGlobalScope>(scriptExecutionContext)) { + // auto* scriptController = downcast<WorkerGlobalScope>(scriptExecutionContext).script(); + // bool terminatorCausedException = vm.isTerminationException(exception); + // if (terminatorCausedException || (scriptController && scriptController->isTerminatingExecution())) { + // scriptController->forbidExecution(); + // return true; + // } + // } + return false; +} + +void DeferredPromise::handleUncaughtException(CatchScope& scope, JSDOMGlobalObject& lexicalGlobalObject) +{ + auto* exception = scope.exception(); + handleTerminationExceptionIfNeeded(scope, lexicalGlobalObject); + reportException(&lexicalGlobalObject, exception); +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMPromiseDeferred.h b/src/bun.js/bindings/webcore/JSDOMPromiseDeferred.h new file mode 100644 index 000000000..701608677 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMPromiseDeferred.h @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2013-2021 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 "ExceptionOr.h" +#include "JSDOMConvert.h" +#include "JSDOMGuardedObject.h" +#include "ScriptExecutionContext.h" +#include <JavaScriptCore/CatchScope.h> +#include <JavaScriptCore/JSPromise.h> + +namespace WebCore { + +class JSDOMWindow; +enum class RejectAsHandled : uint8_t { No, + Yes }; + +class DeferredPromise : public DOMGuarded<JSC::JSPromise> { +public: + enum class Mode { + ClearPromiseOnResolve, + RetainPromiseOnResolve + }; + + static RefPtr<DeferredPromise> create(JSDOMGlobalObject& globalObject, Mode mode = Mode::ClearPromiseOnResolve) + { + JSC::VM& vm = JSC::getVM(&globalObject); + auto* promise = JSC::JSPromise::create(vm, globalObject.promiseStructure()); + ASSERT(promise); + return adoptRef(new DeferredPromise(globalObject, *promise, mode)); + } + + static Ref<DeferredPromise> create(JSDOMGlobalObject& globalObject, JSC::JSPromise& deferred, Mode mode = Mode::ClearPromiseOnResolve) + { + return adoptRef(*new DeferredPromise(globalObject, deferred, mode)); + } + + template<class IDLType> + void resolve(typename IDLType::ParameterType value) + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); + JSC::JSLockHolder locker(lexicalGlobalObject); + resolve(*lexicalGlobalObject, toJS<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value))); + } + + void resolveWithJSValue(JSC::JSValue resolution) + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); + JSC::JSLockHolder locker(lexicalGlobalObject); + resolve(*lexicalGlobalObject, resolution); + } + + void resolve() + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); + JSC::JSLockHolder locker(lexicalGlobalObject); + resolve(*lexicalGlobalObject, JSC::jsUndefined()); + } + + template<class IDLType> + void resolveWithNewlyCreated(typename IDLType::ParameterType value) + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); + JSC::JSLockHolder locker(lexicalGlobalObject); + resolve(*lexicalGlobalObject, toJSNewlyCreated<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value))); + } + + template<class IDLType> + void resolveCallbackValueWithNewlyCreated(const Function<typename IDLType::InnerParameterType(ScriptExecutionContext&)>& createValue) + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + auto* lexicalGlobalObject = globalObject(); + JSC::JSLockHolder locker(lexicalGlobalObject); + resolve(*lexicalGlobalObject, toJSNewlyCreated<IDLType>(*lexicalGlobalObject, *globalObject(), createValue(*globalObject()->scriptExecutionContext()))); + } + + template<class IDLType> + void reject(typename IDLType::ParameterType value, RejectAsHandled rejectAsHandled = RejectAsHandled::No) + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + JSC::JSGlobalObject* lexicalGlobalObject = globalObject(); + JSC::JSLockHolder locker(lexicalGlobalObject); + reject(*lexicalGlobalObject, toJS<IDLType>(*lexicalGlobalObject, *globalObject(), std::forward<typename IDLType::ParameterType>(value)), rejectAsHandled); + } + + void reject(RejectAsHandled = RejectAsHandled::No); + void reject(std::nullptr_t, RejectAsHandled = RejectAsHandled::No); + WEBCORE_EXPORT void reject(Exception, RejectAsHandled = RejectAsHandled::No); + WEBCORE_EXPORT void reject(JSC::JSValue, RejectAsHandled = RejectAsHandled::No); + WEBCORE_EXPORT void reject(ExceptionCode, const String& = {}, RejectAsHandled = RejectAsHandled::No); + void reject(const JSC::PrivateName&, RejectAsHandled = RejectAsHandled::No); + + template<typename Callback> + void resolveWithCallback(Callback callback) + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + auto* lexicalGlobalObject = globalObject(); + JSC::VM& vm = lexicalGlobalObject->vm(); + JSC::JSLockHolder locker(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + resolve(*lexicalGlobalObject, callback(*globalObject())); + if (UNLIKELY(scope.exception())) + handleUncaughtException(scope, *lexicalGlobalObject); + } + + template<typename Callback> + void rejectWithCallback(Callback callback, RejectAsHandled rejectAsHandled = RejectAsHandled::No) + { + if (shouldIgnoreRequestToFulfill()) + return; + + ASSERT(deferred()); + ASSERT(globalObject()); + auto* lexicalGlobalObject = globalObject(); + JSC::VM& vm = lexicalGlobalObject->vm(); + JSC::JSLockHolder locker(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + reject(*lexicalGlobalObject, callback(*globalObject()), rejectAsHandled); + if (UNLIKELY(scope.exception())) + handleUncaughtException(scope, *lexicalGlobalObject); + } + + JSC::JSValue promise() const; + + void whenSettled(Function<void()>&&); + +private: + DeferredPromise(JSDOMGlobalObject& globalObject, JSC::JSPromise& deferred, Mode mode) + : DOMGuarded<JSC::JSPromise>(globalObject, deferred) + , m_mode(mode) + { + } + + bool shouldIgnoreRequestToFulfill() const { return isEmpty(); } + + JSC::JSPromise* deferred() const { return guarded(); } + + enum class ResolveMode { Resolve, + Reject, + RejectAsHandled }; + WEBCORE_EXPORT void callFunction(JSC::JSGlobalObject&, ResolveMode, JSC::JSValue resolution); + + void resolve(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue resolution) { callFunction(lexicalGlobalObject, ResolveMode::Resolve, resolution); } + void reject(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue resolution, RejectAsHandled rejectAsHandled) + { + callFunction(lexicalGlobalObject, rejectAsHandled == RejectAsHandled::Yes ? ResolveMode::RejectAsHandled : ResolveMode::Reject, resolution); + } + + bool handleTerminationExceptionIfNeeded(JSC::CatchScope&, JSDOMGlobalObject& lexicalGlobalObject); + void handleUncaughtException(JSC::CatchScope&, JSDOMGlobalObject& lexicalGlobalObject); + + Mode m_mode; +}; + +class DOMPromiseDeferredBase { + WTF_MAKE_FAST_ALLOCATED; + +public: + DOMPromiseDeferredBase(Ref<DeferredPromise>&& genericPromise) + : m_promise(WTFMove(genericPromise)) + { + } + + DOMPromiseDeferredBase(DOMPromiseDeferredBase&& promise) + : m_promise(WTFMove(promise.m_promise)) + { + } + + DOMPromiseDeferredBase(const DOMPromiseDeferredBase& other) + : m_promise(other.m_promise.copyRef()) + { + } + + DOMPromiseDeferredBase& operator=(const DOMPromiseDeferredBase& other) + { + m_promise = other.m_promise.copyRef(); + return *this; + } + + DOMPromiseDeferredBase& operator=(DOMPromiseDeferredBase&& other) + { + m_promise = WTFMove(other.m_promise); + return *this; + } + + void reject(RejectAsHandled rejectAsHandled = RejectAsHandled::No) + { + m_promise->reject(rejectAsHandled); + } + + template<typename... ErrorType> + void reject(ErrorType&&... error) + { + m_promise->reject(std::forward<ErrorType>(error)...); + } + + template<typename IDLType> + void rejectType(typename IDLType::ParameterType value, RejectAsHandled rejectAsHandled = RejectAsHandled::No) + { + m_promise->reject<IDLType>(std::forward<typename IDLType::ParameterType>(value), rejectAsHandled); + } + + JSC::JSValue promise() const { return m_promise->promise(); }; + + void whenSettled(Function<void()>&& function) + { + m_promise->whenSettled(WTFMove(function)); + } + +protected: + Ref<DeferredPromise> m_promise; +}; + +template<typename IDLType> +class DOMPromiseDeferred : public DOMPromiseDeferredBase { +public: + using DOMPromiseDeferredBase::DOMPromiseDeferredBase; + using DOMPromiseDeferredBase::operator=; + using DOMPromiseDeferredBase::promise; + using DOMPromiseDeferredBase::reject; + + void resolve(typename IDLType::ParameterType value) + { + m_promise->resolve<IDLType>(std::forward<typename IDLType::ParameterType>(value)); + } + + template<typename U> + void settle(ExceptionOr<U>&& result) + { + if (result.hasException()) { + reject(result.releaseException()); + return; + } + resolve(result.releaseReturnValue()); + } +}; + +template<> class DOMPromiseDeferred<void> : public DOMPromiseDeferredBase { +public: + using DOMPromiseDeferredBase::DOMPromiseDeferredBase; + using DOMPromiseDeferredBase::operator=; + using DOMPromiseDeferredBase::promise; + using DOMPromiseDeferredBase::reject; + + void resolve() + { + m_promise->resolve(); + } + + void settle(ExceptionOr<void>&& result) + { + if (result.hasException()) { + reject(result.releaseException()); + return; + } + resolve(); + } +}; + +void fulfillPromiseWithJSON(Ref<DeferredPromise>&&, const String&); +void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&&, ArrayBuffer*); +void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&&, const void*, size_t); +WEBCORE_EXPORT void rejectPromiseWithExceptionIfAny(JSC::JSGlobalObject&, JSDOMGlobalObject&, JSC::JSPromise&, JSC::CatchScope&); + +enum class RejectedPromiseWithTypeErrorCause { NativeGetter, + InvalidThis }; +JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::JSGlobalObject&, const String&, RejectedPromiseWithTypeErrorCause); + +using PromiseFunction = void(JSC::JSGlobalObject&, JSC::CallFrame&, Ref<DeferredPromise>&&); + +template<PromiseFunction promiseFunction> +inline JSC::JSValue callPromiseFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame) +{ + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto catchScope = DECLARE_CATCH_SCOPE(vm); + + auto& globalObject = *JSC::jsSecureCast<JSDOMGlobalObject*>(&lexicalGlobalObject); + auto* promise = JSC::JSPromise::create(vm, globalObject.promiseStructure()); + ASSERT(promise); + + promiseFunction(lexicalGlobalObject, callFrame, DeferredPromise::create(globalObject, *promise)); + + rejectPromiseWithExceptionIfAny(lexicalGlobalObject, globalObject, *promise, catchScope); + // FIXME: We could have error since any JS call can throw stack-overflow errors. + // https://bugs.webkit.org/show_bug.cgi?id=203402 + RETURN_IF_EXCEPTION(catchScope, JSC::jsUndefined()); + return promise; +} + +template<typename PromiseFunctor> +inline JSC::JSValue callPromiseFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, PromiseFunctor functor) +{ + JSC::VM& vm = JSC::getVM(&lexicalGlobalObject); + auto catchScope = DECLARE_CATCH_SCOPE(vm); + + auto& globalObject = *JSC::jsSecureCast<JSDOMGlobalObject*>(&lexicalGlobalObject); + auto* promise = JSC::JSPromise::create(vm, globalObject.promiseStructure()); + ASSERT(promise); + + functor(lexicalGlobalObject, callFrame, DeferredPromise::create(globalObject, *promise)); + + rejectPromiseWithExceptionIfAny(lexicalGlobalObject, globalObject, *promise, catchScope); + // FIXME: We could have error since any JS call can throw stack-overflow errors. + // https://bugs.webkit.org/show_bug.cgi?id=203402 + RETURN_IF_EXCEPTION(catchScope, JSC::jsUndefined()); + return promise; +} + +using BindingPromiseFunction = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*, Ref<DeferredPromise>&&); +template<BindingPromiseFunction bindingFunction> +inline void bindingPromiseFunctionAdapter(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, Ref<DeferredPromise>&& promise) +{ + bindingFunction(&lexicalGlobalObject, &callFrame, WTFMove(promise)); +} + +template<BindingPromiseFunction bindingPromiseFunction> +inline JSC::JSValue callPromiseFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame) +{ + return callPromiseFunction<bindingPromiseFunctionAdapter<bindingPromiseFunction>>(lexicalGlobalObject, callFrame); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMURL.cpp b/src/bun.js/bindings/webcore/JSDOMURL.cpp new file mode 100644 index 000000000..95bf264dd --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMURL.cpp @@ -0,0 +1,846 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "root.h" +#include "JSDOMURL.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +// #include "JSBlob.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMURL.h" +#include "JSDOMWrapperCache.h" +#include "JSURLSearchParams.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include "JavaScriptCore/FunctionPrototype.h" +#include "JavaScriptCore/HeapAnalyzer.h" + +#include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" +#include "JavaScriptCore/SlotVisitorMacros.h" +#include "JavaScriptCore/SubspaceInlines.h" +#include "wtf/GetPtr.h" +#include "wtf/PointerPreparations.h" +#include "wtf/URL.h" + +#if ENABLE(MEDIA_SOURCE) +#include "DOMURLMediaSource.h" +#include "JSMediaSource.h" +#endif + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toJSON); +static JSC_DECLARE_HOST_FUNCTION(jsDOMURLConstructorFunction_createObjectURL); +static JSC_DECLARE_HOST_FUNCTION(jsDOMURLConstructorFunction_revokeObjectURL); +static JSC_DECLARE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toString); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURLConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_href); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_href); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_origin); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_protocol); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_protocol); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_username); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_username); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_password); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_password); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_host); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_host); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_hostname); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_hostname); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_port); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_port); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_pathname); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_pathname); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_hash); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_hash); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_search); +static JSC_DECLARE_CUSTOM_SETTER(setJSDOMURL_search); +static JSC_DECLARE_CUSTOM_GETTER(jsDOMURL_searchParams); + +class JSDOMURLPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSDOMURLPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSDOMURLPrototype* ptr = new (NotNull, JSC::allocateCell<JSDOMURLPrototype>(vm)) JSDOMURLPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDOMURLPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSDOMURLPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSDOMURLPrototype, JSDOMURLPrototype::Base); + +using JSDOMURLDOMConstructor = JSDOMConstructor<JSDOMURL>; + +/* Hash table for constructor */ + +static const HashTableValue JSDOMURLConstructorTableValues[] = { + { "createObjectURL"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsDOMURLConstructorFunction_createObjectURL), (intptr_t)(1) } }, + { "revokeObjectURL"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsDOMURLConstructorFunction_revokeObjectURL), (intptr_t)(1) } }, +}; + +static inline EncodedJSValue constructJSDOMURL1(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSDOMURLDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto url = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto base = argument1.value().isUndefined() ? String() : convert<IDLUSVString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = DOMURL::create(WTFMove(url), WTFMove(base)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<DOMURL>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<DOMURL>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} + +static inline EncodedJSValue constructJSDOMURL2(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSDOMURLDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto url = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto base = convert<IDLInterface<DOMURL>>(*lexicalGlobalObject, argument1.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 1, "base", "URL", nullptr, "DOMURL"); }); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = DOMURL::create(WTFMove(url), *base); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<DOMURL>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<DOMURL>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSDOMURLDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + size_t argsCount = std::min<size_t>(2, callFrame->argumentCount()); + if (argsCount == 1) { + RELEASE_AND_RETURN(throwScope, (constructJSDOMURL1(lexicalGlobalObject, callFrame))); + } + if (argsCount == 2) { + JSValue distinguishingArg = callFrame->uncheckedArgument(1); + if (distinguishingArg.isUndefined()) + RELEASE_AND_RETURN(throwScope, (constructJSDOMURL1(lexicalGlobalObject, callFrame))); + if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSDOMURL>()) + RELEASE_AND_RETURN(throwScope, (constructJSDOMURL2(lexicalGlobalObject, callFrame))); + RELEASE_AND_RETURN(throwScope, (constructJSDOMURL1(lexicalGlobalObject, callFrame))); + } + return argsCount < 1 ? throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)) : throwVMTypeError(lexicalGlobalObject, throwScope); +} +JSC_ANNOTATE_HOST_FUNCTION(JSDOMURLConstructorConstruct, JSDOMURLDOMConstructor::construct); + +template<> const ClassInfo JSDOMURLDOMConstructor::s_info = { "URL"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMURLDOMConstructor) }; + +template<> JSValue JSDOMURLDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSDOMURLDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "URL"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSDOMURL::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); + reifyStaticProperties(vm, JSDOMURL::info(), JSDOMURLConstructorTableValues, *this); +} + +/* Hash table for prototype */ + +static const HashTableValue JSDOMURLPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURLConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "href"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_href), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_href) } }, + { "origin"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_origin), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "protocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_protocol), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_protocol) } }, + { "username"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_username), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_username) } }, + { "password"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_password), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_password) } }, + { "host"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_host), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_host) } }, + { "hostname"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_hostname), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_hostname) } }, + { "port"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_port), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_port) } }, + { "pathname"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_pathname), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_pathname) } }, + { "hash"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_hash), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_hash) } }, + { "search"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_search), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSDOMURL_search) } }, + { "searchParams"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsDOMURL_searchParams), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "toJSON"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsDOMURLPrototypeFunction_toJSON), (intptr_t)(0) } }, + { "toString"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsDOMURLPrototypeFunction_toString), (intptr_t)(0) } }, +}; + +const ClassInfo JSDOMURLPrototype::s_info = { "URL"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMURLPrototype) }; + +void JSDOMURLPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSDOMURL::info(), JSDOMURLPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSDOMURL::s_info = { "URL"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMURL) }; + +JSDOMURL::JSDOMURL(Structure* structure, JSDOMGlobalObject& globalObject, Ref<DOMURL>&& impl) + : JSDOMWrapper<DOMURL>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSDOMURL::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, DOMURL>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSDOMURL::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSDOMURLPrototype::create(vm, &globalObject, JSDOMURLPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSDOMURL::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSDOMURL>(vm, globalObject); +} + +JSValue JSDOMURL::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSDOMURLDOMConstructor, DOMConstructorID::DOMURL>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSDOMURL::destroy(JSC::JSCell* cell) +{ + JSDOMURL* thisObject = static_cast<JSDOMURL*>(cell); + thisObject->JSDOMURL::~JSDOMURL(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURLConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSDOMURLPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSDOMURL::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsDOMURL_hrefGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.href()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_href, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_hrefGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_hrefSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setHref(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_href, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_hrefSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_originGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.origin()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_origin, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_originGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsDOMURL_protocolGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.protocol()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_protocol, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_protocolGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_protocolSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setProtocol(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_protocol, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_protocolSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_usernameGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.username()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_username, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_usernameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_usernameSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setUsername(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_username, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_usernameSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_passwordGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.password()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_password, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_passwordGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_passwordSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setPassword(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_password, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_passwordSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_hostGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.host()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_host, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_hostGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_hostSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setHost(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_host, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_hostSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_hostnameGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.hostname()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_hostname, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_hostnameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_hostnameSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setHostname(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_hostname, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_hostnameSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_portGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.port()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_port, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_portGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_portSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setPort(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_port, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_portSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_pathnameGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.pathname()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_pathname, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_pathnameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_pathnameSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setPathname(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_pathname, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_pathnameSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_hashGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.hash()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_hash, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_hashGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_hashSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setHash(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_hash, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_hashSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_searchGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.search()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_search, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_searchGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSDOMURL_searchSetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLUSVString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setSearch(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSDOMURL_search, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::set<setJSDOMURL_searchSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsDOMURL_searchParamsGetter(JSGlobalObject& lexicalGlobalObject, JSDOMURL& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + if (JSValue cachedValue = thisObject.m_searchParams.get()) + return cachedValue; + auto& impl = thisObject.wrapped(); + JSValue result = toJS<IDLInterface<URLSearchParams>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.searchParams()); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject.m_searchParams.set(JSC::getVM(&lexicalGlobalObject), &thisObject, result); + return result; +} + +JSC_DEFINE_CUSTOM_GETTER(jsDOMURL_searchParams, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSDOMURL>::get<jsDOMURL_searchParamsGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSC::EncodedJSValue jsDOMURLPrototypeFunction_toJSONBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSDOMURL>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUSVString>(*lexicalGlobalObject, throwScope, impl.toJSON()))); +} + +JSC_DEFINE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toJSON, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSDOMURL>::call<jsDOMURLPrototypeFunction_toJSONBody>(*lexicalGlobalObject, *callFrame, "toJSON"); +} + +static inline JSC::EncodedJSValue jsDOMURLConstructorFunction_createObjectURL1Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) +{ + // auto& vm = JSC::getVM(lexicalGlobalObject); + // auto throwScope = DECLARE_THROW_SCOPE(vm); + // UNUSED_PARAM(throwScope); + // UNUSED_PARAM(callFrame); + // auto* context = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)->scriptExecutionContext(); + // if (UNLIKELY(!context)) + return JSValue::encode(jsUndefined()); + // EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + // auto blob = convert<IDLInterface<Blob>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "blob", "URL", "createObjectURL", "Blob"); }); + // RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + // RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLDOMString>(*lexicalGlobalObject, throwScope, DOMURL::createObjectURL(*context, *blob)))); +} + +static inline JSC::EncodedJSValue jsDOMURLConstructorFunction_revokeObjectURLBody(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 url = convert<IDLDOMString>(*lexicalGlobalObject, argument0.value()); + // RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + // RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return DOMURL::revokeObjectURL(*context, WTFMove(url)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsDOMURLConstructorFunction_revokeObjectURL, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSDOMURL>::callStatic<jsDOMURLConstructorFunction_revokeObjectURLBody>(*lexicalGlobalObject, *callFrame, "revokeObjectURL"); +} + +#if ENABLE(MEDIA_SOURCE) +static inline JSC::EncodedJSValue jsDOMURLConstructorFunction_createObjectURL2Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) +{ + // auto& vm = JSC::getVM(lexicalGlobalObject); + // auto throwScope = DECLARE_THROW_SCOPE(vm); + // UNUSED_PARAM(throwScope); + // UNUSED_PARAM(callFrame); + // auto* context = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)->scriptExecutionContext(); + // if (UNLIKELY(!context)) + return JSValue::encode(jsUndefined()); + // EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + // auto source = convert<IDLInterface<MediaSource>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "source", "URL", "createObjectURL", "MediaSource"); }); + // RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + // RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLDOMString>(*lexicalGlobalObject, throwScope, WebCore::DOMURLMediaSource::createObjectURL(*context, *source)))); +} + +#endif + +static inline JSC::EncodedJSValue jsDOMURLConstructorFunction_createObjectURLOverloadDispatcher(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) +{ + return JSValue::encode(jsUndefined()); + + // auto& vm = JSC::getVM(lexicalGlobalObject); + // auto throwScope = DECLARE_THROW_SCOPE(vm); + // UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + // size_t argsCount = std::min<size_t>(1, callFrame->argumentCount()); + // if (argsCount == 1) { + // JSValue distinguishingArg = callFrame->uncheckedArgument(0); + // if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSBlob>()) + // RELEASE_AND_RETURN(throwScope, (jsDOMURLConstructorFunction_createObjectURL1Body(lexicalGlobalObject, callFrame))); + // #if ENABLE(MEDIA_SOURCE) + // if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSMediaSource>()) + // RELEASE_AND_RETURN(throwScope, (jsDOMURLConstructorFunction_createObjectURL2Body(lexicalGlobalObject, callFrame))); + // #endif + // } + // return argsCount < 1 ? throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)) : throwVMTypeError(lexicalGlobalObject, throwScope); +} + +JSC_DEFINE_HOST_FUNCTION(jsDOMURLConstructorFunction_createObjectURL, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSDOMURL>::callStatic<jsDOMURLConstructorFunction_createObjectURLOverloadDispatcher>(*lexicalGlobalObject, *callFrame, "createObjectURL"); +} + +static inline JSC::EncodedJSValue jsDOMURLPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSDOMURL>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUSVString>(*lexicalGlobalObject, throwScope, impl.href()))); +} + +JSC_DEFINE_HOST_FUNCTION(jsDOMURLPrototypeFunction_toString, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSDOMURL>::call<jsDOMURLPrototypeFunction_toStringBody>(*lexicalGlobalObject, *callFrame, "toString"); +} + +JSC::GCClient::IsoSubspace* JSDOMURL::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSDOMURL, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForDOMURL.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForDOMURL = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForDOMURL.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForDOMURL = WTFMove(space); }); +} + +template<typename Visitor> +void JSDOMURL::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSDOMURL*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + visitor.append(thisObject->m_searchParams); +} + +DEFINE_VISIT_CHILDREN(JSDOMURL); + +void JSDOMURL::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSDOMURL*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + // if (thisObject->scriptExecutionContext()) + // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +JSDOMURLOwner::~JSDOMURLOwner() +{ +} + +bool JSDOMURLOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSDOMURLOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsDOMURL = static_cast<JSDOMURL*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsDOMURL->wrapped(), jsDOMURL); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7DOMURL@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore6DOMURLE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<DOMURL>&& impl) +{ + + if constexpr (std::is_polymorphic_v<DOMURL>) { +#if ENABLE(BINDING_INTEGRITY) + const void* actualVTablePointer = getVTablePointer(impl.ptr()); +#if PLATFORM(WIN) + void* expectedVTablePointer = __identifier("??_7DOMURL@WebCore@@6B@"); +#else + void* expectedVTablePointer = &_ZTVN7WebCore6DOMURLE[2]; +#endif + + // If you hit this assertion you either have a use after free bug, or + // DOMURL has subclasses. If DOMURL has subclasses that get passed + // to toJS() we currently require DOMURL you to opt out of binding hardening + // by adding the SkipVTableValidation attribute to the interface IDL definition + RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); +#endif + } + return createWrapper<DOMURL>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, DOMURL& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +DOMURL* JSDOMURL::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSDOMURL*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSDOMURL.h b/src/bun.js/bindings/webcore/JSDOMURL.h new file mode 100644 index 000000000..e89add235 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMURL.h @@ -0,0 +1,98 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "DOMURL.h" +#include "JSDOMWrapper.h" +#include "wtf/NeverDestroyed.h" + +namespace WebCore { + +class WEBCORE_EXPORT JSDOMURL : public JSDOMWrapper<DOMURL> { +public: + using Base = JSDOMWrapper<DOMURL>; + static JSDOMURL* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<DOMURL>&& impl) + { + JSDOMURL* ptr = new (NotNull, JSC::allocateCell<JSDOMURL>(globalObject->vm())) JSDOMURL(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static DOMURL* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + mutable JSC::WriteBarrier<JSC::Unknown> m_searchParams; + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +protected: + JSDOMURL(JSC::Structure*, JSDOMGlobalObject&, Ref<DOMURL>&&); + + void finishCreation(JSC::VM&); +}; + +class JSDOMURLOwner final : public JSC::WeakHandleOwner { +public: + ~JSDOMURLOwner() final; + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, DOMURL*) +{ + static NeverDestroyed<JSDOMURLOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(DOMURL* wrappableObject) +{ + return wrappableObject; +} + +WEBCORE_EXPORT JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, DOMURL&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, DOMURL* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<DOMURL>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<DOMURL>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<DOMURL> { + using WrapperClass = JSDOMURL; + using ToWrappedReturnType = DOMURL*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSDOMWindow.h b/src/bun.js/bindings/webcore/JSDOMWindow.h new file mode 100644 index 000000000..472956eba --- /dev/null +++ b/src/bun.js/bindings/webcore/JSDOMWindow.h @@ -0,0 +1 @@ +// this is a stub header file
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSErrorCallback.cpp b/src/bun.js/bindings/webcore/JSErrorCallback.cpp new file mode 100644 index 000000000..de924d857 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorCallback.cpp @@ -0,0 +1,89 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSErrorCallback.h" + +#include "JSDOMConvertBase.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMException.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "ScriptExecutionContext.h" + +namespace WebCore { +using namespace JSC; + +JSErrorCallback::JSErrorCallback(VM& vm, JSObject* callback) + : ErrorCallback(jsCast<JSDOMGlobalObject*>(callback->globalObject())->scriptExecutionContext()) + , m_data(new JSCallbackDataStrong(vm, callback, this)) +{ +} + +JSErrorCallback::~JSErrorCallback() +{ + ScriptExecutionContext* context = scriptExecutionContext(); + // When the context is destroyed, all tasks with a reference to a callback + // should be deleted. So if the context is 0, we are on the context thread. + if (!context || context->isContextThread()) + delete m_data; + else + context->postTask(new DeleteCallbackDataTask(m_data)); +#ifndef NDEBUG + m_data = nullptr; +#endif +} + +CallbackResult<typename IDLUndefined::ImplementationType> JSErrorCallback::handleEvent(typename IDLInterface<DOMException>::ParameterType error) +{ + if (!canInvokeCallback()) + return CallbackResultType::UnableToExecute; + + Ref<JSErrorCallback> protectedThis(*this); + + auto& globalObject = *jsCast<JSDOMGlobalObject*>(m_data->callback()->globalObject()); + auto& vm = globalObject.vm(); + + JSLockHolder lock(vm); + auto& lexicalGlobalObject = globalObject; + JSValue thisValue = jsUndefined(); + MarkedArgumentBuffer args; + args.append(toJS<IDLInterface<DOMException>>(lexicalGlobalObject, globalObject, error)); + ASSERT(!args.hasOverflowed()); + + NakedPtr<JSC::Exception> returnedException; + m_data->invokeCallback(vm, thisValue, args, JSCallbackData::CallbackType::Function, Identifier(), returnedException); + if (returnedException) { + reportException(&lexicalGlobalObject, returnedException); + return CallbackResultType::ExceptionThrown; + } + + return {}; +} + +JSC::JSValue toJS(ErrorCallback& impl) +{ + if (!static_cast<JSErrorCallback&>(impl).callbackData()) + return jsNull(); + + return static_cast<JSErrorCallback&>(impl).callbackData()->callback(); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSErrorCallback.h b/src/bun.js/bindings/webcore/JSErrorCallback.h new file mode 100644 index 000000000..ecfd5f04f --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorCallback.h @@ -0,0 +1,54 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "ErrorCallback.h" +#include "IDLTypes.h" +#include "JSCallbackData.h" +#include <wtf/Forward.h> + +namespace WebCore { + +class JSErrorCallback final : public ErrorCallback { +public: + static Ref<JSErrorCallback> create(JSC::VM& vm, JSC::JSObject* callback) + { + return adoptRef(*new JSErrorCallback(vm, callback)); + } + + ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); } + + ~JSErrorCallback() final; + JSCallbackDataStrong* callbackData() { return m_data; } + + // Functions + CallbackResult<typename IDLUndefined::ImplementationType> handleEvent(typename IDLInterface<DOMException>::ParameterType error) override; + +private: + JSErrorCallback(JSC::VM&, JSC::JSObject* callback); + + JSCallbackDataStrong* m_data; +}; + +JSC::JSValue toJS(ErrorCallback&); +inline JSC::JSValue toJS(ErrorCallback* impl) { return impl ? toJS(*impl) : JSC::jsNull(); } + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSErrorEvent.cpp b/src/bun.js/bindings/webcore/JSErrorEvent.cpp new file mode 100644 index 000000000..73010ffcb --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorEvent.cpp @@ -0,0 +1,454 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSErrorEvent.h" + +#include "ZigGlobalObject.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +template<> ErrorEvent::Init convertDictionary<ErrorEvent::Init>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + ErrorEvent::Init result; + JSValue bubblesValue; + if (isNullOrUndefined) + bubblesValue = jsUndefined(); + else { + bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!bubblesValue.isUndefined()) { + result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.bubbles = false; + JSValue cancelableValue; + if (isNullOrUndefined) + cancelableValue = jsUndefined(); + else { + cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!cancelableValue.isUndefined()) { + result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.cancelable = false; + JSValue composedValue; + if (isNullOrUndefined) + composedValue = jsUndefined(); + else { + composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!composedValue.isUndefined()) { + result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.composed = false; + JSValue colnoValue; + if (isNullOrUndefined) + colnoValue = jsUndefined(); + else { + colnoValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "colno"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!colnoValue.isUndefined()) { + result.colno = convert<IDLUnsignedLong>(lexicalGlobalObject, colnoValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.colno = 0; + JSValue errorValue; + if (isNullOrUndefined) + errorValue = jsUndefined(); + else { + errorValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "error"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!errorValue.isUndefined()) { + result.error = convert<IDLAny>(lexicalGlobalObject, errorValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.error = jsNull(); + JSValue filenameValue; + if (isNullOrUndefined) + filenameValue = jsUndefined(); + else { + filenameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "filename"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!filenameValue.isUndefined()) { + result.filename = convert<IDLUSVString>(lexicalGlobalObject, filenameValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.filename = emptyString(); + JSValue linenoValue; + if (isNullOrUndefined) + linenoValue = jsUndefined(); + else { + linenoValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "lineno"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!linenoValue.isUndefined()) { + result.lineno = convert<IDLUnsignedLong>(lexicalGlobalObject, linenoValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.lineno = 0; + JSValue messageValue; + if (isNullOrUndefined) + messageValue = jsUndefined(); + else { + messageValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "message"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!messageValue.isUndefined()) { + result.message = convert<IDLDOMString>(lexicalGlobalObject, messageValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.message = emptyString(); + return result; +} + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsErrorEventConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsErrorEvent_message); +static JSC_DECLARE_CUSTOM_GETTER(jsErrorEvent_filename); +static JSC_DECLARE_CUSTOM_GETTER(jsErrorEvent_lineno); +static JSC_DECLARE_CUSTOM_GETTER(jsErrorEvent_colno); +static JSC_DECLARE_CUSTOM_GETTER(jsErrorEvent_error); + +class JSErrorEventPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSErrorEventPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSErrorEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSErrorEventPrototype>(vm)) JSErrorEventPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSErrorEventPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSErrorEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSErrorEventPrototype, JSErrorEventPrototype::Base); + +using JSErrorEventDOMConstructor = JSDOMConstructor<JSErrorEvent>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSErrorEventDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSErrorEventDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto eventInitDict = convert<IDLDictionary<ErrorEvent::Init>>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = ErrorEvent::create(type, WTFMove(eventInitDict)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<ErrorEvent>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<ErrorEvent>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSErrorEventDOMConstructorConstruct, JSErrorEventDOMConstructor::construct); + +template<> const ClassInfo JSErrorEventDOMConstructor::s_info = { "ErrorEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSErrorEventDOMConstructor) }; + +template<> JSValue JSErrorEventDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + return JSEvent::getConstructor(vm, &globalObject); +} + +template<> void JSErrorEventDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ErrorEvent"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSErrorEvent::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSErrorEventPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsErrorEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "message"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsErrorEvent_message), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "filename"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsErrorEvent_filename), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "lineno"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsErrorEvent_lineno), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "colno"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsErrorEvent_colno), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsErrorEvent_error), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, +}; + +const ClassInfo JSErrorEventPrototype::s_info = { "ErrorEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSErrorEventPrototype) }; + +void JSErrorEventPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSErrorEvent::info(), JSErrorEventPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSErrorEvent::s_info = { "ErrorEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSErrorEvent) }; + +JSErrorEvent::JSErrorEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<ErrorEvent>&& impl) + : JSEvent(structure, globalObject, WTFMove(impl)) +{ +} + +void JSErrorEvent::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, ErrorEvent>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSErrorEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSErrorEventPrototype::create(vm, &globalObject, JSErrorEventPrototype::createStructure(vm, &globalObject, JSEvent::prototype(vm, globalObject))); +} + +JSObject* JSErrorEvent::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSErrorEvent>(vm, globalObject); +} + +JSValue JSErrorEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSErrorEventDOMConstructor, DOMConstructorID::ErrorEvent>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsErrorEventConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSErrorEventPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSErrorEvent::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsErrorEvent_messageGetter(JSGlobalObject& lexicalGlobalObject, JSErrorEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.message()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsErrorEvent_message, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSErrorEvent>::get<jsErrorEvent_messageGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsErrorEvent_filenameGetter(JSGlobalObject& lexicalGlobalObject, JSErrorEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.filename()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsErrorEvent_filename, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSErrorEvent>::get<jsErrorEvent_filenameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsErrorEvent_linenoGetter(JSGlobalObject& lexicalGlobalObject, JSErrorEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedLong>(lexicalGlobalObject, throwScope, impl.lineno()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsErrorEvent_lineno, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSErrorEvent>::get<jsErrorEvent_linenoGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsErrorEvent_colnoGetter(JSGlobalObject& lexicalGlobalObject, JSErrorEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedLong>(lexicalGlobalObject, throwScope, impl.colno()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsErrorEvent_colno, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSErrorEvent>::get<jsErrorEvent_colnoGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsErrorEvent_errorGetter(JSGlobalObject& lexicalGlobalObject, JSErrorEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLAny>(lexicalGlobalObject, throwScope, impl.error(*jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject))))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsErrorEvent_error, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSErrorEvent>::get<jsErrorEvent_errorGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +JSC::GCClient::IsoSubspace* JSErrorEvent::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSErrorEvent, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForErrorEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForErrorEvent = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForErrorEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForErrorEvent = WTFMove(space); }); +} + +template<typename Visitor> +void JSErrorEvent::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSErrorEvent*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +DEFINE_VISIT_CHILDREN(JSErrorEvent); + +template<typename Visitor> +void JSErrorEvent::visitOutputConstraints(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSErrorEvent*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitOutputConstraints(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +template void JSErrorEvent::visitOutputConstraints(JSCell*, AbstractSlotVisitor&); +template void JSErrorEvent::visitOutputConstraints(JSCell*, SlotVisitor&); +void JSErrorEvent::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSErrorEvent*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +// #if ENABLE(BINDING_INTEGRITY) +// #if PLATFORM(WIN) +// #pragma warning(disable : 4483) +// extern "C" { +// extern void (*const __identifier("??_7ErrorEvent@WebCore@@6B@")[])(); +// } +// #else +// extern "C" { +// extern void* _ZTVN7WebCore10ErrorEventE[]; +// } +// #endif +// #endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<ErrorEvent>&& impl) +{ + + // if constexpr (std::is_polymorphic_v<ErrorEvent>) { + // #if ENABLE(BINDING_INTEGRITY) + // const void* actualVTablePointer = getVTablePointer(impl.ptr()); + // #if PLATFORM(WIN) + // void* expectedVTablePointer = __identifier("??_7ErrorEvent@WebCore@@6B@"); + // #else + // void* expectedVTablePointer = &_ZTVN7WebCore10ErrorEventE[2]; + // #endif + + // // If you hit this assertion you either have a use after free bug, or + // // ErrorEvent has subclasses. If ErrorEvent has subclasses that get passed + // // to toJS() we currently require ErrorEvent you to opt out of binding hardening + // // by adding the SkipVTableValidation attribute to the interface IDL definition + // RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); + // #endif + return createWrapper<ErrorEvent>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ErrorEvent& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} +} diff --git a/src/bun.js/bindings/webcore/JSErrorEvent.dep b/src/bun.js/bindings/webcore/JSErrorEvent.dep new file mode 100644 index 000000000..bc136344b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorEvent.dep @@ -0,0 +1,3 @@ +JSErrorEvent.h : Event.idl EventInit.idl +Event.idl : +EventInit.idl : diff --git a/src/bun.js/bindings/webcore/JSErrorEvent.h b/src/bun.js/bindings/webcore/JSErrorEvent.h new file mode 100644 index 000000000..5f8bbd802 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorEvent.h @@ -0,0 +1,87 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "root.h" +#include "ErrorEvent.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMWrapper.h" +#include "JSEvent.h" + +namespace WebCore { + +class JSErrorEvent : public JSEvent { +public: + using Base = JSEvent; + using DOMWrapped = ErrorEvent; + static JSErrorEvent* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<ErrorEvent>&& impl) + { + JSErrorEvent* ptr = new (NotNull, JSC::allocateCell<JSErrorEvent>(globalObject->vm())) JSErrorEvent(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + template<typename Visitor> void visitAdditionalChildren(Visitor&); + + template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + ErrorEvent& wrapped() const + { + return static_cast<ErrorEvent&>(Base::wrapped()); + } + +protected: + JSErrorEvent(JSC::Structure*, JSDOMGlobalObject&, Ref<ErrorEvent>&&); + + void finishCreation(JSC::VM&); +}; + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, ErrorEvent&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ErrorEvent* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<ErrorEvent>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<ErrorEvent>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<ErrorEvent> { + using WrapperClass = JSErrorEvent; + using ToWrappedReturnType = ErrorEvent*; +}; +template<> ErrorEvent::Init convertDictionary<ErrorEvent::Init>(JSC::JSGlobalObject&, JSC::JSValue); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSErrorEventCustom.cpp b/src/bun.js/bindings/webcore/JSErrorEventCustom.cpp new file mode 100644 index 000000000..728e404a9 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorEventCustom.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>. + * Copyright (C) 2021 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. + */ + +#include "config.h" +#include "JSErrorEvent.h" + +namespace WebCore { + +template<typename Visitor> +void JSErrorEvent::visitAdditionalChildren(Visitor& visitor) +{ + wrapped().originalError().visit(visitor); +} + +DEFINE_VISIT_ADDITIONAL_CHILDREN(JSErrorEvent); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSErrorHandler.cpp b/src/bun.js/bindings/webcore/JSErrorHandler.cpp new file mode 100644 index 000000000..ee5df32b5 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorHandler.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2013-2018 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "JSErrorHandler.h" + +// #include "Document.h" +#include "ErrorEvent.h" +#include "Event.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertStrings.h" +// #include "JSDOMWindow.h" +#include "JSEvent.h" +// #include "JSExecState.h" +// #include "JSExecStateInstrumentation.h" +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/VMEntryScope.h> +#include <wtf/Ref.h> + +namespace WebCore { +using namespace JSC; + +inline JSErrorHandler::JSErrorHandler(JSObject& listener, JSObject& wrapper, bool isAttribute, DOMWrapperWorld& world) + : JSEventListener(&listener, &wrapper, isAttribute, CreatedFromMarkup::No, world) +{ +} + +Ref<JSErrorHandler> JSErrorHandler::create(JSC::JSObject& listener, JSC::JSObject& wrapper, bool isAttribute, DOMWrapperWorld& world) +{ + return adoptRef(*new JSErrorHandler(listener, wrapper, isAttribute, world)); +} + +JSErrorHandler::~JSErrorHandler() = default; + +void JSErrorHandler::handleEvent(ScriptExecutionContext& scriptExecutionContext, Event& event) +{ + if (!is<ErrorEvent>(event)) + return JSEventListener::handleEvent(scriptExecutionContext, event); + + VM& vm = scriptExecutionContext.vm(); + JSLockHolder lock(vm); + + JSObject* jsFunction = this->ensureJSFunction(scriptExecutionContext); + if (!jsFunction) + return; + + auto* globalObject = toJSDOMGlobalObject(scriptExecutionContext, isolatedWorld()); + if (!globalObject) + return; + + auto callData = getCallData(jsFunction); + if (callData.type != CallData::Type::None) { + Ref<JSErrorHandler> protectedThis(*this); + + RefPtr<Event> savedEvent; + // auto* jsFunctionWindow = jsDynamicCast<JSDOMWindow*>( jsFunction->globalObject()); + // if (jsFunctionWindow) { + // savedEvent = jsFunctionWindow->currentEvent(); + + // // window.event should not be set when the target is inside a shadow tree, as per the DOM specification. + // if (!event.currentTargetIsInShadowTree()) + // jsFunctionWindow->setCurrentEvent(&event); + // } + + auto& errorEvent = downcast<ErrorEvent>(event); + + MarkedArgumentBuffer args; + args.append(toJS<IDLDOMString>(*globalObject, errorEvent.message())); + args.append(toJS<IDLUSVString>(*globalObject, errorEvent.filename())); + args.append(toJS<IDLUnsignedLong>(errorEvent.lineno())); + args.append(toJS<IDLUnsignedLong>(errorEvent.colno())); + args.append(errorEvent.error(*globalObject)); + ASSERT(!args.hasOverflowed()); + + VM& vm = globalObject->vm(); + VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : globalObject); + + // JSExecState::instrumentFunction(&scriptExecutionContext, callData); + + NakedPtr<JSC::Exception> exception; + JSValue returnValue = JSC::profiledCall(globalObject, JSC::ProfilingReason::Other, jsFunction, callData, globalObject, args, exception); + + // InspectorInstrumentation::didCallFunction(&scriptExecutionContext); + + // if (jsFunctionWindow) + // jsFunctionWindow->setCurrentEvent(savedEvent.get()); + + if (exception) + reportException(globalObject, exception); + else { + if (returnValue.isTrue()) + event.preventDefault(); + } + } +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSErrorHandler.h b/src/bun.js/bindings/webcore/JSErrorHandler.h new file mode 100644 index 000000000..d32c55a86 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSErrorHandler.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2017 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +#pragma once + +#include "JSEventListener.h" + +namespace WebCore { + +class JSErrorHandler final : public JSEventListener { +public: + static Ref<JSErrorHandler> create(JSC::JSObject& listener, JSC::JSObject& wrapper, bool isAttribute, DOMWrapperWorld&); + virtual ~JSErrorHandler(); + +private: + JSErrorHandler(JSC::JSObject& listener, JSC::JSObject& wrapper, bool isAttribute, DOMWrapperWorld&); + void handleEvent(ScriptExecutionContext&, Event&) final; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEvent.cpp b/src/bun.js/bindings/webcore/JSEvent.cpp new file mode 100644 index 000000000..fc729b4c8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEvent.cpp @@ -0,0 +1,620 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "root.h" +#include "JSEvent.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertSequences.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "JSEventInit.h" +#include "JSEventTarget.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSArray.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsEventPrototypeFunction_composedPath); +static JSC_DECLARE_HOST_FUNCTION(jsEventPrototypeFunction_stopPropagation); +static JSC_DECLARE_HOST_FUNCTION(jsEventPrototypeFunction_stopImmediatePropagation); +static JSC_DECLARE_HOST_FUNCTION(jsEventPrototypeFunction_preventDefault); +static JSC_DECLARE_HOST_FUNCTION(jsEventPrototypeFunction_initEvent); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsEventConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_type); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_target); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_currentTarget); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_eventPhase); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_cancelBubble); +static JSC_DECLARE_CUSTOM_SETTER(setJSEvent_cancelBubble); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_bubbles); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_cancelable); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_defaultPrevented); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_composed); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_isTrusted); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_timeStamp); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_srcElement); +static JSC_DECLARE_CUSTOM_GETTER(jsEvent_returnValue); +static JSC_DECLARE_CUSTOM_SETTER(setJSEvent_returnValue); + +class JSEventPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSEventPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSEventPrototype>(vm)) JSEventPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSEventPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSEventPrototype, JSEventPrototype::Base); + +using JSEventDOMConstructor = JSDOMConstructor<JSEvent>; + +/* Hash table */ + +static const struct CompactHashIndex JSEventTableIndex[2] = { + { 0, -1 }, + { -1, -1 }, +}; + +static const HashTableValue JSEventTableValues[] = { + { "isTrusted"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_isTrusted), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, +}; + +static const HashTable JSEventTable = { 1, 1, true, JSEvent::info(), JSEventTableValues, JSEventTableIndex }; +/* Hash table for constructor */ + +static const HashTableValue JSEventConstructorTableValues[] = { + { "NONE"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(0) } }, + { "CAPTURING_PHASE"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } }, + { "AT_TARGET"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } }, + { "BUBBLING_PHASE"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } }, +}; + +static_assert(Event::NONE == 0, "NONE in Event does not match value from IDL"); +static_assert(Event::CAPTURING_PHASE == 1, "CAPTURING_PHASE in Event does not match value from IDL"); +static_assert(Event::AT_TARGET == 2, "AT_TARGET in Event does not match value from IDL"); +static_assert(Event::BUBBLING_PHASE == 3, "BUBBLING_PHASE in Event does not match value from IDL"); + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSEventDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSEventDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto eventInitDict = convert<IDLDictionary<EventInit>>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = Event::create(WTFMove(type), WTFMove(eventInitDict)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<Event>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<Event>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSEventDOMConstructorConstruct, JSEventDOMConstructor::construct); + +template<> const ClassInfo JSEventDOMConstructor::s_info = { "Event"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSEventDOMConstructor) }; + +template<> JSValue JSEventDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSEventDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "Event"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSEvent::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); + reifyStaticProperties(vm, JSEvent::info(), JSEventConstructorTableValues, *this); +} + +/* Hash table for prototype */ + +static const HashTableValue JSEventPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "type"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_type), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "target"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_target), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "currentTarget"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_currentTarget), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "eventPhase"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_eventPhase), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "cancelBubble"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_cancelBubble), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSEvent_cancelBubble) } }, + { "bubbles"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_bubbles), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "cancelable"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_cancelable), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "defaultPrevented"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_defaultPrevented), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "composed"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_composed), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "timeStamp"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_timeStamp), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "srcElement"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_srcElement), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "returnValue"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEvent_returnValue), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSEvent_returnValue) } }, + { "composedPath"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventPrototypeFunction_composedPath), (intptr_t)(0) } }, + { "stopPropagation"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventPrototypeFunction_stopPropagation), (intptr_t)(0) } }, + { "stopImmediatePropagation"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventPrototypeFunction_stopImmediatePropagation), (intptr_t)(0) } }, + { "preventDefault"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventPrototypeFunction_preventDefault), (intptr_t)(0) } }, + { "initEvent"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventPrototypeFunction_initEvent), (intptr_t)(1) } }, + { "NONE"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(0) } }, + { "CAPTURING_PHASE"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } }, + { "AT_TARGET"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } }, + { "BUBBLING_PHASE"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } }, +}; + +const ClassInfo JSEventPrototype::s_info = { "Event"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSEventPrototype) }; + +void JSEventPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSEvent::info(), JSEventPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSEvent::s_info = { "Event"_s, &Base::s_info, &JSEventTable +#if 0 + , + &checkSubClassSnippetForJSEvent +#else + , + nullptr +#endif + , + CREATE_METHOD_TABLE(JSEvent) }; + +JSEvent::JSEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<Event>&& impl) + : JSDOMWrapper<Event>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSEvent::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, Event>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSEventPrototype::create(vm, &globalObject, JSEventPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSEvent::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSEvent>(vm, globalObject); +} + +JSValue JSEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSEventDOMConstructor, DOMConstructorID::Event>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSEvent::destroy(JSC::JSCell* cell) +{ + JSEvent* thisObject = static_cast<JSEvent*>(cell); + thisObject->JSEvent::~JSEvent(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEventConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSEventPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSEvent::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsEvent_typeGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.type()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_type, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_typeGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_targetGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLNullable<IDLInterface<EventTarget>>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.target()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_target, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_targetGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_currentTargetGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLNullable<IDLInterface<EventTarget>>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.currentTarget()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_currentTarget, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_currentTargetGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_eventPhaseGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedShort>(lexicalGlobalObject, throwScope, impl.eventPhase()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_eventPhase, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_eventPhaseGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_cancelBubbleGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.cancelBubble()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_cancelBubble, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_cancelBubbleGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSEvent_cancelBubbleSetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLBoolean>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setCancelBubble(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSEvent_cancelBubble, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::set<setJSEvent_cancelBubbleSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsEvent_bubblesGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.bubbles()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_bubbles, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_bubblesGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_cancelableGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.cancelable()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_cancelable, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_cancelableGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_defaultPreventedGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.defaultPrevented()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_defaultPrevented, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_defaultPreventedGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_composedGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.composed()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_composed, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_composedGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_isTrustedGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.isTrusted()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_isTrusted, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_isTrustedGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_timeStampGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* context = (thisObject).globalObject()->scriptExecutionContext(); + if (UNLIKELY(!context)) + return jsUndefined(); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDouble>(lexicalGlobalObject, throwScope, impl.timeStampForBindings(*context)))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_timeStamp, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_timeStampGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_srcElementGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLInterface<EventTarget>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.target()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_srcElement, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_srcElementGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsEvent_returnValueGetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.legacyReturnValue()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEvent_returnValue, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::get<jsEvent_returnValueGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSEvent_returnValueSetter(JSGlobalObject& lexicalGlobalObject, JSEvent& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLBoolean>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setLegacyReturnValue(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSEvent_returnValue, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSEvent>::set<setJSEvent_returnValueSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSC::EncodedJSValue jsEventPrototypeFunction_composedPathBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEvent>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLSequence<IDLInterface<EventTarget>>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, impl.composedPath()))); +} + +JSC_DEFINE_HOST_FUNCTION(jsEventPrototypeFunction_composedPath, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEvent>::call<jsEventPrototypeFunction_composedPathBody>(*lexicalGlobalObject, *callFrame, "composedPath"); +} + +static inline JSC::EncodedJSValue jsEventPrototypeFunction_stopPropagationBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEvent>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.stopPropagation(); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsEventPrototypeFunction_stopPropagation, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEvent>::call<jsEventPrototypeFunction_stopPropagationBody>(*lexicalGlobalObject, *callFrame, "stopPropagation"); +} + +static inline JSC::EncodedJSValue jsEventPrototypeFunction_stopImmediatePropagationBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEvent>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.stopImmediatePropagation(); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsEventPrototypeFunction_stopImmediatePropagation, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEvent>::call<jsEventPrototypeFunction_stopImmediatePropagationBody>(*lexicalGlobalObject, *callFrame, "stopImmediatePropagation"); +} + +static inline JSC::EncodedJSValue jsEventPrototypeFunction_preventDefaultBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEvent>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.preventDefault(); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsEventPrototypeFunction_preventDefault, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEvent>::call<jsEventPrototypeFunction_preventDefaultBody>(*lexicalGlobalObject, *callFrame, "preventDefault"); +} + +static inline JSC::EncodedJSValue jsEventPrototypeFunction_initEventBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEvent>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto bubbles = convert<IDLBoolean>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument2 = callFrame->argument(2); + auto cancelable = convert<IDLBoolean>(*lexicalGlobalObject, argument2.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initEvent(WTFMove(type), WTFMove(bubbles), WTFMove(cancelable)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsEventPrototypeFunction_initEvent, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEvent>::call<jsEventPrototypeFunction_initEventBody>(*lexicalGlobalObject, *callFrame, "initEvent"); +} + +JSC::GCClient::IsoSubspace* JSEvent::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSEvent, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForEvent = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForEvent = WTFMove(space); }); +} + +void JSEvent::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSEvent*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSEventOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSEventOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsEvent = static_cast<JSEvent*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsEvent->wrapped(), jsEvent); +} + +Event* JSEvent::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSEvent*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSEvent.dep b/src/bun.js/bindings/webcore/JSEvent.dep new file mode 100644 index 000000000..573e0bba5 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEvent.dep @@ -0,0 +1 @@ +JSEvent.h : diff --git a/src/bun.js/bindings/webcore/JSEvent.h b/src/bun.js/bindings/webcore/JSEvent.h new file mode 100644 index 000000000..1f4c5f80a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEvent.h @@ -0,0 +1,102 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "Event.h" +#include "JSDOMWrapper.h" +#include <JavaScriptCore/Snippet.h> +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSEvent : public JSDOMWrapper<Event> { +public: + using Base = JSDOMWrapper<Event>; + static JSEvent* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<Event>&& impl) + { + JSEvent* ptr = new (NotNull, JSC::allocateCell<JSEvent>(globalObject->vm())) JSEvent(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static WEBCORE_EXPORT Event* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +public: + static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::HasStaticPropertyTable; + +protected: + JSEvent(JSC::Structure*, JSDOMGlobalObject&, Ref<Event>&&); + + void finishCreation(JSC::VM&); +}; + +class JSEventOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, Event*) +{ + static NeverDestroyed<JSEventOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(Event* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, Event&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, Event* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<Event>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<Event>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +// #if ENABLE(JIT) +// Ref<JSC::Snippet> checkSubClassSnippetForJSEvent(); +// #endif +template<> struct JSDOMWrapperConverterTraits<Event> { + using WrapperClass = JSEvent; + using ToWrappedReturnType = Event*; +}; + +} // namespace WebCore +#include "JSEventCustom.h" diff --git a/src/bun.js/bindings/webcore/JSEventCustom.cpp b/src/bun.js/bindings/webcore/JSEventCustom.cpp new file mode 100644 index 000000000..2f8a9b04d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventCustom.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2007, 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. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#include "config.h" +#include "JSEvent.h" + +#include "JSDOMWrapperCache.h" +#include <JavaScriptCore/JSCJSValue.h> + +namespace WebCore { + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, Event& event) +{ + return wrap(lexicalGlobalObject, globalObject, event); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventCustom.h b/src/bun.js/bindings/webcore/JSEventCustom.h new file mode 100644 index 000000000..c910848f6 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventCustom.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * Copyright (C) 2018 Yusuke Suzuki <utatane.tea@gmail.com>. + * + * 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. + */ + +#pragma once + +#include "JSDOMBinding.h" +#include "JSEvent.h" + +namespace JSC { +namespace JSCastingHelpers { + +template<> +struct InheritsTraits<WebCore::JSEvent> { + static constexpr std::optional<JSTypeRange> typeRange { { static_cast<JSType>(WebCore::JSEventType), static_cast<JSType>(WebCore::JSEventType) } }; + template<typename From> + static inline bool inherits(From* from) + { + return inheritsJSTypeImpl<WebCore::JSEvent>(from, *typeRange); + } +}; + +} // namespace JSCastingHelpers +} // namespace JSC diff --git a/src/bun.js/bindings/webcore/JSEventInit.cpp b/src/bun.js/bindings/webcore/JSEventInit.cpp new file mode 100644 index 000000000..5ec28613e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventInit.cpp @@ -0,0 +1,80 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSEventInit.h" + +#include "JSDOMConvertBoolean.h" +#include <JavaScriptCore/JSCInlines.h> + +namespace WebCore { +using namespace JSC; + +template<> EventInit convertDictionary<EventInit>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + EventInit result; + JSValue bubblesValue; + if (isNullOrUndefined) + bubblesValue = jsUndefined(); + else { + bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!bubblesValue.isUndefined()) { + result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.bubbles = false; + JSValue cancelableValue; + if (isNullOrUndefined) + cancelableValue = jsUndefined(); + else { + cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!cancelableValue.isUndefined()) { + result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.cancelable = false; + JSValue composedValue; + if (isNullOrUndefined) + composedValue = jsUndefined(); + else { + composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!composedValue.isUndefined()) { + result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.composed = false; + return result; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventInit.dep b/src/bun.js/bindings/webcore/JSEventInit.dep new file mode 100644 index 000000000..e1d78f2d8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventInit.dep @@ -0,0 +1 @@ +EventInit.h : diff --git a/src/bun.js/bindings/webcore/JSEventInit.h b/src/bun.js/bindings/webcore/JSEventInit.h new file mode 100644 index 000000000..c7cd96b65 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventInit.h @@ -0,0 +1,30 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "EventInit.h" +#include "JSDOMConvertDictionary.h" + +namespace WebCore { + +template<> EventInit convertDictionary<EventInit>(JSC::JSGlobalObject&, JSC::JSValue); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventListener.cpp b/src/bun.js/bindings/webcore/JSEventListener.cpp new file mode 100644 index 000000000..3d6be9cd0 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventListener.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003-2021 Apple Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "JSEventListener.h" + +// #include "BeforeUnloadEvent.h" +// #include "ContentSecurityPolicy.h" +#include "EventNames.h" +// #include "Frame.h" +// #include "HTMLElement.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMGlobalObject.h" +// #include "JSDocument.h" +#include "JSEvent.h" +#include "JSEventTarget.h" +// #include "JSExecState.h" +// #include "JSExecStateInstrumentation.h" +// #include "JSWorkerGlobalScope.h" +// #include "ScriptController.h" +// #include "WorkerGlobalScope.h" +#include <JavaScriptCore/ExceptionHelpers.h> +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/VMEntryScope.h> +#include <JavaScriptCore/Watchdog.h> +#include <wtf/Ref.h> +#include <wtf/Scope.h> + +namespace WebCore { +using namespace JSC; + +JSEventListener::JSEventListener(JSObject* function, JSObject* wrapper, bool isAttribute, CreatedFromMarkup createdFromMarkup, DOMWrapperWorld& isolatedWorld) + : EventListener(JSEventListenerType) + , m_isAttribute(isAttribute) + , m_wasCreatedFromMarkup(createdFromMarkup == CreatedFromMarkup::Yes) + , m_isInitialized(false) + , m_wrapper(wrapper) + , m_isolatedWorld(isolatedWorld) +{ + if (function) { + ASSERT(wrapper); + m_jsFunction = JSC::Weak<JSC::JSObject>(function); + m_isInitialized = true; + } +} + +JSEventListener::~JSEventListener() = default; + +Ref<JSEventListener> JSEventListener::create(JSC::JSObject& listener, JSC::JSObject& wrapper, bool isAttribute, DOMWrapperWorld& world) +{ + return adoptRef(*new JSEventListener(&listener, &wrapper, isAttribute, CreatedFromMarkup::No, world)); +} + +JSObject* JSEventListener::initializeJSFunction(ScriptExecutionContext&) const +{ + return nullptr; +} + +void JSEventListener::replaceJSFunctionForAttributeListener(JSObject* function, JSObject* wrapper) +{ + ASSERT(m_isAttribute); + ASSERT(function); + ASSERT(wrapper); + + m_wasCreatedFromMarkup = false; + m_jsFunction = Weak { function }; + if (m_isInitialized) + ASSERT(m_wrapper.get() == wrapper); + else { + m_wrapper = Weak { wrapper }; + m_isInitialized = true; + } +} + +JSValue eventHandlerAttribute(EventTarget& eventTarget, const AtomString& eventType, DOMWrapperWorld& isolatedWorld) +{ + if (auto* jsListener = eventTarget.attributeEventListener(eventType, isolatedWorld)) { + if (auto* context = eventTarget.scriptExecutionContext()) { + if (auto* jsFunction = jsListener->ensureJSFunction(*context)) + return jsFunction; + } + } + + return jsNull(); +} + +template<typename Visitor> +inline void JSEventListener::visitJSFunctionImpl(Visitor& visitor) +{ + // If m_wrapper is null, we are not keeping m_jsFunction alive. + if (!m_wrapper) + return; + + visitor.append(m_jsFunction); +} + +void JSEventListener::visitJSFunction(AbstractSlotVisitor& visitor) { visitJSFunctionImpl(visitor); } +void JSEventListener::visitJSFunction(SlotVisitor& visitor) { visitJSFunctionImpl(visitor); } + +// static void handleBeforeUnloadEventReturnValue(BeforeUnloadEvent& event, const String& returnValue) +// { +// if (returnValue.isNull()) +// return; + +// event.preventDefault(); +// if (event.returnValue().isEmpty()) +// event.setReturnValue(returnValue); +// } + +void JSEventListener::handleEvent(ScriptExecutionContext& scriptExecutionContext, Event& event) +{ + if (scriptExecutionContext.isJSExecutionForbidden()) + return; + + VM& vm = scriptExecutionContext.vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + + // See https://dom.spec.whatwg.org/#dispatching-events spec on calling handleEvent. + // "If this throws an exception, report the exception." It should not propagate the + // exception. + + JSObject* jsFunction = ensureJSFunction(scriptExecutionContext); + if (!jsFunction) + return; + + JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, m_isolatedWorld); + if (!globalObject) + return; + + // if (scriptExecutionContext.isDocument()) { + // JSDOMWindow* window = jsCast<JSDOMWindow*>(globalObject); + // if (!window->wrapped().isCurrentlyDisplayedInFrame()) + // return; + // if (wasCreatedFromMarkup()) { + // Element* element = event.target()->isNode() && !downcast<Node>(*event.target()).isDocumentNode() ? dynamicDowncast<Element>(*event.target()) : nullptr; + // if (!scriptExecutionContext.contentSecurityPolicy()->allowInlineEventHandlers(sourceURL().string(), sourcePosition().m_line, code(), element)) + // return; + // } + // // FIXME: Is this check needed for other contexts? + // ScriptController& script = window->wrapped().frame()->script(); + // if (!script.canExecuteScripts(AboutToExecuteScript) || script.isPaused()) + // return; + // } + + // RefPtr<Event> savedEvent; + // auto* jsFunctionWindow = jsDynamicCast<JSDOMWindow*>(vm, jsFunction->globalObject(vm)); + // if (jsFunctionWindow) { + // savedEvent = jsFunctionWindow->currentEvent(); + + // // window.event should not be set when the target is inside a shadow tree, as per the DOM specification. + // if (!event.currentTargetIsInShadowTree()) + // jsFunctionWindow->setCurrentEvent(&event); + // } + + // auto restoreCurrentEventOnExit = makeScopeExit([&] { + // if (jsFunctionWindow) + // jsFunctionWindow->setCurrentEvent(savedEvent.get()); + // }); + + JSGlobalObject* lexicalGlobalObject = jsFunction->globalObject(); + + JSValue handleEventFunction = jsFunction; + + auto callData = getCallData(handleEventFunction); + + // If jsFunction is not actually a function and this is an EventListener, see if it implements callback interface. + if (callData.type == CallData::Type::None) { + if (m_isAttribute) + return; + + handleEventFunction = jsFunction->get(lexicalGlobalObject, Identifier::fromString(vm, "handleEvent"_s)); + if (UNLIKELY(scope.exception())) { + auto* exception = scope.exception(); + scope.clearException(); + event.target()->uncaughtExceptionInEventHandler(); + reportException(lexicalGlobalObject, exception); + return; + } + callData = getCallData(handleEventFunction); + if (callData.type == CallData::Type::None) { + event.target()->uncaughtExceptionInEventHandler(); + reportException(lexicalGlobalObject, createTypeError(lexicalGlobalObject, "'handleEvent' property of event listener should be callable"_s)); + return; + } + } + + Ref<JSEventListener> protectedThis(*this); + + MarkedArgumentBuffer args; + args.append(toJS(lexicalGlobalObject, globalObject, &event)); + ASSERT(!args.hasOverflowed()); + + VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : lexicalGlobalObject); + + // JSExecState::instrumentFunction(&scriptExecutionContext, callData); + + JSValue thisValue = handleEventFunction == jsFunction ? toJS(lexicalGlobalObject, globalObject, event.currentTarget()) : jsFunction; + NakedPtr<JSC::Exception> uncaughtException; + JSValue retval = JSC::profiledCall(lexicalGlobalObject, JSC::ProfilingReason::Other, handleEventFunction, callData, thisValue, args, uncaughtException); + + // InspectorInstrumentation::didCallFunction(&scriptExecutionContext); + + auto handleExceptionIfNeeded = [&](JSC::Exception* exception) -> bool { + // if (is<WorkerGlobalScope>(scriptExecutionContext)) { + // auto* scriptController = downcast<WorkerGlobalScope>(scriptExecutionContext).script(); + // bool terminatorCausedException = (exception && vm.isTerminationException(exception)); + // if (terminatorCausedException || (scriptController && scriptController->isTerminatingExecution())) + // scriptController->forbidExecution(); + // } + + if (exception) { + event.target()->uncaughtExceptionInEventHandler(); + reportException(lexicalGlobalObject, exception); + return true; + } + return false; + }; + + if (handleExceptionIfNeeded(uncaughtException)) + return; + + if (!m_isAttribute) { + // This is an EventListener and there is therefore no need for any return value handling. + return; + } + + // Do return value handling for event handlers (https://html.spec.whatwg.org/#the-event-handler-processing-algorithm). + + // if (event.type() == eventNames().beforeunloadEvent) { + // // This is a OnBeforeUnloadEventHandler, and therefore the return value must be coerced into a String. + // if (is<BeforeUnloadEvent>(event)) { + // String resultStr = convert<IDLNullable<IDLDOMString>>(*lexicalGlobalObject, retval); + // if (UNLIKELY(scope.exception())) { + // if (handleExceptionIfNeeded(scope.exception())) + // return; + // } + // handleBeforeUnloadEventReturnValue(downcast<BeforeUnloadEvent>(event), resultStr); + // } + // return; + // } + + if (retval.isFalse()) + event.preventDefault(); +} + +bool JSEventListener::operator==(const EventListener& listener) const +{ + if (!is<JSEventListener>(listener)) + return false; + auto& other = downcast<JSEventListener>(listener); + return m_jsFunction == other.m_jsFunction && m_isAttribute == other.m_isAttribute; +} + +String JSEventListener::functionName() const +{ + if (!m_wrapper || !m_jsFunction) + return {}; + + auto& vm = isolatedWorld().vm(); + JSC::JSLockHolder lock(vm); + + auto* handlerFunction = JSC::jsDynamicCast<JSC::JSFunction*>(m_jsFunction.get()); + if (!handlerFunction) + return {}; + + return handlerFunction->name(vm); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventListener.h b/src/bun.js/bindings/webcore/JSEventListener.h new file mode 100644 index 000000000..fb8da1bb6 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventListener.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2003-2021 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +// #include "DOMWindow.h" +#include "DOMWrapperWorld.h" +#include "EventListener.h" +#include "EventNames.h" +// #include "HTMLElement.h" +#include <JavaScriptCore/StrongInlines.h> +#include <JavaScriptCore/Weak.h> +#include <JavaScriptCore/WeakInlines.h> +#include <wtf/Ref.h> +#include <wtf/TypeCasts.h> +#include <wtf/text/TextPosition.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class JSEventListener : public EventListener { +public: + WEBCORE_EXPORT static Ref<JSEventListener> create(JSC::JSObject& listener, JSC::JSObject& wrapper, bool isAttribute, DOMWrapperWorld&); + + virtual ~JSEventListener(); + + bool operator==(const EventListener&) const final; + + // Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick". + bool isAttribute() const final { return m_isAttribute; } + + bool wasCreatedFromMarkup() const { return m_wasCreatedFromMarkup; } + + JSC::JSObject* ensureJSFunction(ScriptExecutionContext&) const; + DOMWrapperWorld& isolatedWorld() const { return m_isolatedWorld; } + + JSC::JSObject* jsFunction() const final { return m_jsFunction.get(); } + JSC::JSObject* wrapper() const final { return m_wrapper.get(); } + + virtual URL sourceURL() const { return {}; } + virtual TextPosition sourcePosition() const { return TextPosition(); } + + String functionName() const; + + void replaceJSFunctionForAttributeListener(JSC::JSObject* function, JSC::JSObject* wrapper); + static bool wasCreatedFromMarkup(const EventListener& listener) + { + return is<JSEventListener>(listener) && downcast<JSEventListener>(listener).wasCreatedFromMarkup(); + } + +private: + virtual JSC::JSObject* initializeJSFunction(ScriptExecutionContext&) const; + + template<typename Visitor> void visitJSFunctionImpl(Visitor&); + void visitJSFunction(JSC::AbstractSlotVisitor&) final; + void visitJSFunction(JSC::SlotVisitor&) final; + virtual String code() const { return String(); } + +protected: + enum class CreatedFromMarkup : bool { No, + Yes }; + + JSEventListener(JSC::JSObject* function, JSC::JSObject* wrapper, bool isAttribute, CreatedFromMarkup, DOMWrapperWorld&); + void handleEvent(ScriptExecutionContext&, Event&) override; + void setWrapperWhenInitializingJSFunction(JSC::VM&, JSC::JSObject* wrapper) const { m_wrapper = JSC::Weak<JSC::JSObject>(wrapper); } + +private: + bool m_isAttribute : 1; + bool m_wasCreatedFromMarkup : 1; + + mutable bool m_isInitialized : 1; + mutable JSC::Weak<JSC::JSObject> m_jsFunction; + mutable JSC::Weak<JSC::JSObject> m_wrapper; + + Ref<DOMWrapperWorld> m_isolatedWorld; +}; + +// For "onxxx" attributes that automatically set up JavaScript event listeners. +JSC::JSValue eventHandlerAttribute(EventTarget&, const AtomString& eventType, DOMWrapperWorld&); + +template<typename JSMaybeErrorEventListener> +inline void setEventHandlerAttribute(EventTarget& eventTarget, const AtomString& eventType, JSC::JSValue listener, JSC::JSObject& jsEventTarget) +{ + eventTarget.setAttributeEventListener<JSMaybeErrorEventListener>(eventType, listener, jsEventTarget); +} + +// // Like the functions above, but for attributes that forward event handlers to the window object rather than setting them on the target. +// inline JSC::JSValue windowEventHandlerAttribute(DOMWindow& window, const AtomString& eventType, DOMWrapperWorld& isolatedWorld) +// { +// return eventHandlerAttribute(window, eventType, isolatedWorld); +// } + +// inline JSC::JSValue windowEventHandlerAttribute(HTMLElement& element, const AtomString& eventType, DOMWrapperWorld& isolatedWorld) +// { +// if (auto* domWindow = element.document().domWindow()) +// return eventHandlerAttribute(*domWindow, eventType, isolatedWorld); +// return JSC::jsNull(); +// } + +// template<typename JSMaybeErrorEventListener> +// inline void setWindowEventHandlerAttribute(DOMWindow& window, const AtomString& eventType, JSC::JSValue listener, JSC::JSObject& jsEventTarget) +// { +// window.setAttributeEventListener<JSMaybeErrorEventListener>(eventType, listener, *jsEventTarget.globalObject()); +// } + +// template<typename JSMaybeErrorEventListener> +// inline void setWindowEventHandlerAttribute(HTMLElement& element, const AtomString& eventType, JSC::JSValue listener, JSC::JSObject& jsEventTarget) +// { +// if (auto* domWindow = element.document().domWindow()) +// domWindow->setAttributeEventListener<JSMaybeErrorEventListener>(eventType, listener, *jsEventTarget.globalObject()); +// } + +inline JSC::JSObject* JSEventListener::ensureJSFunction(ScriptExecutionContext& scriptExecutionContext) const +{ + // initializeJSFunction can trigger code that deletes this event listener + // before we're done. It should always return null in this case. + JSC::VM& vm = m_isolatedWorld->vm(); + Ref protect = const_cast<JSEventListener&>(*this); + JSC::EnsureStillAliveScope protectedWrapper(m_wrapper.get()); + + if (!m_isInitialized) { + ASSERT(!m_jsFunction); + auto* function = initializeJSFunction(scriptExecutionContext); + if (function) { + m_jsFunction = JSC::Weak<JSC::JSObject>(function); + // When JSFunction is initialized, initializeJSFunction must ensure that m_wrapper should be initialized too. + ASSERT(m_wrapper); + vm.writeBarrier(m_wrapper.get(), function); + m_isInitialized = true; + } + } + + // m_wrapper and m_jsFunction are Weak<>. nullptr of these fields do not mean that this event-listener is not initialized yet. + // If this is initialized once, m_isInitialized should be true, and then m_wrapper and m_jsFunction must be alive. m_wrapper's + // liveness should be kept correctly by using ActiveDOMObject, output-constraints, etc. And m_jsFunction must be alive if m_wrapper + // is alive since JSEventListener marks m_jsFunction in JSEventListener::visitJSFunction if m_wrapper is alive. + // If the event-listener is not initialized yet, we should skip invoking this event-listener. + if (!m_isInitialized) + return nullptr; + + ASSERT(m_wrapper); + ASSERT(m_jsFunction); + // Ensure m_jsFunction is live JSObject as a quick sanity check (while it is already ensured by Weak<>). If this fails, this is possibly JSC GC side's bug. + ASSERT(static_cast<JSC::JSCell*>(m_jsFunction.get())->isObject()); + + return m_jsFunction.get(); +} + +} // namespace WebCore + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::JSEventListener) +static bool isType(const WebCore::EventListener& input) { return input.type() == WebCore::JSEventListener::JSEventListenerType; } +SPECIALIZE_TYPE_TRAITS_END() diff --git a/src/bun.js/bindings/webcore/JSEventListenerOptions.cpp b/src/bun.js/bindings/webcore/JSEventListenerOptions.cpp new file mode 100644 index 000000000..a1e6fb69f --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventListenerOptions.cpp @@ -0,0 +1,56 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSEventListenerOptions.h" + +#include "JSDOMConvertBoolean.h" +#include <JavaScriptCore/JSCInlines.h> + +namespace WebCore { +using namespace JSC; + +template<> EventListenerOptions convertDictionary<EventListenerOptions>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + EventListenerOptions result; + JSValue captureValue; + if (isNullOrUndefined) + captureValue = jsUndefined(); + else { + captureValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "capture"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!captureValue.isUndefined()) { + result.capture = convert<IDLBoolean>(lexicalGlobalObject, captureValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.capture = false; + return result; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventListenerOptions.dep b/src/bun.js/bindings/webcore/JSEventListenerOptions.dep new file mode 100644 index 000000000..6a7075b90 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventListenerOptions.dep @@ -0,0 +1 @@ +EventListenerOptions.h : diff --git a/src/bun.js/bindings/webcore/JSEventListenerOptions.h b/src/bun.js/bindings/webcore/JSEventListenerOptions.h new file mode 100644 index 000000000..1b4e2027e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventListenerOptions.h @@ -0,0 +1,30 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "EventListenerOptions.h" +#include "JSDOMConvertDictionary.h" + +namespace WebCore { + +template<> EventListenerOptions convertDictionary<EventListenerOptions>(JSC::JSGlobalObject&, JSC::JSValue); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventModifierInit.cpp b/src/bun.js/bindings/webcore/JSEventModifierInit.cpp new file mode 100644 index 000000000..0e9d2c804 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventModifierInit.cpp @@ -0,0 +1,180 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSEventModifierInit.h" + +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertNumbers.h" +// #include "JSWindowProxy.h" +#include <JavaScriptCore/JSCInlines.h> + +namespace WebCore { +using namespace JSC; + +template<> EventModifierInit convertDictionary<EventModifierInit>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + EventModifierInit result; + JSValue bubblesValue; + if (isNullOrUndefined) + bubblesValue = jsUndefined(); + else { + bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!bubblesValue.isUndefined()) { + result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.bubbles = false; + JSValue cancelableValue; + if (isNullOrUndefined) + cancelableValue = jsUndefined(); + else { + cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!cancelableValue.isUndefined()) { + result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.cancelable = false; + JSValue composedValue; + if (isNullOrUndefined) + composedValue = jsUndefined(); + else { + composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!composedValue.isUndefined()) { + result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.composed = false; + JSValue detailValue; + if (isNullOrUndefined) + detailValue = jsUndefined(); + else { + detailValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "detail"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!detailValue.isUndefined()) { + result.detail = convert<IDLLong>(lexicalGlobalObject, detailValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.detail = 0; + JSValue viewValue; + if (isNullOrUndefined) + viewValue = jsUndefined(); + else { + viewValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "view"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + // if (!viewValue.isUndefined()) { + // result.view = convert<IDLNullable<IDLInterface<WindowProxy>>>(lexicalGlobalObject, viewValue); + // RETURN_IF_EXCEPTION(throwScope, { }); + // } else + result.view = nullptr; + JSValue altKeyValue; + if (isNullOrUndefined) + altKeyValue = jsUndefined(); + else { + altKeyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "altKey"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!altKeyValue.isUndefined()) { + result.altKey = convert<IDLBoolean>(lexicalGlobalObject, altKeyValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.altKey = false; + JSValue ctrlKeyValue; + if (isNullOrUndefined) + ctrlKeyValue = jsUndefined(); + else { + ctrlKeyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "ctrlKey"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!ctrlKeyValue.isUndefined()) { + result.ctrlKey = convert<IDLBoolean>(lexicalGlobalObject, ctrlKeyValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.ctrlKey = false; + JSValue metaKeyValue; + if (isNullOrUndefined) + metaKeyValue = jsUndefined(); + else { + metaKeyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "metaKey"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!metaKeyValue.isUndefined()) { + result.metaKey = convert<IDLBoolean>(lexicalGlobalObject, metaKeyValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.metaKey = false; + JSValue modifierAltGraphValue; + if (isNullOrUndefined) + modifierAltGraphValue = jsUndefined(); + else { + modifierAltGraphValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "modifierAltGraph"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!modifierAltGraphValue.isUndefined()) { + result.modifierAltGraph = convert<IDLBoolean>(lexicalGlobalObject, modifierAltGraphValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.modifierAltGraph = false; + JSValue modifierCapsLockValue; + if (isNullOrUndefined) + modifierCapsLockValue = jsUndefined(); + else { + modifierCapsLockValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "modifierCapsLock"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!modifierCapsLockValue.isUndefined()) { + result.modifierCapsLock = convert<IDLBoolean>(lexicalGlobalObject, modifierCapsLockValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.modifierCapsLock = false; + JSValue shiftKeyValue; + if (isNullOrUndefined) + shiftKeyValue = jsUndefined(); + else { + shiftKeyValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "shiftKey"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!shiftKeyValue.isUndefined()) { + result.shiftKey = convert<IDLBoolean>(lexicalGlobalObject, shiftKeyValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.shiftKey = false; + return result; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventModifierInit.dep b/src/bun.js/bindings/webcore/JSEventModifierInit.dep new file mode 100644 index 000000000..f6b60a42f --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventModifierInit.dep @@ -0,0 +1,3 @@ +EventModifierInit.h : UIEventInit.idl EventInit.idl +UIEventInit.idl : +EventInit.idl : diff --git a/src/bun.js/bindings/webcore/JSEventModifierInit.h b/src/bun.js/bindings/webcore/JSEventModifierInit.h new file mode 100644 index 000000000..2f35a2fd2 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventModifierInit.h @@ -0,0 +1,30 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "EventModifierInit.h" +#include "JSDOMConvertDictionary.h" + +namespace WebCore { + +template<> EventModifierInit convertDictionary<EventModifierInit>(JSC::JSGlobalObject&, JSC::JSValue); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventTarget.cpp b/src/bun.js/bindings/webcore/JSEventTarget.cpp new file mode 100644 index 000000000..15f282ef8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventTarget.cpp @@ -0,0 +1,351 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSEventTarget.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSAddEventListenerOptions.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMConvertEventListener.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMConvertUnion.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "JSEvent.h" +#include "JSEventListener.h" +#include "JSEventListenerOptions.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.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> +#include <variant> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsEventTargetPrototypeFunction_addEventListener); +static JSC_DECLARE_HOST_FUNCTION(jsEventTargetPrototypeFunction_removeEventListener); +static JSC_DECLARE_HOST_FUNCTION(jsEventTargetPrototypeFunction_dispatchEvent); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsEventTargetConstructor); + +class JSEventTargetPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSEventTargetPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSEventTargetPrototype* ptr = new (NotNull, JSC::allocateCell<JSEventTargetPrototype>(vm)) JSEventTargetPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSEventTargetPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSEventTargetPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); + +public: + static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::IsImmutablePrototypeExoticObject; +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSEventTargetPrototype, JSEventTargetPrototype::Base); + +using JSEventTargetDOMConstructor = JSDOMConstructor<JSEventTarget>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSEventTargetDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSEventTargetDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + auto* context = castedThis->scriptExecutionContext(); + if (UNLIKELY(!context)) + return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "EventTarget"); + auto object = EventTarget::create(*context); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<EventTarget>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<EventTarget>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSEventTargetDOMConstructorConstruct, JSEventTargetDOMConstructor::construct); + +template<> const ClassInfo JSEventTargetDOMConstructor::s_info = { "EventTarget"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSEventTargetDOMConstructor) }; + +template<> JSValue JSEventTargetDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSEventTargetDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "EventTarget"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSEventTarget::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSEventTargetPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsEventTargetConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "addEventListener"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventTargetPrototypeFunction_addEventListener), (intptr_t)(2) } }, + { "removeEventListener"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventTargetPrototypeFunction_removeEventListener), (intptr_t)(2) } }, + { "dispatchEvent"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsEventTargetPrototypeFunction_dispatchEvent), (intptr_t)(1) } }, +}; + +const ClassInfo JSEventTargetPrototype::s_info = { "EventTarget"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSEventTargetPrototype) }; + +void JSEventTargetPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSEventTarget::info(), JSEventTargetPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSEventTarget::s_info = { "EventTarget"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSEventTarget) }; + +JSEventTarget::JSEventTarget(Structure* structure, JSDOMGlobalObject& globalObject, Ref<EventTarget>&& impl) + : JSDOMWrapper<EventTarget>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSEventTarget::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, EventTarget>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSEventTarget::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSEventTargetPrototype::create(vm, &globalObject, JSEventTargetPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSEventTarget::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSEventTarget>(vm, globalObject); +} + +JSValue JSEventTarget::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSEventTargetDOMConstructor, DOMConstructorID::EventTarget>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSEventTarget::destroy(JSC::JSCell* cell) +{ + JSEventTarget* thisObject = static_cast<JSEventTarget*>(cell); + thisObject->JSEventTarget::~JSEventTarget(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsEventTargetConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSEventTargetPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSEventTarget::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSC::EncodedJSValue jsEventTargetPrototypeFunction_addEventListenerBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEventTarget>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 2)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto listener = convert<IDLNullable<IDLEventListener<JSEventListener>>>(*lexicalGlobalObject, argument1.value(), *castedThis, [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeObjectError(lexicalGlobalObject, scope, 1, "listener", "EventTarget", "addEventListener"); }); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument2 = callFrame->argument(2); + auto options = argument2.value().isUndefined() ? false : convert<IDLUnion<IDLDictionary<AddEventListenerOptions>, IDLBoolean>>(*lexicalGlobalObject, argument2.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto result = JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.addEventListenerForBindings(WTFMove(type), WTFMove(listener), WTFMove(options)); })); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + vm.writeBarrier(&static_cast<JSObject&>(*castedThis), argument1.value()); + return result; +} + +JSC_DEFINE_HOST_FUNCTION(jsEventTargetPrototypeFunction_addEventListener, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEventTarget>::call<jsEventTargetPrototypeFunction_addEventListenerBody>(*lexicalGlobalObject, *callFrame, "addEventListener"); +} + +static inline JSC::EncodedJSValue jsEventTargetPrototypeFunction_removeEventListenerBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEventTarget>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 2)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto listener = convert<IDLNullable<IDLEventListener<JSEventListener>>>(*lexicalGlobalObject, argument1.value(), *castedThis, [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentMustBeObjectError(lexicalGlobalObject, scope, 1, "listener", "EventTarget", "removeEventListener"); }); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument2 = callFrame->argument(2); + auto options = argument2.value().isUndefined() ? false : convert<IDLUnion<IDLDictionary<EventListenerOptions>, IDLBoolean>>(*lexicalGlobalObject, argument2.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto result = JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.removeEventListenerForBindings(WTFMove(type), WTFMove(listener), WTFMove(options)); })); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + vm.writeBarrier(&static_cast<JSObject&>(*castedThis), argument1.value()); + return result; +} + +JSC_DEFINE_HOST_FUNCTION(jsEventTargetPrototypeFunction_removeEventListener, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEventTarget>::call<jsEventTargetPrototypeFunction_removeEventListenerBody>(*lexicalGlobalObject, *callFrame, "removeEventListener"); +} + +static inline JSC::EncodedJSValue jsEventTargetPrototypeFunction_dispatchEventBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSEventTarget>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto event = convert<IDLInterface<Event>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "event", "EventTarget", "dispatchEvent", "Event"); }); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLBoolean>(*lexicalGlobalObject, throwScope, impl.dispatchEventForBindings(*event)))); +} + +JSC_DEFINE_HOST_FUNCTION(jsEventTargetPrototypeFunction_dispatchEvent, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSEventTarget>::call<jsEventTargetPrototypeFunction_dispatchEventBody>(*lexicalGlobalObject, *callFrame, "dispatchEvent"); +} + +JSC::GCClient::IsoSubspace* JSEventTarget::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSEventTarget, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForEventTarget.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForEventTarget = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForEventTarget.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForEventTarget = WTFMove(space); }); +} + +template<typename Visitor> +void JSEventTarget::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSEventTarget*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +DEFINE_VISIT_CHILDREN(JSEventTarget); + +template<typename Visitor> +void JSEventTarget::visitOutputConstraints(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSEventTarget*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitOutputConstraints(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +template void JSEventTarget::visitOutputConstraints(JSCell*, AbstractSlotVisitor&); +template void JSEventTarget::visitOutputConstraints(JSCell*, SlotVisitor&); +void JSEventTarget::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSEventTarget*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSEventTargetOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + auto* jsEventTarget = jsCast<JSEventTarget*>(handle.slot()->asCell()); + if (jsEventTarget->wrapped().isFiringEventListeners()) { + if (UNLIKELY(reason)) + *reason = "EventTarget firing event listeners"; + return true; + } + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSEventTargetOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsEventTarget = static_cast<JSEventTarget*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsEventTarget->wrapped(), jsEventTarget); +} + +} diff --git a/src/bun.js/bindings/webcore/JSEventTarget.h b/src/bun.js/bindings/webcore/JSEventTarget.h new file mode 100644 index 000000000..ac19a2d35 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventTarget.h @@ -0,0 +1,100 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "root.h" +#include "EventTarget.h" +#include "JSDOMWrapper.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSEventTarget : public JSDOMWrapper<EventTarget> { +public: + using Base = JSDOMWrapper<EventTarget>; + static JSEventTarget* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<EventTarget>&& impl) + { + JSEventTarget* ptr = new (NotNull, JSC::allocateCell<JSEventTarget>(globalObject->vm())) JSEventTarget(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static EventTarget* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + template<typename Visitor> void visitAdditionalChildren(Visitor&); + + template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +protected: + JSEventTarget(JSC::Structure*, JSDOMGlobalObject&, Ref<EventTarget>&&); + + void finishCreation(JSC::VM&); +}; + +class JSEventTargetOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, EventTarget*) +{ + static NeverDestroyed<JSEventTargetOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(EventTarget* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, EventTarget&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, EventTarget* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<EventTarget>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<EventTarget>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<EventTarget> { + using WrapperClass = JSEventTarget; + using ToWrappedReturnType = EventTarget*; +}; + +} // namespace WebCore +#include "JSEventTargetCustom.h" diff --git a/src/bun.js/bindings/webcore/JSEventTargetCustom.cpp b/src/bun.js/bindings/webcore/JSEventTargetCustom.cpp new file mode 100644 index 000000000..3b24d0a8a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventTargetCustom.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008-2021 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 "JSEventTarget.h" + +// #include "DOMWindow.h" +#include "EventTarget.h" +// #include "EventTargetHeaders.h" +#include "EventTargetInterfaces.h" +// #include "JSDOMWindow.h" +#include "JSDOMWrapperCache.h" +#include "JSEventListener.h" +// #include "JSWindowProxy.h" +// #include "JSWorkerGlobalScope.h" +// #include "WorkerGlobalScope.h" + +#if ENABLE(OFFSCREEN_CANVAS) +#include "OffscreenCanvas.h" +#endif + +namespace WebCore { +using namespace JSC; + +JSValue toJSNewlyCreated(JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<EventTarget>&& value) +{ + return createWrapper<EventTarget>(globalObject, WTFMove(value)); +} + +EventTarget* JSEventTarget::toWrapped(VM& vm, JSValue value) +{ + // if (value.inherits<JSWindowProxy>()) + // return &jsCast<JSWindowProxy*>(asObject(value))->wrapped(); + // if (value.inherits<JSDOMWindow>()) + // return &jsCast<JSDOMWindow*>(asObject(value))->wrapped(); + // if (value.inherits<JSWorkerGlobalScope>()) + // return &jsCast<JSWorkerGlobalScope*>(asObject(value))->wrapped(); + if (value.inherits<JSEventTarget>()) + return &jsCast<JSEventTarget*>(asObject(value))->wrapped(); + return nullptr; +} + +std::unique_ptr<JSEventTargetWrapper> jsEventTargetCast(VM& vm, JSValue thisValue) +{ + if (auto* target = jsDynamicCast<JSEventTarget*>(thisValue)) + return makeUnique<JSEventTargetWrapper>(target->wrapped(), *target); + // if (auto* window = toJSDOMGlobalObject<JSDOMWindow>(vm, thisValue)) + // return makeUnique<JSEventTargetWrapper>(window->wrapped(), *window); + // if (auto* scope = toJSDOMGlobalObject<JSWorkerGlobalScope>(vm, thisValue)) + // return makeUnique<JSEventTargetWrapper>(scope->wrapped(), *scope); + return nullptr; +} + +template<typename Visitor> +void JSEventTarget::visitAdditionalChildren(Visitor& visitor) +{ + wrapped().visitJSEventListeners(visitor); +} + +DEFINE_VISIT_ADDITIONAL_CHILDREN(JSEventTarget); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSEventTargetCustom.h b/src/bun.js/bindings/webcore/JSEventTargetCustom.h new file mode 100644 index 000000000..9bbc58004 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSEventTargetCustom.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016-2020 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 "JSDOMBinding.h" +#include "JSDOMOperation.h" + +namespace WebCore { + +// Wrapper type for JSEventTarget's castedThis because JSDOMWindow and JSWorkerGlobalScope do not inherit JSEventTarget. +class JSEventTargetWrapper { + WTF_MAKE_FAST_ALLOCATED; + +public: + JSEventTargetWrapper(EventTarget& wrapped, JSC::JSObject& wrapper) + : m_wrapped(wrapped) + , m_wrapper(wrapper) + { + } + + EventTarget& wrapped() { return m_wrapped; } + + operator JSC::JSObject&() { return m_wrapper; } + +private: + EventTarget& m_wrapped; + JSC::JSObject& m_wrapper; +}; + +std::unique_ptr<JSEventTargetWrapper> jsEventTargetCast(JSC::VM&, JSC::JSValue thisValue); + +template<> class IDLOperation<JSEventTarget> { +public: + using ClassParameter = JSEventTargetWrapper*; + using Operation = JSC::EncodedJSValue(JSC::JSGlobalObject*, JSC::CallFrame*, ClassParameter); + + template<Operation operation, CastedThisErrorBehavior = CastedThisErrorBehavior::Throw> + static JSC::EncodedJSValue call(JSC::JSGlobalObject& lexicalGlobalObject, JSC::CallFrame& callFrame, const char* operationName) + { + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + + auto thisValue = callFrame.thisValue().toThis(&lexicalGlobalObject, JSC::ECMAMode::strict()); + auto thisObject = jsEventTargetCast(vm, thisValue.isUndefinedOrNull() ? JSC::JSValue(&lexicalGlobalObject) : thisValue); + if (UNLIKELY(!thisObject)) + return throwThisTypeError(lexicalGlobalObject, throwScope, "EventTarget", operationName); + + auto& wrapped = thisObject->wrapped(); + + RELEASE_AND_RETURN(throwScope, (operation(&lexicalGlobalObject, &callFrame, thisObject.get()))); + } +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSFetchHeaders.cpp b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp new file mode 100644 index 000000000..8ea72b567 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSFetchHeaders.cpp @@ -0,0 +1,502 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSFetchHeaders.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertRecord.h" +#include "JSDOMConvertSequences.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMConvertUnion.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMIterator.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/BuiltinNames.h> +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSArray.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <variant> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> +#include <wtf/Vector.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_append); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_delete); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_get); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_has); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_set); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_entries); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_keys); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_values); +static JSC_DECLARE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_forEach); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsFetchHeadersConstructor); + +class JSFetchHeadersPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSFetchHeadersPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSFetchHeadersPrototype* ptr = new (NotNull, JSC::allocateCell<JSFetchHeadersPrototype>(vm)) JSFetchHeadersPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFetchHeadersPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSFetchHeadersPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFetchHeadersPrototype, JSFetchHeadersPrototype::Base); + +using JSFetchHeadersDOMConstructor = JSDOMConstructor<JSFetchHeaders>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSFetchHeadersDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSFetchHeadersDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->argument(0); + auto init = argument0.value().isUndefined() ? std::optional<Converter<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>::ReturnType>() : std::optional<Converter<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>::ReturnType>(convert<IDLUnion<IDLSequence<IDLSequence<IDLByteString>>, IDLRecord<IDLByteString, IDLByteString>>>(*lexicalGlobalObject, argument0.value())); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = FetchHeaders::create(WTFMove(init)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<FetchHeaders>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<FetchHeaders>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSFetchHeadersDOMConstructorConstruct, JSFetchHeadersDOMConstructor::construct); + +template<> const ClassInfo JSFetchHeadersDOMConstructor::s_info = { "Headers"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFetchHeadersDOMConstructor) }; + +template<> JSValue JSFetchHeadersDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSFetchHeadersDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "Headers"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSFetchHeaders::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSFetchHeadersPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsFetchHeadersConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "append"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_append), (intptr_t)(2) } }, + { "delete"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_delete), (intptr_t)(1) } }, + { "get"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_get), (intptr_t)(1) } }, + { "has"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_has), (intptr_t)(1) } }, + { "set"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_set), (intptr_t)(2) } }, + { "entries"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_entries), (intptr_t)(0) } }, + { "keys"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_keys), (intptr_t)(0) } }, + { "values"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_values), (intptr_t)(0) } }, + { "forEach"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsFetchHeadersPrototypeFunction_forEach), (intptr_t)(1) } }, +}; + +const ClassInfo JSFetchHeadersPrototype::s_info = { "Headers"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFetchHeadersPrototype) }; + +void JSFetchHeadersPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSFetchHeaders::info(), JSFetchHeadersPrototypeTableValues, *this); + putDirect(vm, vm.propertyNames->iteratorSymbol, getDirect(vm, vm.propertyNames->builtinNames().entriesPublicName()), static_cast<unsigned>(JSC::PropertyAttribute::DontEnum)); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSFetchHeaders::s_info = { "Headers"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFetchHeaders) }; + +JSFetchHeaders::JSFetchHeaders(Structure* structure, JSDOMGlobalObject& globalObject, Ref<FetchHeaders>&& impl) + : JSDOMWrapper<FetchHeaders>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSFetchHeaders::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, FetchHeaders>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSFetchHeaders::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSFetchHeadersPrototype::create(vm, &globalObject, JSFetchHeadersPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSFetchHeaders::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSFetchHeaders>(vm, globalObject); +} + +JSValue JSFetchHeaders::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSFetchHeadersDOMConstructor, DOMConstructorID::FetchHeaders>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSFetchHeaders::destroy(JSC::JSCell* cell) +{ + JSFetchHeaders* thisObject = static_cast<JSFetchHeaders*>(cell); + thisObject->JSFetchHeaders::~JSFetchHeaders(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsFetchHeadersConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSFetchHeadersPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSFetchHeaders::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_appendBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSFetchHeaders>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 2)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLByteString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto value = convert<IDLByteString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.append(WTFMove(name), WTFMove(value)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_append, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_appendBody>(*lexicalGlobalObject, *callFrame, "append"); +} + +static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_deleteBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSFetchHeaders>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLByteString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.remove(WTFMove(name)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_delete, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_deleteBody>(*lexicalGlobalObject, *callFrame, "delete"); +} + +static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_getBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSFetchHeaders>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLByteString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLNullable<IDLByteString>>(*lexicalGlobalObject, throwScope, impl.get(WTFMove(name))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_get, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_getBody>(*lexicalGlobalObject, *callFrame, "get"); +} + +static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_hasBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSFetchHeaders>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLByteString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLBoolean>(*lexicalGlobalObject, throwScope, impl.has(WTFMove(name))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_has, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_hasBody>(*lexicalGlobalObject, *callFrame, "has"); +} + +static inline JSC::EncodedJSValue jsFetchHeadersPrototypeFunction_setBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSFetchHeaders>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 2)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLByteString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto value = convert<IDLByteString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.set(WTFMove(name), WTFMove(value)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_set, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_setBody>(*lexicalGlobalObject, *callFrame, "set"); +} + +struct FetchHeadersIteratorTraits { + static constexpr JSDOMIteratorType type = JSDOMIteratorType::Map; + using KeyType = IDLByteString; + using ValueType = IDLByteString; +}; + +using FetchHeadersIteratorBase = JSDOMIteratorBase<JSFetchHeaders, FetchHeadersIteratorTraits>; +class FetchHeadersIterator final : public FetchHeadersIteratorBase { +public: + using Base = FetchHeadersIteratorBase; + DECLARE_INFO; + + template<typename, SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl<FetchHeadersIterator, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForFetchHeadersIterator.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForFetchHeadersIterator = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForFetchHeadersIterator.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForFetchHeadersIterator = WTFMove(space); }); + } + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + + static FetchHeadersIterator* create(JSC::VM& vm, JSC::Structure* structure, JSFetchHeaders& iteratedObject, IterationKind kind) + { + auto* instance = new (NotNull, JSC::allocateCell<FetchHeadersIterator>(vm)) FetchHeadersIterator(structure, iteratedObject, kind); + instance->finishCreation(vm); + return instance; + } + +private: + FetchHeadersIterator(JSC::Structure* structure, JSFetchHeaders& iteratedObject, IterationKind kind) + : Base(structure, iteratedObject, kind) + { + } +}; + +using FetchHeadersIteratorPrototype = JSDOMIteratorPrototype<JSFetchHeaders, FetchHeadersIteratorTraits>; +JSC_ANNOTATE_HOST_FUNCTION(FetchHeadersIteratorPrototypeNext, FetchHeadersIteratorPrototype::next); + +template<> +const JSC::ClassInfo FetchHeadersIteratorBase::s_info = { "Headers Iterator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(FetchHeadersIteratorBase) }; +const JSC::ClassInfo FetchHeadersIterator::s_info = { "Headers Iterator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(FetchHeadersIterator) }; + +template<> +const JSC::ClassInfo FetchHeadersIteratorPrototype::s_info = { "Headers Iterator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(FetchHeadersIteratorPrototype) }; + +static inline EncodedJSValue jsFetchHeadersPrototypeFunction_entriesCaller(JSGlobalObject*, CallFrame*, JSFetchHeaders* thisObject) +{ + return JSValue::encode(iteratorCreate<FetchHeadersIterator>(*thisObject, IterationKind::Entries)); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_entries, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_entriesCaller>(*lexicalGlobalObject, *callFrame, "entries"); +} + +static inline EncodedJSValue jsFetchHeadersPrototypeFunction_keysCaller(JSGlobalObject*, CallFrame*, JSFetchHeaders* thisObject) +{ + return JSValue::encode(iteratorCreate<FetchHeadersIterator>(*thisObject, IterationKind::Keys)); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_keys, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_keysCaller>(*lexicalGlobalObject, *callFrame, "keys"); +} + +static inline EncodedJSValue jsFetchHeadersPrototypeFunction_valuesCaller(JSGlobalObject*, CallFrame*, JSFetchHeaders* thisObject) +{ + return JSValue::encode(iteratorCreate<FetchHeadersIterator>(*thisObject, IterationKind::Values)); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_values, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_valuesCaller>(*lexicalGlobalObject, *callFrame, "values"); +} + +static inline EncodedJSValue jsFetchHeadersPrototypeFunction_forEachCaller(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame, JSFetchHeaders* thisObject) +{ + return JSValue::encode(iteratorForEach<FetchHeadersIterator>(*lexicalGlobalObject, *callFrame, *thisObject)); +} + +JSC_DEFINE_HOST_FUNCTION(jsFetchHeadersPrototypeFunction_forEach, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSFetchHeaders>::call<jsFetchHeadersPrototypeFunction_forEachCaller>(*lexicalGlobalObject, *callFrame, "forEach"); +} + +JSC::GCClient::IsoSubspace* JSFetchHeaders::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSFetchHeaders, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForFetchHeaders.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForFetchHeaders = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForFetchHeaders.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForFetchHeaders = WTFMove(space); }); +} + +void JSFetchHeaders::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSFetchHeaders*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSFetchHeadersOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSFetchHeadersOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsFetchHeaders = static_cast<JSFetchHeaders*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsFetchHeaders->wrapped(), jsFetchHeaders); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7FetchHeaders@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore12FetchHeadersE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<FetchHeaders>&& impl) +{ + + if constexpr (std::is_polymorphic_v<FetchHeaders>) { +#if ENABLE(BINDING_INTEGRITY) + const void* actualVTablePointer = getVTablePointer(impl.ptr()); +#if PLATFORM(WIN) + void* expectedVTablePointer = __identifier("??_7FetchHeaders@WebCore@@6B@"); +#else + void* expectedVTablePointer = &_ZTVN7WebCore12FetchHeadersE[2]; +#endif + + // If you hit this assertion you either have a use after free bug, or + // FetchHeaders has subclasses. If FetchHeaders has subclasses that get passed + // to toJS() we currently require FetchHeaders you to opt out of binding hardening + // by adding the SkipVTableValidation attribute to the interface IDL definition + RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); +#endif + } + return createWrapper<FetchHeaders>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, FetchHeaders& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +FetchHeaders* JSFetchHeaders::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSFetchHeaders*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSFetchHeaders.dep b/src/bun.js/bindings/webcore/JSFetchHeaders.dep new file mode 100644 index 000000000..e553164bd --- /dev/null +++ b/src/bun.js/bindings/webcore/JSFetchHeaders.dep @@ -0,0 +1 @@ +JSFetchHeaders.h : diff --git a/src/bun.js/bindings/webcore/JSFetchHeaders.h b/src/bun.js/bindings/webcore/JSFetchHeaders.h new file mode 100644 index 000000000..4761e3a66 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSFetchHeaders.h @@ -0,0 +1,93 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "FetchHeaders.h" +#include "JSDOMWrapper.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSFetchHeaders : public JSDOMWrapper<FetchHeaders> { +public: + using Base = JSDOMWrapper<FetchHeaders>; + static JSFetchHeaders* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<FetchHeaders>&& impl) + { + JSFetchHeaders* ptr = new (NotNull, JSC::allocateCell<JSFetchHeaders>(globalObject->vm())) JSFetchHeaders(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static FetchHeaders* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); +protected: + JSFetchHeaders(JSC::Structure*, JSDOMGlobalObject&, Ref<FetchHeaders>&&); + + void finishCreation(JSC::VM&); +}; + +class JSFetchHeadersOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, FetchHeaders*) +{ + static NeverDestroyed<JSFetchHeadersOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(FetchHeaders* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, FetchHeaders&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, FetchHeaders* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<FetchHeaders>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<FetchHeaders>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<FetchHeaders> { + using WrapperClass = JSFetchHeaders; + using ToWrappedReturnType = FetchHeaders*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSMessageEvent.cpp b/src/bun.js/bindings/webcore/JSMessageEvent.cpp new file mode 100644 index 000000000..ef0a1093d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSMessageEvent.cpp @@ -0,0 +1,521 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSMessageEvent.h" +#include "JavaScriptCore/ObjectConstructor.h" +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertSequences.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMConvertUnion.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +// #include "JSMessagePort.h" +#include "JSServiceWorker.h" +#include "JSWindowProxy.h" +#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> +#include <JavaScriptCore/SubspaceInlines.h> +#include <variant> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +template<> MessageEvent::Init convertDictionary<MessageEvent::Init>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + MessageEvent::Init result; + JSValue bubblesValue; + if (isNullOrUndefined) + bubblesValue = jsUndefined(); + else { + bubblesValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "bubbles"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!bubblesValue.isUndefined()) { + result.bubbles = convert<IDLBoolean>(lexicalGlobalObject, bubblesValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.bubbles = false; + JSValue cancelableValue; + if (isNullOrUndefined) + cancelableValue = jsUndefined(); + else { + cancelableValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "cancelable"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!cancelableValue.isUndefined()) { + result.cancelable = convert<IDLBoolean>(lexicalGlobalObject, cancelableValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.cancelable = false; + JSValue composedValue; + if (isNullOrUndefined) + composedValue = jsUndefined(); + else { + composedValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "composed"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!composedValue.isUndefined()) { + result.composed = convert<IDLBoolean>(lexicalGlobalObject, composedValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.composed = false; + JSValue dataValue; + if (isNullOrUndefined) + dataValue = jsUndefined(); + else { + dataValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "data"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!dataValue.isUndefined()) { + result.data = convert<IDLAny>(lexicalGlobalObject, dataValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.data = jsNull(); + JSValue lastEventIdValue; + if (isNullOrUndefined) + lastEventIdValue = jsUndefined(); + else { + lastEventIdValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "lastEventId"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!lastEventIdValue.isUndefined()) { + result.lastEventId = convert<IDLDOMString>(lexicalGlobalObject, lastEventIdValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.lastEventId = emptyString(); + JSValue originValue; + if (isNullOrUndefined) + originValue = jsUndefined(); + else { + originValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "origin"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!originValue.isUndefined()) { + result.origin = convert<IDLUSVString>(lexicalGlobalObject, originValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } else + result.origin = emptyString(); + // JSValue portsValue; + // if (isNullOrUndefined) + // portsValue = jsUndefined(); + // else { + // portsValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "ports"_s)); + // RETURN_IF_EXCEPTION(throwScope, { }); + // } + // if (!portsValue.isUndefined()) { + // result.ports = convert<IDLSequence<IDLInterface<MessagePort>>>(lexicalGlobalObject, portsValue); + // RETURN_IF_EXCEPTION(throwScope, { }); + // } else + // result.ports = Converter<IDLSequence<IDLInterface<MessagePort>>>::ReturnType{ }; + JSValue sourceValue; + if (isNullOrUndefined) + sourceValue = jsUndefined(); + else { + sourceValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "source"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + // if (!sourceValue.isUndefined()) { + // result.source = convert<IDLNullable<IDLUnion<IDLInterface<WindowProxy>, IDLInterface<MessagePort>, IDLInterface<ServiceWorker>>>>(lexicalGlobalObject, sourceValue); + // RETURN_IF_EXCEPTION(throwScope, {}); + // } else + result.source = std::nullopt; + return result; +} + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsMessageEventPrototypeFunction_initMessageEvent); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsMessageEventConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_origin); +static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_lastEventId); +static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_source); +static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_data); +static JSC_DECLARE_CUSTOM_GETTER(jsMessageEvent_ports); + +class JSMessageEventPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSMessageEventPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSMessageEventPrototype* ptr = new (NotNull, JSC::allocateCell<JSMessageEventPrototype>(vm)) JSMessageEventPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessageEventPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSMessageEventPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMessageEventPrototype, JSMessageEventPrototype::Base); + +using JSMessageEventDOMConstructor = JSDOMConstructor<JSMessageEvent>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSMessageEventDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSMessageEventDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto eventInitDict = convert<IDLDictionary<MessageEvent::Init>>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = MessageEvent::create(WTFMove(type), WTFMove(eventInitDict)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<MessageEvent>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<MessageEvent>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSMessageEventDOMConstructorConstruct, JSMessageEventDOMConstructor::construct); + +template<> const ClassInfo JSMessageEventDOMConstructor::s_info = { "MessageEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageEventDOMConstructor) }; + +template<> JSValue JSMessageEventDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + return JSEvent::getConstructor(vm, &globalObject); +} + +template<> void JSMessageEventDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "MessageEvent"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSMessageEvent::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSMessageEventPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsMessageEventConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "origin"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_origin), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "lastEventId"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_lastEventId), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "source"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_source), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "data"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_data), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "ports"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsMessageEvent_ports), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "initMessageEvent"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsMessageEventPrototypeFunction_initMessageEvent), (intptr_t)(1) } }, +}; + +const ClassInfo JSMessageEventPrototype::s_info = { "MessageEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageEventPrototype) }; + +void JSMessageEventPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSMessageEvent::info(), JSMessageEventPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSMessageEvent::s_info = { "MessageEvent"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMessageEvent) }; + +JSMessageEvent::JSMessageEvent(Structure* structure, JSDOMGlobalObject& globalObject, Ref<MessageEvent>&& impl) + : JSEvent(structure, globalObject, WTFMove(impl)) +{ +} + +void JSMessageEvent::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, MessageEvent>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); + + vm.heap.reportExtraMemoryAllocated(wrapped().memoryCost()); +} + +JSObject* JSMessageEvent::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSMessageEventPrototype::create(vm, &globalObject, JSMessageEventPrototype::createStructure(vm, &globalObject, JSEvent::prototype(vm, globalObject))); +} + +JSObject* JSMessageEvent::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSMessageEvent>(vm, globalObject); +} + +JSValue JSMessageEvent::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSMessageEventDOMConstructor, DOMConstructorID::MessageEvent>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsMessageEventConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSMessageEventPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSMessageEvent::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsMessageEvent_originGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.origin()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_origin, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_originGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsMessageEvent_lastEventIdGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.lastEventId()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_lastEventId, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_lastEventIdGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsMessageEvent_sourceGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + return lexicalGlobalObject.globalThis(); + // auto throwScope = DECLARE_THROW_SCOPE(vm); + // auto& impl = thisObject.wrapped(); + // RELEASE_AND_RETURN(throwScope, (toJS<IDLNullable<IDLUnion<IDLInterface<WindowProxy>, IDLInterface<MessagePort>, IDLInterface<ServiceWorker>>>>(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.source()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_source, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_sourceGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsMessageEvent_dataGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return thisObject.data(lexicalGlobalObject); +} + +JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_data, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_dataGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsMessageEvent_portsGetter(JSGlobalObject& lexicalGlobalObject, JSMessageEvent& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + // TODO: + return JSArray::create(lexicalGlobalObject.vm(), lexicalGlobalObject.arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0); + // return thisObject.ports(lexicalGlobalObject); +} + +JSC_DEFINE_CUSTOM_GETTER(jsMessageEvent_ports, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSMessageEvent>::get<jsMessageEvent_portsGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSC::EncodedJSValue jsMessageEventPrototypeFunction_initMessageEventBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSMessageEvent>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto type = convert<IDLAtomStringAdaptor<IDLDOMString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto bubbles = convert<IDLBoolean>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument2 = callFrame->argument(2); + auto cancelable = convert<IDLBoolean>(*lexicalGlobalObject, argument2.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument3 = callFrame->argument(3); + auto data = argument3.value().isUndefined() ? jsNull() : convert<IDLAny>(*lexicalGlobalObject, argument3.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument4 = callFrame->argument(4); + auto originArg = argument4.value().isUndefined() ? emptyString() : convert<IDLUSVString>(*lexicalGlobalObject, argument4.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument5 = callFrame->argument(5); + auto lastEventId = argument5.value().isUndefined() ? emptyString() : convert<IDLDOMString>(*lexicalGlobalObject, argument5.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument6 = callFrame->argument(6); + auto source = WebCore::MessageEventSource(); + // RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + // EnsureStillAliveScope argument7 = callFrame->argument(7); + // auto messagePorts = JSArray::create(lexicalGlobalObject.vm(), lexicalGlobalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0); + // auto messagePorts = Converter<IDLSequence<IDLInterface<MessagePort>>>::ReturnType {}; + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + // RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initMessageEvent(WTFMove(type), WTFMove(bubbles), WTFMove(cancelable), WTFMove(data), WTFMove(originArg), WTFMove(lastEventId), WTFMove(source), WTFMove(messagePorts)); }))); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.initMessageEvent(WTFMove(type), WTFMove(bubbles), WTFMove(cancelable), WTFMove(data), WTFMove(originArg), WTFMove(lastEventId), WTFMove(source)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsMessageEventPrototypeFunction_initMessageEvent, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSMessageEvent>::call<jsMessageEventPrototypeFunction_initMessageEventBody>(*lexicalGlobalObject, *callFrame, "initMessageEvent"); +} + +JSC::GCClient::IsoSubspace* JSMessageEvent::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSMessageEvent, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForMessageEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForMessageEvent = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForMessageEvent.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForMessageEvent = WTFMove(space); }); +} + +template<typename Visitor> +void JSMessageEvent::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSMessageEvent*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); + visitor.reportExtraMemoryVisited(thisObject->wrapped().memoryCost()); +} + +DEFINE_VISIT_CHILDREN(JSMessageEvent); + +template<typename Visitor> +void JSMessageEvent::visitOutputConstraints(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSMessageEvent*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitOutputConstraints(thisObject, visitor); + thisObject->visitAdditionalChildren(visitor); +} + +template void JSMessageEvent::visitOutputConstraints(JSCell*, AbstractSlotVisitor&); +template void JSMessageEvent::visitOutputConstraints(JSCell*, SlotVisitor&); +size_t JSMessageEvent::estimatedSize(JSCell* cell, VM& vm) +{ + auto* thisObject = jsCast<JSMessageEvent*>(cell); + return Base::estimatedSize(thisObject, vm) + thisObject->wrapped().memoryCost(); +} + +void JSMessageEvent::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSMessageEvent*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7MessageEvent@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore12MessageEventE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<MessageEvent>&& impl) +{ + + if constexpr (std::is_polymorphic_v<MessageEvent>) { +#if ENABLE(BINDING_INTEGRITY) + const void* actualVTablePointer = getVTablePointer(impl.ptr()); +#if PLATFORM(WIN) + void* expectedVTablePointer = __identifier("??_7MessageEvent@WebCore@@6B@"); +#else + void* expectedVTablePointer = &_ZTVN7WebCore12MessageEventE[2]; +#endif + + // If you hit this assertion you either have a use after free bug, or + // MessageEvent has subclasses. If MessageEvent has subclasses that get passed + // to toJS() we currently require MessageEvent you to opt out of binding hardening + // by adding the SkipVTableValidation attribute to the interface IDL definition + RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); +#endif + } + return createWrapper<MessageEvent>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessageEvent& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +} diff --git a/src/bun.js/bindings/webcore/JSMessageEvent.dep b/src/bun.js/bindings/webcore/JSMessageEvent.dep new file mode 100644 index 000000000..da20f76fa --- /dev/null +++ b/src/bun.js/bindings/webcore/JSMessageEvent.dep @@ -0,0 +1,3 @@ +JSMessageEvent.h : Event.idl EventInit.idl +Event.idl : +EventInit.idl : diff --git a/src/bun.js/bindings/webcore/JSMessageEvent.h b/src/bun.js/bindings/webcore/JSMessageEvent.h new file mode 100644 index 000000000..85424d9ec --- /dev/null +++ b/src/bun.js/bindings/webcore/JSMessageEvent.h @@ -0,0 +1,91 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMConvertDictionary.h" +#include "JSDOMWrapper.h" +#include "JSEvent.h" +#include "MessageEvent.h" + +namespace WebCore { + +class JSMessageEvent : public JSEvent { +public: + using Base = JSEvent; + using DOMWrapped = MessageEvent; + static JSMessageEvent* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<MessageEvent>&& impl) + { + JSMessageEvent* ptr = new (NotNull, JSC::allocateCell<JSMessageEvent>(globalObject->vm())) JSMessageEvent(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static size_t estimatedSize(JSCell*, JSC::VM&); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + template<typename Visitor> void visitAdditionalChildren(Visitor&); + + template<typename Visitor> static void visitOutputConstraints(JSCell*, Visitor&); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + + // Custom attributes + JSC::JSValue data(JSC::JSGlobalObject&) const; + JSC::JSValue ports(JSC::JSGlobalObject&) const; + MessageEvent& wrapped() const + { + return static_cast<MessageEvent&>(Base::wrapped()); + } +protected: + JSMessageEvent(JSC::Structure*, JSDOMGlobalObject&, Ref<MessageEvent>&&); + + void finishCreation(JSC::VM&); +}; + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, MessageEvent&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, MessageEvent* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<MessageEvent>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<MessageEvent>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<MessageEvent> { + using WrapperClass = JSMessageEvent; + using ToWrappedReturnType = MessageEvent*; +}; +template<> MessageEvent::Init convertDictionary<MessageEvent::Init>(JSC::JSGlobalObject&, JSC::JSValue); + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSMessageEventCustom.cpp b/src/bun.js/bindings/webcore/JSMessageEventCustom.cpp new file mode 100644 index 000000000..66390f86b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSMessageEventCustom.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2009-2021 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "JSMessageEvent.h" + +// #include "JSBlob.h" +#include "JSDOMBinding.h" +#include "JSDOMConvert.h" +#include "JSDOMWindow.h" +#include "JSEventTarget.h" +// #include "JSMessagePort.h" +#include <JavaScriptCore/JSArray.h> +#include <JavaScriptCore/JSArrayBuffer.h> + +namespace WebCore { + +JSC::JSValue JSMessageEvent::ports(JSC::JSGlobalObject& lexicalGlobalObject) const +{ + return JSC::jsUndefined(); +} +// auto throwScope = DECLARE_THROW_SCOPE(lexicalGlobalObject.vm()); +// return cachedPropertyValue(lexicalGlobalObject, *this, wrapped().cachedPorts(), [&] { +// JSC::JSValue ports = toJS<IDLFrozenArray<IDLInterface<MessagePort>>>(lexicalGlobalObject, *globalObject(), throwScope, wrapped().ports()); +// return ports; +// }); +// } + +JSC::JSValue JSMessageEvent::data(JSC::JSGlobalObject& lexicalGlobalObject) const +{ + return cachedPropertyValue(lexicalGlobalObject, *this, wrapped().cachedData(), [this, &lexicalGlobalObject] { + return WTF::switchOn( + wrapped().data(), [this](MessageEvent::JSValueTag) -> JSC::JSValue { return wrapped().jsData().getValue(JSC::jsNull()); }, + // [this, &lexicalGlobalObject](const Ref<SerializedScriptValue>& data) { + // // FIXME: Is it best to handle errors by returning null rather than throwing an exception? + // return data->deserialize(lexicalGlobalObject, globalObject(), wrapped().ports(), SerializationErrorMode::NonThrowing); }, + [&lexicalGlobalObject](const String& data) { return toJS<IDLDOMString>(lexicalGlobalObject, data); }, + // [this, &lexicalGlobalObject](const Ref<Blob>& data) { return toJS<IDLInterface<Blob>>(lexicalGlobalObject, *globalObject(), data); }, + [this, &lexicalGlobalObject](const Ref<ArrayBuffer>& data) { return toJS<IDLInterface<ArrayBuffer>>(lexicalGlobalObject, *globalObject(), data); }); + }); +} + +template<typename Visitor> +void JSMessageEvent::visitAdditionalChildren(Visitor& visitor) +{ + wrapped().jsData().visit(visitor); + wrapped().cachedData().visit(visitor); + wrapped().cachedPorts().visit(visitor); +} + +DEFINE_VISIT_ADDITIONAL_CHILDREN(JSMessageEvent); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableByteStreamController.cpp b/src/bun.js/bindings/webcore/JSReadableByteStreamController.cpp new file mode 100644 index 000000000..7f151188f --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableByteStreamController.cpp @@ -0,0 +1,185 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableByteStreamController.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ReadableByteStreamControllerBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsReadableByteStreamControllerConstructor); + +class JSReadableByteStreamControllerPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableByteStreamControllerPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableByteStreamControllerPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableByteStreamControllerPrototype>(vm)) JSReadableByteStreamControllerPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableByteStreamControllerPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableByteStreamControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableByteStreamControllerPrototype, JSReadableByteStreamControllerPrototype::Base); + +using JSReadableByteStreamControllerDOMConstructor = JSDOMBuiltinConstructor<JSReadableByteStreamController>; + +template<> const ClassInfo JSReadableByteStreamControllerDOMConstructor::s_info = { "ReadableByteStreamController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableByteStreamControllerDOMConstructor) }; + +template<> JSValue JSReadableByteStreamControllerDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSReadableByteStreamControllerDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(3), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ReadableByteStreamController"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSReadableByteStreamController::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSReadableByteStreamControllerDOMConstructor::initializeExecutable(VM& vm) +{ + return readableByteStreamControllerInitializeReadableByteStreamControllerCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSReadableByteStreamControllerPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsReadableByteStreamControllerConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "byobRequest"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableByteStreamControllerByobRequestCodeGenerator), (intptr_t) (0) } }, + { "desiredSize"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableByteStreamControllerDesiredSizeCodeGenerator), (intptr_t) (0) } }, + { "enqueue"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableByteStreamControllerEnqueueCodeGenerator), (intptr_t) (0) } }, + { "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableByteStreamControllerCloseCodeGenerator), (intptr_t) (0) } }, + { "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableByteStreamControllerErrorCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSReadableByteStreamControllerPrototype::s_info = { "ReadableByteStreamController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableByteStreamControllerPrototype) }; + +void JSReadableByteStreamControllerPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSReadableByteStreamController::info(), JSReadableByteStreamControllerPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSReadableByteStreamController::s_info = { "ReadableByteStreamController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableByteStreamController) }; + +JSReadableByteStreamController::JSReadableByteStreamController(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSReadableByteStreamController::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSReadableByteStreamController::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableByteStreamControllerPrototype::create(vm, &globalObject, JSReadableByteStreamControllerPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableByteStreamController::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableByteStreamController>(vm, globalObject); +} + +JSValue JSReadableByteStreamController::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSReadableByteStreamControllerDOMConstructor, DOMConstructorID::ReadableByteStreamController>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSReadableByteStreamController::destroy(JSC::JSCell* cell) +{ + JSReadableByteStreamController* thisObject = static_cast<JSReadableByteStreamController*>(cell); + thisObject->JSReadableByteStreamController::~JSReadableByteStreamController(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsReadableByteStreamControllerConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSReadableByteStreamControllerPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSReadableByteStreamController::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSReadableByteStreamController::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableByteStreamController, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForReadableByteStreamController.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableByteStreamController = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForReadableByteStreamController.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForReadableByteStreamController = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSReadableByteStreamController.dep b/src/bun.js/bindings/webcore/JSReadableByteStreamController.dep new file mode 100644 index 000000000..605eb3e4a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableByteStreamController.dep @@ -0,0 +1 @@ +JSReadableByteStreamController.h : diff --git a/src/bun.js/bindings/webcore/JSReadableByteStreamController.h b/src/bun.js/bindings/webcore/JSReadableByteStreamController.h new file mode 100644 index 000000000..6d512aaed --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableByteStreamController.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSReadableByteStreamController : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSReadableByteStreamController* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSReadableByteStreamController* ptr = new (NotNull, JSC::allocateCell<JSReadableByteStreamController>(globalObject->vm())) JSReadableByteStreamController(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSReadableByteStreamController(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStream.cpp b/src/bun.js/bindings/webcore/JSReadableStream.cpp new file mode 100644 index 000000000..7934bf004 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStream.cpp @@ -0,0 +1,186 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableStream.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ReadableStreamBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsReadableStreamConstructor); + +class JSReadableStreamPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableStreamPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableStreamPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamPrototype>(vm)) JSReadableStreamPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableStreamPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamPrototype, JSReadableStreamPrototype::Base); + +using JSReadableStreamDOMConstructor = JSDOMBuiltinConstructor<JSReadableStream>; + +template<> const ClassInfo JSReadableStreamDOMConstructor::s_info = { "ReadableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDOMConstructor) }; + +template<> JSValue JSReadableStreamDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSReadableStreamDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ReadableStream"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSReadableStream::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSReadableStreamDOMConstructor::initializeExecutable(VM& vm) +{ + return readableStreamInitializeReadableStreamCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSReadableStreamPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsReadableStreamConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "locked"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamLockedCodeGenerator), (intptr_t)(0) } }, + { "cancel"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamCancelCodeGenerator), (intptr_t)(0) } }, + { "getReader"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamGetReaderCodeGenerator), (intptr_t)(0) } }, + { "pipeTo"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamPipeToCodeGenerator), (intptr_t)(1) } }, + { "pipeThrough"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamPipeThroughCodeGenerator), (intptr_t)(2) } }, + { "tee"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamTeeCodeGenerator), (intptr_t)(0) } }, +}; + +const ClassInfo JSReadableStreamPrototype::s_info = { "ReadableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamPrototype) }; + +void JSReadableStreamPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + auto clientData = WebCore::clientData(vm); + this->putDirect(vm, clientData->builtinNames().bunNativePtrPrivateName(), jsNumber(0), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0); + this->putDirect(vm, clientData->builtinNames().bunNativeTypePrivateName(), jsNumber(0), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0); + reifyStaticProperties(vm, JSReadableStream::info(), JSReadableStreamPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSReadableStream::s_info = { "ReadableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStream) }; + +JSReadableStream::JSReadableStream(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) +{ +} + +void JSReadableStream::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); +} + +JSObject* JSReadableStream::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableStreamPrototype::create(vm, &globalObject, JSReadableStreamPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableStream::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableStream>(vm, globalObject); +} + +JSValue JSReadableStream::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSReadableStreamDOMConstructor, DOMConstructorID::ReadableStream>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSReadableStream::destroy(JSC::JSCell* cell) +{ + JSReadableStream* thisObject = static_cast<JSReadableStream*>(cell); + thisObject->JSReadableStream::~JSReadableStream(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSReadableStreamPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSReadableStream::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSReadableStream::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableStream, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForReadableStream.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStream = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForReadableStream.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForReadableStream = WTFMove(space); }); +} + +} diff --git a/src/bun.js/bindings/webcore/JSReadableStream.dep b/src/bun.js/bindings/webcore/JSReadableStream.dep new file mode 100644 index 000000000..f4ea48d43 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStream.dep @@ -0,0 +1 @@ +JSReadableStream.h : diff --git a/src/bun.js/bindings/webcore/JSReadableStream.h b/src/bun.js/bindings/webcore/JSReadableStream.h new file mode 100644 index 000000000..137efe15d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStream.h @@ -0,0 +1,63 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSReadableStream : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSReadableStream* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSReadableStream* ptr = new (NotNull, JSC::allocateCell<JSReadableStream>(globalObject->vm())) JSReadableStream(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + +protected: + JSReadableStream(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.cpp b/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.cpp new file mode 100644 index 000000000..e6e5b7743 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.cpp @@ -0,0 +1,184 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableStreamBYOBReader.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ReadableStreamBYOBReaderBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsReadableStreamBYOBReaderConstructor); + +class JSReadableStreamBYOBReaderPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableStreamBYOBReaderPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableStreamBYOBReaderPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamBYOBReaderPrototype>(vm)) JSReadableStreamBYOBReaderPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamBYOBReaderPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableStreamBYOBReaderPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamBYOBReaderPrototype, JSReadableStreamBYOBReaderPrototype::Base); + +using JSReadableStreamBYOBReaderDOMConstructor = JSDOMBuiltinConstructor<JSReadableStreamBYOBReader>; + +template<> const ClassInfo JSReadableStreamBYOBReaderDOMConstructor::s_info = { "ReadableStreamBYOBReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamBYOBReaderDOMConstructor) }; + +template<> JSValue JSReadableStreamBYOBReaderDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSReadableStreamBYOBReaderDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ReadableStreamBYOBReader"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSReadableStreamBYOBReader::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSReadableStreamBYOBReaderDOMConstructor::initializeExecutable(VM& vm) +{ + return readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSReadableStreamBYOBReaderPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsReadableStreamBYOBReaderConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "closed"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableStreamBYOBReaderClosedCodeGenerator), (intptr_t) (0) } }, + { "read"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableStreamBYOBReaderReadCodeGenerator), (intptr_t) (0) } }, + { "cancel"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableStreamBYOBReaderCancelCodeGenerator), (intptr_t) (0) } }, + { "releaseLock"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableStreamBYOBReaderReleaseLockCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSReadableStreamBYOBReaderPrototype::s_info = { "ReadableStreamBYOBReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamBYOBReaderPrototype) }; + +void JSReadableStreamBYOBReaderPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSReadableStreamBYOBReader::info(), JSReadableStreamBYOBReaderPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSReadableStreamBYOBReader::s_info = { "ReadableStreamBYOBReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamBYOBReader) }; + +JSReadableStreamBYOBReader::JSReadableStreamBYOBReader(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSReadableStreamBYOBReader::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSReadableStreamBYOBReader::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableStreamBYOBReaderPrototype::create(vm, &globalObject, JSReadableStreamBYOBReaderPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableStreamBYOBReader::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableStreamBYOBReader>(vm, globalObject); +} + +JSValue JSReadableStreamBYOBReader::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSReadableStreamBYOBReaderDOMConstructor, DOMConstructorID::ReadableStreamBYOBReader>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSReadableStreamBYOBReader::destroy(JSC::JSCell* cell) +{ + JSReadableStreamBYOBReader* thisObject = static_cast<JSReadableStreamBYOBReader*>(cell); + thisObject->JSReadableStreamBYOBReader::~JSReadableStreamBYOBReader(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamBYOBReaderConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSReadableStreamBYOBReaderPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSReadableStreamBYOBReader::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSReadableStreamBYOBReader::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableStreamBYOBReader, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForReadableStreamBYOBReader.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStreamBYOBReader = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForReadableStreamBYOBReader.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForReadableStreamBYOBReader = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.dep b/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.dep new file mode 100644 index 000000000..1acef694c --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.dep @@ -0,0 +1 @@ +JSReadableStreamBYOBReader.h : diff --git a/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.h b/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.h new file mode 100644 index 000000000..8d69390ae --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamBYOBReader.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSReadableStreamBYOBReader : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSReadableStreamBYOBReader* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSReadableStreamBYOBReader* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamBYOBReader>(globalObject->vm())) JSReadableStreamBYOBReader(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSReadableStreamBYOBReader(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.cpp b/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.cpp new file mode 100644 index 000000000..0b3dec469 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.cpp @@ -0,0 +1,183 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableStreamBYOBRequest.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ReadableStreamBYOBRequestBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsReadableStreamBYOBRequestConstructor); + +class JSReadableStreamBYOBRequestPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableStreamBYOBRequestPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableStreamBYOBRequestPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamBYOBRequestPrototype>(vm)) JSReadableStreamBYOBRequestPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamBYOBRequestPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableStreamBYOBRequestPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamBYOBRequestPrototype, JSReadableStreamBYOBRequestPrototype::Base); + +using JSReadableStreamBYOBRequestDOMConstructor = JSDOMBuiltinConstructor<JSReadableStreamBYOBRequest>; + +template<> const ClassInfo JSReadableStreamBYOBRequestDOMConstructor::s_info = { "ReadableStreamBYOBRequest"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamBYOBRequestDOMConstructor) }; + +template<> JSValue JSReadableStreamBYOBRequestDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSReadableStreamBYOBRequestDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(2), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ReadableStreamBYOBRequest"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSReadableStreamBYOBRequest::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSReadableStreamBYOBRequestDOMConstructor::initializeExecutable(VM& vm) +{ + return readableStreamBYOBRequestInitializeReadableStreamBYOBRequestCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSReadableStreamBYOBRequestPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsReadableStreamBYOBRequestConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "view"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableStreamBYOBRequestViewCodeGenerator), (intptr_t) (0) } }, + { "respond"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableStreamBYOBRequestRespondCodeGenerator), (intptr_t) (0) } }, + { "respondWithNewView"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(readableStreamBYOBRequestRespondWithNewViewCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSReadableStreamBYOBRequestPrototype::s_info = { "ReadableStreamBYOBRequest"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamBYOBRequestPrototype) }; + +void JSReadableStreamBYOBRequestPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSReadableStreamBYOBRequest::info(), JSReadableStreamBYOBRequestPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSReadableStreamBYOBRequest::s_info = { "ReadableStreamBYOBRequest"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamBYOBRequest) }; + +JSReadableStreamBYOBRequest::JSReadableStreamBYOBRequest(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSReadableStreamBYOBRequest::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSReadableStreamBYOBRequest::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableStreamBYOBRequestPrototype::create(vm, &globalObject, JSReadableStreamBYOBRequestPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableStreamBYOBRequest::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableStreamBYOBRequest>(vm, globalObject); +} + +JSValue JSReadableStreamBYOBRequest::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSReadableStreamBYOBRequestDOMConstructor, DOMConstructorID::ReadableStreamBYOBRequest>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSReadableStreamBYOBRequest::destroy(JSC::JSCell* cell) +{ + JSReadableStreamBYOBRequest* thisObject = static_cast<JSReadableStreamBYOBRequest*>(cell); + thisObject->JSReadableStreamBYOBRequest::~JSReadableStreamBYOBRequest(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamBYOBRequestConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSReadableStreamBYOBRequestPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSReadableStreamBYOBRequest::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSReadableStreamBYOBRequest::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableStreamBYOBRequest, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForReadableStreamBYOBRequest.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStreamBYOBRequest = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForReadableStreamBYOBRequest.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForReadableStreamBYOBRequest = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.dep b/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.dep new file mode 100644 index 000000000..12e0f602d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.dep @@ -0,0 +1 @@ +JSReadableStreamBYOBRequest.h : diff --git a/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.h b/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.h new file mode 100644 index 000000000..39f18c229 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamBYOBRequest.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSReadableStreamBYOBRequest : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSReadableStreamBYOBRequest* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSReadableStreamBYOBRequest* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamBYOBRequest>(globalObject->vm())) JSReadableStreamBYOBRequest(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSReadableStreamBYOBRequest(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp new file mode 100644 index 000000000..c914cf022 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.cpp @@ -0,0 +1,184 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableStreamDefaultController.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ReadableStreamDefaultControllerBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsReadableStreamDefaultControllerConstructor); + +class JSReadableStreamDefaultControllerPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableStreamDefaultControllerPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableStreamDefaultControllerPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultControllerPrototype>(vm)) JSReadableStreamDefaultControllerPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamDefaultControllerPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableStreamDefaultControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamDefaultControllerPrototype, JSReadableStreamDefaultControllerPrototype::Base); + +using JSReadableStreamDefaultControllerDOMConstructor = JSDOMBuiltinConstructor<JSReadableStreamDefaultController>; + +template<> const ClassInfo JSReadableStreamDefaultControllerDOMConstructor::s_info = { "ReadableStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultControllerDOMConstructor) }; + +template<> JSValue JSReadableStreamDefaultControllerDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSReadableStreamDefaultControllerDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(4), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ReadableStreamDefaultController"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSReadableStreamDefaultController::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSReadableStreamDefaultControllerDOMConstructor::initializeExecutable(VM& vm) +{ + return readableStreamDefaultControllerInitializeReadableStreamDefaultControllerCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSReadableStreamDefaultControllerPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsReadableStreamDefaultControllerConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "desiredSize"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultControllerDesiredSizeCodeGenerator), (intptr_t)(0) } }, + { "enqueue"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultControllerEnqueueCodeGenerator), (intptr_t)(0) } }, + { "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultControllerCloseCodeGenerator), (intptr_t)(0) } }, + { "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultControllerErrorCodeGenerator), (intptr_t)(0) } }, +}; + +const ClassInfo JSReadableStreamDefaultControllerPrototype::s_info = { "ReadableStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultControllerPrototype) }; + +void JSReadableStreamDefaultControllerPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSReadableStreamDefaultController::info(), JSReadableStreamDefaultControllerPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); + + auto clientData = WebCore::clientData(vm); + this->putDirect(vm, clientData->builtinNames().sinkPublicName(), jsUndefined(), JSC::PropertyAttribute::DontDelete | 0); +} + +const ClassInfo JSReadableStreamDefaultController::s_info = { "ReadableStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultController) }; + +JSReadableStreamDefaultController::JSReadableStreamDefaultController(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) +{ +} + +void JSReadableStreamDefaultController::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); +} + +JSObject* JSReadableStreamDefaultController::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableStreamDefaultControllerPrototype::create(vm, &globalObject, JSReadableStreamDefaultControllerPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableStreamDefaultController::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableStreamDefaultController>(vm, globalObject); +} + +JSValue JSReadableStreamDefaultController::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSReadableStreamDefaultControllerDOMConstructor, DOMConstructorID::ReadableStreamDefaultController>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSReadableStreamDefaultController::destroy(JSC::JSCell* cell) +{ + JSReadableStreamDefaultController* thisObject = static_cast<JSReadableStreamDefaultController*>(cell); + thisObject->JSReadableStreamDefaultController::~JSReadableStreamDefaultController(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamDefaultControllerConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSReadableStreamDefaultControllerPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSReadableStreamDefaultController::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSReadableStreamDefaultController::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableStreamDefaultController, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForReadableStreamDefaultController.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStreamDefaultController = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForReadableStreamDefaultController.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForReadableStreamDefaultController = WTFMove(space); }); +} + +} diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.dep b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.dep new file mode 100644 index 000000000..3e3e1cd15 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.dep @@ -0,0 +1 @@ +JSReadableStreamDefaultController.h : diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.h b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.h new file mode 100644 index 000000000..a38c95daf --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultController.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSReadableStreamDefaultController : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSReadableStreamDefaultController* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSReadableStreamDefaultController* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultController>(globalObject->vm())) JSReadableStreamDefaultController(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSReadableStreamDefaultController(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp new file mode 100644 index 000000000..d1080c17e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.cpp @@ -0,0 +1,182 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableStreamDefaultReader.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ReadableStreamDefaultReaderBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsReadableStreamDefaultReaderConstructor); + +class JSReadableStreamDefaultReaderPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableStreamDefaultReaderPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableStreamDefaultReaderPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultReaderPrototype>(vm)) JSReadableStreamDefaultReaderPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamDefaultReaderPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableStreamDefaultReaderPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamDefaultReaderPrototype, JSReadableStreamDefaultReaderPrototype::Base); + +using JSReadableStreamDefaultReaderDOMConstructor = JSDOMBuiltinConstructor<JSReadableStreamDefaultReader>; + +template<> const ClassInfo JSReadableStreamDefaultReaderDOMConstructor::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReaderDOMConstructor) }; + +template<> JSValue JSReadableStreamDefaultReaderDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSReadableStreamDefaultReaderDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ReadableStreamDefaultReader"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSReadableStreamDefaultReader::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSReadableStreamDefaultReaderDOMConstructor::initializeExecutable(VM& vm) +{ + return readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSReadableStreamDefaultReaderPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsReadableStreamDefaultReaderConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "closed"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultReaderClosedCodeGenerator), (intptr_t)(0) } }, + { "read"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultReaderReadCodeGenerator), (intptr_t)(0) } }, + { "readMany"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultReaderReadManyCodeGenerator), (intptr_t)(0) } }, + { "cancel"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultReaderCancelCodeGenerator), (intptr_t)(0) } }, + { "releaseLock"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t) static_cast<BuiltinGenerator>(readableStreamDefaultReaderReleaseLockCodeGenerator), (intptr_t)(0) } }, +}; + +const ClassInfo JSReadableStreamDefaultReaderPrototype::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReaderPrototype) }; + +void JSReadableStreamDefaultReaderPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSReadableStreamDefaultReader::info(), JSReadableStreamDefaultReaderPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSReadableStreamDefaultReader::s_info = { "ReadableStreamDefaultReader"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamDefaultReader) }; + +JSReadableStreamDefaultReader::JSReadableStreamDefaultReader(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) +{ +} + +void JSReadableStreamDefaultReader::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); +} + +JSObject* JSReadableStreamDefaultReader::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableStreamDefaultReaderPrototype::create(vm, &globalObject, JSReadableStreamDefaultReaderPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableStreamDefaultReader::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableStreamDefaultReader>(vm, globalObject); +} + +JSValue JSReadableStreamDefaultReader::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSReadableStreamDefaultReaderDOMConstructor, DOMConstructorID::ReadableStreamDefaultReader>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSReadableStreamDefaultReader::destroy(JSC::JSCell* cell) +{ + JSReadableStreamDefaultReader* thisObject = static_cast<JSReadableStreamDefaultReader*>(cell); + thisObject->JSReadableStreamDefaultReader::~JSReadableStreamDefaultReader(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamDefaultReaderConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSReadableStreamDefaultReaderPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSReadableStreamDefaultReader::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSReadableStreamDefaultReader::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableStreamDefaultReader, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForReadableStreamDefaultReader.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStreamDefaultReader = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForReadableStreamDefaultReader.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForReadableStreamDefaultReader = WTFMove(space); }); +} + +} diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.dep b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.dep new file mode 100644 index 000000000..466ee5c61 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.dep @@ -0,0 +1 @@ +JSReadableStreamDefaultReader.h : diff --git a/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.h b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.h new file mode 100644 index 000000000..61a4d1336 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamDefaultReader.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSReadableStreamDefaultReader : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSReadableStreamDefaultReader* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSReadableStreamDefaultReader* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamDefaultReader>(globalObject->vm())) JSReadableStreamDefaultReader(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSReadableStreamDefaultReader(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStreamSink.cpp b/src/bun.js/bindings/webcore/JSReadableStreamSink.cpp new file mode 100644 index 000000000..2fd819460 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamSink.cpp @@ -0,0 +1,243 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableStreamSink.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMBinding.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBufferSource.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMConvertUnion.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <variant> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsReadableStreamSinkPrototypeFunction_enqueue); +static JSC_DECLARE_HOST_FUNCTION(jsReadableStreamSinkPrototypeFunction_close); +static JSC_DECLARE_HOST_FUNCTION(jsReadableStreamSinkPrototypeFunction_error); + +class JSReadableStreamSinkPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableStreamSinkPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableStreamSinkPrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamSinkPrototype>(vm)) JSReadableStreamSinkPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamSinkPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableStreamSinkPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamSinkPrototype, JSReadableStreamSinkPrototype::Base); + +/* Hash table for prototype */ + +static const HashTableValue JSReadableStreamSinkPrototypeTableValues[] = { + { "enqueue"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsReadableStreamSinkPrototypeFunction_enqueue), (intptr_t)(1) } }, + { "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsReadableStreamSinkPrototypeFunction_close), (intptr_t)(0) } }, + { "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsReadableStreamSinkPrototypeFunction_error), (intptr_t)(1) } }, +}; + +const ClassInfo JSReadableStreamSinkPrototype::s_info = { "ReadableStreamSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamSinkPrototype) }; + +void JSReadableStreamSinkPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSReadableStreamSink::info(), JSReadableStreamSinkPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSReadableStreamSink::s_info = { "ReadableStreamSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamSink) }; + +JSReadableStreamSink::JSReadableStreamSink(Structure* structure, JSDOMGlobalObject& globalObject, Ref<ReadableStreamSink>&& impl) + : JSDOMWrapper<ReadableStreamSink>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSReadableStreamSink::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, ReadableStreamSink>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSReadableStreamSink::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableStreamSinkPrototype::create(vm, &globalObject, JSReadableStreamSinkPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableStreamSink::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableStreamSink>(vm, globalObject); +} + +void JSReadableStreamSink::destroy(JSC::JSCell* cell) +{ + JSReadableStreamSink* thisObject = static_cast<JSReadableStreamSink*>(cell); + thisObject->JSReadableStreamSink::~JSReadableStreamSink(); +} + +static inline JSC::EncodedJSValue jsReadableStreamSinkPrototypeFunction_enqueueBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSReadableStreamSink>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto chunk = convert<IDLUnion<IDLArrayBufferView, IDLArrayBuffer>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.enqueue(WTFMove(chunk)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsReadableStreamSinkPrototypeFunction_enqueue, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSReadableStreamSink>::call<jsReadableStreamSinkPrototypeFunction_enqueueBody>(*lexicalGlobalObject, *callFrame, "enqueue"); +} + +static inline JSC::EncodedJSValue jsReadableStreamSinkPrototypeFunction_closeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSReadableStreamSink>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.close(); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsReadableStreamSinkPrototypeFunction_close, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSReadableStreamSink>::call<jsReadableStreamSinkPrototypeFunction_closeBody>(*lexicalGlobalObject, *callFrame, "close"); +} + +static inline JSC::EncodedJSValue jsReadableStreamSinkPrototypeFunction_errorBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSReadableStreamSink>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto message = convert<IDLDOMString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.error(WTFMove(message)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsReadableStreamSinkPrototypeFunction_error, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSReadableStreamSink>::call<jsReadableStreamSinkPrototypeFunction_errorBody>(*lexicalGlobalObject, *callFrame, "error"); +} + +JSC::GCClient::IsoSubspace* JSReadableStreamSink::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableStreamSink, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForReadableStreamSink.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStreamSink = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForReadableStreamSink.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForReadableStreamSink = WTFMove(space); }); +} + +void JSReadableStreamSink::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSReadableStreamSink*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSReadableStreamSinkOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSReadableStreamSinkOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsReadableStreamSink = static_cast<JSReadableStreamSink*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsReadableStreamSink->wrapped(), jsReadableStreamSink); +} + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<ReadableStreamSink>&& impl) +{ + return createWrapper<ReadableStreamSink>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ReadableStreamSink& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +ReadableStreamSink* JSReadableStreamSink::toWrapped(JSC::VM&, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSReadableStreamSink*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSReadableStreamSink.dep b/src/bun.js/bindings/webcore/JSReadableStreamSink.dep new file mode 100644 index 000000000..9c5594686 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamSink.dep @@ -0,0 +1 @@ +JSReadableStreamSink.h : diff --git a/src/bun.js/bindings/webcore/JSReadableStreamSink.h b/src/bun.js/bindings/webcore/JSReadableStreamSink.h new file mode 100644 index 000000000..83fa457ad --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamSink.h @@ -0,0 +1,92 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" +#include "ReadableStreamSink.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSReadableStreamSink : public JSDOMWrapper<ReadableStreamSink> { +public: + using Base = JSDOMWrapper<ReadableStreamSink>; + static JSReadableStreamSink* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<ReadableStreamSink>&& impl) + { + JSReadableStreamSink* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamSink>(globalObject->vm())) JSReadableStreamSink(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static ReadableStreamSink* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); +protected: + JSReadableStreamSink(JSC::Structure*, JSDOMGlobalObject&, Ref<ReadableStreamSink>&&); + + void finishCreation(JSC::VM&); +}; + +class JSReadableStreamSinkOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, ReadableStreamSink*) +{ + static NeverDestroyed<JSReadableStreamSinkOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(ReadableStreamSink* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, ReadableStreamSink&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ReadableStreamSink* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<ReadableStreamSink>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<ReadableStreamSink>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<ReadableStreamSink> { + using WrapperClass = JSReadableStreamSink; + using ToWrappedReturnType = ReadableStreamSink*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStreamSource.cpp b/src/bun.js/bindings/webcore/JSReadableStreamSource.cpp new file mode 100644 index 000000000..af62fd511 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamSource.cpp @@ -0,0 +1,268 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSReadableStreamSource.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertBase.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMOperation.h" +#include "JSDOMOperationReturningPromise.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsReadableStreamSourcePrototypeFunction_start); +static JSC_DECLARE_HOST_FUNCTION(jsReadableStreamSourcePrototypeFunction_pull); +static JSC_DECLARE_HOST_FUNCTION(jsReadableStreamSourcePrototypeFunction_cancel); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsReadableStreamSource_controller); + +class JSReadableStreamSourcePrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSReadableStreamSourcePrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSReadableStreamSourcePrototype* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamSourcePrototype>(vm)) JSReadableStreamSourcePrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamSourcePrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSReadableStreamSourcePrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSReadableStreamSourcePrototype, JSReadableStreamSourcePrototype::Base); + +/* Hash table for prototype */ + +static const HashTableValue JSReadableStreamSourcePrototypeTableValues[] = { + { "controller"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsReadableStreamSource_controller), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "start"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsReadableStreamSourcePrototypeFunction_start), (intptr_t)(1) } }, + { "pull"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsReadableStreamSourcePrototypeFunction_pull), (intptr_t)(1) } }, + { "cancel"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsReadableStreamSourcePrototypeFunction_cancel), (intptr_t)(1) } }, +}; + +const ClassInfo JSReadableStreamSourcePrototype::s_info = { "ReadableStreamSource"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamSourcePrototype) }; + +void JSReadableStreamSourcePrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + // -- BUN ADDITION -- + auto clientData = WebCore::clientData(vm); + this->putDirect(vm, clientData->builtinNames().bunNativePtrPrivateName(), jsNumber(0), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0); + this->putDirect(vm, clientData->builtinNames().bunNativeTypePrivateName(), jsNumber(0), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | 0); + // -- BUN ADDITION -- + + reifyStaticProperties(vm, JSReadableStreamSource::info(), JSReadableStreamSourcePrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSReadableStreamSource::s_info = { "ReadableStreamSource"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSReadableStreamSource) }; + +JSReadableStreamSource::JSReadableStreamSource(Structure* structure, JSDOMGlobalObject& globalObject, Ref<ReadableStreamSource>&& impl) + : JSDOMWrapper<ReadableStreamSource>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSReadableStreamSource::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, ReadableStreamSource>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSReadableStreamSource::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSReadableStreamSourcePrototype::create(vm, &globalObject, JSReadableStreamSourcePrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSReadableStreamSource::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSReadableStreamSource>(vm, globalObject); +} + +void JSReadableStreamSource::destroy(JSC::JSCell* cell) +{ + JSReadableStreamSource* thisObject = static_cast<JSReadableStreamSource*>(cell); + thisObject->JSReadableStreamSource::~JSReadableStreamSource(); +} + +static inline JSValue jsReadableStreamSource_controllerGetter(JSGlobalObject& lexicalGlobalObject, JSReadableStreamSource& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return thisObject.controller(lexicalGlobalObject); +} + +JSC_DEFINE_CUSTOM_GETTER(jsReadableStreamSource_controller, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSReadableStreamSource>::get<jsReadableStreamSource_controllerGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSC::EncodedJSValue jsReadableStreamSourcePrototypeFunction_startBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSReadableStreamSource>::ClassParameter castedThis, Ref<DeferredPromise>&& promise) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + RELEASE_AND_RETURN(throwScope, (JSValue::encode(castedThis->start(*lexicalGlobalObject, *callFrame, WTFMove(promise))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsReadableStreamSourcePrototypeFunction_start, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperationReturningPromise<JSReadableStreamSource>::call<jsReadableStreamSourcePrototypeFunction_startBody>(*lexicalGlobalObject, *callFrame, "start"); +} + +static inline JSC::EncodedJSValue jsReadableStreamSourcePrototypeFunction_pullBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSReadableStreamSource>::ClassParameter castedThis, Ref<DeferredPromise>&& promise) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + RELEASE_AND_RETURN(throwScope, (JSValue::encode(castedThis->pull(*lexicalGlobalObject, *callFrame, WTFMove(promise))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsReadableStreamSourcePrototypeFunction_pull, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperationReturningPromise<JSReadableStreamSource>::call<jsReadableStreamSourcePrototypeFunction_pullBody>(*lexicalGlobalObject, *callFrame, "pull"); +} + +static inline JSC::EncodedJSValue jsReadableStreamSourcePrototypeFunction_cancelBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSReadableStreamSource>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto reason = convert<IDLAny>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.cancel(WTFMove(reason)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsReadableStreamSourcePrototypeFunction_cancel, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSReadableStreamSource>::call<jsReadableStreamSourcePrototypeFunction_cancelBody>(*lexicalGlobalObject, *callFrame, "cancel"); +} + +JSC::GCClient::IsoSubspace* JSReadableStreamSource::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSReadableStreamSource, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForReadableStreamSource.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForReadableStreamSource = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForReadableStreamSource.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForReadableStreamSource = WTFMove(space); }); +} + +template<typename Visitor> +void JSReadableStreamSource::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast<JSReadableStreamSource*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + visitor.append(thisObject->m_controller); +} + +DEFINE_VISIT_CHILDREN(JSReadableStreamSource); + +void JSReadableStreamSource::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSReadableStreamSource*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSReadableStreamSourceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSReadableStreamSourceOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsReadableStreamSource = static_cast<JSReadableStreamSource*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsReadableStreamSource->wrapped(), jsReadableStreamSource); +} + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<ReadableStreamSource>&& impl) +{ + return createWrapper<ReadableStreamSource>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ReadableStreamSource& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +ReadableStreamSource* JSReadableStreamSource::toWrapped(JSC::VM&, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSReadableStreamSource*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSReadableStreamSource.dep b/src/bun.js/bindings/webcore/JSReadableStreamSource.dep new file mode 100644 index 000000000..f459688e5 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamSource.dep @@ -0,0 +1 @@ +JSReadableStreamSource.h : diff --git a/src/bun.js/bindings/webcore/JSReadableStreamSource.h b/src/bun.js/bindings/webcore/JSReadableStreamSource.h new file mode 100644 index 000000000..4a7fec950 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamSource.h @@ -0,0 +1,102 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" +#include "ReadableStreamSource.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSReadableStreamSource : public JSDOMWrapper<ReadableStreamSource> { +public: + using Base = JSDOMWrapper<ReadableStreamSource>; + static JSReadableStreamSource* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<ReadableStreamSource>&& impl) + { + JSReadableStreamSource* ptr = new (NotNull, JSC::allocateCell<JSReadableStreamSource>(globalObject->vm())) JSReadableStreamSource(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static ReadableStreamSource* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + mutable JSC::WriteBarrier<JSC::Unknown> m_controller; + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + DECLARE_VISIT_CHILDREN; + + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + + // Custom attributes + JSC::JSValue controller(JSC::JSGlobalObject&) const; + + // Custom functions + JSC::JSValue start(JSC::JSGlobalObject&, JSC::CallFrame&, Ref<DeferredPromise>&&); + JSC::JSValue pull(JSC::JSGlobalObject&, JSC::CallFrame&, Ref<DeferredPromise>&&); +protected: + JSReadableStreamSource(JSC::Structure*, JSDOMGlobalObject&, Ref<ReadableStreamSource>&&); + + void finishCreation(JSC::VM&); +}; + +class JSReadableStreamSourceOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, ReadableStreamSource*) +{ + static NeverDestroyed<JSReadableStreamSourceOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(ReadableStreamSource* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, ReadableStreamSource&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ReadableStreamSource* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<ReadableStreamSource>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<ReadableStreamSource>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<ReadableStreamSource> { + using WrapperClass = JSReadableStreamSource; + using ToWrappedReturnType = ReadableStreamSource*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSReadableStreamSourceCustom.cpp b/src/bun.js/bindings/webcore/JSReadableStreamSourceCustom.cpp new file mode 100644 index 000000000..476c0f852 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSReadableStreamSourceCustom.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2016 Canon Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions + * are required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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. + */ + +#include "config.h" +#include "JSReadableStreamSource.h" + +#include "JSDOMPromiseDeferred.h" + +namespace WebCore { +using namespace JSC; + +JSValue JSReadableStreamSource::start(JSGlobalObject& lexicalGlobalObject, CallFrame& callFrame, Ref<DeferredPromise>&& promise) +{ + VM& vm = lexicalGlobalObject.vm(); + + // FIXME: Why is it ok to ASSERT the argument count here? + ASSERT(callFrame.argumentCount()); + JSReadableStreamDefaultController* controller = jsDynamicCast<JSReadableStreamDefaultController*>(callFrame.uncheckedArgument(0)); + ASSERT(controller); + + m_controller.set(vm, this, controller); + + wrapped().start(ReadableStreamDefaultController(controller), WTFMove(promise)); + + return jsUndefined(); +} + +JSValue JSReadableStreamSource::pull(JSGlobalObject&, CallFrame&, Ref<DeferredPromise>&& promise) +{ + wrapped().pull(WTFMove(promise)); + return jsUndefined(); +} + +JSValue JSReadableStreamSource::controller(JSGlobalObject&) const +{ + ASSERT_NOT_REACHED(); + return jsUndefined(); +} + +} diff --git a/src/bun.js/bindings/webcore/JSServiceWorker.h b/src/bun.js/bindings/webcore/JSServiceWorker.h new file mode 100644 index 000000000..d067d0b5a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSServiceWorker.h @@ -0,0 +1 @@ +// stub
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSTextEncoder.cpp b/src/bun.js/bindings/webcore/JSTextEncoder.cpp new file mode 100644 index 000000000..c12c94d56 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTextEncoder.cpp @@ -0,0 +1,423 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "root.h" + +#include "JSTextEncoder.h" + +#include "JavaScriptCore/JavaScript.h" +#include "JavaScriptCore/APICast.h" + +#include "JavaScriptCore/FunctionPrototype.h" +#include "JavaScriptCore/HeapAnalyzer.h" +#include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" +#include "JavaScriptCore/ObjectConstructor.h" +#include "JavaScriptCore/SlotVisitorMacros.h" +#include "JavaScriptCore/SubspaceInlines.h" +#include "wtf/GetPtr.h" +#include "wtf/PointerPreparations.h" +#include "wtf/URL.h" +// #include "JavaScriptCore/JSTypedArrays.h" + +#include "GCDefferalContext.h" +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +// #include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +// #include "JSDOMConvertBufferSource.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertStrings.h" +// #include "JSDOMExceptionHandling.h" +// #include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +// #include "ScriptExecutionContext.h" +// #include "WebCoreJSClientData.h" + +namespace WebCore { +using namespace JSC; + +template<> TextEncoder::EncodeIntoResult convertDictionary<TextEncoder::EncodeIntoResult>(JSGlobalObject& lexicalGlobalObject, JSValue value) +{ + VM& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + bool isNullOrUndefined = value.isUndefinedOrNull(); + auto* object = isNullOrUndefined ? nullptr : value.getObject(); + if (UNLIKELY(!isNullOrUndefined && !object)) { + throwTypeError(&lexicalGlobalObject, throwScope); + return {}; + } + TextEncoder::EncodeIntoResult result; + JSValue readValue; + if (isNullOrUndefined) + readValue = jsUndefined(); + else { + readValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "read"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!readValue.isUndefined()) { + result.read = convert<IDLUnsignedLongLong>(lexicalGlobalObject, readValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } + JSValue writtenValue; + if (isNullOrUndefined) + writtenValue = jsUndefined(); + else { + writtenValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "written"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + } + if (!writtenValue.isUndefined()) { + result.written = convert<IDLUnsignedLongLong>(lexicalGlobalObject, writtenValue); + RETURN_IF_EXCEPTION(throwScope, {}); + } + return result; +} + +JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const TextEncoder::EncodeIntoResult& dictionary) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + + auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype()); + + if (!IDLUnsignedLongLong::isNullValue(dictionary.read)) { + auto readValue = toJS<IDLUnsignedLongLong>(lexicalGlobalObject, throwScope, IDLUnsignedLongLong::extractValueFromNullable(dictionary.read)); + RETURN_IF_EXCEPTION(throwScope, {}); + result->putDirect(vm, JSC::Identifier::fromString(vm, "read"_s), readValue); + } + if (!IDLUnsignedLongLong::isNullValue(dictionary.written)) { + auto writtenValue = toJS<IDLUnsignedLongLong>(lexicalGlobalObject, throwScope, IDLUnsignedLongLong::extractValueFromNullable(dictionary.written)); + RETURN_IF_EXCEPTION(throwScope, {}); + result->putDirect(vm, JSC::Identifier::fromString(vm, "written"_s), writtenValue); + } + return result; +} + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsTextEncoderPrototypeFunction_encode); +static JSC_DECLARE_HOST_FUNCTION(jsTextEncoderPrototypeFunction_encodeInto); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsTextEncoderConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsTextEncoder_encoding); + +class JSTextEncoderPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSTextEncoderPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSTextEncoderPrototype* ptr = new (NotNull, JSC::allocateCell<JSTextEncoderPrototype>(vm)) JSTextEncoderPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTextEncoderPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSTextEncoderPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTextEncoderPrototype, JSTextEncoderPrototype::Base); + +using JSTextEncoderDOMConstructor = JSDOMConstructor<JSTextEncoder>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSTextEncoderDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSTextEncoderDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + auto object = TextEncoder::create(); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<TextEncoder>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<TextEncoder>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSTextEncoderDOMConstructorConstruct, JSTextEncoderDOMConstructor::construct); + +template<> const ClassInfo JSTextEncoderDOMConstructor::s_info = { "TextEncoder"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTextEncoderDOMConstructor) }; + +template<> JSValue JSTextEncoderDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSTextEncoderDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "TextEncoder"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSTextEncoder::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSTextEncoderPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsTextEncoderConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "encoding"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsTextEncoder_encoding), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "encode"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsTextEncoderPrototypeFunction_encode), (intptr_t)(0) } }, + { "encodeInto"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsTextEncoderPrototypeFunction_encodeInto), (intptr_t)(2) } }, +}; + +const ClassInfo JSTextEncoderPrototype::s_info = { "TextEncoder"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTextEncoderPrototype) }; + +void JSTextEncoderPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSTextEncoder::info(), JSTextEncoderPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSTextEncoder::s_info = { "TextEncoder"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTextEncoder) }; + +JSTextEncoder::JSTextEncoder(Structure* structure, JSDOMGlobalObject& globalObject, Ref<TextEncoder>&& impl) + : JSDOMWrapper<TextEncoder>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSTextEncoder::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, TextEncoder>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSTextEncoder::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSTextEncoderPrototype::create(vm, &globalObject, JSTextEncoderPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSTextEncoder::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSTextEncoder>(vm, globalObject); +} + +JSValue JSTextEncoder::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSTextEncoderDOMConstructor, DOMConstructorID::TextEncoder>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSTextEncoder::destroy(JSC::JSCell* cell) +{ + JSTextEncoder* thisObject = static_cast<JSTextEncoder*>(cell); + thisObject->JSTextEncoder::~JSTextEncoder(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsTextEncoderConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSTextEncoderPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSTextEncoder::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsTextEncoder_encodingGetter(JSGlobalObject& lexicalGlobalObject, JSTextEncoder& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.encoding()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsTextEncoder_encoding, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSTextEncoder>::get<jsTextEncoder_encodingGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +extern "C" JSC::EncodedJSValue TextEncoder__encode(JSC::JSGlobalObject* lexicalGlobalObject, const ZigString*); +extern "C" JSC::EncodedJSValue TextEncoder__encodeInto(JSC::JSGlobalObject* lexicalGlobalObject, const ZigString*, void* ptr, size_t len); +extern "C" JSC::EncodedJSValue TextEncoder__encodeRopeString(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSString* str); + +static inline JSC::EncodedJSValue jsTextEncoderPrototypeFunction_encodeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSTextEncoder>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + EnsureStillAliveScope argument0 = callFrame->argument(0); + JSC::JSString* input = argument0.value().toStringOrNull(lexicalGlobalObject); + if (input && input->is8Bit() && input->isRope()) { + auto encodedValue = TextEncoder__encodeRopeString(lexicalGlobalObject, input); + if (!JSC::JSValue::decode(encodedValue).isUndefined()) { + RELEASE_AND_RETURN(throwScope, encodedValue); + } + } + + auto str = Zig::toZigString(input->tryGetValue(lexicalGlobalObject)); + auto res = TextEncoder__encode(lexicalGlobalObject, &str); + if (UNLIKELY(JSC::JSValue::decode(res).isObject() && JSC::JSValue::decode(res).getObject()->isErrorInstance())) { + throwScope.throwException(lexicalGlobalObject, JSC::JSValue::decode(res)); + return encodedJSValue(); + } + RELEASE_AND_RETURN(throwScope, res); +} + +JSC_DEFINE_HOST_FUNCTION(jsTextEncoderPrototypeFunction_encode, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSTextEncoder>::call<jsTextEncoderPrototypeFunction_encodeBody>(*lexicalGlobalObject, *callFrame, "encode"); +} + +static inline JSC::EncodedJSValue jsTextEncoderPrototypeFunction_encodeIntoBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSTextEncoder>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 2)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto source = argument0.value().toWTFString(lexicalGlobalObject); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto* destination = JSC::jsDynamicCast<JSC::JSUint8Array*>(argument1.value()); + if (!destination) { + throwVMTypeError(lexicalGlobalObject, throwScope, "Expected Uint8Array"_s); + return encodedJSValue(); + } + + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto str = Zig::toZigString(WTFMove(source)); + auto res = TextEncoder__encodeInto(lexicalGlobalObject, &str, destination->vector(), destination->length()); + if (UNLIKELY(JSC::JSValue::decode(res).isObject() && JSC::JSValue::decode(res).getObject()->isErrorInstance())) { + throwScope.throwException(lexicalGlobalObject, JSC::JSValue::decode(res)); + return encodedJSValue(); + } + + RELEASE_AND_RETURN(throwScope, res); +} + +JSC_DEFINE_HOST_FUNCTION(jsTextEncoderPrototypeFunction_encodeInto, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSTextEncoder>::call<jsTextEncoderPrototypeFunction_encodeIntoBody>(*lexicalGlobalObject, *callFrame, "encodeInto"); +} + +JSC::GCClient::IsoSubspace* JSTextEncoder::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSTextEncoder, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForTextEncoder.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForTextEncoder = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForTextEncoder.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForTextEncoder = WTFMove(space); }); +} + +void JSTextEncoder::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSTextEncoder*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSTextEncoderOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSTextEncoderOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsTextEncoder = static_cast<JSTextEncoder*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsTextEncoder->wrapped(), jsTextEncoder); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7TextEncoder@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore11TextEncoderE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<TextEncoder>&& impl) +{ + + if constexpr (std::is_polymorphic_v<TextEncoder>) { +#if ENABLE(BINDING_INTEGRITY) + const void* actualVTablePointer = getVTablePointer(impl.ptr()); +#if PLATFORM(WIN) + void* expectedVTablePointer = __identifier("??_7TextEncoder@WebCore@@6B@"); +#else + void* expectedVTablePointer = &_ZTVN7WebCore11TextEncoderE[2]; +#endif + + // If you hit this assertion you either have a use after free bug, or + // TextEncoder has subclasses. If TextEncoder has subclasses that get passed + // to toJS() we currently require TextEncoder you to opt out of binding hardening + // by adding the SkipVTableValidation attribute to the interface IDL definition + RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); +#endif + } + return createWrapper<TextEncoder>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, TextEncoder& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +TextEncoder* JSTextEncoder::toWrapped(JSC::VM&, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSTextEncoder*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSTextEncoder.dep b/src/bun.js/bindings/webcore/JSTextEncoder.dep new file mode 100644 index 000000000..bdb1dfb7c --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTextEncoder.dep @@ -0,0 +1 @@ +JSTextEncoder.h : diff --git a/src/bun.js/bindings/webcore/JSTextEncoder.h b/src/bun.js/bindings/webcore/JSTextEncoder.h new file mode 100644 index 000000000..e37b96256 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTextEncoder.h @@ -0,0 +1,100 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "root.h" + +#include "JSDOMConvertDictionary.h" +#include "JSDOMWrapper.h" +#include "TextEncoder.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSTextEncoder : public JSDOMWrapper<TextEncoder> { +public: + using Base = JSDOMWrapper<TextEncoder>; + static JSTextEncoder* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<TextEncoder>&& impl) + { + JSTextEncoder* ptr = new (NotNull, JSC::allocateCell<JSTextEncoder>(globalObject->vm())) JSTextEncoder(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static TextEncoder* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +protected: + JSTextEncoder(JSC::Structure*, JSDOMGlobalObject&, Ref<TextEncoder>&&); + + void finishCreation(JSC::VM&); +}; + +class JSTextEncoderOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, TextEncoder*) +{ + static NeverDestroyed<JSTextEncoderOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(TextEncoder* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, TextEncoder&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, TextEncoder* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<TextEncoder>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<TextEncoder>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<TextEncoder> { + using WrapperClass = JSTextEncoder; + using ToWrappedReturnType = TextEncoder*; +}; +template<> TextEncoder::EncodeIntoResult convertDictionary<TextEncoder::EncodeIntoResult>(JSC::JSGlobalObject&, JSC::JSValue); + +JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const TextEncoder::EncodeIntoResult&); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSTransformStream.cpp b/src/bun.js/bindings/webcore/JSTransformStream.cpp new file mode 100644 index 000000000..68b9c4dae --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTransformStream.cpp @@ -0,0 +1,178 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSTransformStream.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMWrapperCache.h" +#include "TransformStreamBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsTransformStreamConstructor); + +class JSTransformStreamPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSTransformStreamPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSTransformStreamPrototype* ptr = new (NotNull, JSC::allocateCell<JSTransformStreamPrototype>(vm)) JSTransformStreamPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTransformStreamPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSTransformStreamPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTransformStreamPrototype, JSTransformStreamPrototype::Base); + +using JSTransformStreamDOMConstructor = JSDOMBuiltinConstructor<JSTransformStream>; + +template<> const ClassInfo JSTransformStreamDOMConstructor::s_info = { "TransformStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTransformStreamDOMConstructor) }; + +template<> JSValue JSTransformStreamDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSTransformStreamDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "TransformStream"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSTransformStream::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSTransformStreamDOMConstructor::initializeExecutable(VM& vm) +{ + return transformStreamInitializeTransformStreamCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSTransformStreamPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTransformStreamConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "readable"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(transformStreamReadableCodeGenerator), (intptr_t) (0) } }, + { "writable"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(transformStreamWritableCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSTransformStreamPrototype::s_info = { "TransformStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTransformStreamPrototype) }; + +void JSTransformStreamPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSTransformStream::info(), JSTransformStreamPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSTransformStream::s_info = { "TransformStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTransformStream) }; + +JSTransformStream::JSTransformStream(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSTransformStream::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSTransformStream::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSTransformStreamPrototype::create(vm, &globalObject, JSTransformStreamPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSTransformStream::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSTransformStream>(vm, globalObject); +} + +JSValue JSTransformStream::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSTransformStreamDOMConstructor, DOMConstructorID::TransformStream>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSTransformStream::destroy(JSC::JSCell* cell) +{ + JSTransformStream* thisObject = static_cast<JSTransformStream*>(cell); + thisObject->JSTransformStream::~JSTransformStream(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsTransformStreamConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSTransformStreamPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSTransformStream::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSTransformStream::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSTransformStream, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForTransformStream.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForTransformStream = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForTransformStream.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForTransformStream = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSTransformStream.dep b/src/bun.js/bindings/webcore/JSTransformStream.dep new file mode 100644 index 000000000..30374925b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTransformStream.dep @@ -0,0 +1 @@ +JSTransformStream.h : diff --git a/src/bun.js/bindings/webcore/JSTransformStream.h b/src/bun.js/bindings/webcore/JSTransformStream.h new file mode 100644 index 000000000..26646df03 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTransformStream.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSTransformStream : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSTransformStream* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSTransformStream* ptr = new (NotNull, JSC::allocateCell<JSTransformStream>(globalObject->vm())) JSTransformStream(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSTransformStream(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.cpp b/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.cpp new file mode 100644 index 000000000..77532ac9e --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.cpp @@ -0,0 +1,184 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSTransformStreamDefaultController.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "TransformStreamDefaultControllerBuiltins.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsTransformStreamDefaultControllerConstructor); + +class JSTransformStreamDefaultControllerPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSTransformStreamDefaultControllerPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSTransformStreamDefaultControllerPrototype* ptr = new (NotNull, JSC::allocateCell<JSTransformStreamDefaultControllerPrototype>(vm)) JSTransformStreamDefaultControllerPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTransformStreamDefaultControllerPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSTransformStreamDefaultControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSTransformStreamDefaultControllerPrototype, JSTransformStreamDefaultControllerPrototype::Base); + +using JSTransformStreamDefaultControllerDOMConstructor = JSDOMBuiltinConstructor<JSTransformStreamDefaultController>; + +template<> const ClassInfo JSTransformStreamDefaultControllerDOMConstructor::s_info = { "TransformStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTransformStreamDefaultControllerDOMConstructor) }; + +template<> JSValue JSTransformStreamDefaultControllerDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSTransformStreamDefaultControllerDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "TransformStreamDefaultController"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSTransformStreamDefaultController::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSTransformStreamDefaultControllerDOMConstructor::initializeExecutable(VM& vm) +{ + return transformStreamDefaultControllerInitializeTransformStreamDefaultControllerCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSTransformStreamDefaultControllerPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTransformStreamDefaultControllerConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "desiredSize"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(transformStreamDefaultControllerDesiredSizeCodeGenerator), (intptr_t) (0) } }, + { "enqueue"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(transformStreamDefaultControllerEnqueueCodeGenerator), (intptr_t) (0) } }, + { "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(transformStreamDefaultControllerErrorCodeGenerator), (intptr_t) (0) } }, + { "terminate"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(transformStreamDefaultControllerTerminateCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSTransformStreamDefaultControllerPrototype::s_info = { "TransformStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTransformStreamDefaultControllerPrototype) }; + +void JSTransformStreamDefaultControllerPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSTransformStreamDefaultController::info(), JSTransformStreamDefaultControllerPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSTransformStreamDefaultController::s_info = { "TransformStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTransformStreamDefaultController) }; + +JSTransformStreamDefaultController::JSTransformStreamDefaultController(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSTransformStreamDefaultController::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSTransformStreamDefaultController::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSTransformStreamDefaultControllerPrototype::create(vm, &globalObject, JSTransformStreamDefaultControllerPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSTransformStreamDefaultController::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSTransformStreamDefaultController>(vm, globalObject); +} + +JSValue JSTransformStreamDefaultController::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSTransformStreamDefaultControllerDOMConstructor, DOMConstructorID::TransformStreamDefaultController>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSTransformStreamDefaultController::destroy(JSC::JSCell* cell) +{ + JSTransformStreamDefaultController* thisObject = static_cast<JSTransformStreamDefaultController*>(cell); + thisObject->JSTransformStreamDefaultController::~JSTransformStreamDefaultController(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsTransformStreamDefaultControllerConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSTransformStreamDefaultControllerPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSTransformStreamDefaultController::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSTransformStreamDefaultController::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSTransformStreamDefaultController, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForTransformStreamDefaultController.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForTransformStreamDefaultController = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForTransformStreamDefaultController.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForTransformStreamDefaultController = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.dep b/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.dep new file mode 100644 index 000000000..0d59bed06 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.dep @@ -0,0 +1 @@ +JSTransformStreamDefaultController.h : diff --git a/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.h b/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.h new file mode 100644 index 000000000..e63fdd7c4 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSTransformStreamDefaultController.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSTransformStreamDefaultController : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSTransformStreamDefaultController* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSTransformStreamDefaultController* ptr = new (NotNull, JSC::allocateCell<JSTransformStreamDefaultController>(globalObject->vm())) JSTransformStreamDefaultController(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSTransformStreamDefaultController(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSURLSearchParams.cpp b/src/bun.js/bindings/webcore/JSURLSearchParams.cpp new file mode 100644 index 000000000..e132aecf8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSURLSearchParams.cpp @@ -0,0 +1,559 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSURLSearchParams.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertRecord.h" +#include "JSDOMConvertSequences.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMConvertUnion.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMIterator.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "JavaScriptCore/BuiltinNames.h" +#include "JavaScriptCore/FunctionPrototype.h" +#include "JavaScriptCore/HeapAnalyzer.h" +#include "JavaScriptCore/JSArray.h" + +#include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" +#include "JavaScriptCore/SlotVisitorMacros.h" +#include "JavaScriptCore/SubspaceInlines.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include "wtf/GetPtr.h" +#include "wtf/PointerPreparations.h" +#include "wtf/URL.h" +#include "wtf/Vector.h" +#include <variant> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_append); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_delete); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_get); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_getAll); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_has); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_set); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_sort); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_entries); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_keys); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_values); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_forEach); +static JSC_DECLARE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_toString); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsURLSearchParamsConstructor); + +class JSURLSearchParamsPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSURLSearchParamsPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSURLSearchParamsPrototype* ptr = new (NotNull, JSC::allocateCell<JSURLSearchParamsPrototype>(vm)) JSURLSearchParamsPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSURLSearchParamsPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSURLSearchParamsPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSURLSearchParamsPrototype, JSURLSearchParamsPrototype::Base); + +using JSURLSearchParamsDOMConstructor = JSDOMConstructor<JSURLSearchParams>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSURLSearchParamsDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSURLSearchParamsDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->argument(0); + auto init = argument0.value().isUndefined() ? emptyString() : convert<IDLUnion<IDLSequence<IDLSequence<IDLUSVString>>, IDLRecord<IDLUSVString, IDLUSVString>, IDLUSVString>>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = URLSearchParams::create(WTFMove(init)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<URLSearchParams>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<URLSearchParams>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSURLSearchParamsDOMConstructorConstruct, JSURLSearchParamsDOMConstructor::construct); + +template<> const ClassInfo JSURLSearchParamsDOMConstructor::s_info = { "URLSearchParams"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLSearchParamsDOMConstructor) }; + +template<> JSValue JSURLSearchParamsDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSURLSearchParamsDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "URLSearchParams"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSURLSearchParams::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSURLSearchParamsPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsURLSearchParamsConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "append"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_append), (intptr_t)(2) } }, + { "delete"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_delete), (intptr_t)(1) } }, + { "get"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_get), (intptr_t)(1) } }, + { "getAll"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_getAll), (intptr_t)(1) } }, + { "has"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_has), (intptr_t)(1) } }, + { "set"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_set), (intptr_t)(2) } }, + { "sort"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_sort), (intptr_t)(0) } }, + { "entries"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_entries), (intptr_t)(0) } }, + { "keys"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_keys), (intptr_t)(0) } }, + { "values"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_values), (intptr_t)(0) } }, + { "forEach"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_forEach), (intptr_t)(1) } }, + { "toString"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsURLSearchParamsPrototypeFunction_toString), (intptr_t)(0) } }, +}; + +const ClassInfo JSURLSearchParamsPrototype::s_info = { "URLSearchParams"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLSearchParamsPrototype) }; + +void JSURLSearchParamsPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSURLSearchParams::info(), JSURLSearchParamsPrototypeTableValues, *this); + putDirect(vm, vm.propertyNames->iteratorSymbol, getDirect(vm, vm.propertyNames->builtinNames().entriesPublicName()), static_cast<unsigned>(JSC::PropertyAttribute::DontEnum)); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSURLSearchParams::s_info = { "URLSearchParams"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLSearchParams) }; + +JSURLSearchParams::JSURLSearchParams(Structure* structure, JSDOMGlobalObject& globalObject, Ref<URLSearchParams>&& impl) + : JSDOMWrapper<URLSearchParams>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSURLSearchParams::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, URLSearchParams>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSURLSearchParams::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSURLSearchParamsPrototype::create(vm, &globalObject, JSURLSearchParamsPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSURLSearchParams::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSURLSearchParams>(vm, globalObject); +} + +JSValue JSURLSearchParams::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSURLSearchParamsDOMConstructor, DOMConstructorID::URLSearchParams>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSURLSearchParams::destroy(JSC::JSCell* cell) +{ + JSURLSearchParams* thisObject = static_cast<JSURLSearchParams*>(cell); + thisObject->JSURLSearchParams::~JSURLSearchParams(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsURLSearchParamsConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSURLSearchParamsPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSURLSearchParams::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_appendBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 2)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto value = convert<IDLUSVString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.append(WTFMove(name), WTFMove(value)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_append, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_appendBody>(*lexicalGlobalObject, *callFrame, "append"); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_deleteBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.remove(WTFMove(name)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_delete, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_deleteBody>(*lexicalGlobalObject, *callFrame, "delete"); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_getBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLNullable<IDLUSVString>>(*lexicalGlobalObject, throwScope, impl.get(WTFMove(name))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_get, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_getBody>(*lexicalGlobalObject, *callFrame, "get"); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_getAllBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLSequence<IDLUSVString>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, impl.getAll(WTFMove(name))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_getAll, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_getAllBody>(*lexicalGlobalObject, *callFrame, "getAll"); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_hasBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLBoolean>(*lexicalGlobalObject, throwScope, impl.has(WTFMove(name))))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_has, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_hasBody>(*lexicalGlobalObject, *callFrame, "has"); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_setBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 2)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto name = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto value = convert<IDLUSVString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.set(WTFMove(name), WTFMove(value)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_set, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_setBody>(*lexicalGlobalObject, *callFrame, "set"); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_sortBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.sort(); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_sort, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_sortBody>(*lexicalGlobalObject, *callFrame, "sort"); +} + +static inline JSC::EncodedJSValue jsURLSearchParamsPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLSearchParams>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLDOMString>(*lexicalGlobalObject, throwScope, impl.toString()))); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_toString, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_toStringBody>(*lexicalGlobalObject, *callFrame, "toString"); +} + +struct URLSearchParamsIteratorTraits { + static constexpr JSDOMIteratorType type = JSDOMIteratorType::Map; + using KeyType = IDLUSVString; + using ValueType = IDLUSVString; +}; + +using URLSearchParamsIteratorBase = JSDOMIteratorBase<JSURLSearchParams, URLSearchParamsIteratorTraits>; +class URLSearchParamsIterator final : public URLSearchParamsIteratorBase { +public: + using Base = URLSearchParamsIteratorBase; + DECLARE_INFO; + + template<typename, SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl<URLSearchParamsIterator, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForURLSearchParamsIterator.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForURLSearchParamsIterator = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForURLSearchParamsIterator.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForURLSearchParamsIterator = WTFMove(space); }); + } + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + + static URLSearchParamsIterator* create(JSC::VM& vm, JSC::Structure* structure, JSURLSearchParams& iteratedObject, IterationKind kind) + { + auto* instance = new (NotNull, JSC::allocateCell<URLSearchParamsIterator>(vm)) URLSearchParamsIterator(structure, iteratedObject, kind); + instance->finishCreation(vm); + return instance; + } + +private: + URLSearchParamsIterator(JSC::Structure* structure, JSURLSearchParams& iteratedObject, IterationKind kind) + : Base(structure, iteratedObject, kind) + { + } +}; + +using URLSearchParamsIteratorPrototype = JSDOMIteratorPrototype<JSURLSearchParams, URLSearchParamsIteratorTraits>; +JSC_ANNOTATE_HOST_FUNCTION(URLSearchParamsIteratorPrototypeNext, URLSearchParamsIteratorPrototype::next); + +template<> +const JSC::ClassInfo URLSearchParamsIteratorBase::s_info = { "URLSearchParams Iterator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(URLSearchParamsIteratorBase) }; +const JSC::ClassInfo URLSearchParamsIterator::s_info = { "URLSearchParams Iterator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(URLSearchParamsIterator) }; + +template<> +const JSC::ClassInfo URLSearchParamsIteratorPrototype::s_info = { "URLSearchParams Iterator"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(URLSearchParamsIteratorPrototype) }; + +static inline EncodedJSValue jsURLSearchParamsPrototypeFunction_entriesCaller(JSGlobalObject*, CallFrame*, JSURLSearchParams* thisObject) +{ + return JSValue::encode(iteratorCreate<URLSearchParamsIterator>(*thisObject, IterationKind::Entries)); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_entries, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_entriesCaller>(*lexicalGlobalObject, *callFrame, "entries"); +} + +static inline EncodedJSValue jsURLSearchParamsPrototypeFunction_keysCaller(JSGlobalObject*, CallFrame*, JSURLSearchParams* thisObject) +{ + return JSValue::encode(iteratorCreate<URLSearchParamsIterator>(*thisObject, IterationKind::Keys)); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_keys, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_keysCaller>(*lexicalGlobalObject, *callFrame, "keys"); +} + +static inline EncodedJSValue jsURLSearchParamsPrototypeFunction_valuesCaller(JSGlobalObject*, CallFrame*, JSURLSearchParams* thisObject) +{ + return JSValue::encode(iteratorCreate<URLSearchParamsIterator>(*thisObject, IterationKind::Values)); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_values, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_valuesCaller>(*lexicalGlobalObject, *callFrame, "values"); +} + +static inline EncodedJSValue jsURLSearchParamsPrototypeFunction_forEachCaller(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame, JSURLSearchParams* thisObject) +{ + return JSValue::encode(iteratorForEach<URLSearchParamsIterator>(*lexicalGlobalObject, *callFrame, *thisObject)); +} + +JSC_DEFINE_HOST_FUNCTION(jsURLSearchParamsPrototypeFunction_forEach, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame)) +{ + return IDLOperation<JSURLSearchParams>::call<jsURLSearchParamsPrototypeFunction_forEachCaller>(*lexicalGlobalObject, *callFrame, "forEach"); +} + +JSC::GCClient::IsoSubspace* JSURLSearchParams::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSURLSearchParams, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForURLSearchParams.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForURLSearchParams = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForURLSearchParams.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForURLSearchParams = WTFMove(space); }); +} + +void JSURLSearchParams::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSURLSearchParams*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + // if (thisObject->scriptExecutionContext()) + // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSURLSearchParamsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSURLSearchParamsOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsURLSearchParams = static_cast<JSURLSearchParams*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsURLSearchParams->wrapped(), jsURLSearchParams); +} + +// #if ENABLE(BINDING_INTEGRITY) +// #if PLATFORM(WIN) +// #pragma warning(disable : 4483) +// extern "C" { +// extern void (*const __identifier("??_7URLSearchParams@WebCore@@6B@")[])(); +// } +// #else +// extern "C" { +// extern void* _ZTVN7WebCore15URLSearchParamsE[]; +// } +// #endif +// #endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<URLSearchParams>&& impl) +{ + + // if constexpr (std::is_polymorphic_v<URLSearchParams>) { + // #if ENABLE(BINDING_INTEGRITY) + // const void* actualVTablePointer = getVTablePointer(impl.ptr()); + // #if PLATFORM(WIN) + // void* expectedVTablePointer = __identifier("??_7URLSearchParams@WebCore@@6B@"); + // #else + // void* expectedVTablePointer = &_ZTVN7WebCore15URLSearchParamsE[2]; + // #endif + + // // If you hit this assertion you either have a use after free bug, or + // // URLSearchParams has subclasses. If URLSearchParams has subclasses that get passed + // // to toJS() we currently require URLSearchParams you to opt out of binding hardening + // // by adding the SkipVTableValidation attribute to the interface IDL definition + // RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); + // #endif + // } + return createWrapper<URLSearchParams>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, URLSearchParams& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +URLSearchParams* JSURLSearchParams::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSURLSearchParams*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSURLSearchParams.dep b/src/bun.js/bindings/webcore/JSURLSearchParams.dep new file mode 100644 index 000000000..73a94dc7b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSURLSearchParams.dep @@ -0,0 +1 @@ +JSURLSearchParams.h : diff --git a/src/bun.js/bindings/webcore/JSURLSearchParams.h b/src/bun.js/bindings/webcore/JSURLSearchParams.h new file mode 100644 index 000000000..b7e90a3fb --- /dev/null +++ b/src/bun.js/bindings/webcore/JSURLSearchParams.h @@ -0,0 +1,94 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" +#include "URLSearchParams.h" +#include "wtf/NeverDestroyed.h" + +namespace WebCore { + +class JSURLSearchParams : public JSDOMWrapper<URLSearchParams> { +public: + using Base = JSDOMWrapper<URLSearchParams>; + static JSURLSearchParams* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<URLSearchParams>&& impl) + { + JSURLSearchParams* ptr = new (NotNull, JSC::allocateCell<JSURLSearchParams>(globalObject->vm())) JSURLSearchParams(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static URLSearchParams* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +protected: + JSURLSearchParams(JSC::Structure*, JSDOMGlobalObject&, Ref<URLSearchParams>&&); + + void finishCreation(JSC::VM&); +}; + +class JSURLSearchParamsOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, URLSearchParams*) +{ + static NeverDestroyed<JSURLSearchParamsOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(URLSearchParams* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, URLSearchParams&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, URLSearchParams* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<URLSearchParams>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<URLSearchParams>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<URLSearchParams> { + using WrapperClass = JSURLSearchParams; + using ToWrappedReturnType = URLSearchParams*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSValueInWrappedObject.h b/src/bun.js/bindings/webcore/JSValueInWrappedObject.h new file mode 100644 index 000000000..d05fdb8fd --- /dev/null +++ b/src/bun.js/bindings/webcore/JSValueInWrappedObject.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018-2021 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 "DOMWrapperWorld.h" +#include "JSDOMWrapper.h" +#include "JavaScriptCore/JSCJSValue.h" +#include "JavaScriptCore/SlotVisitor.h" +#include "JavaScriptCore/Weak.h" +#include <variant> + +namespace WebCore { + +// This class includes a lot of GC related subtle things, and changing this class easily causes GC crashes. +// Any changes on this class must be reviewed by JavaScriptCore reviewers too. +class JSValueInWrappedObject { + // It must be neither copyable nor movable. Changing this will break concurrent GC. + WTF_MAKE_NONCOPYABLE(JSValueInWrappedObject); + WTF_MAKE_NONMOVABLE(JSValueInWrappedObject); + +public: + JSValueInWrappedObject(JSC::JSValue = {}); + + explicit operator bool() const; + template<typename Visitor> void visit(Visitor&) const; + void clear(); + + void set(JSC::VM&, const JSC::JSCell* owner, JSC::JSValue); + 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 {}; + JSC::Weak<JSC::JSCell> m_cell {}; +}; + +JSC::JSValue cachedPropertyValue(JSC::JSGlobalObject&, const JSDOMObject& owner, JSValueInWrappedObject& cacheSlot, const Function<JSC::JSValue()>&); + +inline JSValueInWrappedObject::JSValueInWrappedObject(JSC::JSValue value) +{ + setWeakly(value); +} + +inline JSC::JSValue JSValueInWrappedObject::getValue(JSC::JSValue nullValue) const +{ + if (m_nonCell) + return m_nonCell; + return m_cell ? m_cell.get() : nullValue; +} + +inline JSValueInWrappedObject::operator bool() const +{ + return m_nonCell || m_cell; +} + +template<typename Visitor> +inline void JSValueInWrappedObject::visit(Visitor& visitor) const +{ + visitor.append(m_cell); +} + +template void JSValueInWrappedObject::visit(JSC::AbstractSlotVisitor&) const; +template void JSValueInWrappedObject::visit(JSC::SlotVisitor&) const; + +inline void JSValueInWrappedObject::setWeakly(JSC::JSValue value) +{ + if (!value.isCell()) { + m_nonCell = value; + m_cell.clear(); + return; + } + m_nonCell = {}; + JSC::Weak weak { value.asCell() }; + WTF::storeStoreFence(); + m_cell = WTFMove(weak); +} + +inline void JSValueInWrappedObject::set(JSC::VM& vm, const JSC::JSCell* owner, JSC::JSValue value) +{ + setWeakly(value); + vm.writeBarrier(owner, value); +} + +inline void JSValueInWrappedObject::clear() +{ + m_nonCell = {}; + 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())) + return cachedValue.getValue(); + auto value = function(); + cachedValue.set(lexicalGlobalObject.vm(), &owner, cloneAcrossWorlds(lexicalGlobalObject, owner, value)); + ASSERT(isWorldCompatible(lexicalGlobalObject, cachedValue.getValue())); + return cachedValue.getValue(); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSWebSocket.cpp b/src/bun.js/bindings/webcore/JSWebSocket.cpp new file mode 100644 index 000000000..aa351fba3 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWebSocket.cpp @@ -0,0 +1,705 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSWebSocket.h" + +#include "ActiveDOMObject.h" +#include "EventNames.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +// #include "JSBlob.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertBufferSource.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNullable.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMConvertSequences.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "JSEventListener.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/IteratorOperations.h> +#include <JavaScriptCore/JSArray.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsWebSocketPrototypeFunction_send); +static JSC_DECLARE_HOST_FUNCTION(jsWebSocketPrototypeFunction_close); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocketConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_URL); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_url); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_readyState); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_bufferedAmount); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_onopen); +static JSC_DECLARE_CUSTOM_SETTER(setJSWebSocket_onopen); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_onmessage); +static JSC_DECLARE_CUSTOM_SETTER(setJSWebSocket_onmessage); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_onerror); +static JSC_DECLARE_CUSTOM_SETTER(setJSWebSocket_onerror); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_onclose); +static JSC_DECLARE_CUSTOM_SETTER(setJSWebSocket_onclose); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_protocol); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_extensions); +static JSC_DECLARE_CUSTOM_GETTER(jsWebSocket_binaryType); +static JSC_DECLARE_CUSTOM_SETTER(setJSWebSocket_binaryType); + +class JSWebSocketPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSWebSocketPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSWebSocketPrototype* ptr = new (NotNull, JSC::allocateCell<JSWebSocketPrototype>(vm)) JSWebSocketPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWebSocketPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSWebSocketPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWebSocketPrototype, JSWebSocketPrototype::Base); + +using JSWebSocketDOMConstructor = JSDOMConstructor<JSWebSocket>; + +/* Hash table for constructor */ + +static const HashTableValue JSWebSocketConstructorTableValues[] = { + { "CONNECTING"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(0) } }, + { "OPEN"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } }, + { "CLOSING"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } }, + { "CLOSED"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } }, +}; + +static_assert(WebSocket::CONNECTING == 0, "CONNECTING in WebSocket does not match value from IDL"); +static_assert(WebSocket::OPEN == 1, "OPEN in WebSocket does not match value from IDL"); +static_assert(WebSocket::CLOSING == 2, "CLOSING in WebSocket does not match value from IDL"); +static_assert(WebSocket::CLOSED == 3, "CLOSED in WebSocket does not match value from IDL"); + +static inline EncodedJSValue constructJSWebSocket1(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSWebSocketDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + auto* context = castedThis->scriptExecutionContext(); + if (UNLIKELY(!context)) + return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "WebSocket"); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto url = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto protocols = argument1.value().isUndefined() ? Converter<IDLSequence<IDLDOMString>>::ReturnType {} : convert<IDLSequence<IDLDOMString>>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = WebSocket::create(*context, WTFMove(url), WTFMove(protocols)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<WebSocket>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<WebSocket>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} + +static inline EncodedJSValue constructJSWebSocket2(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSWebSocketDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + auto* context = castedThis->scriptExecutionContext(); + if (UNLIKELY(!context)) + return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "WebSocket"); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto url = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto protocol = convert<IDLDOMString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = WebSocket::create(*context, WTFMove(url), WTFMove(protocol)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<WebSocket>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<WebSocket>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWebSocketDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + size_t argsCount = std::min<size_t>(2, callFrame->argumentCount()); + if (argsCount == 1) { + RELEASE_AND_RETURN(throwScope, (constructJSWebSocket1(lexicalGlobalObject, callFrame))); + } + if (argsCount == 2) { + JSValue distinguishingArg = callFrame->uncheckedArgument(1); + if (distinguishingArg.isUndefined()) + RELEASE_AND_RETURN(throwScope, (constructJSWebSocket1(lexicalGlobalObject, callFrame))); + { + bool success = hasIteratorMethod(lexicalGlobalObject, distinguishingArg); + RETURN_IF_EXCEPTION(throwScope, {}); + if (success) + RELEASE_AND_RETURN(throwScope, (constructJSWebSocket1(lexicalGlobalObject, callFrame))); + } + RELEASE_AND_RETURN(throwScope, (constructJSWebSocket2(lexicalGlobalObject, callFrame))); + } + return argsCount < 1 ? throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)) : throwVMTypeError(lexicalGlobalObject, throwScope); +} +JSC_ANNOTATE_HOST_FUNCTION(JSWebSocketConstructorConstruct, JSWebSocketDOMConstructor::construct); + +template<> const ClassInfo JSWebSocketDOMConstructor::s_info = { "WebSocket"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebSocketDOMConstructor) }; + +template<> JSValue JSWebSocketDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + return JSEventTarget::getConstructor(vm, &globalObject); +} + +template<> void JSWebSocketDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "WebSocket"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSWebSocket::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); + reifyStaticProperties(vm, JSWebSocket::info(), JSWebSocketConstructorTableValues, *this); +} + +/* Hash table for prototype */ + +static const HashTableValue JSWebSocketPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocketConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "URL"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_URL), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "url"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_url), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "readyState"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_readyState), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "bufferedAmount"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_bufferedAmount), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "onopen"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_onopen), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocket_onopen) } }, + { "onmessage"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_onmessage), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocket_onmessage) } }, + { "onerror"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_onerror), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocket_onerror) } }, + { "onclose"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_onclose), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocket_onclose) } }, + { "protocol"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_protocol), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "extensions"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_extensions), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "binaryType"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWebSocket_binaryType), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSWebSocket_binaryType) } }, + { "send"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWebSocketPrototypeFunction_send), (intptr_t)(1) } }, + { "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWebSocketPrototypeFunction_close), (intptr_t)(0) } }, + { "CONNECTING"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(0) } }, + { "OPEN"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(1) } }, + { "CLOSING"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(2) } }, + { "CLOSED"_s, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic, { (long long)(3) } }, +}; + +const ClassInfo JSWebSocketPrototype::s_info = { "WebSocket"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebSocketPrototype) }; + +void JSWebSocketPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSWebSocket::info(), JSWebSocketPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSWebSocket::s_info = { "WebSocket"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebSocket) }; + +JSWebSocket::JSWebSocket(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WebSocket>&& impl) + : JSEventTarget(structure, globalObject, WTFMove(impl)) +{ +} + +void JSWebSocket::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(std::is_base_of<ActiveDOMObject, WebSocket>::value, "Interface is marked as [ActiveDOMObject] but implementation class does not subclass ActiveDOMObject."); +} + +JSObject* JSWebSocket::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSWebSocketPrototype::create(vm, &globalObject, JSWebSocketPrototype::createStructure(vm, &globalObject, JSEventTarget::prototype(vm, globalObject))); +} + +JSObject* JSWebSocket::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSWebSocket>(vm, globalObject); +} + +JSValue JSWebSocket::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSWebSocketDOMConstructor, DOMConstructorID::WebSocket>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocketConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSWebSocketPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSWebSocket::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsWebSocket_URLGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.url()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_URL, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_URLGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsWebSocket_urlGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.url()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_url, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_urlGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsWebSocket_readyStateGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedShort>(lexicalGlobalObject, throwScope, impl.readyState()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_readyState, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_readyStateGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsWebSocket_bufferedAmountGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLUnsignedLong>(lexicalGlobalObject, throwScope, impl.bufferedAmount()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_bufferedAmount, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_bufferedAmountGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsWebSocket_onopenGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return eventHandlerAttribute(thisObject.wrapped(), eventNames().openEvent, worldForDOMObject(thisObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_onopen, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_onopenGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSWebSocket_onopenSetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + setEventHandlerAttribute<JSEventListener>(thisObject.wrapped(), eventNames().openEvent, value, thisObject); + vm.writeBarrier(&thisObject, value); + ensureStillAliveHere(value); + + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSWebSocket_onopen, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::set<setJSWebSocket_onopenSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsWebSocket_onmessageGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return eventHandlerAttribute(thisObject.wrapped(), eventNames().messageEvent, worldForDOMObject(thisObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_onmessage, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_onmessageGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSWebSocket_onmessageSetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + setEventHandlerAttribute<JSEventListener>(thisObject.wrapped(), eventNames().messageEvent, value, thisObject); + vm.writeBarrier(&thisObject, value); + ensureStillAliveHere(value); + + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSWebSocket_onmessage, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::set<setJSWebSocket_onmessageSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsWebSocket_onerrorGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return eventHandlerAttribute(thisObject.wrapped(), eventNames().errorEvent, worldForDOMObject(thisObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_onerror, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_onerrorGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSWebSocket_onerrorSetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + setEventHandlerAttribute<JSEventListener>(thisObject.wrapped(), eventNames().errorEvent, value, thisObject); + vm.writeBarrier(&thisObject, value); + ensureStillAliveHere(value); + + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSWebSocket_onerror, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::set<setJSWebSocket_onerrorSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsWebSocket_oncloseGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + UNUSED_PARAM(lexicalGlobalObject); + return eventHandlerAttribute(thisObject.wrapped(), eventNames().closeEvent, worldForDOMObject(thisObject)); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_onclose, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_oncloseGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSWebSocket_oncloseSetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + setEventHandlerAttribute<JSEventListener>(thisObject.wrapped(), eventNames().closeEvent, value, thisObject); + vm.writeBarrier(&thisObject, value); + ensureStillAliveHere(value); + + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSWebSocket_onclose, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::set<setJSWebSocket_oncloseSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSValue jsWebSocket_protocolGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLNullable<IDLDOMString>>(lexicalGlobalObject, throwScope, impl.protocol()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_protocol, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_protocolGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsWebSocket_extensionsGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLNullable<IDLDOMString>>(lexicalGlobalObject, throwScope, impl.extensions()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_extensions, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_extensionsGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsWebSocket_binaryTypeGetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLDOMString>(lexicalGlobalObject, throwScope, impl.binaryType()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWebSocket_binaryType, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::get<jsWebSocket_binaryTypeGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline bool setJSWebSocket_binaryTypeSetter(JSGlobalObject& lexicalGlobalObject, JSWebSocket& thisObject, JSValue value) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + auto nativeValue = convert<IDLDOMString>(lexicalGlobalObject, value); + RETURN_IF_EXCEPTION(throwScope, false); + invokeFunctorPropagatingExceptionIfNecessary(lexicalGlobalObject, throwScope, [&] { + return impl.setBinaryType(WTFMove(nativeValue)); + }); + return true; +} + +JSC_DEFINE_CUSTOM_SETTER(setJSWebSocket_binaryType, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWebSocket>::set<setJSWebSocket_binaryTypeSetter>(*lexicalGlobalObject, thisValue, encodedValue, attributeName); +} + +static inline JSC::EncodedJSValue jsWebSocketPrototypeFunction_send1Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWebSocket>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto data = convert<IDLArrayBuffer>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "data", "WebSocket", "send", "ArrayBuffer"); }); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.send(*data); }))); +} + +static inline JSC::EncodedJSValue jsWebSocketPrototypeFunction_send2Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWebSocket>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto data = convert<IDLArrayBufferView>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "data", "WebSocket", "send", "ArrayBufferView"); }); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.send(data.releaseNonNull()); }))); +} + +// static inline JSC::EncodedJSValue jsWebSocketPrototypeFunction_send3Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWebSocket>::ClassParameter castedThis) +// { +// auto& vm = JSC::getVM(lexicalGlobalObject); +// auto throwScope = DECLARE_THROW_SCOPE(vm); +// UNUSED_PARAM(throwScope); +// UNUSED_PARAM(callFrame); +// auto& impl = castedThis->wrapped(); +// EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); +// auto data = convert<IDLInterface<Blob>>(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "data", "WebSocket", "send", "Blob"); }); +// RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); +// RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.send(*data); }))); +// } + +static inline JSC::EncodedJSValue jsWebSocketPrototypeFunction_send4Body(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWebSocket>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto data = convert<IDLUSVString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.send(WTFMove(data)); }))); +} + +static inline JSC::EncodedJSValue jsWebSocketPrototypeFunction_sendOverloadDispatcher(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWebSocket>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + size_t argsCount = std::min<size_t>(1, callFrame->argumentCount()); + if (argsCount == 1) { + JSValue distinguishingArg = callFrame->uncheckedArgument(0); + if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSArrayBuffer>()) + RELEASE_AND_RETURN(throwScope, (jsWebSocketPrototypeFunction_send1Body(lexicalGlobalObject, callFrame, castedThis))); + if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSArrayBufferView>()) + RELEASE_AND_RETURN(throwScope, (jsWebSocketPrototypeFunction_send2Body(lexicalGlobalObject, callFrame, castedThis))); + // if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits<JSBlob>()) + // RELEASE_AND_RETURN(throwScope, (jsWebSocketPrototypeFunction_send3Body(lexicalGlobalObject, callFrame, castedThis))); + RELEASE_AND_RETURN(throwScope, (jsWebSocketPrototypeFunction_send4Body(lexicalGlobalObject, callFrame, castedThis))); + } + return argsCount < 1 ? throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)) : throwVMTypeError(lexicalGlobalObject, throwScope); +} + +JSC_DEFINE_HOST_FUNCTION(jsWebSocketPrototypeFunction_send, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSWebSocket>::call<jsWebSocketPrototypeFunction_sendOverloadDispatcher>(*lexicalGlobalObject, *callFrame, "send"); +} + +static inline JSC::EncodedJSValue jsWebSocketPrototypeFunction_closeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWebSocket>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + EnsureStillAliveScope argument0 = callFrame->argument(0); + auto code = argument0.value().isUndefined() ? std::optional<Converter<IDLClampAdaptor<IDLUnsignedShort>>::ReturnType>() : std::optional<Converter<IDLClampAdaptor<IDLUnsignedShort>>::ReturnType>(convert<IDLClampAdaptor<IDLUnsignedShort>>(*lexicalGlobalObject, argument0.value())); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto reason = argument1.value().isUndefined() ? String() : convert<IDLUSVString>(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.close(WTFMove(code), WTFMove(reason)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsWebSocketPrototypeFunction_close, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSWebSocket>::call<jsWebSocketPrototypeFunction_closeBody>(*lexicalGlobalObject, *callFrame, "close"); +} + +JSC::GCClient::IsoSubspace* JSWebSocket::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSWebSocket, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForWebSocket.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForWebSocket = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForWebSocket.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForWebSocket = WTFMove(space); }); +} + +void JSWebSocket::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSWebSocket*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSWebSocketOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + auto* jsWebSocket = jsCast<JSWebSocket*>(handle.slot()->asCell()); + auto& wrapped = jsWebSocket->wrapped(); + // if (!wrapped.isContextStopped() && wrapped.hasPendingActivity()) { + // if (UNLIKELY(reason)) + // *reason = "ActiveDOMObject with pending activity"; + // return true; + // } + if (jsWebSocket->wrapped().isFiringEventListeners()) { + if (UNLIKELY(reason)) + *reason = "EventTarget firing event listeners"; + return true; + } + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSWebSocketOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsWebSocket = static_cast<JSWebSocket*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsWebSocket->wrapped(), jsWebSocket); +} + +#if ENABLE(BINDING_INTEGRITY) +#if PLATFORM(WIN) +#pragma warning(disable : 4483) +extern "C" { +extern void (*const __identifier("??_7WebSocket@WebCore@@6B@")[])(); +} +#else +extern "C" { +extern void* _ZTVN7WebCore9WebSocketE[]; +} +#endif +#endif + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<WebSocket>&& impl) +{ + + if constexpr (std::is_polymorphic_v<WebSocket>) { +#if ENABLE(BINDING_INTEGRITY) + const void* actualVTablePointer = getVTablePointer(impl.ptr()); +#if PLATFORM(WIN) + void* expectedVTablePointer = __identifier("??_7WebSocket@WebCore@@6B@"); +#else + void* expectedVTablePointer = &_ZTVN7WebCore9WebSocketE[2]; +#endif + + // If you hit this assertion you either have a use after free bug, or + // WebSocket has subclasses. If WebSocket has subclasses that get passed + // to toJS() we currently require WebSocket you to opt out of binding hardening + // by adding the SkipVTableValidation attribute to the interface IDL definition + RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer); +#endif + } + return createWrapper<WebSocket>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WebSocket& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +WebSocket* JSWebSocket::toWrapped(JSC::VM&, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSWebSocket*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSWebSocket.dep b/src/bun.js/bindings/webcore/JSWebSocket.dep new file mode 100644 index 000000000..69bc1775b --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWebSocket.dep @@ -0,0 +1,2 @@ +JSWebSocket.h : EventTarget.idl +EventTarget.idl : diff --git a/src/bun.js/bindings/webcore/JSWebSocket.h b/src/bun.js/bindings/webcore/JSWebSocket.h new file mode 100644 index 000000000..ae99a9887 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWebSocket.h @@ -0,0 +1,98 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" +#include "JSEventTarget.h" +#include "WebSocket.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSWebSocket : public JSEventTarget { +public: + using Base = JSEventTarget; + using DOMWrapped = WebSocket; + static JSWebSocket* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<WebSocket>&& impl) + { + JSWebSocket* ptr = new (NotNull, JSC::allocateCell<JSWebSocket>(globalObject->vm())) JSWebSocket(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static WebSocket* toWrapped(JSC::VM&, JSC::JSValue); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + WebSocket& wrapped() const + { + return static_cast<WebSocket&>(Base::wrapped()); + } +protected: + JSWebSocket(JSC::Structure*, JSDOMGlobalObject&, Ref<WebSocket>&&); + + void finishCreation(JSC::VM&); +}; + +class JSWebSocketOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, WebSocket*) +{ + static NeverDestroyed<JSWebSocketOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(WebSocket* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, WebSocket&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WebSocket* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<WebSocket>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<WebSocket>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<WebSocket> { + using WrapperClass = JSWebSocket; + using ToWrappedReturnType = WebSocket*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSWindowProxy.h b/src/bun.js/bindings/webcore/JSWindowProxy.h new file mode 100644 index 000000000..d067d0b5a --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWindowProxy.h @@ -0,0 +1 @@ +// stub
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/JSWritableStream.cpp b/src/bun.js/bindings/webcore/JSWritableStream.cpp new file mode 100644 index 000000000..1d996f3ef --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStream.cpp @@ -0,0 +1,311 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSWritableStream.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBoolean.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertObject.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMOperationReturningPromise.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.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> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsWritableStreamPrototypeFunction_abort); +static JSC_DECLARE_HOST_FUNCTION(jsWritableStreamPrototypeFunction_close); +static JSC_DECLARE_HOST_FUNCTION(jsWritableStreamPrototypeFunction_getWriter); + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsWritableStreamConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsWritableStream_locked); + +class JSWritableStreamPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSWritableStreamPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSWritableStreamPrototype* ptr = new (NotNull, JSC::allocateCell<JSWritableStreamPrototype>(vm)) JSWritableStreamPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSWritableStreamPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamPrototype, JSWritableStreamPrototype::Base); + +using JSWritableStreamDOMConstructor = JSDOMConstructor<JSWritableStream>; + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWritableStreamDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast<JSWritableStreamDOMConstructor*>(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->argument(0); + auto underlyingSink = argument0.value().isUndefined() ? std::optional<Converter<IDLObject>::ReturnType>() : std::optional<Converter<IDLObject>::ReturnType>(convert<IDLObject>(*lexicalGlobalObject, argument0.value())); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->argument(1); + auto strategy = argument1.value().isUndefined() ? std::optional<Converter<IDLObject>::ReturnType>() : std::optional<Converter<IDLObject>::ReturnType>(convert<IDLObject>(*lexicalGlobalObject, argument1.value())); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = WritableStream::create(*castedThis->globalObject(), WTFMove(underlyingSink), WTFMove(strategy)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef); + auto jsValue = toJSNewlyCreated<IDLInterface<WritableStream>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr<decltype(object)>) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded<WritableStream>(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} +JSC_ANNOTATE_HOST_FUNCTION(JSWritableStreamDOMConstructorConstruct, JSWritableStreamDOMConstructor::construct); + +template<> const ClassInfo JSWritableStreamDOMConstructor::s_info = { "WritableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamDOMConstructor) }; + +template<> JSValue JSWritableStreamDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSWritableStreamDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "WritableStream"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSWritableStream::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSWritableStreamPrototypeTableValues[] = { + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWritableStreamConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "locked"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast<PropertySlot::GetValueFunc>(jsWritableStream_locked), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "abort"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWritableStreamPrototypeFunction_abort), (intptr_t)(0) } }, + { "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWritableStreamPrototypeFunction_close), (intptr_t)(0) } }, + { "getWriter"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWritableStreamPrototypeFunction_getWriter), (intptr_t)(0) } }, +}; + +const ClassInfo JSWritableStreamPrototype::s_info = { "WritableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamPrototype) }; + +void JSWritableStreamPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSWritableStream::info(), JSWritableStreamPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSWritableStream::s_info = { "WritableStream"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStream) }; + +JSWritableStream::JSWritableStream(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WritableStream>&& impl) + : JSDOMWrapper<WritableStream>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSWritableStream::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, WritableStream>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSWritableStream::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSWritableStreamPrototype::create(vm, &globalObject, JSWritableStreamPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSWritableStream::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSWritableStream>(vm, globalObject); +} + +JSValue JSWritableStream::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSWritableStreamDOMConstructor, DOMConstructorID::WritableStream>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSWritableStream::destroy(JSC::JSCell* cell) +{ + JSWritableStream* thisObject = static_cast<JSWritableStream*>(cell); + thisObject->JSWritableStream::~JSWritableStream(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWritableStreamConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSWritableStreamPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSWritableStream::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsWritableStream_lockedGetter(JSGlobalObject& lexicalGlobalObject, JSWritableStream& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.locked()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWritableStream_locked, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute<JSWritableStream>::get<jsWritableStream_lockedGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSC::EncodedJSValue jsWritableStreamPrototypeFunction_abortBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSWritableStream>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + RELEASE_AND_RETURN(throwScope, (JSValue::encode(castedThis->abort(*lexicalGlobalObject, *callFrame)))); +} + +JSC_DEFINE_HOST_FUNCTION(jsWritableStreamPrototypeFunction_abort, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperationReturningPromise<JSWritableStream>::callReturningOwnPromise<jsWritableStreamPrototypeFunction_abortBody>(*lexicalGlobalObject, *callFrame, "abort"); +} + +static inline JSC::EncodedJSValue jsWritableStreamPrototypeFunction_closeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSWritableStream>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + RELEASE_AND_RETURN(throwScope, (JSValue::encode(castedThis->close(*lexicalGlobalObject, *callFrame)))); +} + +JSC_DEFINE_HOST_FUNCTION(jsWritableStreamPrototypeFunction_close, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperationReturningPromise<JSWritableStream>::callReturningOwnPromise<jsWritableStreamPrototypeFunction_closeBody>(*lexicalGlobalObject, *callFrame, "close"); +} + +static inline JSC::EncodedJSValue jsWritableStreamPrototypeFunction_getWriterBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWritableStream>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + RELEASE_AND_RETURN(throwScope, (JSValue::encode(castedThis->getWriter(*lexicalGlobalObject, *callFrame)))); +} + +JSC_DEFINE_HOST_FUNCTION(jsWritableStreamPrototypeFunction_getWriter, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSWritableStream>::call<jsWritableStreamPrototypeFunction_getWriterBody>(*lexicalGlobalObject, *callFrame, "getWriter"); +} + +JSC::GCClient::IsoSubspace* JSWritableStream::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSWritableStream, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForWritableStream.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForWritableStream = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForWritableStream.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForWritableStream = WTFMove(space); }); +} + +void JSWritableStream::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSWritableStream*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSWritableStreamOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSWritableStreamOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsWritableStream = static_cast<JSWritableStream*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsWritableStream->wrapped(), jsWritableStream); +} + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<WritableStream>&& impl) +{ + return createWrapper<WritableStream>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WritableStream& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +WritableStream* JSWritableStream::toWrapped(JSC::VM&, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSWritableStream*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSWritableStream.dep b/src/bun.js/bindings/webcore/JSWritableStream.dep new file mode 100644 index 000000000..d936b4581 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStream.dep @@ -0,0 +1 @@ +JSWritableStream.h : diff --git a/src/bun.js/bindings/webcore/JSWritableStream.h b/src/bun.js/bindings/webcore/JSWritableStream.h new file mode 100644 index 000000000..d8b971645 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStream.h @@ -0,0 +1,98 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" +#include "WritableStream.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSWritableStream : public JSDOMWrapper<WritableStream> { +public: + using Base = JSDOMWrapper<WritableStream>; + static JSWritableStream* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<WritableStream>&& impl) + { + JSWritableStream* ptr = new (NotNull, JSC::allocateCell<JSWritableStream>(globalObject->vm())) JSWritableStream(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static WritableStream* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + + // Custom functions + JSC::JSValue abort(JSC::JSGlobalObject&, JSC::CallFrame&); + JSC::JSValue close(JSC::JSGlobalObject&, JSC::CallFrame&); + JSC::JSValue getWriter(JSC::JSGlobalObject&, JSC::CallFrame&); +protected: + JSWritableStream(JSC::Structure*, JSDOMGlobalObject&, Ref<WritableStream>&&); + + void finishCreation(JSC::VM&); +}; + +class JSWritableStreamOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, WritableStream*) +{ + static NeverDestroyed<JSWritableStreamOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(WritableStream* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, WritableStream&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WritableStream* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<WritableStream>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<WritableStream>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<WritableStream> { + using WrapperClass = JSWritableStream; + using ToWrappedReturnType = WritableStream*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.cpp b/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.cpp new file mode 100644 index 000000000..fd4a50e3c --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.cpp @@ -0,0 +1,180 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSWritableStreamDefaultController.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "WebCoreJSClientData.h" +#include "WritableStreamDefaultControllerBuiltins.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsWritableStreamDefaultControllerConstructor); + +class JSWritableStreamDefaultControllerPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSWritableStreamDefaultControllerPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSWritableStreamDefaultControllerPrototype* ptr = new (NotNull, JSC::allocateCell<JSWritableStreamDefaultControllerPrototype>(vm)) JSWritableStreamDefaultControllerPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamDefaultControllerPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSWritableStreamDefaultControllerPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamDefaultControllerPrototype, JSWritableStreamDefaultControllerPrototype::Base); + +using JSWritableStreamDefaultControllerDOMConstructor = JSDOMBuiltinConstructor<JSWritableStreamDefaultController>; + +template<> const ClassInfo JSWritableStreamDefaultControllerDOMConstructor::s_info = { "WritableStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamDefaultControllerDOMConstructor) }; + +template<> JSValue JSWritableStreamDefaultControllerDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSWritableStreamDefaultControllerDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "WritableStreamDefaultController"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSWritableStreamDefaultController::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSWritableStreamDefaultControllerDOMConstructor::initializeExecutable(VM& vm) +{ + return writableStreamDefaultControllerInitializeWritableStreamDefaultControllerCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSWritableStreamDefaultControllerPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWritableStreamDefaultControllerConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultControllerErrorCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSWritableStreamDefaultControllerPrototype::s_info = { "WritableStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamDefaultControllerPrototype) }; + +void JSWritableStreamDefaultControllerPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSWritableStreamDefaultController::info(), JSWritableStreamDefaultControllerPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSWritableStreamDefaultController::s_info = { "WritableStreamDefaultController"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamDefaultController) }; + +JSWritableStreamDefaultController::JSWritableStreamDefaultController(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSWritableStreamDefaultController::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSWritableStreamDefaultController::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSWritableStreamDefaultControllerPrototype::create(vm, &globalObject, JSWritableStreamDefaultControllerPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSWritableStreamDefaultController::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSWritableStreamDefaultController>(vm, globalObject); +} + +JSValue JSWritableStreamDefaultController::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSWritableStreamDefaultControllerDOMConstructor, DOMConstructorID::WritableStreamDefaultController>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSWritableStreamDefaultController::destroy(JSC::JSCell* cell) +{ + JSWritableStreamDefaultController* thisObject = static_cast<JSWritableStreamDefaultController*>(cell); + thisObject->JSWritableStreamDefaultController::~JSWritableStreamDefaultController(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWritableStreamDefaultControllerConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSWritableStreamDefaultControllerPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSWritableStreamDefaultController::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSWritableStreamDefaultController::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSWritableStreamDefaultController, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForWritableStreamDefaultController.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForWritableStreamDefaultController = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForWritableStreamDefaultController.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForWritableStreamDefaultController = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.dep b/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.dep new file mode 100644 index 000000000..a1ac70d47 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.dep @@ -0,0 +1 @@ +JSWritableStreamDefaultController.h : diff --git a/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.h b/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.h new file mode 100644 index 000000000..8da0be568 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamDefaultController.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSWritableStreamDefaultController : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSWritableStreamDefaultController* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSWritableStreamDefaultController* ptr = new (NotNull, JSC::allocateCell<JSWritableStreamDefaultController>(globalObject->vm())) JSWritableStreamDefaultController(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSWritableStreamDefaultController(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.cpp b/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.cpp new file mode 100644 index 000000000..4a5eb707d --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.cpp @@ -0,0 +1,187 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSWritableStreamDefaultWriter.h" + +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMBuiltinConstructor.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMOperation.h" +#include "JSDOMWrapperCache.h" +#include "WebCoreJSClientData.h" +#include "WritableStreamDefaultWriterBuiltins.h" +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> + + +namespace WebCore { +using namespace JSC; + +// Functions + + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsWritableStreamDefaultWriterConstructor); + +class JSWritableStreamDefaultWriterPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSWritableStreamDefaultWriterPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSWritableStreamDefaultWriterPrototype* ptr = new (NotNull, JSC::allocateCell<JSWritableStreamDefaultWriterPrototype>(vm)) JSWritableStreamDefaultWriterPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamDefaultWriterPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSWritableStreamDefaultWriterPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamDefaultWriterPrototype, JSWritableStreamDefaultWriterPrototype::Base); + +using JSWritableStreamDefaultWriterDOMConstructor = JSDOMBuiltinConstructor<JSWritableStreamDefaultWriter>; + +template<> const ClassInfo JSWritableStreamDefaultWriterDOMConstructor::s_info = { "WritableStreamDefaultWriter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamDefaultWriterDOMConstructor) }; + +template<> JSValue JSWritableStreamDefaultWriterDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSWritableStreamDefaultWriterDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(1), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "WritableStreamDefaultWriter"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSWritableStreamDefaultWriter::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +template<> FunctionExecutable* JSWritableStreamDefaultWriterDOMConstructor::initializeExecutable(VM& vm) +{ + return writableStreamDefaultWriterInitializeWritableStreamDefaultWriterCodeGenerator(vm); +} + +/* Hash table for prototype */ + +static const HashTableValue JSWritableStreamDefaultWriterPrototypeTableValues[] = +{ + { "constructor"_s, static_cast<unsigned>(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsWritableStreamDefaultWriterConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, + { "closed"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultWriterClosedCodeGenerator), (intptr_t) (0) } }, + { "desiredSize"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultWriterDesiredSizeCodeGenerator), (intptr_t) (0) } }, + { "ready"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::Accessor | JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultWriterReadyCodeGenerator), (intptr_t) (0) } }, + { "abort"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultWriterAbortCodeGenerator), (intptr_t) (0) } }, + { "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultWriterCloseCodeGenerator), (intptr_t) (0) } }, + { "releaseLock"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultWriterReleaseLockCodeGenerator), (intptr_t) (0) } }, + { "write"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { (intptr_t)static_cast<BuiltinGenerator>(writableStreamDefaultWriterWriteCodeGenerator), (intptr_t) (0) } }, +}; + +const ClassInfo JSWritableStreamDefaultWriterPrototype::s_info = { "WritableStreamDefaultWriter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamDefaultWriterPrototype) }; + +void JSWritableStreamDefaultWriterPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSWritableStreamDefaultWriter::info(), JSWritableStreamDefaultWriterPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSWritableStreamDefaultWriter::s_info = { "WritableStreamDefaultWriter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamDefaultWriter) }; + +JSWritableStreamDefaultWriter::JSWritableStreamDefaultWriter(Structure* structure, JSDOMGlobalObject& globalObject) + : JSDOMObject(structure, globalObject) { } + +void JSWritableStreamDefaultWriter::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + +} + +JSObject* JSWritableStreamDefaultWriter::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSWritableStreamDefaultWriterPrototype::create(vm, &globalObject, JSWritableStreamDefaultWriterPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSWritableStreamDefaultWriter::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSWritableStreamDefaultWriter>(vm, globalObject); +} + +JSValue JSWritableStreamDefaultWriter::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor<JSWritableStreamDefaultWriterDOMConstructor, DOMConstructorID::WritableStreamDefaultWriter>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject)); +} + +void JSWritableStreamDefaultWriter::destroy(JSC::JSCell* cell) +{ + JSWritableStreamDefaultWriter* thisObject = static_cast<JSWritableStreamDefaultWriter*>(cell); + thisObject->JSWritableStreamDefaultWriter::~JSWritableStreamDefaultWriter(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsWritableStreamDefaultWriterConstructor, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast<JSWritableStreamDefaultWriterPrototype*>(JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSWritableStreamDefaultWriter::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +JSC::GCClient::IsoSubspace* JSWritableStreamDefaultWriter::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSWritableStreamDefaultWriter, UseCustomHeapCellType::No>(vm, + [] (auto& spaces) { return spaces.m_clientSubspaceForWritableStreamDefaultWriter.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_clientSubspaceForWritableStreamDefaultWriter = WTFMove(space); }, + [] (auto& spaces) { return spaces.m_subspaceForWritableStreamDefaultWriter.get(); }, + [] (auto& spaces, auto&& space) { spaces.m_subspaceForWritableStreamDefaultWriter = WTFMove(space); } + ); +} + + +} diff --git a/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.dep b/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.dep new file mode 100644 index 000000000..3016ea662 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.dep @@ -0,0 +1 @@ +JSWritableStreamDefaultWriter.h : diff --git a/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.h b/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.h new file mode 100644 index 000000000..bc13fb8c1 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamDefaultWriter.h @@ -0,0 +1,64 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" + +namespace WebCore { + +class JSWritableStreamDefaultWriter : public JSDOMObject { +public: + using Base = JSDOMObject; + static JSWritableStreamDefaultWriter* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject) + { + JSWritableStreamDefaultWriter* ptr = new (NotNull, JSC::allocateCell<JSWritableStreamDefaultWriter>(globalObject->vm())) JSWritableStreamDefaultWriter(structure, *globalObject); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); +protected: + JSWritableStreamDefaultWriter(JSC::Structure*, JSDOMGlobalObject&); + + void finishCreation(JSC::VM&); +}; + + + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/JSWritableStreamSink.cpp b/src/bun.js/bindings/webcore/JSWritableStreamSink.cpp new file mode 100644 index 000000000..ffc2816f5 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamSink.cpp @@ -0,0 +1,248 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSWritableStreamSink.h" + +#include "ActiveDOMObject.h" +#include "DOMPromiseProxy.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "IDLTypes.h" +#include "JSDOMBinding.h" +#include "JSDOMConvertAny.h" +#include "JSDOMConvertBase.h" +#include "JSDOMConvertPromise.h" +#include "JSDOMConvertStrings.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMOperation.h" +#include "JSDOMOperationReturningPromise.h" +#include "JSDOMWrapperCache.h" +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/HeapAnalyzer.h> +#include <JavaScriptCore/JSCInlines.h> +#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h> +#include <JavaScriptCore/SlotVisitorMacros.h> +#include <JavaScriptCore/SubspaceInlines.h> +#include <wtf/GetPtr.h> +#include <wtf/PointerPreparations.h> +#include <wtf/URL.h> + +namespace WebCore { +using namespace JSC; + +// Functions + +static JSC_DECLARE_HOST_FUNCTION(jsWritableStreamSinkPrototypeFunction_write); +static JSC_DECLARE_HOST_FUNCTION(jsWritableStreamSinkPrototypeFunction_close); +static JSC_DECLARE_HOST_FUNCTION(jsWritableStreamSinkPrototypeFunction_error); + +class JSWritableStreamSinkPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSWritableStreamSinkPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSWritableStreamSinkPrototype* ptr = new (NotNull, JSC::allocateCell<JSWritableStreamSinkPrototype>(vm)) JSWritableStreamSinkPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamSinkPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSWritableStreamSinkPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSWritableStreamSinkPrototype, JSWritableStreamSinkPrototype::Base); + +/* Hash table for prototype */ + +static const HashTableValue JSWritableStreamSinkPrototypeTableValues[] = { + { "write"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWritableStreamSinkPrototypeFunction_write), (intptr_t)(1) } }, + { "close"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWritableStreamSinkPrototypeFunction_close), (intptr_t)(0) } }, + { "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t) static_cast<RawNativeFunction>(jsWritableStreamSinkPrototypeFunction_error), (intptr_t)(1) } }, +}; + +const ClassInfo JSWritableStreamSinkPrototype::s_info = { "WritableStreamSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamSinkPrototype) }; + +void JSWritableStreamSinkPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSWritableStreamSink::info(), JSWritableStreamSinkPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSWritableStreamSink::s_info = { "WritableStreamSink"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWritableStreamSink) }; + +JSWritableStreamSink::JSWritableStreamSink(Structure* structure, JSDOMGlobalObject& globalObject, Ref<WritableStreamSink>&& impl) + : JSDOMWrapper<WritableStreamSink>(structure, globalObject, WTFMove(impl)) +{ +} + +void JSWritableStreamSink::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); + + // static_assert(!std::is_base_of<ActiveDOMObject, WritableStreamSink>::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSWritableStreamSink::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSWritableStreamSinkPrototype::create(vm, &globalObject, JSWritableStreamSinkPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSWritableStreamSink::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype<JSWritableStreamSink>(vm, globalObject); +} + +void JSWritableStreamSink::destroy(JSC::JSCell* cell) +{ + JSWritableStreamSink* thisObject = static_cast<JSWritableStreamSink*>(cell); + thisObject->JSWritableStreamSink::~JSWritableStreamSink(); +} + +static inline JSC::EncodedJSValue jsWritableStreamSinkPrototypeFunction_writeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperationReturningPromise<JSWritableStreamSink>::ClassParameter castedThis, Ref<DeferredPromise>&& promise) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + 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 value = convert<IDLAny>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLPromise<IDLUndefined>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, [&]() -> decltype(auto) { return impl.write(*context, WTFMove(value), WTFMove(promise)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsWritableStreamSinkPrototypeFunction_write, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperationReturningPromise<JSWritableStreamSink>::call<jsWritableStreamSinkPrototypeFunction_writeBody>(*lexicalGlobalObject, *callFrame, "write"); +} + +static inline JSC::EncodedJSValue jsWritableStreamSinkPrototypeFunction_closeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWritableStreamSink>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.close(); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsWritableStreamSinkPrototypeFunction_close, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSWritableStreamSink>::call<jsWritableStreamSinkPrototypeFunction_closeBody>(*lexicalGlobalObject, *callFrame, "close"); +} + +static inline JSC::EncodedJSValue jsWritableStreamSinkPrototypeFunction_errorBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSWritableStreamSink>::ClassParameter castedThis) +{ + auto& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + UNUSED_PARAM(callFrame); + auto& impl = castedThis->wrapped(); + if (UNLIKELY(callFrame->argumentCount() < 1)) + return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto message = convert<IDLDOMString>(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLUndefined>(*lexicalGlobalObject, throwScope, [&]() -> decltype(auto) { return impl.error(WTFMove(message)); }))); +} + +JSC_DEFINE_HOST_FUNCTION(jsWritableStreamSinkPrototypeFunction_error, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + return IDLOperation<JSWritableStreamSink>::call<jsWritableStreamSinkPrototypeFunction_errorBody>(*lexicalGlobalObject, *callFrame, "error"); +} + +JSC::GCClient::IsoSubspace* JSWritableStreamSink::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl<JSWritableStreamSink, UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForWritableStreamSink.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForWritableStreamSink = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForWritableStreamSink.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForWritableStreamSink = WTFMove(space); }); +} + +void JSWritableStreamSink::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSWritableStreamSink*>(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSWritableStreamSinkOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSWritableStreamSinkOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto* jsWritableStreamSink = static_cast<JSWritableStreamSink*>(handle.slot()->asCell()); + auto& world = *static_cast<DOMWrapperWorld*>(context); + uncacheWrapper(world, &jsWritableStreamSink->wrapped(), jsWritableStreamSink); +} + +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<WritableStreamSink>&& impl) +{ + return createWrapper<WritableStreamSink>(globalObject, WTFMove(impl)); +} + +JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WritableStreamSink& impl) +{ + return wrap(lexicalGlobalObject, globalObject, impl); +} + +WritableStreamSink* JSWritableStreamSink::toWrapped(JSC::VM&, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast<JSWritableStreamSink*>(value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/bun.js/bindings/webcore/JSWritableStreamSink.dep b/src/bun.js/bindings/webcore/JSWritableStreamSink.dep new file mode 100644 index 000000000..c1891fdd8 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamSink.dep @@ -0,0 +1 @@ +JSWritableStreamSink.h : diff --git a/src/bun.js/bindings/webcore/JSWritableStreamSink.h b/src/bun.js/bindings/webcore/JSWritableStreamSink.h new file mode 100644 index 000000000..7537792a2 --- /dev/null +++ b/src/bun.js/bindings/webcore/JSWritableStreamSink.h @@ -0,0 +1,92 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "JSDOMWrapper.h" +#include "WritableStreamSink.h" +#include <wtf/NeverDestroyed.h> + +namespace WebCore { + +class JSWritableStreamSink : public JSDOMWrapper<WritableStreamSink> { +public: + using Base = JSDOMWrapper<WritableStreamSink>; + static JSWritableStreamSink* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<WritableStreamSink>&& impl) + { + JSWritableStreamSink* ptr = new (NotNull, JSC::allocateCell<JSWritableStreamSink>(globalObject->vm())) JSWritableStreamSink(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static WritableStreamSink* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); +protected: + JSWritableStreamSink(JSC::Structure*, JSDOMGlobalObject&, Ref<WritableStreamSink>&&); + + void finishCreation(JSC::VM&); +}; + +class JSWritableStreamSinkOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle<JSC::Unknown>, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, WritableStreamSink*) +{ + static NeverDestroyed<JSWritableStreamSinkOwner> owner; + return &owner.get(); +} + +inline void* wrapperKey(WritableStreamSink* wrappableObject) +{ + return wrappableObject; +} + +JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, WritableStreamSink&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, WritableStreamSink* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<WritableStreamSink>&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<WritableStreamSink>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits<WritableStreamSink> { + using WrapperClass = JSWritableStreamSink; + using ToWrappedReturnType = WritableStreamSink*; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/MessageEvent.cpp b/src/bun.js/bindings/webcore/MessageEvent.cpp new file mode 100644 index 000000000..b210f4cec --- /dev/null +++ b/src/bun.js/bindings/webcore/MessageEvent.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2007 Henry Mason (hmason@mac.com) + * Copyright (C) 2003-2018 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 "root.h" +#include "config.h" +#include "MessageEvent.h" + +// #include "Blob.h" +#include "EventNames.h" +#include <JavaScriptCore/JSCInlines.h> +// #include <wtf/IsoMallocInlines.h> + +namespace WebCore { + +using namespace JSC; + +WTF_MAKE_ISO_ALLOCATED_IMPL(MessageEvent); + +MessageEvent::MessageEvent() = default; + +inline MessageEvent::MessageEvent(const AtomString& type, Init&& initializer, IsTrusted isTrusted) + : Event(type, initializer, isTrusted) + , m_data(JSValueTag {}) + , m_origin(initializer.origin) + , m_lastEventId(initializer.lastEventId) + , m_source(WTFMove(initializer.source)) + // , m_ports(WTFMove(initializer.ports)) + , m_jsData(initializer.data) +{ +} + +inline MessageEvent::MessageEvent(const AtomString& type, DataType&& data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source /*, Vector<RefPtr<MessagePort>>&& ports*/) + : Event(type, CanBubble::No, IsCancelable::No) + , m_data(WTFMove(data)) + , m_origin(origin) + , m_lastEventId(lastEventId) + , m_source(WTFMove(source)) +// , m_ports(WTFMove(ports)) +{ +} + +Ref<MessageEvent> MessageEvent::create(const AtomString& type, DataType&& data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source /*, Vector<RefPtr<MessagePort>>&& ports*/) +{ + return adoptRef(*new MessageEvent(type, WTFMove(data), origin, lastEventId, WTFMove(source) /*, /*WTFMove(ports)*/)); +} + +Ref<MessageEvent> MessageEvent::create(DataType&& data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source /*, Vector<RefPtr<MessagePort>>&& ports*/) +{ + return create(eventNames().messageEvent, WTFMove(data), origin, lastEventId, WTFMove(source) /*, /*WTFMove(ports)*/); +} + +Ref<MessageEvent> MessageEvent::createForBindings() +{ + return adoptRef(*new MessageEvent); +} + +Ref<MessageEvent> MessageEvent::create(const AtomString& type, Init&& initializer, IsTrusted isTrusted) +{ + return adoptRef(*new MessageEvent(type, WTFMove(initializer), isTrusted)); +} + +MessageEvent::~MessageEvent() = default; + +void MessageEvent::initMessageEvent(const AtomString& type, bool canBubble, bool cancelable, JSValue data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& source /*, Vector<RefPtr<MessagePort>>&& ports*/) +{ + if (isBeingDispatched()) + return; + + initEvent(type, canBubble, cancelable); + + { + Locker { m_concurrentDataAccessLock }; + m_data = JSValueTag {}; + } + // 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 + m_jsData.setWeakly(data); + m_cachedData.clear(); + m_origin = origin; + m_lastEventId = lastEventId; + m_source = WTFMove(source); + // m_ports = WTFMove(ports); + m_cachedPorts.clear(); +} + +EventInterface MessageEvent::eventInterface() const +{ + return MessageEventInterfaceType; +} + +size_t MessageEvent::memoryCost() const +{ + Locker { m_concurrentDataAccessLock }; + return WTF::switchOn( + m_data, [](JSValueTag) -> size_t { return 0; }, + // [](const Ref<SerializedScriptValue>& data) -> size_t { return data->memoryCost(); }, + [](const String& string) -> size_t { return string.sizeInBytes(); }, + // [](const Ref<Blob>& blob) -> size_t { return blob->size(); }, + [](const Ref<ArrayBuffer>& buffer) -> size_t { return buffer->byteLength(); }); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/MessageEvent.h b/src/bun.js/bindings/webcore/MessageEvent.h new file mode 100644 index 000000000..4089e2ca1 --- /dev/null +++ b/src/bun.js/bindings/webcore/MessageEvent.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2007 Henry Mason (hmason@mac.com) + * Copyright (C) 2003-2018 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. + * + */ + +#pragma once + +#include "Event.h" +#include "JSValueInWrappedObject.h" +// #include "MessagePort.h" +// #include "SerializedScriptValue.h" +// #include "ServiceWorker.h" +// #include "WindowProxy.h" +#include <variant> + +namespace WebCore { + +class MessagePort : public RefCounted<MessagePort> { +}; + +class MessageEventSource { +}; + +class MessageEvent final : public Event { + WTF_MAKE_ISO_ALLOCATED(MessageEvent); + +public: + struct JSValueTag { + }; + // using DataType = std::variant<JSValueTag, Ref<SerializedScriptValue>, String, Ref<Blob>, Ref<ArrayBuffer>>; + using DataType = std::variant<JSValueTag, String, Ref<ArrayBuffer>>; + static Ref<MessageEvent> create(const AtomString& type, DataType&&, const String& origin = {}, const String& lastEventId = {}, std::optional<MessageEventSource>&& = std::nullopt /*, Vector<RefPtr<MessagePort>>&& = {}*/); + static Ref<MessageEvent> create(DataType&&, const String& origin = {}, const String& lastEventId = {}, std::optional<MessageEventSource>&& = std::nullopt /*, Vector<RefPtr<MessagePort>>&& = {}*/); + static Ref<MessageEvent> createForBindings(); + + struct Init : EventInit { + JSC::JSValue data; + String origin; + String lastEventId; + std::optional<MessageEventSource> source; + // Vector<RefPtr<MessagePort>> ports; + }; + static Ref<MessageEvent> create(const AtomString& type, Init&&, IsTrusted = IsTrusted::No); + + virtual ~MessageEvent(); + + void initMessageEvent(const AtomString& type, bool canBubble, bool cancelable, JSC::JSValue data, const String& origin, const String& lastEventId, std::optional<MessageEventSource>&& /*, Vector<RefPtr<MessagePort>>&&*/); + + const String& origin() const { return m_origin; } + const String& lastEventId() const { return m_lastEventId; } + const std::optional<MessageEventSource>& source() const { return m_source; } + // const Vector<RefPtr<MessagePort>>& ports() const { return m_ports; } + + const DataType& data() const { return m_data; } + + JSValueInWrappedObject& jsData() { return m_jsData; } + JSValueInWrappedObject& cachedData() { return m_cachedData; } + JSValueInWrappedObject& cachedPorts() { return m_cachedPorts; } + + size_t memoryCost() const; + +private: + MessageEvent(); + MessageEvent(const AtomString& type, Init&&, IsTrusted); + MessageEvent(const AtomString& type, DataType&&, const String& origin, const String& lastEventId = {}, std::optional<MessageEventSource>&& = std::nullopt /*, Vector<RefPtr<MessagePort>>&& = {}*/); + + EventInterface eventInterface() const final; + + DataType m_data; + String m_origin; + String m_lastEventId; + std::optional<MessageEventSource> m_source; + // Vector<RefPtr<MessagePort>> m_ports; + + JSValueInWrappedObject m_jsData; + JSValueInWrappedObject m_cachedData; + JSValueInWrappedObject m_cachedPorts; + + mutable Lock m_concurrentDataAccessLock; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/MessageEvent.idl b/src/bun.js/bindings/webcore/MessageEvent.idl new file mode 100644 index 000000000..dff0a218a --- /dev/null +++ b/src/bun.js/bindings/webcore/MessageEvent.idl @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007 Henry Mason <hmason@mac.com> + * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 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. + * + */ + +#if defined(ENABLE_SERVICE_WORKER) && ENABLE_SERVICE_WORKER +typedef (WindowProxy or MessagePort or ServiceWorker) MessageEventSource; +#else +typedef (WindowProxy or MessagePort) MessageEventSource; +#endif + +[ + Exposed=(Window,Worker,AudioWorklet), + JSCustomMarkFunction, + ReportExtraMemoryCost, +] interface MessageEvent : Event { + constructor([AtomString] DOMString type, optional MessageEventInit eventInitDict); + + readonly attribute USVString origin; + readonly attribute DOMString lastEventId; + readonly attribute MessageEventSource? source; + [CustomGetter] readonly attribute any data; + [CustomGetter] readonly attribute FrozenArray<MessagePort> ports; + + undefined initMessageEvent([AtomString] DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, + optional any data = null, optional USVString originArg = "", optional DOMString lastEventId = "", optional MessageEventSource? source = null, + optional sequence<MessagePort> messagePorts = []); +}; + +dictionary MessageEventInit : EventInit { + any data = null; + USVString origin = ""; + DOMString lastEventId = ""; + MessageEventSource? source = null; + sequence<MessagePort> ports = []; +}; diff --git a/src/bun.js/bindings/webcore/Node.h b/src/bun.js/bindings/webcore/Node.h new file mode 100644 index 000000000..df9917a25 --- /dev/null +++ b/src/bun.js/bindings/webcore/Node.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 1999 Antti Koivisto (koivisto@kde.org) + * (C) 2001 Dirk Mueller (mueller@kde.org) + * Copyright (C) 2004-2020 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +#include "root.h" + +#include "EventTarget.h" +#include "ExceptionOr.h" +#include <wtf/CompactUniquePtrTuple.h> +#include <wtf/FixedVector.h> +#include <wtf/Forward.h> +// #include <wtf/IsoMalloc.h> +#include <wtf/ListHashSet.h> +#include <wtf/MainThread.h> +#include <wtf/OptionSet.h> +#include <wtf/URLHash.h> +#include <wtf/WeakPtr.h> +#include "EventTargetConcrete.h" + +namespace WebCore { + +// The full Node type is way too much stuff +// this ones just a baby +class Node : public RefPtr<Node>, CanMakeWeakPtr<Node>, public EventTarget { + WTF_MAKE_ISO_ALLOCATED(Node); + + static constexpr uint32_t s_refCountIncrement = 2; + static constexpr uint32_t s_refCountMask = ~static_cast<uint32_t>(1); + +public: + void defaultEventHandler(Event&) + { + // do nothing + } + + void handleEvent(ScriptExecutionContext&, Event&) + { + } + + bool hasEventTargetData() + { + return true; + } + + void ref() const; + void deref() const; + bool hasOneRef() const; + unsigned refCount() const; + + void removedLastRef() {} + + mutable uint32_t m_refCountAndParentBit { s_refCountIncrement }; + // mutable OptionSet<NodeFlag> m_nodeFlags; +}; + +#if ASSERT_ENABLED + +inline void adopted(Node* node) +{ + if (!node) + return; + ASSERT(!node->m_deletionHasBegun); + ASSERT(!node->m_inRemovedLastRefFunction); + node->m_adoptionIsRequired = false; +} + +#endif // ASSERT_ENABLED + +ALWAYS_INLINE void Node::ref() const +{ + ASSERT(isMainThread()); + ASSERT(!m_deletionHasBegun); + ASSERT(!m_inRemovedLastRefFunction); + ASSERT(!m_adoptionIsRequired); + m_refCountAndParentBit += s_refCountIncrement; +} + +ALWAYS_INLINE void Node::deref() const +{ + ASSERT(isMainThread()); + ASSERT(refCount()); + ASSERT(!m_deletionHasBegun); + ASSERT(!m_inRemovedLastRefFunction); + ASSERT(!m_adoptionIsRequired); + auto updatedRefCount = m_refCountAndParentBit - s_refCountIncrement; + if (!updatedRefCount) { + // Don't update m_refCountAndParentBit to avoid double destruction through use of Ref<T>/RefPtr<T>. + // (This is a security mitigation in case of programmer error. It will ASSERT in debug builds.) +#if ASSERT_ENABLED + m_inRemovedLastRefFunction = true; +#endif + const_cast<Node&>(*this).removedLastRef(); + return; + } + m_refCountAndParentBit = updatedRefCount; +} + +ALWAYS_INLINE bool Node::hasOneRef() const +{ + ASSERT(!m_deletionHasBegun); + ASSERT(!m_inRemovedLastRefFunction); + return refCount() == 1; +} + +ALWAYS_INLINE unsigned Node::refCount() const +{ + return m_refCountAndParentBit / s_refCountIncrement; +} + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/ParsedContentType.cpp b/src/bun.js/bindings/webcore/ParsedContentType.cpp new file mode 100644 index 000000000..04b30cf9b --- /dev/null +++ b/src/bun.js/bindings/webcore/ParsedContentType.cpp @@ -0,0 +1,421 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "ParsedContentType.h" + +#include "HTTPParsers.h" +#include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> + +namespace WebCore { + +static void skipSpaces(StringView input, unsigned& startIndex) +{ + while (startIndex < input.length() && isHTTPSpace(input[startIndex])) + ++startIndex; +} + +static bool isQuotedStringTokenCharacter(UChar c) +{ + return (c >= ' ' && c <= '~') || (c >= 0x80 && c <= 0xFF) || c == '\t'; +} + +static bool isTokenCharacter(UChar c) +{ + return isASCII(c) && c > ' ' && c != '"' && c != '(' && c != ')' && c != ',' && c != '/' && (c < ':' || c > '@') && (c < '[' || c > ']'); +} + +using CharacterMeetsCondition = bool (*)(UChar); + +static StringView parseToken(StringView input, unsigned& startIndex, CharacterMeetsCondition characterMeetsCondition, Mode mode, bool skipTrailingWhitespace = false) +{ + unsigned inputLength = input.length(); + unsigned tokenStart = startIndex; + unsigned& tokenEnd = startIndex; + + if (tokenEnd >= inputLength) + return StringView(); + + while (tokenEnd < inputLength && characterMeetsCondition(input[tokenEnd])) { + if (mode == Mode::Rfc2045 && !isTokenCharacter(input[tokenEnd])) + break; + ++tokenEnd; + } + + if (tokenEnd == tokenStart) + return StringView(); + if (skipTrailingWhitespace) { + if (mode == Mode::Rfc2045) { + while (input[tokenEnd - 1] == ' ') + --tokenEnd; + } else { + while (isHTTPSpace(input[tokenEnd - 1])) + --tokenEnd; + } + } + return input.substring(tokenStart, tokenEnd - tokenStart); +} + +static bool isNotQuoteOrBackslash(UChar ch) +{ + return ch != '"' && ch != '\\'; +} + +static String collectHTTPQuotedString(StringView input, unsigned& startIndex) +{ + ASSERT(input[startIndex] == '"'); + unsigned inputLength = input.length(); + unsigned& position = startIndex; + position++; + StringBuilder builder; + while (true) { + unsigned positionStart = position; + parseToken(input, position, isNotQuoteOrBackslash, Mode::MimeSniff); + builder.append(input.substring(positionStart, position - positionStart)); + if (position >= inputLength) + break; + UChar quoteOrBackslash = input[position++]; + if (quoteOrBackslash == '\\') { + if (position >= inputLength) { + builder.append(quoteOrBackslash); + break; + } + builder.append(input[position++]); + } else { + ASSERT(quoteOrBackslash == '"'); + break; + } + } + return builder.toString(); +} + +static bool containsNonTokenCharacters(StringView input, Mode mode) +{ + if (mode == Mode::MimeSniff) + return !isValidHTTPToken(input); + for (unsigned index = 0; index < input.length(); ++index) { + if (!isTokenCharacter(input[index])) + return true; + } + return false; +} + +static StringView parseQuotedString(StringView input, unsigned& startIndex) +{ + unsigned inputLength = input.length(); + unsigned quotedStringStart = startIndex + 1; + unsigned& quotedStringEnd = startIndex; + + if (quotedStringEnd >= inputLength) + return StringView(); + + if (input[quotedStringEnd++] != '"' || quotedStringEnd >= inputLength) + return StringView(); + + bool lastCharacterWasBackslash = false; + char currentCharacter; + while ((currentCharacter = input[quotedStringEnd++]) != '"' || lastCharacterWasBackslash) { + if (quotedStringEnd >= inputLength) + return StringView(); + if (currentCharacter == '\\' && !lastCharacterWasBackslash) { + lastCharacterWasBackslash = true; + continue; + } + if (lastCharacterWasBackslash) + lastCharacterWasBackslash = false; + } + if (input[quotedStringEnd - 1] == '"') + quotedStringEnd++; + return input.substring(quotedStringStart, quotedStringEnd - quotedStringStart); +} + +// From http://tools.ietf.org/html/rfc2045#section-5.1: +// +// content := "Content-Type" ":" type "/" subtype +// *(";" parameter) +// ; Matching of media type and subtype +// ; is ALWAYS case-insensitive. +// +// type := discrete-type / composite-type +// +// discrete-type := "text" / "image" / "audio" / "video" / +// "application" / extension-token +// +// composite-type := "message" / "multipart" / extension-token +// +// extension-token := ietf-token / x-token +// +// ietf-token := <An extension token defined by a +// standards-track RFC and registered +// with IANA.> +// +// x-token := <The two characters "X-" or "x-" followed, with +// no intervening white space, by any token> +// +// subtype := extension-token / iana-token +// +// iana-token := <A publicly-defined extension token. Tokens +// of this form must be registered with IANA +// as specified in RFC 2048.> +// +// parameter := attribute "=" value +// +// attribute := token +// ; Matching of attributes +// ; is ALWAYS case-insensitive. +// +// value := token / quoted-string +// +// token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, +// or tspecials> +// +// tspecials := "(" / ")" / "<" / ">" / "@" / +// "," / ";" / ":" / "\" / <"> +// "/" / "[" / "]" / "?" / "=" +// ; Must be in quoted-string, +// ; to use within parameter values + +static bool isNotForwardSlash(UChar ch) +{ + return ch != '/'; +} + +static bool isNotSemicolon(UChar ch) +{ + return ch != ';'; +} + +static bool isNotSemicolonOrEqualSign(UChar ch) +{ + return ch != ';' && ch != '='; +} + +static bool containsNewline(UChar ch) +{ + return ch == '\r' || ch == '\n'; +} + +bool ParsedContentType::parseContentType(Mode mode) +{ + if (mode == Mode::Rfc2045 && m_contentType.find(containsNewline) != notFound) + return false; + unsigned index = 0; + unsigned contentTypeLength = m_contentType.length(); + skipSpaces(m_contentType, index); + if (index >= contentTypeLength) { + LOG_ERROR("Invalid Content-Type string '%s'", m_contentType.ascii().data()); + return false; + } + + unsigned contentTypeStart = index; + auto typeRange = parseToken(m_contentType, index, isNotForwardSlash, mode); + if (typeRange.isNull() || containsNonTokenCharacters(typeRange, mode)) { + LOG_ERROR("Invalid Content-Type, invalid type value."); + return false; + } + + if (index >= contentTypeLength || m_contentType[index++] != '/') { + LOG_ERROR("Invalid Content-Type, missing '/'."); + return false; + } + + auto subTypeRange = parseToken(m_contentType, index, isNotSemicolon, mode, mode == Mode::MimeSniff); + if (subTypeRange.isNull() || containsNonTokenCharacters(subTypeRange, mode)) { + LOG_ERROR("Invalid Content-Type, invalid subtype value."); + return false; + } + + // There should not be any quoted strings until we reach the parameters. + size_t semiColonIndex = m_contentType.find(';', contentTypeStart); + if (semiColonIndex == notFound) { + setContentType(m_contentType.substring(contentTypeStart, contentTypeLength - contentTypeStart), mode); + return true; + } + + setContentType(m_contentType.substring(contentTypeStart, semiColonIndex - contentTypeStart), mode); + index = semiColonIndex + 1; + while (true) { + skipSpaces(m_contentType, index); + auto keyRange = parseToken(m_contentType, index, isNotSemicolonOrEqualSign, mode); + if (mode == Mode::Rfc2045 && (keyRange.isNull() || index >= contentTypeLength)) { + LOG_ERROR("Invalid Content-Type parameter name."); + return false; + } + + // Should we tolerate spaces here? + if (mode == Mode::Rfc2045) { + if (index >= contentTypeLength || m_contentType[index++] != '=') { + LOG_ERROR("Invalid Content-Type malformed parameter."); + return false; + } + } else { + if (index >= contentTypeLength) + break; + if (m_contentType[index] != '=' && m_contentType[index] != ';') { + LOG_ERROR("Invalid Content-Type malformed parameter."); + return false; + } + if (m_contentType[index++] == ';') + continue; + } + + // Should we tolerate spaces here? + String parameterValue; + StringView valueRange; + if (index < contentTypeLength && m_contentType[index] == '"') { + if (mode == Mode::MimeSniff) { + parameterValue = collectHTTPQuotedString(m_contentType, index); + parseToken(m_contentType, index, isNotSemicolon, mode); + } else + valueRange = parseQuotedString(m_contentType, index); + } else + valueRange = parseToken(m_contentType, index, isNotSemicolon, mode, mode == Mode::MimeSniff); + + if (parameterValue.isNull()) { + if (valueRange.isNull()) { + if (mode == Mode::MimeSniff) + continue; + LOG_ERROR("Invalid Content-Type, invalid parameter value."); + return false; + } + parameterValue = valueRange.toString(); + } + + // Should we tolerate spaces here? + if (mode == Mode::Rfc2045 && index < contentTypeLength && m_contentType[index++] != ';') { + LOG_ERROR("Invalid Content-Type, invalid character at the end of key/value parameter."); + return false; + } + + if (!keyRange.isNull()) + setContentTypeParameter(keyRange.toString(), parameterValue, mode); + + if (index >= contentTypeLength) + return true; + } + + return true; +} + +std::optional<ParsedContentType> ParsedContentType::create(const String& contentType, Mode mode) +{ + ParsedContentType parsedContentType(mode == Mode::Rfc2045 ? contentType : stripLeadingAndTrailingHTTPSpaces(contentType)); + if (!parsedContentType.parseContentType(mode)) + return std::nullopt; + return { WTFMove(parsedContentType) }; +} + +bool isValidContentType(const String& contentType, Mode mode) +{ + return ParsedContentType::create(contentType, mode) != std::nullopt; +} + +ParsedContentType::ParsedContentType(const String& contentType) + : m_contentType(contentType) +{ +} + +String ParsedContentType::charset() const +{ + return parameterValueForName("charset"_s); +} + +void ParsedContentType::setCharset(String&& charset) +{ + m_parameterValues.set("charset"_s, WTFMove(charset)); +} + +String ParsedContentType::parameterValueForName(const String& name) const +{ + return m_parameterValues.get(name); +} + +size_t ParsedContentType::parameterCount() const +{ + return m_parameterValues.size(); +} + +void ParsedContentType::setContentType(String&& contentRange, Mode mode) +{ + m_mimeType = WTFMove(contentRange); + if (mode == Mode::MimeSniff) + m_mimeType = stripLeadingAndTrailingHTTPSpaces(StringView(m_mimeType)).convertToASCIILowercase(); + else + m_mimeType = m_mimeType.stripWhiteSpace(); +} + +static bool containsNonQuoteStringTokenCharacters(const String& input) +{ + for (unsigned index = 0; index < input.length(); ++index) { + if (!isQuotedStringTokenCharacter(input[index])) + return true; + } + return false; +} + +void ParsedContentType::setContentTypeParameter(const String& keyName, const String& keyValue, Mode mode) +{ + String name = keyName; + if (mode == Mode::MimeSniff) { + if (m_parameterValues.contains(name) || !isValidHTTPToken(name) || containsNonQuoteStringTokenCharacters(keyValue)) + return; + name = name.convertToASCIILowercase(); + } + m_parameterValues.set(name, keyValue); + m_parameterNames.append(name); +} + +String ParsedContentType::serialize() const +{ + StringBuilder builder; + builder.append(m_mimeType); + for (auto& name : m_parameterNames) { + builder.append(';'); + builder.append(name); + builder.append('='); + String value = m_parameterValues.get(name); + if (value.isEmpty() || !isValidHTTPToken(value)) { + builder.append('"'); + for (unsigned index = 0; index < value.length(); ++index) { + auto ch = value[index]; + if (ch == '\\' || ch == '"') + builder.append('\\'); + builder.append(ch); + } + builder.append('"'); + } else + builder.append(value); + } + return builder.toString(); +} + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/ParsedContentType.h b/src/bun.js/bindings/webcore/ParsedContentType.h new file mode 100644 index 000000000..03837e6d9 --- /dev/null +++ b/src/bun.js/bindings/webcore/ParsedContentType.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +#pragma once + +#include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> + +namespace WebCore { + +enum class Mode { + Rfc2045, + MimeSniff +}; +WEBCORE_EXPORT bool isValidContentType(const String&, Mode = Mode::MimeSniff); + +// FIXME: add support for comments. +class ParsedContentType { +public: + WEBCORE_EXPORT static std::optional<ParsedContentType> create(const String&, Mode = Mode::MimeSniff); + ParsedContentType(ParsedContentType&&) = default; + + String mimeType() const { return m_mimeType; } + String charset() const; + void setCharset(String&&); + + // Note that in the case of multiple values for the same name, the last value is returned. + String parameterValueForName(const String&) const; + size_t parameterCount() const; + + WEBCORE_EXPORT String serialize() const; + +private: + ParsedContentType(const String&); + ParsedContentType(const ParsedContentType&) = delete; + ParsedContentType& operator=(ParsedContentType const&) = delete; + bool parseContentType(Mode); + void setContentType(String&&, Mode); + void setContentTypeParameter(const String&, const String&, Mode); + + typedef HashMap<String, String> KeyValuePairs; + String m_contentType; + KeyValuePairs m_parameterValues; + Vector<String> m_parameterNames; + String m_mimeType; +}; + +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/ReadableStream.cpp b/src/bun.js/bindings/webcore/ReadableStream.cpp new file mode 100644 index 000000000..0a85942b9 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStream.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2017-2021 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 CANON 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 CANON 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 "ReadableStream.h" + +#include "Exception.h" +#include "ExceptionCode.h" +#include "JSDOMConvertSequences.h" +#include "JSReadableStreamSink.h" +#include "JSReadableStreamSource.h" +#include "WebCoreJSClientData.h" + +namespace WebCore { +using namespace JSC; + +static inline ExceptionOr<JSObject*> invokeConstructor(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::Identifier& identifier, const Function<void(MarkedArgumentBuffer&, JSC::JSGlobalObject&, JSDOMGlobalObject&)>& buildArguments) +{ + VM& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject); + + auto constructorValue = globalObject.get(&lexicalGlobalObject, identifier); + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError }); + auto constructor = JSC::asObject(constructorValue); + + auto constructData = JSC::getConstructData(constructor); + ASSERT(constructData.type != CallData::Type::None); + + MarkedArgumentBuffer args; + buildArguments(args, lexicalGlobalObject, globalObject); + ASSERT(!args.hasOverflowed()); + + JSObject* object = JSC::construct(&lexicalGlobalObject, constructor, constructData, args); + ASSERT(!!scope.exception() == !object); + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError }); + + return object; +} + +ExceptionOr<Ref<ReadableStream>> ReadableStream::create(JSC::JSGlobalObject& lexicalGlobalObject, RefPtr<ReadableStreamSource>&& source) +{ + auto& builtinNames = WebCore::builtinNames(lexicalGlobalObject.vm()); + + auto objectOrException = invokeConstructor(lexicalGlobalObject, builtinNames.ReadableStreamPrivateName(), [&source](auto& args, auto& lexicalGlobalObject, auto& globalObject) { + args.append(source ? toJSNewlyCreated(&lexicalGlobalObject, &globalObject, source.releaseNonNull()) : JSC::jsUndefined()); + }); + + if (objectOrException.hasException()) + return objectOrException.releaseException(); + + return create(*JSC::jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject), *jsCast<JSReadableStream*>(objectOrException.releaseReturnValue())); +} + +ExceptionOr<Ref<ReadableStream>> ReadableStream::create(JSC::JSGlobalObject& lexicalGlobalObject, RefPtr<ReadableStreamSource>&& source, JSC::JSValue nativePtr) +{ + auto& builtinNames = WebCore::builtinNames(lexicalGlobalObject.vm()); + RELEASE_ASSERT(source != nullptr); + + auto objectOrException = invokeConstructor(lexicalGlobalObject, builtinNames.ReadableStreamPrivateName(), [&source, nativePtr](auto& args, auto& lexicalGlobalObject, auto& globalObject) { + auto sourceStream = toJSNewlyCreated(&lexicalGlobalObject, &globalObject, source.releaseNonNull()); + auto tag = WebCore::clientData(lexicalGlobalObject.vm())->builtinNames().bunNativePtrPrivateName(); + sourceStream.getObject()->putDirect(lexicalGlobalObject.vm(), tag, nativePtr, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::DontEnum); + args.append(sourceStream); + }); + + if (objectOrException.hasException()) + return objectOrException.releaseException(); + + return create(*JSC::jsCast<JSDOMGlobalObject*>(&lexicalGlobalObject), *jsCast<JSReadableStream*>(objectOrException.releaseReturnValue())); +} + +static inline std::optional<JSC::JSValue> invokeReadableStreamFunction(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::Identifier& identifier, JSC::JSValue thisValue, const JSC::MarkedArgumentBuffer& arguments) +{ + JSC::VM& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder lock(vm); + + auto function = lexicalGlobalObject.get(&lexicalGlobalObject, identifier); + ASSERT(function.isCallable()); + + auto scope = DECLARE_CATCH_SCOPE(vm); + auto callData = JSC::getCallData(function); + auto result = call(&lexicalGlobalObject, function, callData, thisValue, arguments); + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + if (scope.exception()) + return {}; + return result; +} + +void ReadableStream::pipeTo(ReadableStreamSink& sink) +{ + auto& lexicalGlobalObject = *m_globalObject; + auto* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamPipeToPrivateName(); + + MarkedArgumentBuffer arguments; + arguments.append(readableStream()); + arguments.append(toJS(&lexicalGlobalObject, m_globalObject.get(), sink)); + ASSERT(!arguments.hasOverflowed()); + invokeReadableStreamFunction(lexicalGlobalObject, privateName, JSC::jsUndefined(), arguments); +} + +std::optional<std::pair<Ref<ReadableStream>, Ref<ReadableStream>>> ReadableStream::tee() +{ + auto& lexicalGlobalObject = *m_globalObject; + auto* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamTeePrivateName(); + + MarkedArgumentBuffer arguments; + arguments.append(readableStream()); + arguments.append(JSC::jsBoolean(true)); + ASSERT(!arguments.hasOverflowed()); + auto returnedValue = invokeReadableStreamFunction(lexicalGlobalObject, privateName, JSC::jsUndefined(), arguments); + if (!returnedValue) + return {}; + + auto results = Detail::SequenceConverter<IDLInterface<ReadableStream>>::convert(lexicalGlobalObject, *returnedValue); + + ASSERT(results.size() == 2); + return std::make_pair(results[0].releaseNonNull(), results[1].releaseNonNull()); +} + +void ReadableStream::lock() +{ + auto& builtinNames = WebCore::builtinNames(m_globalObject->vm()); + invokeConstructor(*m_globalObject, builtinNames.ReadableStreamDefaultReaderPrivateName(), [this](auto& args, auto&, auto&) { + args.append(readableStream()); + }); +} + +void ReadableStream::cancel(const Exception& exception) +{ + auto& lexicalGlobalObject = *m_globalObject; + auto* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamCancelPrivateName(); + + auto& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + auto value = createDOMException(&lexicalGlobalObject, exception.code(), exception.message()); + if (UNLIKELY(scope.exception())) { + ASSERT(vm.hasPendingTerminationException()); + return; + } + + MarkedArgumentBuffer arguments; + arguments.append(readableStream()); + arguments.append(value); + ASSERT(!arguments.hasOverflowed()); + invokeReadableStreamFunction(lexicalGlobalObject, privateName, JSC::jsUndefined(), arguments); +} + +static inline bool checkReadableStream(JSDOMGlobalObject& globalObject, JSReadableStream* readableStream, JSC::JSValue function) +{ + auto& lexicalGlobalObject = globalObject; + + ASSERT(function); + JSC::MarkedArgumentBuffer arguments; + arguments.append(readableStream); + ASSERT(!arguments.hasOverflowed()); + + auto& vm = lexicalGlobalObject.vm(); + auto scope = DECLARE_CATCH_SCOPE(vm); + auto callData = JSC::getCallData(function); + ASSERT(callData.type != JSC::CallData::Type::None); + + auto result = call(&lexicalGlobalObject, function, callData, JSC::jsUndefined(), arguments); + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + + return result.isTrue() || scope.exception(); +} + +bool ReadableStream::isLocked() const +{ + return checkReadableStream(*globalObject(), readableStream(), globalObject()->builtinInternalFunctions().readableStreamInternals().m_isReadableStreamLockedFunction.get()); +} + +bool ReadableStream::isLocked(JSGlobalObject* globalObject, JSReadableStream* readableStream) +{ + auto* dom = reinterpret_cast<JSDOMGlobalObject*>(globalObject); + return checkReadableStream(*dom, readableStream, dom->builtinInternalFunctions().readableStreamInternals().m_isReadableStreamLockedFunction.get()); +} + +bool ReadableStream::isDisturbed(JSGlobalObject* globalObject, JSReadableStream* readableStream) +{ + auto* dom = reinterpret_cast<JSDOMGlobalObject*>(globalObject); + return checkReadableStream(*dom, readableStream, dom->builtinInternalFunctions().readableStreamInternals().m_isReadableStreamDisturbedFunction.get()); +} + +bool ReadableStream::isDisturbed() const +{ + return checkReadableStream(*globalObject(), readableStream(), globalObject()->builtinInternalFunctions().readableStreamInternals().m_isReadableStreamDisturbedFunction.get()); +} + +} diff --git a/src/bun.js/bindings/webcore/ReadableStream.h b/src/bun.js/bindings/webcore/ReadableStream.h new file mode 100644 index 000000000..f50185865 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStream.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2017-2020 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 CANON 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 CANON 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. + */ + +#pragma once + +#include "ExceptionOr.h" +#include "JSDOMBinding.h" +#include "JSDOMConvert.h" +#include "JSDOMGuardedObject.h" +#include "JSReadableStream.h" + +namespace WebCore { + +class ReadableStreamSink; +class ReadableStreamSource; + +class ReadableStream final : public DOMGuarded<JSReadableStream> { +public: + static Ref<ReadableStream> create(JSDOMGlobalObject& globalObject, JSReadableStream& readableStream) { return adoptRef(*new ReadableStream(globalObject, readableStream)); } + + static ExceptionOr<Ref<ReadableStream>> create(JSC::JSGlobalObject&, RefPtr<ReadableStreamSource>&&); + static ExceptionOr<Ref<ReadableStream>> create(JSC::JSGlobalObject& lexicalGlobalObject, RefPtr<ReadableStreamSource>&& source, JSC::JSValue nativePtr); + + WEBCORE_EXPORT static bool isDisturbed(JSC::JSGlobalObject*, JSReadableStream*); + WEBCORE_EXPORT static bool isLocked(JSC::JSGlobalObject*, JSReadableStream*); + + std::optional<std::pair<Ref<ReadableStream>, Ref<ReadableStream>>> tee(); + + void cancel(const Exception&); + void lock(); + void pipeTo(ReadableStreamSink&); + bool isLocked() const; + bool isDisturbed() const; + + JSReadableStream* readableStream() const + { + return guarded(); + } + +private: + ReadableStream(JSDOMGlobalObject& globalObject, JSReadableStream& readableStream) + : DOMGuarded<JSReadableStream>(globalObject, readableStream) + { + } +}; + +struct JSReadableStreamWrapperConverter { + static RefPtr<ReadableStream> toWrapped(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) + { + auto* globalObject = JSC::jsDynamicCast<JSDOMGlobalObject*>(&lexicalGlobalObject); + if (!globalObject) + return nullptr; + + auto* readableStream = JSC::jsDynamicCast<JSReadableStream*>(value); + if (!readableStream) + return nullptr; + + return ReadableStream::create(*globalObject, *readableStream); + } +}; + +template<> struct JSDOMWrapperConverterTraits<ReadableStream> { + using WrapperClass = JSReadableStreamWrapperConverter; + using ToWrappedReturnType = RefPtr<ReadableStream>; + static constexpr bool needsState = true; +}; + +inline JSC::JSValue toJS(JSC::JSGlobalObject*, JSC::JSGlobalObject*, ReadableStream* stream) +{ + return stream ? stream->readableStream() : JSC::jsUndefined(); +} + +inline JSC::JSValue toJS(JSC::JSGlobalObject*, JSC::JSGlobalObject*, ReadableStream& stream) +{ + return stream.readableStream(); +} + +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<ReadableStream>&& stream) +{ + return stream->readableStream(); +} + +} diff --git a/src/bun.js/bindings/webcore/ReadableStreamDefaultController.cpp b/src/bun.js/bindings/webcore/ReadableStreamDefaultController.cpp new file mode 100644 index 000000000..229a02d38 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStreamDefaultController.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2016 Canon Inc. + * Copyright (C) 2016-2021 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 required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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. + */ + +#include "config.h" +#include "ReadableStreamDefaultController.h" + +#include "WebCoreJSClientData.h" +#include <JavaScriptCore/CatchScope.h> +#include <JavaScriptCore/HeapInlines.h> +#include <JavaScriptCore/IdentifierInlines.h> +#include <JavaScriptCore/JSObjectInlines.h> +#include <JavaScriptCore/JSCInlines.h> + +namespace WebCore { + +static bool invokeReadableStreamDefaultControllerFunction(JSC::JSGlobalObject& lexicalGlobalObject, const JSC::Identifier& identifier, const JSC::MarkedArgumentBuffer& arguments) +{ + JSC::VM& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder lock(vm); + + auto scope = DECLARE_CATCH_SCOPE(vm); + auto function = lexicalGlobalObject.get(&lexicalGlobalObject, identifier); + + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + RETURN_IF_EXCEPTION(scope, false); + + ASSERT(function.isCallable()); + + auto callData = JSC::getCallData(function); + call(&lexicalGlobalObject, function, callData, JSC::jsUndefined(), arguments); + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + return !scope.exception(); +} + +void ReadableStreamDefaultController::close() +{ + JSC::MarkedArgumentBuffer arguments; + arguments.append(&jsController()); + + auto* clientData = static_cast<JSVMClientData*>(globalObject().vm().clientData); + auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamDefaultControllerClosePrivateName(); + + invokeReadableStreamDefaultControllerFunction(globalObject(), privateName, arguments); +} + +void ReadableStreamDefaultController::error(const Exception& exception) +{ + JSC::JSGlobalObject& lexicalGlobalObject = this->globalObject(); + auto& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + auto value = createDOMException(&lexicalGlobalObject, exception.code(), exception.message()); + + if (UNLIKELY(scope.exception())) { + ASSERT(vm.hasPendingTerminationException()); + return; + } + + JSC::MarkedArgumentBuffer arguments; + arguments.append(&jsController()); + arguments.append(value); + + auto* clientData = static_cast<JSVMClientData*>(vm.clientData); + auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamDefaultControllerErrorPrivateName(); + + invokeReadableStreamDefaultControllerFunction(globalObject(), privateName, arguments); +} + +void ReadableStreamDefaultController::error(JSC::JSValue error) +{ + JSC::JSGlobalObject& lexicalGlobalObject = this->globalObject(); + auto& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder lock(vm); + auto scope = DECLARE_THROW_SCOPE(vm); + auto value = JSC::Exception::create(vm, error); + + if (UNLIKELY(scope.exception())) { + ASSERT(vm.hasPendingTerminationException()); + return; + } + + JSC::MarkedArgumentBuffer arguments; + arguments.append(&jsController()); + arguments.append(value); + + auto* clientData = static_cast<JSVMClientData*>(vm.clientData); + auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamDefaultControllerErrorPrivateName(); + + invokeReadableStreamDefaultControllerFunction(globalObject(), privateName, arguments); +} + +bool ReadableStreamDefaultController::enqueue(JSC::JSValue value) +{ + JSC::JSGlobalObject& lexicalGlobalObject = this->globalObject(); + auto& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder lock(vm); + + JSC::MarkedArgumentBuffer arguments; + arguments.append(&jsController()); + arguments.append(value); + + auto* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData); + auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamDefaultControllerEnqueuePrivateName(); + + return invokeReadableStreamDefaultControllerFunction(globalObject(), privateName, arguments); +} + +bool ReadableStreamDefaultController::enqueue(RefPtr<JSC::ArrayBuffer>&& buffer) +{ + if (!buffer) { + error(Exception { OutOfMemoryError }); + return false; + } + + JSC::JSGlobalObject& lexicalGlobalObject = this->globalObject(); + auto& vm = lexicalGlobalObject.vm(); + JSC::JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + auto length = buffer->byteLength(); + auto value = JSC::JSUint8Array::create(&lexicalGlobalObject, lexicalGlobalObject.typedArrayStructure(JSC::TypeUint8), WTFMove(buffer), 0, length); + + EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); + RETURN_IF_EXCEPTION(scope, false); + + return enqueue(value); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ReadableStreamDefaultController.h b/src/bun.js/bindings/webcore/ReadableStreamDefaultController.h new file mode 100644 index 000000000..bb3bc9409 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStreamDefaultController.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 Canon Inc. + * Copyright (C) 2017 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 required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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 "JSDOMConvertBufferSource.h" +#include "JSReadableStreamDefaultController.h" +#include <JavaScriptCore/JSCJSValue.h> +#include <JavaScriptCore/JSCJSValueInlines.h> +#include <JavaScriptCore/TypedArrays.h> + +namespace WebCore { + +class ReadableStreamSource; + +class ReadableStreamDefaultController { +public: + explicit ReadableStreamDefaultController(JSReadableStreamDefaultController* controller) + : m_jsController(controller) + { + } + + bool enqueue(RefPtr<JSC::ArrayBuffer>&&); + bool enqueue(JSC::JSValue); + void error(const Exception&); + void error(JSC::JSValue error); + void close(); + JSDOMGlobalObject& globalObject() const; + JSReadableStreamDefaultController& jsController() const; + // The owner of ReadableStreamDefaultController is responsible to keep uncollected the JSReadableStreamDefaultController. + JSReadableStreamDefaultController* m_jsController { nullptr }; + +private: +}; + +inline JSReadableStreamDefaultController& ReadableStreamDefaultController::jsController() const +{ + ASSERT(m_jsController); + return *m_jsController; +} + +inline JSDOMGlobalObject& ReadableStreamDefaultController::globalObject() const +{ + ASSERT(m_jsController); + ASSERT(m_jsController->globalObject()); + return *static_cast<JSDOMGlobalObject*>(m_jsController->globalObject()); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ReadableStreamSink.cpp b/src/bun.js/bindings/webcore/ReadableStreamSink.cpp new file mode 100644 index 000000000..960756a28 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStreamSink.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config.h" +#include "ReadableStreamSink.h" + +#include "BufferSource.h" +#include "DOMException.h" +#include "ReadableStream.h" + +namespace WebCore { + +ReadableStreamToSharedBufferSink::ReadableStreamToSharedBufferSink(Callback&& callback) + : m_callback { WTFMove(callback) } +{ +} + +void ReadableStreamToSharedBufferSink::pipeFrom(ReadableStream& stream) +{ + stream.pipeTo(*this); +} + +void ReadableStreamToSharedBufferSink::enqueue(const BufferSource& buffer) +{ + if (!buffer.length()) + return; + + if (m_callback) { + Span chunk { buffer.data(), buffer.length() }; + m_callback(&chunk); + } +} + +void ReadableStreamToSharedBufferSink::close() +{ + if (m_callback) + m_callback(nullptr); +} + +void ReadableStreamToSharedBufferSink::error(String&& message) +{ + if (auto callback = WTFMove(m_callback)) + callback(Exception { TypeError, WTFMove(message) }); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ReadableStreamSink.h b/src/bun.js/bindings/webcore/ReadableStreamSink.h new file mode 100644 index 000000000..fee988422 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStreamSink.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017 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 "ExceptionOr.h" +#include <wtf/Function.h> +#include <wtf/RefCounted.h> +#include <wtf/Span.h> + +namespace WebCore { + +class BufferSource; +class ReadableStream; + +class ReadableStreamSink : public RefCounted<ReadableStreamSink> { +public: + virtual ~ReadableStreamSink() = default; + + virtual void enqueue(const BufferSource&) = 0; + virtual void close() = 0; + virtual void error(String&&) = 0; +}; + +class ReadableStreamToSharedBufferSink final : public ReadableStreamSink { +public: + using Callback = Function<void(ExceptionOr<Span<const uint8_t>*>&&)>; + static Ref<ReadableStreamToSharedBufferSink> create(Callback&& callback) { return adoptRef(*new ReadableStreamToSharedBufferSink(WTFMove(callback))); } + void pipeFrom(ReadableStream&); + void clearCallback() { m_callback = { }; } + +private: + explicit ReadableStreamToSharedBufferSink(Callback&&); + + void enqueue(const BufferSource&) final; + void close() final; + void error(String&&) final; + + Callback m_callback; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ReadableStreamSource.cpp b/src/bun.js/bindings/webcore/ReadableStreamSource.cpp new file mode 100644 index 000000000..f969c84b1 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStreamSource.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config.h" +#include "ReadableStreamSource.h" + +namespace WebCore { + +ReadableStreamSource::~ReadableStreamSource() = default; + +void ReadableStreamSource::start(ReadableStreamDefaultController&& controller, DOMPromiseDeferred<void>&& promise) +{ + ASSERT(!m_promise); + m_promise = makeUnique<DOMPromiseDeferred<void>>(WTFMove(promise)); + m_controller = WTFMove(controller); + + setActive(); + doStart(); +} + +void ReadableStreamSource::pull(DOMPromiseDeferred<void>&& promise) +{ + ASSERT(!m_promise); + ASSERT(m_controller); + + m_promise = makeUnique<DOMPromiseDeferred<void>>(WTFMove(promise)); + + setActive(); + doPull(); +} + +void ReadableStreamSource::startFinished() +{ + ASSERT(m_promise); + m_promise->resolve(); + m_promise = nullptr; + setInactive(); +} + +void ReadableStreamSource::pullFinished() +{ + ASSERT(m_promise); + m_promise->resolve(); + m_promise = nullptr; + setInactive(); +} + +void ReadableStreamSource::cancel(JSC::JSValue) +{ + clean(); + doCancel(); +} + +void ReadableStreamSource::clean() +{ + if (m_promise) { + m_promise = nullptr; + setInactive(); + } +} + +void ReadableStreamSource::error(JSC::JSValue value) +{ + if (m_promise) { + m_promise->reject(value, RejectAsHandled::Yes); + m_promise = nullptr; + setInactive(); + } else { + controller().error(value); + } +} + +void SimpleReadableStreamSource::doCancel() +{ + m_isCancelled = true; +} + +void SimpleReadableStreamSource::close() +{ + if (!m_isCancelled) + controller().close(); +} + +void SimpleReadableStreamSource::enqueue(JSC::JSValue value) +{ + if (!m_isCancelled) + controller().enqueue(value); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ReadableStreamSource.h b/src/bun.js/bindings/webcore/ReadableStreamSource.h new file mode 100644 index 000000000..0886ab423 --- /dev/null +++ b/src/bun.js/bindings/webcore/ReadableStreamSource.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2016 Canon Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions + * are required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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 "JSDOMPromiseDeferred.h" +#include "ReadableStreamDefaultController.h" +#include <wtf/WeakPtr.h> + +namespace WebCore { + +class ReadableStreamSource : public RefCounted<ReadableStreamSource> { +public: + virtual ~ReadableStreamSource(); + + void start(ReadableStreamDefaultController&&, DOMPromiseDeferred<void>&&); + void pull(DOMPromiseDeferred<void>&&); + void cancel(JSC::JSValue); + void error(JSC::JSValue error); + + bool hasController() const { return !!m_controller; } + + bool isPulling() const { return !!m_promise; } + +protected: + ReadableStreamDefaultController& controller() { return m_controller.value(); } + const ReadableStreamDefaultController& controller() const { return m_controller.value(); } + + void startFinished(); + void pullFinished(); + void cancelFinished(); + void clean(); + + virtual void setActive() = 0; + virtual void setInactive() = 0; + + virtual void doStart() = 0; + virtual void doPull() = 0; + virtual void doCancel() = 0; + + std::unique_ptr<DOMPromiseDeferred<void>> m_promise; + +private: + std::optional<ReadableStreamDefaultController> m_controller; +}; + +class SimpleReadableStreamSource + : public ReadableStreamSource, + public CanMakeWeakPtr<SimpleReadableStreamSource> { +public: + static Ref<SimpleReadableStreamSource> create() { return adoptRef(*new SimpleReadableStreamSource); } + + void close(); + void enqueue(JSC::JSValue); + +private: + SimpleReadableStreamSource() = default; + + // ReadableStreamSource + void setActive() final {} + void setInactive() final {} + void doStart() final {} + void doPull() final {} + void doCancel() final; + + bool m_isCancelled { false }; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/RegisteredEventListener.h b/src/bun.js/bindings/webcore/RegisteredEventListener.h new file mode 100644 index 000000000..1b2f48af4 --- /dev/null +++ b/src/bun.js/bindings/webcore/RegisteredEventListener.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2001 Peter Kelly (pmk@post.com) + * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de) + * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) + * Copyright (C) 2003-2021 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#pragma once + +#include "EventListener.h" +#include <wtf/Ref.h> + +namespace WebCore { + +// https://dom.spec.whatwg.org/#concept-event-listener +class RegisteredEventListener : public RefCounted<RegisteredEventListener> { +public: + struct Options { + Options(bool capture = false, bool passive = false, bool once = false) + : capture(capture) + , passive(passive) + , once(once) + { } + + bool capture; + bool passive; + bool once; + }; + + static Ref<RegisteredEventListener> create(Ref<EventListener>&& listener, const Options& options) + { + return adoptRef(*new RegisteredEventListener(WTFMove(listener), options)); + } + + EventListener& callback() const { return m_callback; } + bool useCapture() const { return m_useCapture; } + bool isPassive() const { return m_isPassive; } + bool isOnce() const { return m_isOnce; } + bool wasRemoved() const { return m_wasRemoved; } + + void markAsRemoved() { m_wasRemoved = true; } + +private: + RegisteredEventListener(Ref<EventListener>&& listener, const Options& options) + : m_useCapture(options.capture) + , m_isPassive(options.passive) + , m_isOnce(options.once) + , m_wasRemoved(false) + , m_callback(WTFMove(listener)) + { + } + + bool m_useCapture : 1; + bool m_isPassive : 1; + bool m_isOnce : 1; + bool m_wasRemoved : 1; + Ref<EventListener> m_callback; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ScriptWrappable.cpp b/src/bun.js/bindings/webcore/ScriptWrappable.cpp new file mode 100644 index 000000000..c55b2ac92 --- /dev/null +++ b/src/bun.js/bindings/webcore/ScriptWrappable.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 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. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#include "config.h" +#include "ScriptWrappable.h" + +// #include "wtf/IsoMallocInlines.h" + +namespace WebCore { + +// WTF_MAKE_FAST_ALLOCATED + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ScriptWrappable.h b/src/bun.js/bindings/webcore/ScriptWrappable.h new file mode 100644 index 000000000..20aafa6a1 --- /dev/null +++ b/src/bun.js/bindings/webcore/ScriptWrappable.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (c) 2010, Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +#pragma once + +#include "root.h" + +#include "JSDOMWrapper.h" + +// #include "wtf/IsoMalloc.h" + +namespace WebCore { + +class ScriptWrappable { + WTF_MAKE_FAST_ALLOCATED; + +public: + JSDOMObject* wrapper() const; + void setWrapper(JSDOMObject*, JSC::WeakHandleOwner*, void*); + void clearWrapper(JSDOMObject*); + + template<typename Derived> + static ptrdiff_t offsetOfWrapper() { return CAST_OFFSET(Derived*, ScriptWrappable*) + OBJECT_OFFSETOF(ScriptWrappable, m_wrapper); } + +protected: + ~ScriptWrappable() = default; + +private: + JSC::Weak<JSDOMObject> m_wrapper; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/ScriptWrappableInlines.h b/src/bun.js/bindings/webcore/ScriptWrappableInlines.h new file mode 100644 index 000000000..80b8087bf --- /dev/null +++ b/src/bun.js/bindings/webcore/ScriptWrappableInlines.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (c) 2010, Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +#pragma once + +#include "JSDOMWrapper.h" +#include "JavaScriptCore/Weak.h" +#include "JavaScriptCore/WeakInlines.h" + +namespace WebCore { + +inline JSDOMObject* ScriptWrappable::wrapper() const +{ + return m_wrapper.get(); +} + +inline void ScriptWrappable::setWrapper(JSDOMObject* wrapper, JSC::WeakHandleOwner* wrapperOwner, void* context) +{ + ASSERT(!m_wrapper); + m_wrapper = JSC::Weak<JSDOMObject>(wrapper, wrapperOwner, context); +} + +inline void ScriptWrappable::clearWrapper(JSDOMObject* wrapper) +{ + weakClear(m_wrapper, wrapper); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/StructuredClone.cpp b/src/bun.js/bindings/webcore/StructuredClone.cpp new file mode 100644 index 000000000..aabc9009c --- /dev/null +++ b/src/bun.js/bindings/webcore/StructuredClone.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2016 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 "StructuredClone.h" + +#include "JSDOMBinding.h" +#include "JSDOMExceptionHandling.h" +#include <JavaScriptCore/JSTypedArrays.h> + +namespace WebCore { +using namespace JSC; + +enum class CloneMode { + Full, + Partial, +}; + +static EncodedJSValue cloneArrayBufferImpl(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame, CloneMode mode) +{ + VM& vm = lexicalGlobalObject->vm(); + + ASSERT(lexicalGlobalObject); + ASSERT(callFrame->argumentCount()); + ASSERT(callFrame->lexicalGlobalObject(vm) == lexicalGlobalObject); + + auto* buffer = toUnsharedArrayBuffer(vm, callFrame->uncheckedArgument(0)); + if (!buffer) { + auto scope = DECLARE_THROW_SCOPE(vm); + throwDataCloneError(*lexicalGlobalObject, scope); + return { }; + } + if (mode == CloneMode::Partial) { + ASSERT(callFrame->argumentCount() == 3); + int srcByteOffset = static_cast<int>(callFrame->uncheckedArgument(1).toNumber(lexicalGlobalObject)); + int srcLength = static_cast<int>(callFrame->uncheckedArgument(2).toNumber(lexicalGlobalObject)); + return JSValue::encode(JSArrayBuffer::create(lexicalGlobalObject->vm(), lexicalGlobalObject->arrayBufferStructure(ArrayBufferSharingMode::Default), buffer->slice(srcByteOffset, srcByteOffset + srcLength))); + } + return JSValue::encode(JSArrayBuffer::create(lexicalGlobalObject->vm(), lexicalGlobalObject->arrayBufferStructure(ArrayBufferSharingMode::Default), ArrayBuffer::tryCreate(buffer->data(), buffer->byteLength()))); +} + +JSC_DEFINE_HOST_FUNCTION(cloneArrayBuffer, (JSGlobalObject* globalObject, CallFrame* callFrame)) +{ + return cloneArrayBufferImpl(globalObject, callFrame, CloneMode::Partial); +} + +JSC_DEFINE_HOST_FUNCTION(structuredCloneForStream, (JSGlobalObject* globalObject, CallFrame* callFrame)) +{ + ASSERT(callFrame); + ASSERT(callFrame->argumentCount()); + + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + JSValue value = callFrame->uncheckedArgument(0); + + if (value.inherits<JSArrayBuffer>()) + RELEASE_AND_RETURN(scope, cloneArrayBufferImpl(globalObject, callFrame, CloneMode::Full)); + + if (value.inherits<JSArrayBufferView>()) { + auto* bufferView = jsCast<JSArrayBufferView*>(value); + ASSERT(bufferView); + + auto* buffer = bufferView->unsharedBuffer(); + if (!buffer) { + throwDataCloneError(*globalObject, scope); + return { }; + } + auto bufferClone = ArrayBuffer::tryCreate(buffer->data(), buffer->byteLength()); + Structure* structure = bufferView->structure(); + +#define CLONE_TYPED_ARRAY(name) \ + do { \ + if (bufferView->inherits<JS##name##Array>()) \ + RELEASE_AND_RETURN(scope, JSValue::encode(JS##name##Array::create(globalObject, structure, WTFMove(bufferClone), bufferView->byteOffset(), bufferView->length()))); \ + } while (0); + + FOR_EACH_TYPED_ARRAY_TYPE_EXCLUDING_DATA_VIEW(CLONE_TYPED_ARRAY) + +#undef CLONE_TYPED_ARRAY + + if (value.inherits<JSDataView>()) + RELEASE_AND_RETURN(scope, JSValue::encode(JSDataView::create(globalObject, structure, WTFMove(bufferClone), bufferView->byteOffset(), bufferView->length()))); + } + + throwTypeError(globalObject, scope, "structuredClone not implemented for non-ArrayBuffer / non-ArrayBufferView"_s); + return { }; +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/StructuredClone.h b/src/bun.js/bindings/webcore/StructuredClone.h new file mode 100644 index 000000000..af14c0873 --- /dev/null +++ b/src/bun.js/bindings/webcore/StructuredClone.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016-2020 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. + * + */ + +#pragma once + +namespace JSC { +class CallFrame; +class JSGlobalObject; +using EncodedJSValue = int64_t; +} + +namespace WebCore { + +JSC_DECLARE_HOST_FUNCTION(cloneArrayBuffer); +JSC_DECLARE_HOST_FUNCTION(structuredCloneForStream); + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/TaskSource.h b/src/bun.js/bindings/webcore/TaskSource.h new file mode 100644 index 000000000..2c0a128e8 --- /dev/null +++ b/src/bun.js/bindings/webcore/TaskSource.h @@ -0,0 +1,29 @@ +#pragma once + +namespace WebCore { + +enum class TaskSource : uint8_t { + DOMManipulation, + DatabaseAccess, + FileReading, + FontLoading, + Geolocation, + IdleTask, + IndexedDB, + MediaElement, + Microtask, + Networking, + PerformanceTimeline, + Permission, + PostedMessageQueue, + Speech, + UserInteraction, + WebGL, + WebXR, + WebSocket, + + // Internal to WebCore + InternalAsyncTask, // Safe to re-order or delay. +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/TextEncoder.cpp b/src/bun.js/bindings/webcore/TextEncoder.cpp new file mode 100644 index 000000000..1942694cc --- /dev/null +++ b/src/bun.js/bindings/webcore/TextEncoder.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 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, + * 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 "TextEncoder.h" + +#include <JavaScriptCore/GenericTypedArrayViewInlines.h> +#include <JavaScriptCore/JSCInlines.h> + +namespace WebCore { + +String TextEncoder::encoding() const +{ + return "utf-8"_s; +} + +RefPtr<Uint8Array> TextEncoder::encode(String&& input) const +{ + // THIS CODE SHOULD NEVER BE REACHED IN BUN + RELEASE_ASSERT(1); + return nullptr; +} + +auto TextEncoder::encodeInto(String&& input, Ref<Uint8Array>&& array) -> EncodeIntoResult +{ + // THIS CODE SHOULD NEVER BE REACHED IN BUN + RELEASE_ASSERT(1); + + auto* destinationBytes = static_cast<uint8_t*>(array->baseAddress()); + auto capacity = array->byteLength(); + + uint64_t read = 0; + uint64_t written = 0; + + for (auto token : StringView(input).codePoints()) { + if (written >= capacity) { + ASSERT(written == capacity); + break; + } + UBool sawError = false; + U8_APPEND(destinationBytes, written, capacity, token, sawError); + if (sawError) + break; + if (U_IS_BMP(token)) + read++; + else + read += 2; + } + + return { read, written }; +} + +} diff --git a/src/bun.js/bindings/webcore/TextEncoder.h b/src/bun.js/bindings/webcore/TextEncoder.h new file mode 100644 index 000000000..6a0145c78 --- /dev/null +++ b/src/bun.js/bindings/webcore/TextEncoder.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 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, + * 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 "JSDOMConvertBufferSource.h" +#include <JavaScriptCore/Forward.h> +#include <wtf/Ref.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> + +// THIS FILE IS UNUSED +// IT EXISTS TO MAKE THE BINDINGS HAPPY +namespace WebCore { + +class TextEncoder : public RefCounted<TextEncoder> { +public: + struct EncodeIntoResult { + uint64_t read { 0 }; + uint64_t written { 0 }; + }; + + static Ref<TextEncoder> create() { return adoptRef(*new TextEncoder); } + String encoding() const; + RefPtr<Uint8Array> encode(String&&) const; + EncodeIntoResult encodeInto(String&&, Ref<Uint8Array>&& destination); + +private: + TextEncoder() {}; +}; + +} diff --git a/src/bun.js/bindings/webcore/UIEventInit.h b/src/bun.js/bindings/webcore/UIEventInit.h new file mode 100644 index 000000000..4511ba84a --- /dev/null +++ b/src/bun.js/bindings/webcore/UIEventInit.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 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 "EventInit.h" +// #include "WindowProxy.h" +#include <wtf/RefPtr.h> +#include <wtf/Ref.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +struct UIEventInitView { + int garbage; + + void ref() + { + } + + void deref() + { + } +}; + +struct UIEventInit : public EventInit { + RefPtr<UIEventInitView> view; + int detail { 0 }; +}; + +} diff --git a/src/bun.js/bindings/webcore/WebCoreBuiltins.h b/src/bun.js/bindings/webcore/WebCoreBuiltins.h new file mode 100644 index 000000000..abd53c142 --- /dev/null +++ b/src/bun.js/bindings/webcore/WebCoreBuiltins.h @@ -0,0 +1,2227 @@ +/* + * Copyright (c) 2015 Igalia + * Copyright (c) 2015 Igalia S.L. + * Copyright (c) 2015 Igalia. + * Copyright (c) 2015, 2016 Canon Inc. All rights reserved. + * Copyright (c) 2015, 2016, 2017 Canon Inc. + * Copyright (c) 2016, 2020 Apple Inc. All rights reserved. + * Copyright (c) 2022 Codeblog Corp. 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. + * + */ + +// DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for +// builtins by the script: Source/JavaScriptCore/Scripts/generate-js-builtins.py + +#pragma once + +namespace JSC { +class FunctionExecutable; +class VM; + +enum class ConstructAbility : uint8_t; +enum class ConstructorKind : uint8_t; +} + +namespace WebCore { + +extern const char s_WebCoreCombinedCode[]; + +extern const unsigned s_WebCoreCombinedCodeLength; + +/* ByteLengthQueuingStrategy */ +extern const char* const s_byteLengthQueuingStrategyHighWaterMarkCode; +extern const int s_byteLengthQueuingStrategyHighWaterMarkCodeLength; +extern const JSC::ConstructAbility s_byteLengthQueuingStrategyHighWaterMarkCodeConstructAbility; +extern const JSC::ConstructorKind s_byteLengthQueuingStrategyHighWaterMarkCodeConstructorKind; +extern const char* const s_byteLengthQueuingStrategySizeCode; +extern const int s_byteLengthQueuingStrategySizeCodeLength; +extern const JSC::ConstructAbility s_byteLengthQueuingStrategySizeCodeConstructAbility; +extern const JSC::ConstructorKind s_byteLengthQueuingStrategySizeCodeConstructorKind; +extern const char* const s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCode; +extern const int s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeLength; +extern const JSC::ConstructAbility s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeConstructAbility; +extern const JSC::ConstructorKind s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeConstructorKind; + +#define WEBCORE_FOREACH_BYTELENGTHQUEUINGSTRATEGY_BUILTIN_DATA(macro) \ + macro(highWaterMark, byteLengthQueuingStrategyHighWaterMark, 0) \ + macro(size, byteLengthQueuingStrategySize, 1) \ + macro(initializeByteLengthQueuingStrategy, byteLengthQueuingStrategyInitializeByteLengthQueuingStrategy, 1) \ + +/* CountQueuingStrategy */ +extern const char* const s_countQueuingStrategyHighWaterMarkCode; +extern const int s_countQueuingStrategyHighWaterMarkCodeLength; +extern const JSC::ConstructAbility s_countQueuingStrategyHighWaterMarkCodeConstructAbility; +extern const JSC::ConstructorKind s_countQueuingStrategyHighWaterMarkCodeConstructorKind; +extern const char* const s_countQueuingStrategySizeCode; +extern const int s_countQueuingStrategySizeCodeLength; +extern const JSC::ConstructAbility s_countQueuingStrategySizeCodeConstructAbility; +extern const JSC::ConstructorKind s_countQueuingStrategySizeCodeConstructorKind; +extern const char* const s_countQueuingStrategyInitializeCountQueuingStrategyCode; +extern const int s_countQueuingStrategyInitializeCountQueuingStrategyCodeLength; +extern const JSC::ConstructAbility s_countQueuingStrategyInitializeCountQueuingStrategyCodeConstructAbility; +extern const JSC::ConstructorKind s_countQueuingStrategyInitializeCountQueuingStrategyCodeConstructorKind; + +#define WEBCORE_FOREACH_COUNTQUEUINGSTRATEGY_BUILTIN_DATA(macro) \ + macro(highWaterMark, countQueuingStrategyHighWaterMark, 0) \ + macro(size, countQueuingStrategySize, 0) \ + macro(initializeCountQueuingStrategy, countQueuingStrategyInitializeCountQueuingStrategy, 1) \ + +/* JSBufferConstructor */ +extern const char* const s_jsBufferConstructorFromCode; +extern const int s_jsBufferConstructorFromCodeLength; +extern const JSC::ConstructAbility s_jsBufferConstructorFromCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferConstructorFromCodeConstructorKind; + +#define WEBCORE_FOREACH_JSBUFFERCONSTRUCTOR_BUILTIN_DATA(macro) \ + macro(from, jsBufferConstructorFrom, 1) \ + +/* JSBufferPrototype */ +extern const char* const s_jsBufferPrototypeSetBigUint64Code; +extern const int s_jsBufferPrototypeSetBigUint64CodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeSetBigUint64CodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeSetBigUint64CodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadInt8Code; +extern const int s_jsBufferPrototypeReadInt8CodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadInt8CodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadInt8CodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadUInt8Code; +extern const int s_jsBufferPrototypeReadUInt8CodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadUInt8CodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadUInt8CodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadInt16LECode; +extern const int s_jsBufferPrototypeReadInt16LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadInt16LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadInt16LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadInt16BECode; +extern const int s_jsBufferPrototypeReadInt16BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadInt16BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadInt16BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadUInt16LECode; +extern const int s_jsBufferPrototypeReadUInt16LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadUInt16LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadUInt16LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadUInt16BECode; +extern const int s_jsBufferPrototypeReadUInt16BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadUInt16BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadUInt16BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadInt32LECode; +extern const int s_jsBufferPrototypeReadInt32LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadInt32LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadInt32LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadInt32BECode; +extern const int s_jsBufferPrototypeReadInt32BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadInt32BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadInt32BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadUInt32LECode; +extern const int s_jsBufferPrototypeReadUInt32LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadUInt32LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadUInt32LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadUInt32BECode; +extern const int s_jsBufferPrototypeReadUInt32BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadUInt32BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadUInt32BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadFloatLECode; +extern const int s_jsBufferPrototypeReadFloatLECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadFloatLECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadFloatLECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadFloatBECode; +extern const int s_jsBufferPrototypeReadFloatBECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadFloatBECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadFloatBECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadDoubleLECode; +extern const int s_jsBufferPrototypeReadDoubleLECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadDoubleLECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadDoubleLECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadDoubleBECode; +extern const int s_jsBufferPrototypeReadDoubleBECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadDoubleBECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadDoubleBECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadBigInt64LECode; +extern const int s_jsBufferPrototypeReadBigInt64LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadBigInt64LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadBigInt64LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadBigInt64BECode; +extern const int s_jsBufferPrototypeReadBigInt64BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadBigInt64BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadBigInt64BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadBigUInt64LECode; +extern const int s_jsBufferPrototypeReadBigUInt64LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadBigUInt64LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadBigUInt64LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeReadBigUInt64BECode; +extern const int s_jsBufferPrototypeReadBigUInt64BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeReadBigUInt64BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeReadBigUInt64BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteInt8Code; +extern const int s_jsBufferPrototypeWriteInt8CodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteInt8CodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteInt8CodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteUInt8Code; +extern const int s_jsBufferPrototypeWriteUInt8CodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt8CodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt8CodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteInt16LECode; +extern const int s_jsBufferPrototypeWriteInt16LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteInt16LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteInt16LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteInt16BECode; +extern const int s_jsBufferPrototypeWriteInt16BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteInt16BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteInt16BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteUInt16LECode; +extern const int s_jsBufferPrototypeWriteUInt16LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt16LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt16LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteUInt16BECode; +extern const int s_jsBufferPrototypeWriteUInt16BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt16BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt16BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteInt32LECode; +extern const int s_jsBufferPrototypeWriteInt32LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteInt32LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteInt32LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteInt32BECode; +extern const int s_jsBufferPrototypeWriteInt32BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteInt32BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteInt32BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteUInt32LECode; +extern const int s_jsBufferPrototypeWriteUInt32LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt32LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt32LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteUInt32BECode; +extern const int s_jsBufferPrototypeWriteUInt32BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteUInt32BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteUInt32BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteFloatLECode; +extern const int s_jsBufferPrototypeWriteFloatLECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteFloatLECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteFloatLECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteFloatBECode; +extern const int s_jsBufferPrototypeWriteFloatBECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteFloatBECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteFloatBECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteDoubleLECode; +extern const int s_jsBufferPrototypeWriteDoubleLECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteDoubleLECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteDoubleLECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteDoubleBECode; +extern const int s_jsBufferPrototypeWriteDoubleBECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteDoubleBECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteDoubleBECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteBigInt64LECode; +extern const int s_jsBufferPrototypeWriteBigInt64LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteBigInt64LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteBigInt64LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteBigInt64BECode; +extern const int s_jsBufferPrototypeWriteBigInt64BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteBigInt64BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteBigInt64BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteBigUInt64LECode; +extern const int s_jsBufferPrototypeWriteBigUInt64LECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteBigUInt64LECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteBigUInt64LECodeConstructorKind; +extern const char* const s_jsBufferPrototypeWriteBigUInt64BECode; +extern const int s_jsBufferPrototypeWriteBigUInt64BECodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeWriteBigUInt64BECodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeWriteBigUInt64BECodeConstructorKind; +extern const char* const s_jsBufferPrototypeSliceCode; +extern const int s_jsBufferPrototypeSliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeSliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeSliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeUtf8WriteCode; +extern const int s_jsBufferPrototypeUtf8WriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeUtf8WriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeUtf8WriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeUcs2WriteCode; +extern const int s_jsBufferPrototypeUcs2WriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeUcs2WriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeUcs2WriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeUtf16leWriteCode; +extern const int s_jsBufferPrototypeUtf16leWriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeUtf16leWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeUtf16leWriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeLatin1WriteCode; +extern const int s_jsBufferPrototypeLatin1WriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeLatin1WriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeLatin1WriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeAsciiWriteCode; +extern const int s_jsBufferPrototypeAsciiWriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeAsciiWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeAsciiWriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeBase64WriteCode; +extern const int s_jsBufferPrototypeBase64WriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeBase64WriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeBase64WriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeBase64urlWriteCode; +extern const int s_jsBufferPrototypeBase64urlWriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeBase64urlWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeBase64urlWriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeHexWriteCode; +extern const int s_jsBufferPrototypeHexWriteCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeHexWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeHexWriteCodeConstructorKind; +extern const char* const s_jsBufferPrototypeUtf8SliceCode; +extern const int s_jsBufferPrototypeUtf8SliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeUtf8SliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeUtf8SliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeUcs2SliceCode; +extern const int s_jsBufferPrototypeUcs2SliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeUcs2SliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeUcs2SliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeUtf16leSliceCode; +extern const int s_jsBufferPrototypeUtf16leSliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeUtf16leSliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeUtf16leSliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeLatin1SliceCode; +extern const int s_jsBufferPrototypeLatin1SliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeLatin1SliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeLatin1SliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeAsciiSliceCode; +extern const int s_jsBufferPrototypeAsciiSliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeAsciiSliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeAsciiSliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeBase64SliceCode; +extern const int s_jsBufferPrototypeBase64SliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeBase64SliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeBase64SliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeBase64urlSliceCode; +extern const int s_jsBufferPrototypeBase64urlSliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeBase64urlSliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeBase64urlSliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeHexSliceCode; +extern const int s_jsBufferPrototypeHexSliceCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeHexSliceCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeHexSliceCodeConstructorKind; +extern const char* const s_jsBufferPrototypeToJSONCode; +extern const int s_jsBufferPrototypeToJSONCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeToJSONCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeToJSONCodeConstructorKind; +extern const char* const s_jsBufferPrototypeSubarrayCode; +extern const int s_jsBufferPrototypeSubarrayCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeSubarrayCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeSubarrayCodeConstructorKind; +extern const char* const s_jsBufferPrototypeInitializeBunBufferCode; +extern const int s_jsBufferPrototypeInitializeBunBufferCodeLength; +extern const JSC::ConstructAbility s_jsBufferPrototypeInitializeBunBufferCodeConstructAbility; +extern const JSC::ConstructorKind s_jsBufferPrototypeInitializeBunBufferCodeConstructorKind; + +#define WEBCORE_FOREACH_JSBUFFERPROTOTYPE_BUILTIN_DATA(macro) \ + macro(setBigUint64, jsBufferPrototypeSetBigUint64, 3) \ + macro(readInt8, jsBufferPrototypeReadInt8, 1) \ + macro(readUInt8, jsBufferPrototypeReadUInt8, 1) \ + macro(readInt16LE, jsBufferPrototypeReadInt16LE, 1) \ + macro(readInt16BE, jsBufferPrototypeReadInt16BE, 1) \ + macro(readUInt16LE, jsBufferPrototypeReadUInt16LE, 1) \ + macro(readUInt16BE, jsBufferPrototypeReadUInt16BE, 1) \ + macro(readInt32LE, jsBufferPrototypeReadInt32LE, 1) \ + macro(readInt32BE, jsBufferPrototypeReadInt32BE, 1) \ + macro(readUInt32LE, jsBufferPrototypeReadUInt32LE, 1) \ + macro(readUInt32BE, jsBufferPrototypeReadUInt32BE, 1) \ + macro(readFloatLE, jsBufferPrototypeReadFloatLE, 1) \ + macro(readFloatBE, jsBufferPrototypeReadFloatBE, 1) \ + macro(readDoubleLE, jsBufferPrototypeReadDoubleLE, 1) \ + macro(readDoubleBE, jsBufferPrototypeReadDoubleBE, 1) \ + macro(readBigInt64LE, jsBufferPrototypeReadBigInt64LE, 1) \ + macro(readBigInt64BE, jsBufferPrototypeReadBigInt64BE, 1) \ + macro(readBigUInt64LE, jsBufferPrototypeReadBigUInt64LE, 1) \ + macro(readBigUInt64BE, jsBufferPrototypeReadBigUInt64BE, 1) \ + macro(writeInt8, jsBufferPrototypeWriteInt8, 2) \ + macro(writeUInt8, jsBufferPrototypeWriteUInt8, 2) \ + macro(writeInt16LE, jsBufferPrototypeWriteInt16LE, 2) \ + macro(writeInt16BE, jsBufferPrototypeWriteInt16BE, 2) \ + macro(writeUInt16LE, jsBufferPrototypeWriteUInt16LE, 2) \ + macro(writeUInt16BE, jsBufferPrototypeWriteUInt16BE, 2) \ + macro(writeInt32LE, jsBufferPrototypeWriteInt32LE, 2) \ + macro(writeInt32BE, jsBufferPrototypeWriteInt32BE, 2) \ + macro(writeUInt32LE, jsBufferPrototypeWriteUInt32LE, 2) \ + macro(writeUInt32BE, jsBufferPrototypeWriteUInt32BE, 2) \ + macro(writeFloatLE, jsBufferPrototypeWriteFloatLE, 2) \ + macro(writeFloatBE, jsBufferPrototypeWriteFloatBE, 2) \ + macro(writeDoubleLE, jsBufferPrototypeWriteDoubleLE, 2) \ + macro(writeDoubleBE, jsBufferPrototypeWriteDoubleBE, 2) \ + macro(writeBigInt64LE, jsBufferPrototypeWriteBigInt64LE, 2) \ + macro(writeBigInt64BE, jsBufferPrototypeWriteBigInt64BE, 2) \ + macro(writeBigUInt64LE, jsBufferPrototypeWriteBigUInt64LE, 2) \ + macro(writeBigUInt64BE, jsBufferPrototypeWriteBigUInt64BE, 2) \ + macro(slice, jsBufferPrototypeSlice, 2) \ + macro(utf8Write, jsBufferPrototypeUtf8Write, 3) \ + macro(ucs2Write, jsBufferPrototypeUcs2Write, 3) \ + macro(utf16leWrite, jsBufferPrototypeUtf16leWrite, 3) \ + macro(latin1Write, jsBufferPrototypeLatin1Write, 3) \ + macro(asciiWrite, jsBufferPrototypeAsciiWrite, 3) \ + macro(base64Write, jsBufferPrototypeBase64Write, 3) \ + macro(base64urlWrite, jsBufferPrototypeBase64urlWrite, 3) \ + macro(hexWrite, jsBufferPrototypeHexWrite, 3) \ + macro(utf8Slice, jsBufferPrototypeUtf8Slice, 2) \ + macro(ucs2Slice, jsBufferPrototypeUcs2Slice, 2) \ + macro(utf16leSlice, jsBufferPrototypeUtf16leSlice, 2) \ + macro(latin1Slice, jsBufferPrototypeLatin1Slice, 2) \ + macro(asciiSlice, jsBufferPrototypeAsciiSlice, 2) \ + macro(base64Slice, jsBufferPrototypeBase64Slice, 2) \ + macro(base64urlSlice, jsBufferPrototypeBase64urlSlice, 2) \ + macro(hexSlice, jsBufferPrototypeHexSlice, 2) \ + macro(toJSON, jsBufferPrototypeToJSON, 0) \ + macro(subarray, jsBufferPrototypeSubarray, 2) \ + macro(initializeBunBuffer, jsBufferPrototypeInitializeBunBuffer, 1) \ + +/* JSZigGlobalObject */ +extern const char* const s_jsZigGlobalObjectRequireCode; +extern const int s_jsZigGlobalObjectRequireCodeLength; +extern const JSC::ConstructAbility s_jsZigGlobalObjectRequireCodeConstructAbility; +extern const JSC::ConstructorKind s_jsZigGlobalObjectRequireCodeConstructorKind; + +#define WEBCORE_FOREACH_JSZIGGLOBALOBJECT_BUILTIN_DATA(macro) \ + macro(require, jsZigGlobalObjectRequire, 1) \ + +/* ReadableByteStreamController */ +extern const char* const s_readableByteStreamControllerInitializeReadableByteStreamControllerCode; +extern const int s_readableByteStreamControllerInitializeReadableByteStreamControllerCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamControllerInitializeReadableByteStreamControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamControllerInitializeReadableByteStreamControllerCodeConstructorKind; +extern const char* const s_readableByteStreamControllerEnqueueCode; +extern const int s_readableByteStreamControllerEnqueueCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamControllerEnqueueCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamControllerEnqueueCodeConstructorKind; +extern const char* const s_readableByteStreamControllerErrorCode; +extern const int s_readableByteStreamControllerErrorCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamControllerErrorCodeConstructorKind; +extern const char* const s_readableByteStreamControllerCloseCode; +extern const int s_readableByteStreamControllerCloseCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamControllerCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamControllerCloseCodeConstructorKind; +extern const char* const s_readableByteStreamControllerByobRequestCode; +extern const int s_readableByteStreamControllerByobRequestCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamControllerByobRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamControllerByobRequestCodeConstructorKind; +extern const char* const s_readableByteStreamControllerDesiredSizeCode; +extern const int s_readableByteStreamControllerDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamControllerDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamControllerDesiredSizeCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLEBYTESTREAMCONTROLLER_BUILTIN_DATA(macro) \ + macro(initializeReadableByteStreamController, readableByteStreamControllerInitializeReadableByteStreamController, 3) \ + macro(enqueue, readableByteStreamControllerEnqueue, 1) \ + macro(error, readableByteStreamControllerError, 1) \ + macro(close, readableByteStreamControllerClose, 0) \ + macro(byobRequest, readableByteStreamControllerByobRequest, 0) \ + macro(desiredSize, readableByteStreamControllerDesiredSize, 0) \ + +/* ReadableByteStreamInternals */ +extern const char* const s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCode; +extern const int s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCode; +extern const int s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsPrivateInitializeReadableStreamBYOBRequestCode; +extern const int s_readableByteStreamInternalsPrivateInitializeReadableStreamBYOBRequestCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsPrivateInitializeReadableStreamBYOBRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsPrivateInitializeReadableStreamBYOBRequestCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsIsReadableByteStreamControllerCode; +extern const int s_readableByteStreamInternalsIsReadableByteStreamControllerCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsIsReadableByteStreamControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsIsReadableByteStreamControllerCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsIsReadableStreamBYOBRequestCode; +extern const int s_readableByteStreamInternalsIsReadableStreamBYOBRequestCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsIsReadableStreamBYOBRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsIsReadableStreamBYOBRequestCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsIsReadableStreamBYOBReaderCode; +extern const int s_readableByteStreamInternalsIsReadableStreamBYOBReaderCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsIsReadableStreamBYOBReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsIsReadableStreamBYOBReaderCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerCancelCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerErrorCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerErrorCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerErrorCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerCloseCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerGetDesiredSizeCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerGetDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerGetDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerGetDesiredSizeCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableStreamHasBYOBReaderCode; +extern const int s_readableByteStreamInternalsReadableStreamHasBYOBReaderCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamHasBYOBReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamHasBYOBReaderCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableStreamHasDefaultReaderCode; +extern const int s_readableByteStreamInternalsReadableStreamHasDefaultReaderCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamHasDefaultReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamHasDefaultReaderCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerHandleQueueDrainCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerHandleQueueDrainCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerHandleQueueDrainCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerHandleQueueDrainCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerPullCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerPullCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerPullCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerCallPullIfNeededCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerCallPullIfNeededCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerCallPullIfNeededCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerCallPullIfNeededCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsTransferBufferToCurrentRealmCode; +extern const int s_readableByteStreamInternalsTransferBufferToCurrentRealmCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsTransferBufferToCurrentRealmCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsTransferBufferToCurrentRealmCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableStreamReaderKindCode; +extern const int s_readableByteStreamInternalsReadableStreamReaderKindCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamReaderKindCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamReaderKindCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerInvalidateBYOBRequestCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerInvalidateBYOBRequestCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerInvalidateBYOBRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerInvalidateBYOBRequestCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerCommitDescriptorCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerCommitDescriptorCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerCommitDescriptorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerCommitDescriptorCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerConvertDescriptorCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerConvertDescriptorCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerConvertDescriptorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerConvertDescriptorCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCode; +extern const int s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableStreamBYOBReaderReadCode; +extern const int s_readableByteStreamInternalsReadableStreamBYOBReaderReadCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamBYOBReaderReadCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamBYOBReaderReadCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCode; +extern const int s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeConstructorKind; +extern const char* const s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCode; +extern const int s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeLength; +extern const JSC::ConstructAbility s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLEBYTESTREAMINTERNALS_BUILTIN_DATA(macro) \ + macro(privateInitializeReadableByteStreamController, readableByteStreamInternalsPrivateInitializeReadableByteStreamController, 3) \ + macro(readableStreamByteStreamControllerStart, readableByteStreamInternalsReadableStreamByteStreamControllerStart, 1) \ + macro(privateInitializeReadableStreamBYOBRequest, readableByteStreamInternalsPrivateInitializeReadableStreamBYOBRequest, 2) \ + macro(isReadableByteStreamController, readableByteStreamInternalsIsReadableByteStreamController, 1) \ + macro(isReadableStreamBYOBRequest, readableByteStreamInternalsIsReadableStreamBYOBRequest, 1) \ + macro(isReadableStreamBYOBReader, readableByteStreamInternalsIsReadableStreamBYOBReader, 1) \ + macro(readableByteStreamControllerCancel, readableByteStreamInternalsReadableByteStreamControllerCancel, 2) \ + macro(readableByteStreamControllerError, readableByteStreamInternalsReadableByteStreamControllerError, 2) \ + macro(readableByteStreamControllerClose, readableByteStreamInternalsReadableByteStreamControllerClose, 1) \ + macro(readableByteStreamControllerClearPendingPullIntos, readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntos, 1) \ + macro(readableByteStreamControllerGetDesiredSize, readableByteStreamInternalsReadableByteStreamControllerGetDesiredSize, 1) \ + macro(readableStreamHasBYOBReader, readableByteStreamInternalsReadableStreamHasBYOBReader, 1) \ + macro(readableStreamHasDefaultReader, readableByteStreamInternalsReadableStreamHasDefaultReader, 1) \ + macro(readableByteStreamControllerHandleQueueDrain, readableByteStreamInternalsReadableByteStreamControllerHandleQueueDrain, 1) \ + macro(readableByteStreamControllerPull, readableByteStreamInternalsReadableByteStreamControllerPull, 1) \ + macro(readableByteStreamControllerShouldCallPull, readableByteStreamInternalsReadableByteStreamControllerShouldCallPull, 1) \ + macro(readableByteStreamControllerCallPullIfNeeded, readableByteStreamInternalsReadableByteStreamControllerCallPullIfNeeded, 1) \ + macro(transferBufferToCurrentRealm, readableByteStreamInternalsTransferBufferToCurrentRealm, 1) \ + macro(readableStreamReaderKind, readableByteStreamInternalsReadableStreamReaderKind, 1) \ + macro(readableByteStreamControllerEnqueue, readableByteStreamInternalsReadableByteStreamControllerEnqueue, 2) \ + macro(readableByteStreamControllerEnqueueChunk, readableByteStreamInternalsReadableByteStreamControllerEnqueueChunk, 4) \ + macro(readableByteStreamControllerRespondWithNewView, readableByteStreamInternalsReadableByteStreamControllerRespondWithNewView, 2) \ + macro(readableByteStreamControllerRespond, readableByteStreamInternalsReadableByteStreamControllerRespond, 2) \ + macro(readableByteStreamControllerRespondInternal, readableByteStreamInternalsReadableByteStreamControllerRespondInternal, 2) \ + macro(readableByteStreamControllerRespondInReadableState, readableByteStreamInternalsReadableByteStreamControllerRespondInReadableState, 3) \ + macro(readableByteStreamControllerRespondInClosedState, readableByteStreamInternalsReadableByteStreamControllerRespondInClosedState, 2) \ + macro(readableByteStreamControllerProcessPullDescriptors, readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptors, 1) \ + macro(readableByteStreamControllerFillDescriptorFromQueue, readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueue, 2) \ + macro(readableByteStreamControllerShiftPendingDescriptor, readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptor, 1) \ + macro(readableByteStreamControllerInvalidateBYOBRequest, readableByteStreamInternalsReadableByteStreamControllerInvalidateBYOBRequest, 1) \ + macro(readableByteStreamControllerCommitDescriptor, readableByteStreamInternalsReadableByteStreamControllerCommitDescriptor, 2) \ + macro(readableByteStreamControllerConvertDescriptor, readableByteStreamInternalsReadableByteStreamControllerConvertDescriptor, 1) \ + macro(readableStreamFulfillReadIntoRequest, readableByteStreamInternalsReadableStreamFulfillReadIntoRequest, 3) \ + macro(readableStreamBYOBReaderRead, readableByteStreamInternalsReadableStreamBYOBReaderRead, 2) \ + macro(readableByteStreamControllerPullInto, readableByteStreamInternalsReadableByteStreamControllerPullInto, 2) \ + macro(readableStreamAddReadIntoRequest, readableByteStreamInternalsReadableStreamAddReadIntoRequest, 1) \ + +/* ReadableStream */ +extern const char* const s_readableStreamInitializeReadableStreamCode; +extern const int s_readableStreamInitializeReadableStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInitializeReadableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInitializeReadableStreamCodeConstructorKind; +extern const char* const s_readableStreamReadableStreamToArrayCode; +extern const int s_readableStreamReadableStreamToArrayCodeLength; +extern const JSC::ConstructAbility s_readableStreamReadableStreamToArrayCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamReadableStreamToArrayCodeConstructorKind; +extern const char* const s_readableStreamReadableStreamToTextCode; +extern const int s_readableStreamReadableStreamToTextCodeLength; +extern const JSC::ConstructAbility s_readableStreamReadableStreamToTextCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamReadableStreamToTextCodeConstructorKind; +extern const char* const s_readableStreamReadableStreamToJSONCode; +extern const int s_readableStreamReadableStreamToJSONCodeLength; +extern const JSC::ConstructAbility s_readableStreamReadableStreamToJSONCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamReadableStreamToJSONCodeConstructorKind; +extern const char* const s_readableStreamReadableStreamToBlobCode; +extern const int s_readableStreamReadableStreamToBlobCodeLength; +extern const JSC::ConstructAbility s_readableStreamReadableStreamToBlobCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamReadableStreamToBlobCodeConstructorKind; +extern const char* const s_readableStreamReadableStreamToArrayPublicCode; +extern const int s_readableStreamReadableStreamToArrayPublicCodeLength; +extern const JSC::ConstructAbility s_readableStreamReadableStreamToArrayPublicCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamReadableStreamToArrayPublicCodeConstructorKind; +extern const char* const s_readableStreamConsumeReadableStreamCode; +extern const int s_readableStreamConsumeReadableStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamConsumeReadableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamConsumeReadableStreamCodeConstructorKind; +extern const char* const s_readableStreamCreateEmptyReadableStreamCode; +extern const int s_readableStreamCreateEmptyReadableStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamCreateEmptyReadableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamCreateEmptyReadableStreamCodeConstructorKind; +extern const char* const s_readableStreamCreateNativeReadableStreamCode; +extern const int s_readableStreamCreateNativeReadableStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamCreateNativeReadableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamCreateNativeReadableStreamCodeConstructorKind; +extern const char* const s_readableStreamCancelCode; +extern const int s_readableStreamCancelCodeLength; +extern const JSC::ConstructAbility s_readableStreamCancelCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamCancelCodeConstructorKind; +extern const char* const s_readableStreamGetReaderCode; +extern const int s_readableStreamGetReaderCodeLength; +extern const JSC::ConstructAbility s_readableStreamGetReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamGetReaderCodeConstructorKind; +extern const char* const s_readableStreamPipeThroughCode; +extern const int s_readableStreamPipeThroughCodeLength; +extern const JSC::ConstructAbility s_readableStreamPipeThroughCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamPipeThroughCodeConstructorKind; +extern const char* const s_readableStreamPipeToCode; +extern const int s_readableStreamPipeToCodeLength; +extern const JSC::ConstructAbility s_readableStreamPipeToCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamPipeToCodeConstructorKind; +extern const char* const s_readableStreamTeeCode; +extern const int s_readableStreamTeeCodeLength; +extern const JSC::ConstructAbility s_readableStreamTeeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamTeeCodeConstructorKind; +extern const char* const s_readableStreamLockedCode; +extern const int s_readableStreamLockedCodeLength; +extern const JSC::ConstructAbility s_readableStreamLockedCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLESTREAM_BUILTIN_DATA(macro) \ + macro(initializeReadableStream, readableStreamInitializeReadableStream, 2) \ + macro(readableStreamToArray, readableStreamReadableStreamToArray, 1) \ + macro(readableStreamToText, readableStreamReadableStreamToText, 1) \ + macro(readableStreamToJSON, readableStreamReadableStreamToJSON, 1) \ + macro(readableStreamToBlob, readableStreamReadableStreamToBlob, 1) \ + macro(readableStreamToArrayPublic, readableStreamReadableStreamToArrayPublic, 1) \ + macro(consumeReadableStream, readableStreamConsumeReadableStream, 3) \ + macro(createEmptyReadableStream, readableStreamCreateEmptyReadableStream, 0) \ + macro(createNativeReadableStream, readableStreamCreateNativeReadableStream, 3) \ + macro(cancel, readableStreamCancel, 1) \ + macro(getReader, readableStreamGetReader, 1) \ + macro(pipeThrough, readableStreamPipeThrough, 2) \ + macro(pipeTo, readableStreamPipeTo, 1) \ + macro(tee, readableStreamTee, 0) \ + macro(locked, readableStreamLocked, 0) \ + +/* ReadableStreamBYOBReader */ +extern const char* const s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCode; +extern const int s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeConstructorKind; +extern const char* const s_readableStreamBYOBReaderCancelCode; +extern const int s_readableStreamBYOBReaderCancelCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBReaderCancelCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBReaderCancelCodeConstructorKind; +extern const char* const s_readableStreamBYOBReaderReadCode; +extern const int s_readableStreamBYOBReaderReadCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBReaderReadCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBReaderReadCodeConstructorKind; +extern const char* const s_readableStreamBYOBReaderReleaseLockCode; +extern const int s_readableStreamBYOBReaderReleaseLockCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBReaderReleaseLockCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBReaderReleaseLockCodeConstructorKind; +extern const char* const s_readableStreamBYOBReaderClosedCode; +extern const int s_readableStreamBYOBReaderClosedCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBReaderClosedCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBReaderClosedCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLESTREAMBYOBREADER_BUILTIN_DATA(macro) \ + macro(initializeReadableStreamBYOBReader, readableStreamBYOBReaderInitializeReadableStreamBYOBReader, 1) \ + macro(cancel, readableStreamBYOBReaderCancel, 1) \ + macro(read, readableStreamBYOBReaderRead, 1) \ + macro(releaseLock, readableStreamBYOBReaderReleaseLock, 0) \ + macro(closed, readableStreamBYOBReaderClosed, 0) \ + +/* ReadableStreamBYOBRequest */ +extern const char* const s_readableStreamBYOBRequestInitializeReadableStreamBYOBRequestCode; +extern const int s_readableStreamBYOBRequestInitializeReadableStreamBYOBRequestCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBRequestInitializeReadableStreamBYOBRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBRequestInitializeReadableStreamBYOBRequestCodeConstructorKind; +extern const char* const s_readableStreamBYOBRequestRespondCode; +extern const int s_readableStreamBYOBRequestRespondCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBRequestRespondCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBRequestRespondCodeConstructorKind; +extern const char* const s_readableStreamBYOBRequestRespondWithNewViewCode; +extern const int s_readableStreamBYOBRequestRespondWithNewViewCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBRequestRespondWithNewViewCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBRequestRespondWithNewViewCodeConstructorKind; +extern const char* const s_readableStreamBYOBRequestViewCode; +extern const int s_readableStreamBYOBRequestViewCodeLength; +extern const JSC::ConstructAbility s_readableStreamBYOBRequestViewCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamBYOBRequestViewCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLESTREAMBYOBREQUEST_BUILTIN_DATA(macro) \ + macro(initializeReadableStreamBYOBRequest, readableStreamBYOBRequestInitializeReadableStreamBYOBRequest, 2) \ + macro(respond, readableStreamBYOBRequestRespond, 1) \ + macro(respondWithNewView, readableStreamBYOBRequestRespondWithNewView, 1) \ + macro(view, readableStreamBYOBRequestView, 0) \ + +/* ReadableStreamDefaultController */ +extern const char* const s_readableStreamDefaultControllerInitializeReadableStreamDefaultControllerCode; +extern const int s_readableStreamDefaultControllerInitializeReadableStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultControllerInitializeReadableStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultControllerInitializeReadableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_readableStreamDefaultControllerEnqueueCode; +extern const int s_readableStreamDefaultControllerEnqueueCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultControllerEnqueueCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultControllerEnqueueCodeConstructorKind; +extern const char* const s_readableStreamDefaultControllerErrorCode; +extern const int s_readableStreamDefaultControllerErrorCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultControllerErrorCodeConstructorKind; +extern const char* const s_readableStreamDefaultControllerCloseCode; +extern const int s_readableStreamDefaultControllerCloseCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultControllerCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultControllerCloseCodeConstructorKind; +extern const char* const s_readableStreamDefaultControllerDesiredSizeCode; +extern const int s_readableStreamDefaultControllerDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultControllerDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultControllerDesiredSizeCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLESTREAMDEFAULTCONTROLLER_BUILTIN_DATA(macro) \ + macro(initializeReadableStreamDefaultController, readableStreamDefaultControllerInitializeReadableStreamDefaultController, 4) \ + macro(enqueue, readableStreamDefaultControllerEnqueue, 1) \ + macro(error, readableStreamDefaultControllerError, 1) \ + macro(close, readableStreamDefaultControllerClose, 0) \ + macro(desiredSize, readableStreamDefaultControllerDesiredSize, 0) \ + +/* ReadableStreamDefaultReader */ +extern const char* const s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCode; +extern const int s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeConstructorKind; +extern const char* const s_readableStreamDefaultReaderCancelCode; +extern const int s_readableStreamDefaultReaderCancelCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultReaderCancelCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultReaderCancelCodeConstructorKind; +extern const char* const s_readableStreamDefaultReaderReadManyCode; +extern const int s_readableStreamDefaultReaderReadManyCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultReaderReadManyCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultReaderReadManyCodeConstructorKind; +extern const char* const s_readableStreamDefaultReaderReadCode; +extern const int s_readableStreamDefaultReaderReadCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultReaderReadCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultReaderReadCodeConstructorKind; +extern const char* const s_readableStreamDefaultReaderReleaseLockCode; +extern const int s_readableStreamDefaultReaderReleaseLockCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultReaderReleaseLockCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultReaderReleaseLockCodeConstructorKind; +extern const char* const s_readableStreamDefaultReaderClosedCode; +extern const int s_readableStreamDefaultReaderClosedCodeLength; +extern const JSC::ConstructAbility s_readableStreamDefaultReaderClosedCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamDefaultReaderClosedCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLESTREAMDEFAULTREADER_BUILTIN_DATA(macro) \ + macro(initializeReadableStreamDefaultReader, readableStreamDefaultReaderInitializeReadableStreamDefaultReader, 1) \ + macro(cancel, readableStreamDefaultReaderCancel, 1) \ + macro(readMany, readableStreamDefaultReaderReadMany, 0) \ + macro(read, readableStreamDefaultReaderRead, 0) \ + macro(releaseLock, readableStreamDefaultReaderReleaseLock, 0) \ + macro(closed, readableStreamDefaultReaderClosed, 0) \ + +/* ReadableStreamInternals */ +extern const char* const s_readableStreamInternalsReadableStreamReaderGenericInitializeCode; +extern const int s_readableStreamInternalsReadableStreamReaderGenericInitializeCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamReaderGenericInitializeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamReaderGenericInitializeCodeConstructorKind; +extern const char* const s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCode; +extern const int s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerErrorCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamPipeToCode; +extern const int s_readableStreamInternalsReadableStreamPipeToCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamPipeToCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamPipeToCodeConstructorKind; +extern const char* const s_readableStreamInternalsAcquireReadableStreamDefaultReaderCode; +extern const int s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeConstructorKind; +extern const char* const s_readableStreamInternalsSetupReadableStreamDefaultControllerCode; +extern const int s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_readableStreamInternalsCreateReadableStreamControllerCode; +extern const int s_readableStreamInternalsCreateReadableStreamControllerCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsCreateReadableStreamControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsCreateReadableStreamControllerCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerStartCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerStartCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamPipeToWritableStreamCode; +extern const int s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToLoopCode; +extern const int s_readableStreamInternalsPipeToLoopCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToLoopCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToLoopCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToDoReadWriteCode; +extern const int s_readableStreamInternalsPipeToDoReadWriteCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToDoReadWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToDoReadWriteCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToErrorsMustBePropagatedForwardCode; +extern const int s_readableStreamInternalsPipeToErrorsMustBePropagatedForwardCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToErrorsMustBePropagatedForwardCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToErrorsMustBePropagatedForwardCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCode; +extern const int s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToClosingMustBePropagatedForwardCode; +extern const int s_readableStreamInternalsPipeToClosingMustBePropagatedForwardCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToClosingMustBePropagatedForwardCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToClosingMustBePropagatedForwardCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToClosingMustBePropagatedBackwardCode; +extern const int s_readableStreamInternalsPipeToClosingMustBePropagatedBackwardCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToClosingMustBePropagatedBackwardCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToClosingMustBePropagatedBackwardCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToShutdownWithActionCode; +extern const int s_readableStreamInternalsPipeToShutdownWithActionCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToShutdownWithActionCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToShutdownWithActionCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToShutdownCode; +extern const int s_readableStreamInternalsPipeToShutdownCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToShutdownCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToShutdownCodeConstructorKind; +extern const char* const s_readableStreamInternalsPipeToFinalizeCode; +extern const int s_readableStreamInternalsPipeToFinalizeCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsPipeToFinalizeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsPipeToFinalizeCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamTeeCode; +extern const int s_readableStreamInternalsReadableStreamTeeCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamTeeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamTeeCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamTeePullFunctionCode; +extern const int s_readableStreamInternalsReadableStreamTeePullFunctionCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamTeePullFunctionCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamTeePullFunctionCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamTeeBranch1CancelFunctionCode; +extern const int s_readableStreamInternalsReadableStreamTeeBranch1CancelFunctionCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamTeeBranch1CancelFunctionCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamTeeBranch1CancelFunctionCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamTeeBranch2CancelFunctionCode; +extern const int s_readableStreamInternalsReadableStreamTeeBranch2CancelFunctionCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamTeeBranch2CancelFunctionCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamTeeBranch2CancelFunctionCodeConstructorKind; +extern const char* const s_readableStreamInternalsIsReadableStreamCode; +extern const int s_readableStreamInternalsIsReadableStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsIsReadableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsIsReadableStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsIsReadableStreamDefaultReaderCode; +extern const int s_readableStreamInternalsIsReadableStreamDefaultReaderCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsIsReadableStreamDefaultReaderCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsIsReadableStreamDefaultReaderCodeConstructorKind; +extern const char* const s_readableStreamInternalsIsReadableStreamDefaultControllerCode; +extern const int s_readableStreamInternalsIsReadableStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsIsReadableStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsIsReadableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_readableStreamInternalsAssignDirectStreamCode; +extern const int s_readableStreamInternalsAssignDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsAssignDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsAssignDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsHandleDirectStreamErrorCode; +extern const int s_readableStreamInternalsHandleDirectStreamErrorCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsHandleDirectStreamErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsHandleDirectStreamErrorCodeConstructorKind; +extern const char* const s_readableStreamInternalsHandleDirectStreamErrorRejectCode; +extern const int s_readableStreamInternalsHandleDirectStreamErrorRejectCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsHandleDirectStreamErrorRejectCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsHandleDirectStreamErrorRejectCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnPullDirectStreamCode; +extern const int s_readableStreamInternalsOnPullDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnPullDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnPullDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsNoopDoneFunctionCode; +extern const int s_readableStreamInternalsNoopDoneFunctionCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsNoopDoneFunctionCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsNoopDoneFunctionCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnReadableStreamDirectControllerClosedCode; +extern const int s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnCloseDirectStreamCode; +extern const int s_readableStreamInternalsOnCloseDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnCloseDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnCloseDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsOnDrainDirectStreamCode; +extern const int s_readableStreamInternalsOnDrainDirectStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsOnDrainDirectStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsOnDrainDirectStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsInitializeArrayBufferStreamCode; +extern const int s_readableStreamInternalsInitializeArrayBufferStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsInitializeArrayBufferStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsInitializeArrayBufferStreamCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamErrorCode; +extern const int s_readableStreamInternalsReadableStreamErrorCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamErrorCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeConstructorKind; +extern const char* const s_readableStreamInternalsIsReadableStreamLockedCode; +extern const int s_readableStreamInternalsIsReadableStreamLockedCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsIsReadableStreamLockedCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsIsReadableStreamLockedCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerGetDesiredSizeCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerGetDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerGetDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerGetDesiredSizeCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamReaderGenericCancelCode; +extern const int s_readableStreamInternalsReadableStreamReaderGenericCancelCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamReaderGenericCancelCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamReaderGenericCancelCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamCancelCode; +extern const int s_readableStreamInternalsReadableStreamCancelCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamCancelCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamCancelCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerCancelCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerCancelCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerCancelCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerCancelCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerPullCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerPullCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerPullCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerPullCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerCloseCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamCloseCode; +extern const int s_readableStreamInternalsReadableStreamCloseCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamCloseCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamFulfillReadRequestCode; +extern const int s_readableStreamInternalsReadableStreamFulfillReadRequestCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamFulfillReadRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamFulfillReadRequestCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultReaderReadCode; +extern const int s_readableStreamInternalsReadableStreamDefaultReaderReadCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultReaderReadCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultReaderReadCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamAddReadRequestCode; +extern const int s_readableStreamInternalsReadableStreamAddReadRequestCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamAddReadRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamAddReadRequestCodeConstructorKind; +extern const char* const s_readableStreamInternalsIsReadableStreamDisturbedCode; +extern const int s_readableStreamInternalsIsReadableStreamDisturbedCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsIsReadableStreamDisturbedCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsIsReadableStreamDisturbedCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamReaderGenericReleaseCode; +extern const int s_readableStreamInternalsReadableStreamReaderGenericReleaseCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamReaderGenericReleaseCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamReaderGenericReleaseCodeConstructorKind; +extern const char* const s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCode; +extern const int s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeConstructorKind; +extern const char* const s_readableStreamInternalsLazyLoadStreamCode; +extern const int s_readableStreamInternalsLazyLoadStreamCodeLength; +extern const JSC::ConstructAbility s_readableStreamInternalsLazyLoadStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_readableStreamInternalsLazyLoadStreamCodeConstructorKind; + +#define WEBCORE_FOREACH_READABLESTREAMINTERNALS_BUILTIN_DATA(macro) \ + macro(readableStreamReaderGenericInitialize, readableStreamInternalsReadableStreamReaderGenericInitialize, 2) \ + macro(privateInitializeReadableStreamDefaultController, readableStreamInternalsPrivateInitializeReadableStreamDefaultController, 4) \ + macro(readableStreamDefaultControllerError, readableStreamInternalsReadableStreamDefaultControllerError, 2) \ + macro(readableStreamPipeTo, readableStreamInternalsReadableStreamPipeTo, 2) \ + macro(acquireReadableStreamDefaultReader, readableStreamInternalsAcquireReadableStreamDefaultReader, 1) \ + macro(setupReadableStreamDefaultController, readableStreamInternalsSetupReadableStreamDefaultController, 7) \ + macro(createReadableStreamController, readableStreamInternalsCreateReadableStreamController, 3) \ + macro(readableStreamDefaultControllerStart, readableStreamInternalsReadableStreamDefaultControllerStart, 1) \ + macro(readableStreamPipeToWritableStream, readableStreamInternalsReadableStreamPipeToWritableStream, 6) \ + macro(pipeToLoop, readableStreamInternalsPipeToLoop, 1) \ + macro(pipeToDoReadWrite, readableStreamInternalsPipeToDoReadWrite, 1) \ + macro(pipeToErrorsMustBePropagatedForward, readableStreamInternalsPipeToErrorsMustBePropagatedForward, 1) \ + macro(pipeToErrorsMustBePropagatedBackward, readableStreamInternalsPipeToErrorsMustBePropagatedBackward, 1) \ + macro(pipeToClosingMustBePropagatedForward, readableStreamInternalsPipeToClosingMustBePropagatedForward, 1) \ + macro(pipeToClosingMustBePropagatedBackward, readableStreamInternalsPipeToClosingMustBePropagatedBackward, 1) \ + macro(pipeToShutdownWithAction, readableStreamInternalsPipeToShutdownWithAction, 2) \ + macro(pipeToShutdown, readableStreamInternalsPipeToShutdown, 1) \ + macro(pipeToFinalize, readableStreamInternalsPipeToFinalize, 1) \ + macro(readableStreamTee, readableStreamInternalsReadableStreamTee, 2) \ + macro(readableStreamTeePullFunction, readableStreamInternalsReadableStreamTeePullFunction, 3) \ + macro(readableStreamTeeBranch1CancelFunction, readableStreamInternalsReadableStreamTeeBranch1CancelFunction, 2) \ + macro(readableStreamTeeBranch2CancelFunction, readableStreamInternalsReadableStreamTeeBranch2CancelFunction, 2) \ + macro(isReadableStream, readableStreamInternalsIsReadableStream, 1) \ + macro(isReadableStreamDefaultReader, readableStreamInternalsIsReadableStreamDefaultReader, 1) \ + macro(isReadableStreamDefaultController, readableStreamInternalsIsReadableStreamDefaultController, 1) \ + macro(assignDirectStream, readableStreamInternalsAssignDirectStream, 0) \ + macro(handleDirectStreamError, readableStreamInternalsHandleDirectStreamError, 1) \ + macro(handleDirectStreamErrorReject, readableStreamInternalsHandleDirectStreamErrorReject, 1) \ + macro(onPullDirectStream, readableStreamInternalsOnPullDirectStream, 1) \ + macro(noopDoneFunction, readableStreamInternalsNoopDoneFunction, 0) \ + macro(onReadableStreamDirectControllerClosed, readableStreamInternalsOnReadableStreamDirectControllerClosed, 1) \ + macro(onCloseDirectStream, readableStreamInternalsOnCloseDirectStream, 1) \ + macro(onDrainDirectStream, readableStreamInternalsOnDrainDirectStream, 0) \ + macro(initializeArrayBufferStream, readableStreamInternalsInitializeArrayBufferStream, 2) \ + macro(readableStreamError, readableStreamInternalsReadableStreamError, 2) \ + macro(readableStreamDefaultControllerShouldCallPull, readableStreamInternalsReadableStreamDefaultControllerShouldCallPull, 1) \ + macro(readableStreamDefaultControllerCallPullIfNeeded, readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeeded, 1) \ + macro(isReadableStreamLocked, readableStreamInternalsIsReadableStreamLocked, 1) \ + macro(readableStreamDefaultControllerGetDesiredSize, readableStreamInternalsReadableStreamDefaultControllerGetDesiredSize, 1) \ + macro(readableStreamReaderGenericCancel, readableStreamInternalsReadableStreamReaderGenericCancel, 2) \ + macro(readableStreamCancel, readableStreamInternalsReadableStreamCancel, 2) \ + macro(readableStreamDefaultControllerCancel, readableStreamInternalsReadableStreamDefaultControllerCancel, 2) \ + macro(readableStreamDefaultControllerPull, readableStreamInternalsReadableStreamDefaultControllerPull, 1) \ + macro(readableStreamDefaultControllerClose, readableStreamInternalsReadableStreamDefaultControllerClose, 1) \ + macro(readableStreamClose, readableStreamInternalsReadableStreamClose, 1) \ + macro(readableStreamFulfillReadRequest, readableStreamInternalsReadableStreamFulfillReadRequest, 3) \ + macro(readableStreamDefaultControllerEnqueue, readableStreamInternalsReadableStreamDefaultControllerEnqueue, 2) \ + macro(readableStreamDefaultReaderRead, readableStreamInternalsReadableStreamDefaultReaderRead, 1) \ + macro(readableStreamAddReadRequest, readableStreamInternalsReadableStreamAddReadRequest, 1) \ + macro(isReadableStreamDisturbed, readableStreamInternalsIsReadableStreamDisturbed, 1) \ + macro(readableStreamReaderGenericRelease, readableStreamInternalsReadableStreamReaderGenericRelease, 1) \ + macro(readableStreamDefaultControllerCanCloseOrEnqueue, readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueue, 1) \ + macro(lazyLoadStream, readableStreamInternalsLazyLoadStream, 2) \ + +/* StreamInternals */ +extern const char* const s_streamInternalsMarkPromiseAsHandledCode; +extern const int s_streamInternalsMarkPromiseAsHandledCodeLength; +extern const JSC::ConstructAbility s_streamInternalsMarkPromiseAsHandledCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsMarkPromiseAsHandledCodeConstructorKind; +extern const char* const s_streamInternalsShieldingPromiseResolveCode; +extern const int s_streamInternalsShieldingPromiseResolveCodeLength; +extern const JSC::ConstructAbility s_streamInternalsShieldingPromiseResolveCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsShieldingPromiseResolveCodeConstructorKind; +extern const char* const s_streamInternalsPromiseInvokeOrNoopMethodNoCatchCode; +extern const int s_streamInternalsPromiseInvokeOrNoopMethodNoCatchCodeLength; +extern const JSC::ConstructAbility s_streamInternalsPromiseInvokeOrNoopMethodNoCatchCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsPromiseInvokeOrNoopMethodNoCatchCodeConstructorKind; +extern const char* const s_streamInternalsPromiseInvokeOrNoopNoCatchCode; +extern const int s_streamInternalsPromiseInvokeOrNoopNoCatchCodeLength; +extern const JSC::ConstructAbility s_streamInternalsPromiseInvokeOrNoopNoCatchCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsPromiseInvokeOrNoopNoCatchCodeConstructorKind; +extern const char* const s_streamInternalsPromiseInvokeOrNoopMethodCode; +extern const int s_streamInternalsPromiseInvokeOrNoopMethodCodeLength; +extern const JSC::ConstructAbility s_streamInternalsPromiseInvokeOrNoopMethodCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsPromiseInvokeOrNoopMethodCodeConstructorKind; +extern const char* const s_streamInternalsPromiseInvokeOrNoopCode; +extern const int s_streamInternalsPromiseInvokeOrNoopCodeLength; +extern const JSC::ConstructAbility s_streamInternalsPromiseInvokeOrNoopCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsPromiseInvokeOrNoopCodeConstructorKind; +extern const char* const s_streamInternalsPromiseInvokeOrFallbackOrNoopCode; +extern const int s_streamInternalsPromiseInvokeOrFallbackOrNoopCodeLength; +extern const JSC::ConstructAbility s_streamInternalsPromiseInvokeOrFallbackOrNoopCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsPromiseInvokeOrFallbackOrNoopCodeConstructorKind; +extern const char* const s_streamInternalsValidateAndNormalizeQueuingStrategyCode; +extern const int s_streamInternalsValidateAndNormalizeQueuingStrategyCodeLength; +extern const JSC::ConstructAbility s_streamInternalsValidateAndNormalizeQueuingStrategyCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsValidateAndNormalizeQueuingStrategyCodeConstructorKind; +extern const char* const s_streamInternalsCreateFIFOCode; +extern const int s_streamInternalsCreateFIFOCodeLength; +extern const JSC::ConstructAbility s_streamInternalsCreateFIFOCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsCreateFIFOCodeConstructorKind; +extern const char* const s_streamInternalsNewQueueCode; +extern const int s_streamInternalsNewQueueCodeLength; +extern const JSC::ConstructAbility s_streamInternalsNewQueueCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsNewQueueCodeConstructorKind; +extern const char* const s_streamInternalsDequeueValueCode; +extern const int s_streamInternalsDequeueValueCodeLength; +extern const JSC::ConstructAbility s_streamInternalsDequeueValueCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsDequeueValueCodeConstructorKind; +extern const char* const s_streamInternalsEnqueueValueWithSizeCode; +extern const int s_streamInternalsEnqueueValueWithSizeCodeLength; +extern const JSC::ConstructAbility s_streamInternalsEnqueueValueWithSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsEnqueueValueWithSizeCodeConstructorKind; +extern const char* const s_streamInternalsPeekQueueValueCode; +extern const int s_streamInternalsPeekQueueValueCodeLength; +extern const JSC::ConstructAbility s_streamInternalsPeekQueueValueCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsPeekQueueValueCodeConstructorKind; +extern const char* const s_streamInternalsResetQueueCode; +extern const int s_streamInternalsResetQueueCodeLength; +extern const JSC::ConstructAbility s_streamInternalsResetQueueCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsResetQueueCodeConstructorKind; +extern const char* const s_streamInternalsExtractSizeAlgorithmCode; +extern const int s_streamInternalsExtractSizeAlgorithmCodeLength; +extern const JSC::ConstructAbility s_streamInternalsExtractSizeAlgorithmCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsExtractSizeAlgorithmCodeConstructorKind; +extern const char* const s_streamInternalsExtractHighWaterMarkCode; +extern const int s_streamInternalsExtractHighWaterMarkCodeLength; +extern const JSC::ConstructAbility s_streamInternalsExtractHighWaterMarkCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsExtractHighWaterMarkCodeConstructorKind; +extern const char* const s_streamInternalsExtractHighWaterMarkFromQueuingStrategyInitCode; +extern const int s_streamInternalsExtractHighWaterMarkFromQueuingStrategyInitCodeLength; +extern const JSC::ConstructAbility s_streamInternalsExtractHighWaterMarkFromQueuingStrategyInitCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsExtractHighWaterMarkFromQueuingStrategyInitCodeConstructorKind; +extern const char* const s_streamInternalsCreateFulfilledPromiseCode; +extern const int s_streamInternalsCreateFulfilledPromiseCodeLength; +extern const JSC::ConstructAbility s_streamInternalsCreateFulfilledPromiseCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsCreateFulfilledPromiseCodeConstructorKind; +extern const char* const s_streamInternalsToDictionaryCode; +extern const int s_streamInternalsToDictionaryCodeLength; +extern const JSC::ConstructAbility s_streamInternalsToDictionaryCodeConstructAbility; +extern const JSC::ConstructorKind s_streamInternalsToDictionaryCodeConstructorKind; + +#define WEBCORE_FOREACH_STREAMINTERNALS_BUILTIN_DATA(macro) \ + macro(markPromiseAsHandled, streamInternalsMarkPromiseAsHandled, 1) \ + macro(shieldingPromiseResolve, streamInternalsShieldingPromiseResolve, 1) \ + macro(promiseInvokeOrNoopMethodNoCatch, streamInternalsPromiseInvokeOrNoopMethodNoCatch, 3) \ + macro(promiseInvokeOrNoopNoCatch, streamInternalsPromiseInvokeOrNoopNoCatch, 3) \ + macro(promiseInvokeOrNoopMethod, streamInternalsPromiseInvokeOrNoopMethod, 3) \ + macro(promiseInvokeOrNoop, streamInternalsPromiseInvokeOrNoop, 3) \ + macro(promiseInvokeOrFallbackOrNoop, streamInternalsPromiseInvokeOrFallbackOrNoop, 5) \ + macro(validateAndNormalizeQueuingStrategy, streamInternalsValidateAndNormalizeQueuingStrategy, 2) \ + macro(createFIFO, streamInternalsCreateFIFO, 0) \ + macro(newQueue, streamInternalsNewQueue, 0) \ + macro(dequeueValue, streamInternalsDequeueValue, 1) \ + macro(enqueueValueWithSize, streamInternalsEnqueueValueWithSize, 3) \ + macro(peekQueueValue, streamInternalsPeekQueueValue, 1) \ + macro(resetQueue, streamInternalsResetQueue, 1) \ + macro(extractSizeAlgorithm, streamInternalsExtractSizeAlgorithm, 1) \ + macro(extractHighWaterMark, streamInternalsExtractHighWaterMark, 2) \ + macro(extractHighWaterMarkFromQueuingStrategyInit, streamInternalsExtractHighWaterMarkFromQueuingStrategyInit, 1) \ + macro(createFulfilledPromise, streamInternalsCreateFulfilledPromise, 1) \ + macro(toDictionary, streamInternalsToDictionary, 3) \ + +/* TransformStream */ +extern const char* const s_transformStreamInitializeTransformStreamCode; +extern const int s_transformStreamInitializeTransformStreamCodeLength; +extern const JSC::ConstructAbility s_transformStreamInitializeTransformStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInitializeTransformStreamCodeConstructorKind; +extern const char* const s_transformStreamReadableCode; +extern const int s_transformStreamReadableCodeLength; +extern const JSC::ConstructAbility s_transformStreamReadableCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamReadableCodeConstructorKind; +extern const char* const s_transformStreamWritableCode; +extern const int s_transformStreamWritableCodeLength; +extern const JSC::ConstructAbility s_transformStreamWritableCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamWritableCodeConstructorKind; + +#define WEBCORE_FOREACH_TRANSFORMSTREAM_BUILTIN_DATA(macro) \ + macro(initializeTransformStream, transformStreamInitializeTransformStream, 0) \ + macro(readable, transformStreamReadable, 0) \ + macro(writable, transformStreamWritable, 0) \ + +/* TransformStreamDefaultController */ +extern const char* const s_transformStreamDefaultControllerInitializeTransformStreamDefaultControllerCode; +extern const int s_transformStreamDefaultControllerInitializeTransformStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_transformStreamDefaultControllerInitializeTransformStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamDefaultControllerInitializeTransformStreamDefaultControllerCodeConstructorKind; +extern const char* const s_transformStreamDefaultControllerDesiredSizeCode; +extern const int s_transformStreamDefaultControllerDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_transformStreamDefaultControllerDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamDefaultControllerDesiredSizeCodeConstructorKind; +extern const char* const s_transformStreamDefaultControllerEnqueueCode; +extern const int s_transformStreamDefaultControllerEnqueueCodeLength; +extern const JSC::ConstructAbility s_transformStreamDefaultControllerEnqueueCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamDefaultControllerEnqueueCodeConstructorKind; +extern const char* const s_transformStreamDefaultControllerErrorCode; +extern const int s_transformStreamDefaultControllerErrorCodeLength; +extern const JSC::ConstructAbility s_transformStreamDefaultControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamDefaultControllerErrorCodeConstructorKind; +extern const char* const s_transformStreamDefaultControllerTerminateCode; +extern const int s_transformStreamDefaultControllerTerminateCodeLength; +extern const JSC::ConstructAbility s_transformStreamDefaultControllerTerminateCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamDefaultControllerTerminateCodeConstructorKind; + +#define WEBCORE_FOREACH_TRANSFORMSTREAMDEFAULTCONTROLLER_BUILTIN_DATA(macro) \ + macro(initializeTransformStreamDefaultController, transformStreamDefaultControllerInitializeTransformStreamDefaultController, 0) \ + macro(desiredSize, transformStreamDefaultControllerDesiredSize, 0) \ + macro(enqueue, transformStreamDefaultControllerEnqueue, 1) \ + macro(error, transformStreamDefaultControllerError, 1) \ + macro(terminate, transformStreamDefaultControllerTerminate, 0) \ + +/* TransformStreamInternals */ +extern const char* const s_transformStreamInternalsIsTransformStreamCode; +extern const int s_transformStreamInternalsIsTransformStreamCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsIsTransformStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsIsTransformStreamCodeConstructorKind; +extern const char* const s_transformStreamInternalsIsTransformStreamDefaultControllerCode; +extern const int s_transformStreamInternalsIsTransformStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsIsTransformStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsIsTransformStreamDefaultControllerCodeConstructorKind; +extern const char* const s_transformStreamInternalsCreateTransformStreamCode; +extern const int s_transformStreamInternalsCreateTransformStreamCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsCreateTransformStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsCreateTransformStreamCodeConstructorKind; +extern const char* const s_transformStreamInternalsInitializeTransformStreamCode; +extern const int s_transformStreamInternalsInitializeTransformStreamCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsInitializeTransformStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsInitializeTransformStreamCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamErrorCode; +extern const int s_transformStreamInternalsTransformStreamErrorCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamErrorCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamErrorWritableAndUnblockWriteCode; +extern const int s_transformStreamInternalsTransformStreamErrorWritableAndUnblockWriteCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamErrorWritableAndUnblockWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamErrorWritableAndUnblockWriteCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamSetBackpressureCode; +extern const int s_transformStreamInternalsTransformStreamSetBackpressureCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamSetBackpressureCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamSetBackpressureCodeConstructorKind; +extern const char* const s_transformStreamInternalsSetUpTransformStreamDefaultControllerCode; +extern const int s_transformStreamInternalsSetUpTransformStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsSetUpTransformStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsSetUpTransformStreamDefaultControllerCodeConstructorKind; +extern const char* const s_transformStreamInternalsSetUpTransformStreamDefaultControllerFromTransformerCode; +extern const int s_transformStreamInternalsSetUpTransformStreamDefaultControllerFromTransformerCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsSetUpTransformStreamDefaultControllerFromTransformerCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsSetUpTransformStreamDefaultControllerFromTransformerCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultControllerClearAlgorithmsCode; +extern const int s_transformStreamInternalsTransformStreamDefaultControllerClearAlgorithmsCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultControllerClearAlgorithmsCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultControllerClearAlgorithmsCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultControllerEnqueueCode; +extern const int s_transformStreamInternalsTransformStreamDefaultControllerEnqueueCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultControllerEnqueueCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultControllerEnqueueCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultControllerErrorCode; +extern const int s_transformStreamInternalsTransformStreamDefaultControllerErrorCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultControllerErrorCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCode; +extern const int s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultControllerTerminateCode; +extern const int s_transformStreamInternalsTransformStreamDefaultControllerTerminateCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultControllerTerminateCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultControllerTerminateCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCode; +extern const int s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithmCode; +extern const int s_transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithmCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithmCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithmCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCode; +extern const int s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeConstructorKind; +extern const char* const s_transformStreamInternalsTransformStreamDefaultSourcePullAlgorithmCode; +extern const int s_transformStreamInternalsTransformStreamDefaultSourcePullAlgorithmCodeLength; +extern const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSourcePullAlgorithmCodeConstructAbility; +extern const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultSourcePullAlgorithmCodeConstructorKind; + +#define WEBCORE_FOREACH_TRANSFORMSTREAMINTERNALS_BUILTIN_DATA(macro) \ + macro(isTransformStream, transformStreamInternalsIsTransformStream, 1) \ + macro(isTransformStreamDefaultController, transformStreamInternalsIsTransformStreamDefaultController, 1) \ + macro(createTransformStream, transformStreamInternalsCreateTransformStream, 7) \ + macro(initializeTransformStream, transformStreamInternalsInitializeTransformStream, 6) \ + macro(transformStreamError, transformStreamInternalsTransformStreamError, 2) \ + macro(transformStreamErrorWritableAndUnblockWrite, transformStreamInternalsTransformStreamErrorWritableAndUnblockWrite, 2) \ + macro(transformStreamSetBackpressure, transformStreamInternalsTransformStreamSetBackpressure, 2) \ + macro(setUpTransformStreamDefaultController, transformStreamInternalsSetUpTransformStreamDefaultController, 4) \ + macro(setUpTransformStreamDefaultControllerFromTransformer, transformStreamInternalsSetUpTransformStreamDefaultControllerFromTransformer, 3) \ + macro(transformStreamDefaultControllerClearAlgorithms, transformStreamInternalsTransformStreamDefaultControllerClearAlgorithms, 1) \ + macro(transformStreamDefaultControllerEnqueue, transformStreamInternalsTransformStreamDefaultControllerEnqueue, 2) \ + macro(transformStreamDefaultControllerError, transformStreamInternalsTransformStreamDefaultControllerError, 2) \ + macro(transformStreamDefaultControllerPerformTransform, transformStreamInternalsTransformStreamDefaultControllerPerformTransform, 2) \ + macro(transformStreamDefaultControllerTerminate, transformStreamInternalsTransformStreamDefaultControllerTerminate, 1) \ + macro(transformStreamDefaultSinkWriteAlgorithm, transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithm, 2) \ + macro(transformStreamDefaultSinkAbortAlgorithm, transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithm, 2) \ + macro(transformStreamDefaultSinkCloseAlgorithm, transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithm, 1) \ + macro(transformStreamDefaultSourcePullAlgorithm, transformStreamInternalsTransformStreamDefaultSourcePullAlgorithm, 1) \ + +/* WritableStreamDefaultController */ +extern const char* const s_writableStreamDefaultControllerInitializeWritableStreamDefaultControllerCode; +extern const int s_writableStreamDefaultControllerInitializeWritableStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultControllerInitializeWritableStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultControllerInitializeWritableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_writableStreamDefaultControllerErrorCode; +extern const int s_writableStreamDefaultControllerErrorCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultControllerErrorCodeConstructorKind; + +#define WEBCORE_FOREACH_WRITABLESTREAMDEFAULTCONTROLLER_BUILTIN_DATA(macro) \ + macro(initializeWritableStreamDefaultController, writableStreamDefaultControllerInitializeWritableStreamDefaultController, 0) \ + macro(error, writableStreamDefaultControllerError, 1) \ + +/* WritableStreamDefaultWriter */ +extern const char* const s_writableStreamDefaultWriterInitializeWritableStreamDefaultWriterCode; +extern const int s_writableStreamDefaultWriterInitializeWritableStreamDefaultWriterCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterInitializeWritableStreamDefaultWriterCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterInitializeWritableStreamDefaultWriterCodeConstructorKind; +extern const char* const s_writableStreamDefaultWriterClosedCode; +extern const int s_writableStreamDefaultWriterClosedCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterClosedCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterClosedCodeConstructorKind; +extern const char* const s_writableStreamDefaultWriterDesiredSizeCode; +extern const int s_writableStreamDefaultWriterDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterDesiredSizeCodeConstructorKind; +extern const char* const s_writableStreamDefaultWriterReadyCode; +extern const int s_writableStreamDefaultWriterReadyCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterReadyCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterReadyCodeConstructorKind; +extern const char* const s_writableStreamDefaultWriterAbortCode; +extern const int s_writableStreamDefaultWriterAbortCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterAbortCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterAbortCodeConstructorKind; +extern const char* const s_writableStreamDefaultWriterCloseCode; +extern const int s_writableStreamDefaultWriterCloseCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterCloseCodeConstructorKind; +extern const char* const s_writableStreamDefaultWriterReleaseLockCode; +extern const int s_writableStreamDefaultWriterReleaseLockCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterReleaseLockCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterReleaseLockCodeConstructorKind; +extern const char* const s_writableStreamDefaultWriterWriteCode; +extern const int s_writableStreamDefaultWriterWriteCodeLength; +extern const JSC::ConstructAbility s_writableStreamDefaultWriterWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamDefaultWriterWriteCodeConstructorKind; + +#define WEBCORE_FOREACH_WRITABLESTREAMDEFAULTWRITER_BUILTIN_DATA(macro) \ + macro(initializeWritableStreamDefaultWriter, writableStreamDefaultWriterInitializeWritableStreamDefaultWriter, 1) \ + macro(closed, writableStreamDefaultWriterClosed, 0) \ + macro(desiredSize, writableStreamDefaultWriterDesiredSize, 0) \ + macro(ready, writableStreamDefaultWriterReady, 0) \ + macro(abort, writableStreamDefaultWriterAbort, 1) \ + macro(close, writableStreamDefaultWriterClose, 0) \ + macro(releaseLock, writableStreamDefaultWriterReleaseLock, 0) \ + macro(write, writableStreamDefaultWriterWrite, 1) \ + +/* WritableStreamInternals */ +extern const char* const s_writableStreamInternalsIsWritableStreamCode; +extern const int s_writableStreamInternalsIsWritableStreamCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsIsWritableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsIsWritableStreamCodeConstructorKind; +extern const char* const s_writableStreamInternalsIsWritableStreamDefaultWriterCode; +extern const int s_writableStreamInternalsIsWritableStreamDefaultWriterCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsIsWritableStreamDefaultWriterCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsIsWritableStreamDefaultWriterCodeConstructorKind; +extern const char* const s_writableStreamInternalsAcquireWritableStreamDefaultWriterCode; +extern const int s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeConstructorKind; +extern const char* const s_writableStreamInternalsCreateWritableStreamCode; +extern const int s_writableStreamInternalsCreateWritableStreamCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsCreateWritableStreamCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsCreateWritableStreamCodeConstructorKind; +extern const char* const s_writableStreamInternalsCreateInternalWritableStreamFromUnderlyingSinkCode; +extern const int s_writableStreamInternalsCreateInternalWritableStreamFromUnderlyingSinkCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsCreateInternalWritableStreamFromUnderlyingSinkCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsCreateInternalWritableStreamFromUnderlyingSinkCodeConstructorKind; +extern const char* const s_writableStreamInternalsInitializeWritableStreamSlotsCode; +extern const int s_writableStreamInternalsInitializeWritableStreamSlotsCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsInitializeWritableStreamSlotsCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsInitializeWritableStreamSlotsCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamCloseForBindingsCode; +extern const int s_writableStreamInternalsWritableStreamCloseForBindingsCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamCloseForBindingsCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamCloseForBindingsCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamAbortForBindingsCode; +extern const int s_writableStreamInternalsWritableStreamAbortForBindingsCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamAbortForBindingsCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamAbortForBindingsCodeConstructorKind; +extern const char* const s_writableStreamInternalsIsWritableStreamLockedCode; +extern const int s_writableStreamInternalsIsWritableStreamLockedCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsIsWritableStreamLockedCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsIsWritableStreamLockedCodeConstructorKind; +extern const char* const s_writableStreamInternalsSetUpWritableStreamDefaultWriterCode; +extern const int s_writableStreamInternalsSetUpWritableStreamDefaultWriterCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsSetUpWritableStreamDefaultWriterCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsSetUpWritableStreamDefaultWriterCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamAbortCode; +extern const int s_writableStreamInternalsWritableStreamAbortCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamAbortCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamAbortCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamCloseCode; +extern const int s_writableStreamInternalsWritableStreamCloseCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamCloseCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamAddWriteRequestCode; +extern const int s_writableStreamInternalsWritableStreamAddWriteRequestCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamAddWriteRequestCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamAddWriteRequestCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamCloseQueuedOrInFlightCode; +extern const int s_writableStreamInternalsWritableStreamCloseQueuedOrInFlightCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamCloseQueuedOrInFlightCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamCloseQueuedOrInFlightCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDealWithRejectionCode; +extern const int s_writableStreamInternalsWritableStreamDealWithRejectionCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDealWithRejectionCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDealWithRejectionCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamFinishErroringCode; +extern const int s_writableStreamInternalsWritableStreamFinishErroringCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamFinishErroringCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamFinishErroringCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamFinishInFlightCloseCode; +extern const int s_writableStreamInternalsWritableStreamFinishInFlightCloseCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamFinishInFlightCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamFinishInFlightCloseCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamFinishInFlightCloseWithErrorCode; +extern const int s_writableStreamInternalsWritableStreamFinishInFlightCloseWithErrorCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamFinishInFlightCloseWithErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamFinishInFlightCloseWithErrorCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamFinishInFlightWriteCode; +extern const int s_writableStreamInternalsWritableStreamFinishInFlightWriteCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamFinishInFlightWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamFinishInFlightWriteCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamFinishInFlightWriteWithErrorCode; +extern const int s_writableStreamInternalsWritableStreamFinishInFlightWriteWithErrorCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamFinishInFlightWriteWithErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamFinishInFlightWriteWithErrorCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamHasOperationMarkedInFlightCode; +extern const int s_writableStreamInternalsWritableStreamHasOperationMarkedInFlightCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamHasOperationMarkedInFlightCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamHasOperationMarkedInFlightCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamMarkCloseRequestInFlightCode; +extern const int s_writableStreamInternalsWritableStreamMarkCloseRequestInFlightCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamMarkCloseRequestInFlightCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamMarkCloseRequestInFlightCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCode; +extern const int s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamRejectCloseAndClosedPromiseIfNeededCode; +extern const int s_writableStreamInternalsWritableStreamRejectCloseAndClosedPromiseIfNeededCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamRejectCloseAndClosedPromiseIfNeededCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamRejectCloseAndClosedPromiseIfNeededCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamStartErroringCode; +extern const int s_writableStreamInternalsWritableStreamStartErroringCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamStartErroringCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamStartErroringCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamUpdateBackpressureCode; +extern const int s_writableStreamInternalsWritableStreamUpdateBackpressureCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamUpdateBackpressureCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamUpdateBackpressureCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterAbortCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterAbortCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterAbortCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterAbortCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterCloseCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterCloseCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterCloseCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterCloseWithErrorPropagationCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterCloseWithErrorPropagationCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterCloseWithErrorPropagationCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterCloseWithErrorPropagationCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterEnsureClosedPromiseRejectedCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterEnsureClosedPromiseRejectedCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterEnsureClosedPromiseRejectedCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterEnsureClosedPromiseRejectedCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterEnsureReadyPromiseRejectedCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterEnsureReadyPromiseRejectedCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterEnsureReadyPromiseRejectedCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterEnsureReadyPromiseRejectedCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterGetDesiredSizeCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterGetDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterGetDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterGetDesiredSizeCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterReleaseCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterReleaseCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterReleaseCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterReleaseCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultWriterWriteCode; +extern const int s_writableStreamInternalsWritableStreamDefaultWriterWriteCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultWriterWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultWriterWriteCodeConstructorKind; +extern const char* const s_writableStreamInternalsSetUpWritableStreamDefaultControllerCode; +extern const int s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerStartCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerStartCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerStartCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerStartCodeConstructorKind; +extern const char* const s_writableStreamInternalsSetUpWritableStreamDefaultControllerFromUnderlyingSinkCode; +extern const int s_writableStreamInternalsSetUpWritableStreamDefaultControllerFromUnderlyingSinkCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsSetUpWritableStreamDefaultControllerFromUnderlyingSinkCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsSetUpWritableStreamDefaultControllerFromUnderlyingSinkCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeConstructorKind; +extern const char* const s_writableStreamInternalsIsCloseSentinelCode; +extern const int s_writableStreamInternalsIsCloseSentinelCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsIsCloseSentinelCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsIsCloseSentinelCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerClearAlgorithmsCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerClearAlgorithmsCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerClearAlgorithmsCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerClearAlgorithmsCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerCloseCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerCloseCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerCloseCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerErrorCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerErrorCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerErrorCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerErrorCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerErrorIfNeededCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerErrorIfNeededCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerErrorIfNeededCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerErrorIfNeededCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerGetBackpressureCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerGetBackpressureCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerGetBackpressureCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerGetBackpressureCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerGetChunkSizeCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerGetChunkSizeCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerGetChunkSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerGetChunkSizeCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerGetDesiredSizeCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerGetDesiredSizeCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerGetDesiredSizeCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerGetDesiredSizeCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerProcessWriteCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerProcessWriteCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerProcessWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerProcessWriteCodeConstructorKind; +extern const char* const s_writableStreamInternalsWritableStreamDefaultControllerWriteCode; +extern const int s_writableStreamInternalsWritableStreamDefaultControllerWriteCodeLength; +extern const JSC::ConstructAbility s_writableStreamInternalsWritableStreamDefaultControllerWriteCodeConstructAbility; +extern const JSC::ConstructorKind s_writableStreamInternalsWritableStreamDefaultControllerWriteCodeConstructorKind; + +#define WEBCORE_FOREACH_WRITABLESTREAMINTERNALS_BUILTIN_DATA(macro) \ + macro(isWritableStream, writableStreamInternalsIsWritableStream, 1) \ + macro(isWritableStreamDefaultWriter, writableStreamInternalsIsWritableStreamDefaultWriter, 1) \ + macro(acquireWritableStreamDefaultWriter, writableStreamInternalsAcquireWritableStreamDefaultWriter, 1) \ + macro(createWritableStream, writableStreamInternalsCreateWritableStream, 6) \ + macro(createInternalWritableStreamFromUnderlyingSink, writableStreamInternalsCreateInternalWritableStreamFromUnderlyingSink, 2) \ + macro(initializeWritableStreamSlots, writableStreamInternalsInitializeWritableStreamSlots, 2) \ + macro(writableStreamCloseForBindings, writableStreamInternalsWritableStreamCloseForBindings, 1) \ + macro(writableStreamAbortForBindings, writableStreamInternalsWritableStreamAbortForBindings, 2) \ + macro(isWritableStreamLocked, writableStreamInternalsIsWritableStreamLocked, 1) \ + macro(setUpWritableStreamDefaultWriter, writableStreamInternalsSetUpWritableStreamDefaultWriter, 2) \ + macro(writableStreamAbort, writableStreamInternalsWritableStreamAbort, 2) \ + macro(writableStreamClose, writableStreamInternalsWritableStreamClose, 1) \ + macro(writableStreamAddWriteRequest, writableStreamInternalsWritableStreamAddWriteRequest, 1) \ + macro(writableStreamCloseQueuedOrInFlight, writableStreamInternalsWritableStreamCloseQueuedOrInFlight, 1) \ + macro(writableStreamDealWithRejection, writableStreamInternalsWritableStreamDealWithRejection, 2) \ + macro(writableStreamFinishErroring, writableStreamInternalsWritableStreamFinishErroring, 1) \ + macro(writableStreamFinishInFlightClose, writableStreamInternalsWritableStreamFinishInFlightClose, 1) \ + macro(writableStreamFinishInFlightCloseWithError, writableStreamInternalsWritableStreamFinishInFlightCloseWithError, 2) \ + macro(writableStreamFinishInFlightWrite, writableStreamInternalsWritableStreamFinishInFlightWrite, 1) \ + macro(writableStreamFinishInFlightWriteWithError, writableStreamInternalsWritableStreamFinishInFlightWriteWithError, 2) \ + macro(writableStreamHasOperationMarkedInFlight, writableStreamInternalsWritableStreamHasOperationMarkedInFlight, 1) \ + macro(writableStreamMarkCloseRequestInFlight, writableStreamInternalsWritableStreamMarkCloseRequestInFlight, 1) \ + macro(writableStreamMarkFirstWriteRequestInFlight, writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlight, 1) \ + macro(writableStreamRejectCloseAndClosedPromiseIfNeeded, writableStreamInternalsWritableStreamRejectCloseAndClosedPromiseIfNeeded, 1) \ + macro(writableStreamStartErroring, writableStreamInternalsWritableStreamStartErroring, 2) \ + macro(writableStreamUpdateBackpressure, writableStreamInternalsWritableStreamUpdateBackpressure, 2) \ + macro(writableStreamDefaultWriterAbort, writableStreamInternalsWritableStreamDefaultWriterAbort, 2) \ + macro(writableStreamDefaultWriterClose, writableStreamInternalsWritableStreamDefaultWriterClose, 1) \ + macro(writableStreamDefaultWriterCloseWithErrorPropagation, writableStreamInternalsWritableStreamDefaultWriterCloseWithErrorPropagation, 1) \ + macro(writableStreamDefaultWriterEnsureClosedPromiseRejected, writableStreamInternalsWritableStreamDefaultWriterEnsureClosedPromiseRejected, 2) \ + macro(writableStreamDefaultWriterEnsureReadyPromiseRejected, writableStreamInternalsWritableStreamDefaultWriterEnsureReadyPromiseRejected, 2) \ + macro(writableStreamDefaultWriterGetDesiredSize, writableStreamInternalsWritableStreamDefaultWriterGetDesiredSize, 1) \ + macro(writableStreamDefaultWriterRelease, writableStreamInternalsWritableStreamDefaultWriterRelease, 1) \ + macro(writableStreamDefaultWriterWrite, writableStreamInternalsWritableStreamDefaultWriterWrite, 2) \ + macro(setUpWritableStreamDefaultController, writableStreamInternalsSetUpWritableStreamDefaultController, 8) \ + macro(writableStreamDefaultControllerStart, writableStreamInternalsWritableStreamDefaultControllerStart, 1) \ + macro(setUpWritableStreamDefaultControllerFromUnderlyingSink, writableStreamInternalsSetUpWritableStreamDefaultControllerFromUnderlyingSink, 5) \ + macro(writableStreamDefaultControllerAdvanceQueueIfNeeded, writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeeded, 1) \ + macro(isCloseSentinel, writableStreamInternalsIsCloseSentinel, 0) \ + macro(writableStreamDefaultControllerClearAlgorithms, writableStreamInternalsWritableStreamDefaultControllerClearAlgorithms, 1) \ + macro(writableStreamDefaultControllerClose, writableStreamInternalsWritableStreamDefaultControllerClose, 1) \ + macro(writableStreamDefaultControllerError, writableStreamInternalsWritableStreamDefaultControllerError, 2) \ + macro(writableStreamDefaultControllerErrorIfNeeded, writableStreamInternalsWritableStreamDefaultControllerErrorIfNeeded, 2) \ + macro(writableStreamDefaultControllerGetBackpressure, writableStreamInternalsWritableStreamDefaultControllerGetBackpressure, 1) \ + macro(writableStreamDefaultControllerGetChunkSize, writableStreamInternalsWritableStreamDefaultControllerGetChunkSize, 2) \ + macro(writableStreamDefaultControllerGetDesiredSize, writableStreamInternalsWritableStreamDefaultControllerGetDesiredSize, 1) \ + macro(writableStreamDefaultControllerProcessClose, writableStreamInternalsWritableStreamDefaultControllerProcessClose, 1) \ + macro(writableStreamDefaultControllerProcessWrite, writableStreamInternalsWritableStreamDefaultControllerProcessWrite, 2) \ + macro(writableStreamDefaultControllerWrite, writableStreamInternalsWritableStreamDefaultControllerWrite, 3) \ + +#define WEBCORE_FOREACH_BUILTIN_CODE(macro) \ + macro(writableStreamDefaultWriterAbortCode, abort, ASCIILiteral(), s_writableStreamDefaultWriterAbortCodeLength) \ + macro(readableStreamInternalsAcquireReadableStreamDefaultReaderCode, acquireReadableStreamDefaultReader, ASCIILiteral(), s_readableStreamInternalsAcquireReadableStreamDefaultReaderCodeLength) \ + macro(writableStreamInternalsAcquireWritableStreamDefaultWriterCode, acquireWritableStreamDefaultWriter, ASCIILiteral(), s_writableStreamInternalsAcquireWritableStreamDefaultWriterCodeLength) \ + macro(jsBufferPrototypeAsciiSliceCode, asciiSlice, ASCIILiteral(), s_jsBufferPrototypeAsciiSliceCodeLength) \ + macro(jsBufferPrototypeAsciiWriteCode, asciiWrite, ASCIILiteral(), s_jsBufferPrototypeAsciiWriteCodeLength) \ + macro(readableStreamInternalsAssignDirectStreamCode, assignDirectStream, ASCIILiteral(), s_readableStreamInternalsAssignDirectStreamCodeLength) \ + macro(jsBufferPrototypeBase64SliceCode, base64Slice, ASCIILiteral(), s_jsBufferPrototypeBase64SliceCodeLength) \ + macro(jsBufferPrototypeBase64WriteCode, base64Write, ASCIILiteral(), s_jsBufferPrototypeBase64WriteCodeLength) \ + macro(jsBufferPrototypeBase64urlSliceCode, base64urlSlice, ASCIILiteral(), s_jsBufferPrototypeBase64urlSliceCodeLength) \ + macro(jsBufferPrototypeBase64urlWriteCode, base64urlWrite, ASCIILiteral(), s_jsBufferPrototypeBase64urlWriteCodeLength) \ + macro(readableByteStreamControllerByobRequestCode, byobRequest, "get byobRequest"_s, s_readableByteStreamControllerByobRequestCodeLength) \ + macro(readableStreamCancelCode, cancel, ASCIILiteral(), s_readableStreamCancelCodeLength) \ + macro(readableStreamBYOBReaderCancelCode, cancel, ASCIILiteral(), s_readableStreamBYOBReaderCancelCodeLength) \ + macro(readableStreamDefaultReaderCancelCode, cancel, ASCIILiteral(), s_readableStreamDefaultReaderCancelCodeLength) \ + macro(readableByteStreamControllerCloseCode, close, ASCIILiteral(), s_readableByteStreamControllerCloseCodeLength) \ + macro(readableStreamDefaultControllerCloseCode, close, ASCIILiteral(), s_readableStreamDefaultControllerCloseCodeLength) \ + macro(writableStreamDefaultWriterCloseCode, close, ASCIILiteral(), s_writableStreamDefaultWriterCloseCodeLength) \ + macro(readableStreamBYOBReaderClosedCode, closed, "get closed"_s, s_readableStreamBYOBReaderClosedCodeLength) \ + macro(readableStreamDefaultReaderClosedCode, closed, "get closed"_s, s_readableStreamDefaultReaderClosedCodeLength) \ + macro(writableStreamDefaultWriterClosedCode, closed, "get closed"_s, s_writableStreamDefaultWriterClosedCodeLength) \ + macro(readableStreamConsumeReadableStreamCode, consumeReadableStream, ASCIILiteral(), s_readableStreamConsumeReadableStreamCodeLength) \ + macro(readableStreamCreateEmptyReadableStreamCode, createEmptyReadableStream, ASCIILiteral(), s_readableStreamCreateEmptyReadableStreamCodeLength) \ + macro(streamInternalsCreateFIFOCode, createFIFO, ASCIILiteral(), s_streamInternalsCreateFIFOCodeLength) \ + macro(streamInternalsCreateFulfilledPromiseCode, createFulfilledPromise, ASCIILiteral(), s_streamInternalsCreateFulfilledPromiseCodeLength) \ + macro(writableStreamInternalsCreateInternalWritableStreamFromUnderlyingSinkCode, createInternalWritableStreamFromUnderlyingSink, ASCIILiteral(), s_writableStreamInternalsCreateInternalWritableStreamFromUnderlyingSinkCodeLength) \ + macro(readableStreamCreateNativeReadableStreamCode, createNativeReadableStream, ASCIILiteral(), s_readableStreamCreateNativeReadableStreamCodeLength) \ + macro(readableStreamInternalsCreateReadableStreamControllerCode, createReadableStreamController, ASCIILiteral(), s_readableStreamInternalsCreateReadableStreamControllerCodeLength) \ + macro(transformStreamInternalsCreateTransformStreamCode, createTransformStream, ASCIILiteral(), s_transformStreamInternalsCreateTransformStreamCodeLength) \ + macro(writableStreamInternalsCreateWritableStreamCode, createWritableStream, ASCIILiteral(), s_writableStreamInternalsCreateWritableStreamCodeLength) \ + macro(streamInternalsDequeueValueCode, dequeueValue, ASCIILiteral(), s_streamInternalsDequeueValueCodeLength) \ + macro(readableByteStreamControllerDesiredSizeCode, desiredSize, "get desiredSize"_s, s_readableByteStreamControllerDesiredSizeCodeLength) \ + macro(readableStreamDefaultControllerDesiredSizeCode, desiredSize, "get desiredSize"_s, s_readableStreamDefaultControllerDesiredSizeCodeLength) \ + macro(transformStreamDefaultControllerDesiredSizeCode, desiredSize, "get desiredSize"_s, s_transformStreamDefaultControllerDesiredSizeCodeLength) \ + macro(writableStreamDefaultWriterDesiredSizeCode, desiredSize, "get desiredSize"_s, s_writableStreamDefaultWriterDesiredSizeCodeLength) \ + macro(readableByteStreamControllerEnqueueCode, enqueue, ASCIILiteral(), s_readableByteStreamControllerEnqueueCodeLength) \ + macro(readableStreamDefaultControllerEnqueueCode, enqueue, ASCIILiteral(), s_readableStreamDefaultControllerEnqueueCodeLength) \ + macro(transformStreamDefaultControllerEnqueueCode, enqueue, ASCIILiteral(), s_transformStreamDefaultControllerEnqueueCodeLength) \ + macro(streamInternalsEnqueueValueWithSizeCode, enqueueValueWithSize, ASCIILiteral(), s_streamInternalsEnqueueValueWithSizeCodeLength) \ + macro(readableByteStreamControllerErrorCode, error, ASCIILiteral(), s_readableByteStreamControllerErrorCodeLength) \ + macro(readableStreamDefaultControllerErrorCode, error, ASCIILiteral(), s_readableStreamDefaultControllerErrorCodeLength) \ + macro(transformStreamDefaultControllerErrorCode, error, ASCIILiteral(), s_transformStreamDefaultControllerErrorCodeLength) \ + macro(writableStreamDefaultControllerErrorCode, error, ASCIILiteral(), s_writableStreamDefaultControllerErrorCodeLength) \ + macro(streamInternalsExtractHighWaterMarkCode, extractHighWaterMark, ASCIILiteral(), s_streamInternalsExtractHighWaterMarkCodeLength) \ + macro(streamInternalsExtractHighWaterMarkFromQueuingStrategyInitCode, extractHighWaterMarkFromQueuingStrategyInit, ASCIILiteral(), s_streamInternalsExtractHighWaterMarkFromQueuingStrategyInitCodeLength) \ + macro(streamInternalsExtractSizeAlgorithmCode, extractSizeAlgorithm, ASCIILiteral(), s_streamInternalsExtractSizeAlgorithmCodeLength) \ + macro(jsBufferConstructorFromCode, from, ASCIILiteral(), s_jsBufferConstructorFromCodeLength) \ + macro(readableStreamGetReaderCode, getReader, ASCIILiteral(), s_readableStreamGetReaderCodeLength) \ + macro(readableStreamInternalsHandleDirectStreamErrorCode, handleDirectStreamError, ASCIILiteral(), s_readableStreamInternalsHandleDirectStreamErrorCodeLength) \ + macro(readableStreamInternalsHandleDirectStreamErrorRejectCode, handleDirectStreamErrorReject, ASCIILiteral(), s_readableStreamInternalsHandleDirectStreamErrorRejectCodeLength) \ + macro(jsBufferPrototypeHexSliceCode, hexSlice, ASCIILiteral(), s_jsBufferPrototypeHexSliceCodeLength) \ + macro(jsBufferPrototypeHexWriteCode, hexWrite, ASCIILiteral(), s_jsBufferPrototypeHexWriteCodeLength) \ + macro(byteLengthQueuingStrategyHighWaterMarkCode, highWaterMark, "get highWaterMark"_s, s_byteLengthQueuingStrategyHighWaterMarkCodeLength) \ + macro(countQueuingStrategyHighWaterMarkCode, highWaterMark, "get highWaterMark"_s, s_countQueuingStrategyHighWaterMarkCodeLength) \ + macro(readableStreamInternalsInitializeArrayBufferStreamCode, initializeArrayBufferStream, ASCIILiteral(), s_readableStreamInternalsInitializeArrayBufferStreamCodeLength) \ + macro(jsBufferPrototypeInitializeBunBufferCode, initializeBunBuffer, ASCIILiteral(), s_jsBufferPrototypeInitializeBunBufferCodeLength) \ + macro(byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCode, initializeByteLengthQueuingStrategy, ASCIILiteral(), s_byteLengthQueuingStrategyInitializeByteLengthQueuingStrategyCodeLength) \ + macro(countQueuingStrategyInitializeCountQueuingStrategyCode, initializeCountQueuingStrategy, ASCIILiteral(), s_countQueuingStrategyInitializeCountQueuingStrategyCodeLength) \ + macro(readableByteStreamControllerInitializeReadableByteStreamControllerCode, initializeReadableByteStreamController, ASCIILiteral(), s_readableByteStreamControllerInitializeReadableByteStreamControllerCodeLength) \ + macro(readableStreamInitializeReadableStreamCode, initializeReadableStream, ASCIILiteral(), s_readableStreamInitializeReadableStreamCodeLength) \ + macro(readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCode, initializeReadableStreamBYOBReader, ASCIILiteral(), s_readableStreamBYOBReaderInitializeReadableStreamBYOBReaderCodeLength) \ + macro(readableStreamBYOBRequestInitializeReadableStreamBYOBRequestCode, initializeReadableStreamBYOBRequest, ASCIILiteral(), s_readableStreamBYOBRequestInitializeReadableStreamBYOBRequestCodeLength) \ + macro(readableStreamDefaultControllerInitializeReadableStreamDefaultControllerCode, initializeReadableStreamDefaultController, ASCIILiteral(), s_readableStreamDefaultControllerInitializeReadableStreamDefaultControllerCodeLength) \ + macro(readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCode, initializeReadableStreamDefaultReader, ASCIILiteral(), s_readableStreamDefaultReaderInitializeReadableStreamDefaultReaderCodeLength) \ + macro(transformStreamInitializeTransformStreamCode, initializeTransformStream, ASCIILiteral(), s_transformStreamInitializeTransformStreamCodeLength) \ + macro(transformStreamInternalsInitializeTransformStreamCode, initializeTransformStream, ASCIILiteral(), s_transformStreamInternalsInitializeTransformStreamCodeLength) \ + macro(transformStreamDefaultControllerInitializeTransformStreamDefaultControllerCode, initializeTransformStreamDefaultController, ASCIILiteral(), s_transformStreamDefaultControllerInitializeTransformStreamDefaultControllerCodeLength) \ + macro(writableStreamDefaultControllerInitializeWritableStreamDefaultControllerCode, initializeWritableStreamDefaultController, ASCIILiteral(), s_writableStreamDefaultControllerInitializeWritableStreamDefaultControllerCodeLength) \ + macro(writableStreamDefaultWriterInitializeWritableStreamDefaultWriterCode, initializeWritableStreamDefaultWriter, ASCIILiteral(), s_writableStreamDefaultWriterInitializeWritableStreamDefaultWriterCodeLength) \ + macro(writableStreamInternalsInitializeWritableStreamSlotsCode, initializeWritableStreamSlots, ASCIILiteral(), s_writableStreamInternalsInitializeWritableStreamSlotsCodeLength) \ + macro(writableStreamInternalsIsCloseSentinelCode, isCloseSentinel, ASCIILiteral(), s_writableStreamInternalsIsCloseSentinelCodeLength) \ + macro(readableByteStreamInternalsIsReadableByteStreamControllerCode, isReadableByteStreamController, ASCIILiteral(), s_readableByteStreamInternalsIsReadableByteStreamControllerCodeLength) \ + macro(readableStreamInternalsIsReadableStreamCode, isReadableStream, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamCodeLength) \ + macro(readableByteStreamInternalsIsReadableStreamBYOBReaderCode, isReadableStreamBYOBReader, ASCIILiteral(), s_readableByteStreamInternalsIsReadableStreamBYOBReaderCodeLength) \ + macro(readableByteStreamInternalsIsReadableStreamBYOBRequestCode, isReadableStreamBYOBRequest, ASCIILiteral(), s_readableByteStreamInternalsIsReadableStreamBYOBRequestCodeLength) \ + macro(readableStreamInternalsIsReadableStreamDefaultControllerCode, isReadableStreamDefaultController, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamDefaultControllerCodeLength) \ + macro(readableStreamInternalsIsReadableStreamDefaultReaderCode, isReadableStreamDefaultReader, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamDefaultReaderCodeLength) \ + macro(readableStreamInternalsIsReadableStreamDisturbedCode, isReadableStreamDisturbed, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamDisturbedCodeLength) \ + macro(readableStreamInternalsIsReadableStreamLockedCode, isReadableStreamLocked, ASCIILiteral(), s_readableStreamInternalsIsReadableStreamLockedCodeLength) \ + macro(transformStreamInternalsIsTransformStreamCode, isTransformStream, ASCIILiteral(), s_transformStreamInternalsIsTransformStreamCodeLength) \ + macro(transformStreamInternalsIsTransformStreamDefaultControllerCode, isTransformStreamDefaultController, ASCIILiteral(), s_transformStreamInternalsIsTransformStreamDefaultControllerCodeLength) \ + macro(writableStreamInternalsIsWritableStreamCode, isWritableStream, ASCIILiteral(), s_writableStreamInternalsIsWritableStreamCodeLength) \ + macro(writableStreamInternalsIsWritableStreamDefaultWriterCode, isWritableStreamDefaultWriter, ASCIILiteral(), s_writableStreamInternalsIsWritableStreamDefaultWriterCodeLength) \ + macro(writableStreamInternalsIsWritableStreamLockedCode, isWritableStreamLocked, ASCIILiteral(), s_writableStreamInternalsIsWritableStreamLockedCodeLength) \ + macro(jsBufferPrototypeLatin1SliceCode, latin1Slice, ASCIILiteral(), s_jsBufferPrototypeLatin1SliceCodeLength) \ + macro(jsBufferPrototypeLatin1WriteCode, latin1Write, ASCIILiteral(), s_jsBufferPrototypeLatin1WriteCodeLength) \ + macro(readableStreamInternalsLazyLoadStreamCode, lazyLoadStream, ASCIILiteral(), s_readableStreamInternalsLazyLoadStreamCodeLength) \ + macro(readableStreamLockedCode, locked, "get locked"_s, s_readableStreamLockedCodeLength) \ + macro(streamInternalsMarkPromiseAsHandledCode, markPromiseAsHandled, ASCIILiteral(), s_streamInternalsMarkPromiseAsHandledCodeLength) \ + macro(streamInternalsNewQueueCode, newQueue, ASCIILiteral(), s_streamInternalsNewQueueCodeLength) \ + macro(readableStreamInternalsNoopDoneFunctionCode, noopDoneFunction, ASCIILiteral(), s_readableStreamInternalsNoopDoneFunctionCodeLength) \ + macro(readableStreamInternalsOnCloseDirectStreamCode, onCloseDirectStream, ASCIILiteral(), s_readableStreamInternalsOnCloseDirectStreamCodeLength) \ + macro(readableStreamInternalsOnDrainDirectStreamCode, onDrainDirectStream, ASCIILiteral(), s_readableStreamInternalsOnDrainDirectStreamCodeLength) \ + macro(readableStreamInternalsOnPullDirectStreamCode, onPullDirectStream, ASCIILiteral(), s_readableStreamInternalsOnPullDirectStreamCodeLength) \ + macro(readableStreamInternalsOnReadableStreamDirectControllerClosedCode, onReadableStreamDirectControllerClosed, ASCIILiteral(), s_readableStreamInternalsOnReadableStreamDirectControllerClosedCodeLength) \ + macro(streamInternalsPeekQueueValueCode, peekQueueValue, ASCIILiteral(), s_streamInternalsPeekQueueValueCodeLength) \ + macro(readableStreamPipeThroughCode, pipeThrough, ASCIILiteral(), s_readableStreamPipeThroughCodeLength) \ + macro(readableStreamPipeToCode, pipeTo, ASCIILiteral(), s_readableStreamPipeToCodeLength) \ + macro(readableStreamInternalsPipeToClosingMustBePropagatedBackwardCode, pipeToClosingMustBePropagatedBackward, ASCIILiteral(), s_readableStreamInternalsPipeToClosingMustBePropagatedBackwardCodeLength) \ + macro(readableStreamInternalsPipeToClosingMustBePropagatedForwardCode, pipeToClosingMustBePropagatedForward, ASCIILiteral(), s_readableStreamInternalsPipeToClosingMustBePropagatedForwardCodeLength) \ + macro(readableStreamInternalsPipeToDoReadWriteCode, pipeToDoReadWrite, ASCIILiteral(), s_readableStreamInternalsPipeToDoReadWriteCodeLength) \ + macro(readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCode, pipeToErrorsMustBePropagatedBackward, ASCIILiteral(), s_readableStreamInternalsPipeToErrorsMustBePropagatedBackwardCodeLength) \ + macro(readableStreamInternalsPipeToErrorsMustBePropagatedForwardCode, pipeToErrorsMustBePropagatedForward, ASCIILiteral(), s_readableStreamInternalsPipeToErrorsMustBePropagatedForwardCodeLength) \ + macro(readableStreamInternalsPipeToFinalizeCode, pipeToFinalize, ASCIILiteral(), s_readableStreamInternalsPipeToFinalizeCodeLength) \ + macro(readableStreamInternalsPipeToLoopCode, pipeToLoop, ASCIILiteral(), s_readableStreamInternalsPipeToLoopCodeLength) \ + macro(readableStreamInternalsPipeToShutdownCode, pipeToShutdown, ASCIILiteral(), s_readableStreamInternalsPipeToShutdownCodeLength) \ + macro(readableStreamInternalsPipeToShutdownWithActionCode, pipeToShutdownWithAction, ASCIILiteral(), s_readableStreamInternalsPipeToShutdownWithActionCodeLength) \ + macro(readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCode, privateInitializeReadableByteStreamController, ASCIILiteral(), s_readableByteStreamInternalsPrivateInitializeReadableByteStreamControllerCodeLength) \ + macro(readableByteStreamInternalsPrivateInitializeReadableStreamBYOBRequestCode, privateInitializeReadableStreamBYOBRequest, ASCIILiteral(), s_readableByteStreamInternalsPrivateInitializeReadableStreamBYOBRequestCodeLength) \ + macro(readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCode, privateInitializeReadableStreamDefaultController, ASCIILiteral(), s_readableStreamInternalsPrivateInitializeReadableStreamDefaultControllerCodeLength) \ + macro(streamInternalsPromiseInvokeOrFallbackOrNoopCode, promiseInvokeOrFallbackOrNoop, ASCIILiteral(), s_streamInternalsPromiseInvokeOrFallbackOrNoopCodeLength) \ + macro(streamInternalsPromiseInvokeOrNoopCode, promiseInvokeOrNoop, ASCIILiteral(), s_streamInternalsPromiseInvokeOrNoopCodeLength) \ + macro(streamInternalsPromiseInvokeOrNoopMethodCode, promiseInvokeOrNoopMethod, ASCIILiteral(), s_streamInternalsPromiseInvokeOrNoopMethodCodeLength) \ + macro(streamInternalsPromiseInvokeOrNoopMethodNoCatchCode, promiseInvokeOrNoopMethodNoCatch, ASCIILiteral(), s_streamInternalsPromiseInvokeOrNoopMethodNoCatchCodeLength) \ + macro(streamInternalsPromiseInvokeOrNoopNoCatchCode, promiseInvokeOrNoopNoCatch, ASCIILiteral(), s_streamInternalsPromiseInvokeOrNoopNoCatchCodeLength) \ + macro(readableStreamBYOBReaderReadCode, read, ASCIILiteral(), s_readableStreamBYOBReaderReadCodeLength) \ + macro(readableStreamDefaultReaderReadCode, read, ASCIILiteral(), s_readableStreamDefaultReaderReadCodeLength) \ + macro(jsBufferPrototypeReadBigInt64BECode, readBigInt64BE, ASCIILiteral(), s_jsBufferPrototypeReadBigInt64BECodeLength) \ + macro(jsBufferPrototypeReadBigInt64LECode, readBigInt64LE, ASCIILiteral(), s_jsBufferPrototypeReadBigInt64LECodeLength) \ + macro(jsBufferPrototypeReadBigUInt64BECode, readBigUInt64BE, ASCIILiteral(), s_jsBufferPrototypeReadBigUInt64BECodeLength) \ + macro(jsBufferPrototypeReadBigUInt64LECode, readBigUInt64LE, ASCIILiteral(), s_jsBufferPrototypeReadBigUInt64LECodeLength) \ + macro(jsBufferPrototypeReadDoubleBECode, readDoubleBE, ASCIILiteral(), s_jsBufferPrototypeReadDoubleBECodeLength) \ + macro(jsBufferPrototypeReadDoubleLECode, readDoubleLE, ASCIILiteral(), s_jsBufferPrototypeReadDoubleLECodeLength) \ + macro(jsBufferPrototypeReadFloatBECode, readFloatBE, ASCIILiteral(), s_jsBufferPrototypeReadFloatBECodeLength) \ + macro(jsBufferPrototypeReadFloatLECode, readFloatLE, ASCIILiteral(), s_jsBufferPrototypeReadFloatLECodeLength) \ + macro(jsBufferPrototypeReadInt16BECode, readInt16BE, ASCIILiteral(), s_jsBufferPrototypeReadInt16BECodeLength) \ + macro(jsBufferPrototypeReadInt16LECode, readInt16LE, ASCIILiteral(), s_jsBufferPrototypeReadInt16LECodeLength) \ + macro(jsBufferPrototypeReadInt32BECode, readInt32BE, ASCIILiteral(), s_jsBufferPrototypeReadInt32BECodeLength) \ + macro(jsBufferPrototypeReadInt32LECode, readInt32LE, ASCIILiteral(), s_jsBufferPrototypeReadInt32LECodeLength) \ + macro(jsBufferPrototypeReadInt8Code, readInt8, ASCIILiteral(), s_jsBufferPrototypeReadInt8CodeLength) \ + macro(readableStreamDefaultReaderReadManyCode, readMany, ASCIILiteral(), s_readableStreamDefaultReaderReadManyCodeLength) \ + macro(jsBufferPrototypeReadUInt16BECode, readUInt16BE, ASCIILiteral(), s_jsBufferPrototypeReadUInt16BECodeLength) \ + macro(jsBufferPrototypeReadUInt16LECode, readUInt16LE, ASCIILiteral(), s_jsBufferPrototypeReadUInt16LECodeLength) \ + macro(jsBufferPrototypeReadUInt32BECode, readUInt32BE, ASCIILiteral(), s_jsBufferPrototypeReadUInt32BECodeLength) \ + macro(jsBufferPrototypeReadUInt32LECode, readUInt32LE, ASCIILiteral(), s_jsBufferPrototypeReadUInt32LECodeLength) \ + macro(jsBufferPrototypeReadUInt8Code, readUInt8, ASCIILiteral(), s_jsBufferPrototypeReadUInt8CodeLength) \ + macro(transformStreamReadableCode, readable, "get readable"_s, s_transformStreamReadableCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerCallPullIfNeededCode, readableByteStreamControllerCallPullIfNeeded, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerCallPullIfNeededCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerCancelCode, readableByteStreamControllerCancel, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerCancelCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCode, readableByteStreamControllerClearPendingPullIntos, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerClearPendingPullIntosCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerCloseCode, readableByteStreamControllerClose, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerCloseCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerCommitDescriptorCode, readableByteStreamControllerCommitDescriptor, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerCommitDescriptorCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerConvertDescriptorCode, readableByteStreamControllerConvertDescriptor, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerConvertDescriptorCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerEnqueueCode, readableByteStreamControllerEnqueue, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerEnqueueCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCode, readableByteStreamControllerEnqueueChunk, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerEnqueueChunkCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerErrorCode, readableByteStreamControllerError, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerErrorCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCode, readableByteStreamControllerFillDescriptorFromQueue, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerFillDescriptorFromQueueCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerGetDesiredSizeCode, readableByteStreamControllerGetDesiredSize, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerGetDesiredSizeCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerHandleQueueDrainCode, readableByteStreamControllerHandleQueueDrain, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerHandleQueueDrainCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerInvalidateBYOBRequestCode, readableByteStreamControllerInvalidateBYOBRequest, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerInvalidateBYOBRequestCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCode, readableByteStreamControllerProcessPullDescriptors, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerProcessPullDescriptorsCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerPullCode, readableByteStreamControllerPull, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerPullCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerPullIntoCode, readableByteStreamControllerPullInto, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerPullIntoCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerRespondCode, readableByteStreamControllerRespond, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerRespondCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCode, readableByteStreamControllerRespondInClosedState, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerRespondInClosedStateCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCode, readableByteStreamControllerRespondInReadableState, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerRespondInReadableStateCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerRespondInternalCode, readableByteStreamControllerRespondInternal, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerRespondInternalCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCode, readableByteStreamControllerRespondWithNewView, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerRespondWithNewViewCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCode, readableByteStreamControllerShiftPendingDescriptor, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerShiftPendingDescriptorCodeLength) \ + macro(readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCode, readableByteStreamControllerShouldCallPull, ASCIILiteral(), s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeLength) \ + macro(readableByteStreamInternalsReadableStreamAddReadIntoRequestCode, readableStreamAddReadIntoRequest, ASCIILiteral(), s_readableByteStreamInternalsReadableStreamAddReadIntoRequestCodeLength) \ + macro(readableStreamInternalsReadableStreamAddReadRequestCode, readableStreamAddReadRequest, ASCIILiteral(), s_readableStreamInternalsReadableStreamAddReadRequestCodeLength) \ + macro(readableByteStreamInternalsReadableStreamBYOBReaderReadCode, readableStreamBYOBReaderRead, ASCIILiteral(), s_readableByteStreamInternalsReadableStreamBYOBReaderReadCodeLength) \ + macro(readableByteStreamInternalsReadableStreamByteStreamControllerStartCode, readableStreamByteStreamControllerStart, ASCIILiteral(), s_readableByteStreamInternalsReadableStreamByteStreamControllerStartCodeLength) \ + macro(readableStreamInternalsReadableStreamCancelCode, readableStreamCancel, ASCIILiteral(), s_readableStreamInternalsReadableStreamCancelCodeLength) \ + macro(readableStreamInternalsReadableStreamCloseCode, readableStreamClose, ASCIILiteral(), s_readableStreamInternalsReadableStreamCloseCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCode, readableStreamDefaultControllerCallPullIfNeeded, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerCallPullIfNeededCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCode, readableStreamDefaultControllerCanCloseOrEnqueue, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerCanCloseOrEnqueueCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerCancelCode, readableStreamDefaultControllerCancel, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerCancelCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerCloseCode, readableStreamDefaultControllerClose, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerCloseCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerEnqueueCode, readableStreamDefaultControllerEnqueue, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerEnqueueCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerErrorCode, readableStreamDefaultControllerError, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerErrorCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerGetDesiredSizeCode, readableStreamDefaultControllerGetDesiredSize, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerGetDesiredSizeCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerPullCode, readableStreamDefaultControllerPull, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerPullCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCode, readableStreamDefaultControllerShouldCallPull, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerShouldCallPullCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultControllerStartCode, readableStreamDefaultControllerStart, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultControllerStartCodeLength) \ + macro(readableStreamInternalsReadableStreamDefaultReaderReadCode, readableStreamDefaultReaderRead, ASCIILiteral(), s_readableStreamInternalsReadableStreamDefaultReaderReadCodeLength) \ + macro(readableStreamInternalsReadableStreamErrorCode, readableStreamError, ASCIILiteral(), s_readableStreamInternalsReadableStreamErrorCodeLength) \ + macro(readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCode, readableStreamFulfillReadIntoRequest, ASCIILiteral(), s_readableByteStreamInternalsReadableStreamFulfillReadIntoRequestCodeLength) \ + macro(readableStreamInternalsReadableStreamFulfillReadRequestCode, readableStreamFulfillReadRequest, ASCIILiteral(), s_readableStreamInternalsReadableStreamFulfillReadRequestCodeLength) \ + macro(readableByteStreamInternalsReadableStreamHasBYOBReaderCode, readableStreamHasBYOBReader, ASCIILiteral(), s_readableByteStreamInternalsReadableStreamHasBYOBReaderCodeLength) \ + macro(readableByteStreamInternalsReadableStreamHasDefaultReaderCode, readableStreamHasDefaultReader, ASCIILiteral(), s_readableByteStreamInternalsReadableStreamHasDefaultReaderCodeLength) \ + macro(readableStreamInternalsReadableStreamPipeToCode, readableStreamPipeTo, ASCIILiteral(), s_readableStreamInternalsReadableStreamPipeToCodeLength) \ + macro(readableStreamInternalsReadableStreamPipeToWritableStreamCode, readableStreamPipeToWritableStream, ASCIILiteral(), s_readableStreamInternalsReadableStreamPipeToWritableStreamCodeLength) \ + macro(readableStreamInternalsReadableStreamReaderGenericCancelCode, readableStreamReaderGenericCancel, ASCIILiteral(), s_readableStreamInternalsReadableStreamReaderGenericCancelCodeLength) \ + macro(readableStreamInternalsReadableStreamReaderGenericInitializeCode, readableStreamReaderGenericInitialize, ASCIILiteral(), s_readableStreamInternalsReadableStreamReaderGenericInitializeCodeLength) \ + macro(readableStreamInternalsReadableStreamReaderGenericReleaseCode, readableStreamReaderGenericRelease, ASCIILiteral(), s_readableStreamInternalsReadableStreamReaderGenericReleaseCodeLength) \ + macro(readableByteStreamInternalsReadableStreamReaderKindCode, readableStreamReaderKind, ASCIILiteral(), s_readableByteStreamInternalsReadableStreamReaderKindCodeLength) \ + macro(readableStreamInternalsReadableStreamTeeCode, readableStreamTee, ASCIILiteral(), s_readableStreamInternalsReadableStreamTeeCodeLength) \ + macro(readableStreamInternalsReadableStreamTeeBranch1CancelFunctionCode, readableStreamTeeBranch1CancelFunction, ASCIILiteral(), s_readableStreamInternalsReadableStreamTeeBranch1CancelFunctionCodeLength) \ + macro(readableStreamInternalsReadableStreamTeeBranch2CancelFunctionCode, readableStreamTeeBranch2CancelFunction, ASCIILiteral(), s_readableStreamInternalsReadableStreamTeeBranch2CancelFunctionCodeLength) \ + macro(readableStreamInternalsReadableStreamTeePullFunctionCode, readableStreamTeePullFunction, ASCIILiteral(), s_readableStreamInternalsReadableStreamTeePullFunctionCodeLength) \ + macro(readableStreamReadableStreamToArrayCode, readableStreamToArray, ASCIILiteral(), s_readableStreamReadableStreamToArrayCodeLength) \ + macro(readableStreamReadableStreamToArrayPublicCode, readableStreamToArrayPublic, ASCIILiteral(), s_readableStreamReadableStreamToArrayPublicCodeLength) \ + macro(readableStreamReadableStreamToBlobCode, readableStreamToBlob, ASCIILiteral(), s_readableStreamReadableStreamToBlobCodeLength) \ + macro(readableStreamReadableStreamToJSONCode, readableStreamToJSON, ASCIILiteral(), s_readableStreamReadableStreamToJSONCodeLength) \ + macro(readableStreamReadableStreamToTextCode, readableStreamToText, ASCIILiteral(), s_readableStreamReadableStreamToTextCodeLength) \ + macro(writableStreamDefaultWriterReadyCode, ready, "get ready"_s, s_writableStreamDefaultWriterReadyCodeLength) \ + macro(readableStreamBYOBReaderReleaseLockCode, releaseLock, ASCIILiteral(), s_readableStreamBYOBReaderReleaseLockCodeLength) \ + macro(readableStreamDefaultReaderReleaseLockCode, releaseLock, ASCIILiteral(), s_readableStreamDefaultReaderReleaseLockCodeLength) \ + macro(writableStreamDefaultWriterReleaseLockCode, releaseLock, ASCIILiteral(), s_writableStreamDefaultWriterReleaseLockCodeLength) \ + macro(jsZigGlobalObjectRequireCode, require, ASCIILiteral(), s_jsZigGlobalObjectRequireCodeLength) \ + macro(streamInternalsResetQueueCode, resetQueue, ASCIILiteral(), s_streamInternalsResetQueueCodeLength) \ + macro(readableStreamBYOBRequestRespondCode, respond, ASCIILiteral(), s_readableStreamBYOBRequestRespondCodeLength) \ + macro(readableStreamBYOBRequestRespondWithNewViewCode, respondWithNewView, ASCIILiteral(), s_readableStreamBYOBRequestRespondWithNewViewCodeLength) \ + macro(jsBufferPrototypeSetBigUint64Code, setBigUint64, ASCIILiteral(), s_jsBufferPrototypeSetBigUint64CodeLength) \ + macro(transformStreamInternalsSetUpTransformStreamDefaultControllerCode, setUpTransformStreamDefaultController, ASCIILiteral(), s_transformStreamInternalsSetUpTransformStreamDefaultControllerCodeLength) \ + macro(transformStreamInternalsSetUpTransformStreamDefaultControllerFromTransformerCode, setUpTransformStreamDefaultControllerFromTransformer, ASCIILiteral(), s_transformStreamInternalsSetUpTransformStreamDefaultControllerFromTransformerCodeLength) \ + macro(writableStreamInternalsSetUpWritableStreamDefaultControllerCode, setUpWritableStreamDefaultController, ASCIILiteral(), s_writableStreamInternalsSetUpWritableStreamDefaultControllerCodeLength) \ + macro(writableStreamInternalsSetUpWritableStreamDefaultControllerFromUnderlyingSinkCode, setUpWritableStreamDefaultControllerFromUnderlyingSink, ASCIILiteral(), s_writableStreamInternalsSetUpWritableStreamDefaultControllerFromUnderlyingSinkCodeLength) \ + macro(writableStreamInternalsSetUpWritableStreamDefaultWriterCode, setUpWritableStreamDefaultWriter, ASCIILiteral(), s_writableStreamInternalsSetUpWritableStreamDefaultWriterCodeLength) \ + macro(readableStreamInternalsSetupReadableStreamDefaultControllerCode, setupReadableStreamDefaultController, ASCIILiteral(), s_readableStreamInternalsSetupReadableStreamDefaultControllerCodeLength) \ + macro(streamInternalsShieldingPromiseResolveCode, shieldingPromiseResolve, ASCIILiteral(), s_streamInternalsShieldingPromiseResolveCodeLength) \ + macro(byteLengthQueuingStrategySizeCode, size, ASCIILiteral(), s_byteLengthQueuingStrategySizeCodeLength) \ + macro(countQueuingStrategySizeCode, size, ASCIILiteral(), s_countQueuingStrategySizeCodeLength) \ + macro(jsBufferPrototypeSliceCode, slice, ASCIILiteral(), s_jsBufferPrototypeSliceCodeLength) \ + macro(jsBufferPrototypeSubarrayCode, subarray, ASCIILiteral(), s_jsBufferPrototypeSubarrayCodeLength) \ + macro(readableStreamTeeCode, tee, ASCIILiteral(), s_readableStreamTeeCodeLength) \ + macro(transformStreamDefaultControllerTerminateCode, terminate, ASCIILiteral(), s_transformStreamDefaultControllerTerminateCodeLength) \ + macro(streamInternalsToDictionaryCode, toDictionary, ASCIILiteral(), s_streamInternalsToDictionaryCodeLength) \ + macro(jsBufferPrototypeToJSONCode, toJSON, ASCIILiteral(), s_jsBufferPrototypeToJSONCodeLength) \ + macro(readableByteStreamInternalsTransferBufferToCurrentRealmCode, transferBufferToCurrentRealm, ASCIILiteral(), s_readableByteStreamInternalsTransferBufferToCurrentRealmCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultControllerClearAlgorithmsCode, transformStreamDefaultControllerClearAlgorithms, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultControllerClearAlgorithmsCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultControllerEnqueueCode, transformStreamDefaultControllerEnqueue, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultControllerEnqueueCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultControllerErrorCode, transformStreamDefaultControllerError, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultControllerErrorCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultControllerPerformTransformCode, transformStreamDefaultControllerPerformTransform, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultControllerTerminateCode, transformStreamDefaultControllerTerminate, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultControllerTerminateCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithmCode, transformStreamDefaultSinkAbortAlgorithm, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithmCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCode, transformStreamDefaultSinkCloseAlgorithm, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCode, transformStreamDefaultSinkWriteAlgorithm, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeLength) \ + macro(transformStreamInternalsTransformStreamDefaultSourcePullAlgorithmCode, transformStreamDefaultSourcePullAlgorithm, ASCIILiteral(), s_transformStreamInternalsTransformStreamDefaultSourcePullAlgorithmCodeLength) \ + macro(transformStreamInternalsTransformStreamErrorCode, transformStreamError, ASCIILiteral(), s_transformStreamInternalsTransformStreamErrorCodeLength) \ + macro(transformStreamInternalsTransformStreamErrorWritableAndUnblockWriteCode, transformStreamErrorWritableAndUnblockWrite, ASCIILiteral(), s_transformStreamInternalsTransformStreamErrorWritableAndUnblockWriteCodeLength) \ + macro(transformStreamInternalsTransformStreamSetBackpressureCode, transformStreamSetBackpressure, ASCIILiteral(), s_transformStreamInternalsTransformStreamSetBackpressureCodeLength) \ + macro(jsBufferPrototypeUcs2SliceCode, ucs2Slice, ASCIILiteral(), s_jsBufferPrototypeUcs2SliceCodeLength) \ + macro(jsBufferPrototypeUcs2WriteCode, ucs2Write, ASCIILiteral(), s_jsBufferPrototypeUcs2WriteCodeLength) \ + macro(jsBufferPrototypeUtf16leSliceCode, utf16leSlice, ASCIILiteral(), s_jsBufferPrototypeUtf16leSliceCodeLength) \ + macro(jsBufferPrototypeUtf16leWriteCode, utf16leWrite, ASCIILiteral(), s_jsBufferPrototypeUtf16leWriteCodeLength) \ + macro(jsBufferPrototypeUtf8SliceCode, utf8Slice, ASCIILiteral(), s_jsBufferPrototypeUtf8SliceCodeLength) \ + macro(jsBufferPrototypeUtf8WriteCode, utf8Write, ASCIILiteral(), s_jsBufferPrototypeUtf8WriteCodeLength) \ + macro(streamInternalsValidateAndNormalizeQueuingStrategyCode, validateAndNormalizeQueuingStrategy, ASCIILiteral(), s_streamInternalsValidateAndNormalizeQueuingStrategyCodeLength) \ + macro(readableStreamBYOBRequestViewCode, view, "get view"_s, s_readableStreamBYOBRequestViewCodeLength) \ + macro(transformStreamWritableCode, writable, ASCIILiteral(), s_transformStreamWritableCodeLength) \ + macro(writableStreamInternalsWritableStreamAbortCode, writableStreamAbort, ASCIILiteral(), s_writableStreamInternalsWritableStreamAbortCodeLength) \ + macro(writableStreamInternalsWritableStreamAbortForBindingsCode, writableStreamAbortForBindings, ASCIILiteral(), s_writableStreamInternalsWritableStreamAbortForBindingsCodeLength) \ + macro(writableStreamInternalsWritableStreamAddWriteRequestCode, writableStreamAddWriteRequest, ASCIILiteral(), s_writableStreamInternalsWritableStreamAddWriteRequestCodeLength) \ + macro(writableStreamInternalsWritableStreamCloseCode, writableStreamClose, ASCIILiteral(), s_writableStreamInternalsWritableStreamCloseCodeLength) \ + macro(writableStreamInternalsWritableStreamCloseForBindingsCode, writableStreamCloseForBindings, ASCIILiteral(), s_writableStreamInternalsWritableStreamCloseForBindingsCodeLength) \ + macro(writableStreamInternalsWritableStreamCloseQueuedOrInFlightCode, writableStreamCloseQueuedOrInFlight, ASCIILiteral(), s_writableStreamInternalsWritableStreamCloseQueuedOrInFlightCodeLength) \ + macro(writableStreamInternalsWritableStreamDealWithRejectionCode, writableStreamDealWithRejection, ASCIILiteral(), s_writableStreamInternalsWritableStreamDealWithRejectionCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCode, writableStreamDefaultControllerAdvanceQueueIfNeeded, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerAdvanceQueueIfNeededCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerClearAlgorithmsCode, writableStreamDefaultControllerClearAlgorithms, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerClearAlgorithmsCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerCloseCode, writableStreamDefaultControllerClose, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerCloseCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerErrorCode, writableStreamDefaultControllerError, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerErrorCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerErrorIfNeededCode, writableStreamDefaultControllerErrorIfNeeded, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerErrorIfNeededCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerGetBackpressureCode, writableStreamDefaultControllerGetBackpressure, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerGetBackpressureCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerGetChunkSizeCode, writableStreamDefaultControllerGetChunkSize, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerGetChunkSizeCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerGetDesiredSizeCode, writableStreamDefaultControllerGetDesiredSize, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerGetDesiredSizeCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerProcessCloseCode, writableStreamDefaultControllerProcessClose, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerProcessCloseCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerProcessWriteCode, writableStreamDefaultControllerProcessWrite, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerProcessWriteCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerStartCode, writableStreamDefaultControllerStart, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerStartCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultControllerWriteCode, writableStreamDefaultControllerWrite, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultControllerWriteCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterAbortCode, writableStreamDefaultWriterAbort, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterAbortCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterCloseCode, writableStreamDefaultWriterClose, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterCloseCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterCloseWithErrorPropagationCode, writableStreamDefaultWriterCloseWithErrorPropagation, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterCloseWithErrorPropagationCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterEnsureClosedPromiseRejectedCode, writableStreamDefaultWriterEnsureClosedPromiseRejected, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterEnsureClosedPromiseRejectedCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterEnsureReadyPromiseRejectedCode, writableStreamDefaultWriterEnsureReadyPromiseRejected, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterEnsureReadyPromiseRejectedCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterGetDesiredSizeCode, writableStreamDefaultWriterGetDesiredSize, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterGetDesiredSizeCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterReleaseCode, writableStreamDefaultWriterRelease, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterReleaseCodeLength) \ + macro(writableStreamInternalsWritableStreamDefaultWriterWriteCode, writableStreamDefaultWriterWrite, ASCIILiteral(), s_writableStreamInternalsWritableStreamDefaultWriterWriteCodeLength) \ + macro(writableStreamInternalsWritableStreamFinishErroringCode, writableStreamFinishErroring, ASCIILiteral(), s_writableStreamInternalsWritableStreamFinishErroringCodeLength) \ + macro(writableStreamInternalsWritableStreamFinishInFlightCloseCode, writableStreamFinishInFlightClose, ASCIILiteral(), s_writableStreamInternalsWritableStreamFinishInFlightCloseCodeLength) \ + macro(writableStreamInternalsWritableStreamFinishInFlightCloseWithErrorCode, writableStreamFinishInFlightCloseWithError, ASCIILiteral(), s_writableStreamInternalsWritableStreamFinishInFlightCloseWithErrorCodeLength) \ + macro(writableStreamInternalsWritableStreamFinishInFlightWriteCode, writableStreamFinishInFlightWrite, ASCIILiteral(), s_writableStreamInternalsWritableStreamFinishInFlightWriteCodeLength) \ + macro(writableStreamInternalsWritableStreamFinishInFlightWriteWithErrorCode, writableStreamFinishInFlightWriteWithError, ASCIILiteral(), s_writableStreamInternalsWritableStreamFinishInFlightWriteWithErrorCodeLength) \ + macro(writableStreamInternalsWritableStreamHasOperationMarkedInFlightCode, writableStreamHasOperationMarkedInFlight, ASCIILiteral(), s_writableStreamInternalsWritableStreamHasOperationMarkedInFlightCodeLength) \ + macro(writableStreamInternalsWritableStreamMarkCloseRequestInFlightCode, writableStreamMarkCloseRequestInFlight, ASCIILiteral(), s_writableStreamInternalsWritableStreamMarkCloseRequestInFlightCodeLength) \ + macro(writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCode, writableStreamMarkFirstWriteRequestInFlight, ASCIILiteral(), s_writableStreamInternalsWritableStreamMarkFirstWriteRequestInFlightCodeLength) \ + macro(writableStreamInternalsWritableStreamRejectCloseAndClosedPromiseIfNeededCode, writableStreamRejectCloseAndClosedPromiseIfNeeded, ASCIILiteral(), s_writableStreamInternalsWritableStreamRejectCloseAndClosedPromiseIfNeededCodeLength) \ + macro(writableStreamInternalsWritableStreamStartErroringCode, writableStreamStartErroring, ASCIILiteral(), s_writableStreamInternalsWritableStreamStartErroringCodeLength) \ + macro(writableStreamInternalsWritableStreamUpdateBackpressureCode, writableStreamUpdateBackpressure, ASCIILiteral(), s_writableStreamInternalsWritableStreamUpdateBackpressureCodeLength) \ + macro(writableStreamDefaultWriterWriteCode, write, ASCIILiteral(), s_writableStreamDefaultWriterWriteCodeLength) \ + macro(jsBufferPrototypeWriteBigInt64BECode, writeBigInt64BE, ASCIILiteral(), s_jsBufferPrototypeWriteBigInt64BECodeLength) \ + macro(jsBufferPrototypeWriteBigInt64LECode, writeBigInt64LE, ASCIILiteral(), s_jsBufferPrototypeWriteBigInt64LECodeLength) \ + macro(jsBufferPrototypeWriteBigUInt64BECode, writeBigUInt64BE, ASCIILiteral(), s_jsBufferPrototypeWriteBigUInt64BECodeLength) \ + macro(jsBufferPrototypeWriteBigUInt64LECode, writeBigUInt64LE, ASCIILiteral(), s_jsBufferPrototypeWriteBigUInt64LECodeLength) \ + macro(jsBufferPrototypeWriteDoubleBECode, writeDoubleBE, ASCIILiteral(), s_jsBufferPrototypeWriteDoubleBECodeLength) \ + macro(jsBufferPrototypeWriteDoubleLECode, writeDoubleLE, ASCIILiteral(), s_jsBufferPrototypeWriteDoubleLECodeLength) \ + macro(jsBufferPrototypeWriteFloatBECode, writeFloatBE, ASCIILiteral(), s_jsBufferPrototypeWriteFloatBECodeLength) \ + macro(jsBufferPrototypeWriteFloatLECode, writeFloatLE, ASCIILiteral(), s_jsBufferPrototypeWriteFloatLECodeLength) \ + macro(jsBufferPrototypeWriteInt16BECode, writeInt16BE, ASCIILiteral(), s_jsBufferPrototypeWriteInt16BECodeLength) \ + macro(jsBufferPrototypeWriteInt16LECode, writeInt16LE, ASCIILiteral(), s_jsBufferPrototypeWriteInt16LECodeLength) \ + macro(jsBufferPrototypeWriteInt32BECode, writeInt32BE, ASCIILiteral(), s_jsBufferPrototypeWriteInt32BECodeLength) \ + macro(jsBufferPrototypeWriteInt32LECode, writeInt32LE, ASCIILiteral(), s_jsBufferPrototypeWriteInt32LECodeLength) \ + macro(jsBufferPrototypeWriteInt8Code, writeInt8, ASCIILiteral(), s_jsBufferPrototypeWriteInt8CodeLength) \ + macro(jsBufferPrototypeWriteUInt16BECode, writeUInt16BE, ASCIILiteral(), s_jsBufferPrototypeWriteUInt16BECodeLength) \ + macro(jsBufferPrototypeWriteUInt16LECode, writeUInt16LE, ASCIILiteral(), s_jsBufferPrototypeWriteUInt16LECodeLength) \ + macro(jsBufferPrototypeWriteUInt32BECode, writeUInt32BE, ASCIILiteral(), s_jsBufferPrototypeWriteUInt32BECodeLength) \ + macro(jsBufferPrototypeWriteUInt32LECode, writeUInt32LE, ASCIILiteral(), s_jsBufferPrototypeWriteUInt32LECodeLength) \ + macro(jsBufferPrototypeWriteUInt8Code, writeUInt8, ASCIILiteral(), s_jsBufferPrototypeWriteUInt8CodeLength) \ + +#define WEBCORE_FOREACH_BUILTIN_FUNCTION_NAME(macro) \ + macro(abort) \ + macro(acquireReadableStreamDefaultReader) \ + macro(acquireWritableStreamDefaultWriter) \ + macro(asciiSlice) \ + macro(asciiWrite) \ + macro(assignDirectStream) \ + macro(base64Slice) \ + macro(base64Write) \ + macro(base64urlSlice) \ + macro(base64urlWrite) \ + macro(byobRequest) \ + macro(cancel) \ + macro(close) \ + macro(closed) \ + macro(consumeReadableStream) \ + macro(createEmptyReadableStream) \ + macro(createFIFO) \ + macro(createFulfilledPromise) \ + macro(createInternalWritableStreamFromUnderlyingSink) \ + macro(createNativeReadableStream) \ + macro(createReadableStreamController) \ + macro(createTransformStream) \ + macro(createWritableStream) \ + macro(dequeueValue) \ + macro(desiredSize) \ + macro(enqueue) \ + macro(enqueueValueWithSize) \ + macro(error) \ + macro(extractHighWaterMark) \ + macro(extractHighWaterMarkFromQueuingStrategyInit) \ + macro(extractSizeAlgorithm) \ + macro(from) \ + macro(getReader) \ + macro(handleDirectStreamError) \ + macro(handleDirectStreamErrorReject) \ + macro(hexSlice) \ + macro(hexWrite) \ + macro(highWaterMark) \ + macro(initializeArrayBufferStream) \ + macro(initializeBunBuffer) \ + macro(initializeByteLengthQueuingStrategy) \ + macro(initializeCountQueuingStrategy) \ + macro(initializeReadableByteStreamController) \ + macro(initializeReadableStream) \ + macro(initializeReadableStreamBYOBReader) \ + macro(initializeReadableStreamBYOBRequest) \ + macro(initializeReadableStreamDefaultController) \ + macro(initializeReadableStreamDefaultReader) \ + macro(initializeTransformStream) \ + macro(initializeTransformStreamDefaultController) \ + macro(initializeWritableStreamDefaultController) \ + macro(initializeWritableStreamDefaultWriter) \ + macro(initializeWritableStreamSlots) \ + macro(isCloseSentinel) \ + macro(isReadableByteStreamController) \ + macro(isReadableStream) \ + macro(isReadableStreamBYOBReader) \ + macro(isReadableStreamBYOBRequest) \ + macro(isReadableStreamDefaultController) \ + macro(isReadableStreamDefaultReader) \ + macro(isReadableStreamDisturbed) \ + macro(isReadableStreamLocked) \ + macro(isTransformStream) \ + macro(isTransformStreamDefaultController) \ + macro(isWritableStream) \ + macro(isWritableStreamDefaultWriter) \ + macro(isWritableStreamLocked) \ + macro(latin1Slice) \ + macro(latin1Write) \ + macro(lazyLoadStream) \ + macro(locked) \ + macro(markPromiseAsHandled) \ + macro(newQueue) \ + macro(noopDoneFunction) \ + macro(onCloseDirectStream) \ + macro(onDrainDirectStream) \ + macro(onPullDirectStream) \ + macro(onReadableStreamDirectControllerClosed) \ + macro(peekQueueValue) \ + macro(pipeThrough) \ + macro(pipeTo) \ + macro(pipeToClosingMustBePropagatedBackward) \ + macro(pipeToClosingMustBePropagatedForward) \ + macro(pipeToDoReadWrite) \ + macro(pipeToErrorsMustBePropagatedBackward) \ + macro(pipeToErrorsMustBePropagatedForward) \ + macro(pipeToFinalize) \ + macro(pipeToLoop) \ + macro(pipeToShutdown) \ + macro(pipeToShutdownWithAction) \ + macro(privateInitializeReadableByteStreamController) \ + macro(privateInitializeReadableStreamBYOBRequest) \ + macro(privateInitializeReadableStreamDefaultController) \ + macro(promiseInvokeOrFallbackOrNoop) \ + macro(promiseInvokeOrNoop) \ + macro(promiseInvokeOrNoopMethod) \ + macro(promiseInvokeOrNoopMethodNoCatch) \ + macro(promiseInvokeOrNoopNoCatch) \ + macro(read) \ + macro(readBigInt64BE) \ + macro(readBigInt64LE) \ + macro(readBigUInt64BE) \ + macro(readBigUInt64LE) \ + macro(readDoubleBE) \ + macro(readDoubleLE) \ + macro(readFloatBE) \ + macro(readFloatLE) \ + macro(readInt16BE) \ + macro(readInt16LE) \ + macro(readInt32BE) \ + macro(readInt32LE) \ + macro(readInt8) \ + macro(readMany) \ + macro(readUInt16BE) \ + macro(readUInt16LE) \ + macro(readUInt32BE) \ + macro(readUInt32LE) \ + macro(readUInt8) \ + macro(readable) \ + macro(readableByteStreamControllerCallPullIfNeeded) \ + macro(readableByteStreamControllerCancel) \ + macro(readableByteStreamControllerClearPendingPullIntos) \ + macro(readableByteStreamControllerClose) \ + macro(readableByteStreamControllerCommitDescriptor) \ + macro(readableByteStreamControllerConvertDescriptor) \ + macro(readableByteStreamControllerEnqueue) \ + macro(readableByteStreamControllerEnqueueChunk) \ + macro(readableByteStreamControllerError) \ + macro(readableByteStreamControllerFillDescriptorFromQueue) \ + macro(readableByteStreamControllerGetDesiredSize) \ + macro(readableByteStreamControllerHandleQueueDrain) \ + macro(readableByteStreamControllerInvalidateBYOBRequest) \ + macro(readableByteStreamControllerProcessPullDescriptors) \ + macro(readableByteStreamControllerPull) \ + macro(readableByteStreamControllerPullInto) \ + macro(readableByteStreamControllerRespond) \ + macro(readableByteStreamControllerRespondInClosedState) \ + macro(readableByteStreamControllerRespondInReadableState) \ + macro(readableByteStreamControllerRespondInternal) \ + macro(readableByteStreamControllerRespondWithNewView) \ + macro(readableByteStreamControllerShiftPendingDescriptor) \ + macro(readableByteStreamControllerShouldCallPull) \ + macro(readableStreamAddReadIntoRequest) \ + macro(readableStreamAddReadRequest) \ + macro(readableStreamBYOBReaderRead) \ + macro(readableStreamByteStreamControllerStart) \ + macro(readableStreamCancel) \ + macro(readableStreamClose) \ + macro(readableStreamDefaultControllerCallPullIfNeeded) \ + macro(readableStreamDefaultControllerCanCloseOrEnqueue) \ + macro(readableStreamDefaultControllerCancel) \ + macro(readableStreamDefaultControllerClose) \ + macro(readableStreamDefaultControllerEnqueue) \ + macro(readableStreamDefaultControllerError) \ + macro(readableStreamDefaultControllerGetDesiredSize) \ + macro(readableStreamDefaultControllerPull) \ + macro(readableStreamDefaultControllerShouldCallPull) \ + macro(readableStreamDefaultControllerStart) \ + macro(readableStreamDefaultReaderRead) \ + macro(readableStreamError) \ + macro(readableStreamFulfillReadIntoRequest) \ + macro(readableStreamFulfillReadRequest) \ + macro(readableStreamHasBYOBReader) \ + macro(readableStreamHasDefaultReader) \ + macro(readableStreamPipeTo) \ + macro(readableStreamPipeToWritableStream) \ + macro(readableStreamReaderGenericCancel) \ + macro(readableStreamReaderGenericInitialize) \ + macro(readableStreamReaderGenericRelease) \ + macro(readableStreamReaderKind) \ + macro(readableStreamTee) \ + macro(readableStreamTeeBranch1CancelFunction) \ + macro(readableStreamTeeBranch2CancelFunction) \ + macro(readableStreamTeePullFunction) \ + macro(readableStreamToArray) \ + macro(readableStreamToArrayPublic) \ + macro(readableStreamToBlob) \ + macro(readableStreamToJSON) \ + macro(readableStreamToText) \ + macro(ready) \ + macro(releaseLock) \ + macro(require) \ + macro(resetQueue) \ + macro(respond) \ + macro(respondWithNewView) \ + macro(setBigUint64) \ + macro(setUpTransformStreamDefaultController) \ + macro(setUpTransformStreamDefaultControllerFromTransformer) \ + macro(setUpWritableStreamDefaultController) \ + macro(setUpWritableStreamDefaultControllerFromUnderlyingSink) \ + macro(setUpWritableStreamDefaultWriter) \ + macro(setupReadableStreamDefaultController) \ + macro(shieldingPromiseResolve) \ + macro(size) \ + macro(slice) \ + macro(subarray) \ + macro(tee) \ + macro(terminate) \ + macro(toDictionary) \ + macro(toJSON) \ + macro(transferBufferToCurrentRealm) \ + macro(transformStreamDefaultControllerClearAlgorithms) \ + macro(transformStreamDefaultControllerEnqueue) \ + macro(transformStreamDefaultControllerError) \ + macro(transformStreamDefaultControllerPerformTransform) \ + macro(transformStreamDefaultControllerTerminate) \ + macro(transformStreamDefaultSinkAbortAlgorithm) \ + macro(transformStreamDefaultSinkCloseAlgorithm) \ + macro(transformStreamDefaultSinkWriteAlgorithm) \ + macro(transformStreamDefaultSourcePullAlgorithm) \ + macro(transformStreamError) \ + macro(transformStreamErrorWritableAndUnblockWrite) \ + macro(transformStreamSetBackpressure) \ + macro(ucs2Slice) \ + macro(ucs2Write) \ + macro(utf16leSlice) \ + macro(utf16leWrite) \ + macro(utf8Slice) \ + macro(utf8Write) \ + macro(validateAndNormalizeQueuingStrategy) \ + macro(view) \ + macro(writable) \ + macro(writableStreamAbort) \ + macro(writableStreamAbortForBindings) \ + macro(writableStreamAddWriteRequest) \ + macro(writableStreamClose) \ + macro(writableStreamCloseForBindings) \ + macro(writableStreamCloseQueuedOrInFlight) \ + macro(writableStreamDealWithRejection) \ + macro(writableStreamDefaultControllerAdvanceQueueIfNeeded) \ + macro(writableStreamDefaultControllerClearAlgorithms) \ + macro(writableStreamDefaultControllerClose) \ + macro(writableStreamDefaultControllerError) \ + macro(writableStreamDefaultControllerErrorIfNeeded) \ + macro(writableStreamDefaultControllerGetBackpressure) \ + macro(writableStreamDefaultControllerGetChunkSize) \ + macro(writableStreamDefaultControllerGetDesiredSize) \ + macro(writableStreamDefaultControllerProcessClose) \ + macro(writableStreamDefaultControllerProcessWrite) \ + macro(writableStreamDefaultControllerStart) \ + macro(writableStreamDefaultControllerWrite) \ + macro(writableStreamDefaultWriterAbort) \ + macro(writableStreamDefaultWriterClose) \ + macro(writableStreamDefaultWriterCloseWithErrorPropagation) \ + macro(writableStreamDefaultWriterEnsureClosedPromiseRejected) \ + macro(writableStreamDefaultWriterEnsureReadyPromiseRejected) \ + macro(writableStreamDefaultWriterGetDesiredSize) \ + macro(writableStreamDefaultWriterRelease) \ + macro(writableStreamDefaultWriterWrite) \ + macro(writableStreamFinishErroring) \ + macro(writableStreamFinishInFlightClose) \ + macro(writableStreamFinishInFlightCloseWithError) \ + macro(writableStreamFinishInFlightWrite) \ + macro(writableStreamFinishInFlightWriteWithError) \ + macro(writableStreamHasOperationMarkedInFlight) \ + macro(writableStreamMarkCloseRequestInFlight) \ + macro(writableStreamMarkFirstWriteRequestInFlight) \ + macro(writableStreamRejectCloseAndClosedPromiseIfNeeded) \ + macro(writableStreamStartErroring) \ + macro(writableStreamUpdateBackpressure) \ + macro(write) \ + macro(writeBigInt64BE) \ + macro(writeBigInt64LE) \ + macro(writeBigUInt64BE) \ + macro(writeBigUInt64LE) \ + macro(writeDoubleBE) \ + macro(writeDoubleLE) \ + macro(writeFloatBE) \ + macro(writeFloatLE) \ + macro(writeInt16BE) \ + macro(writeInt16LE) \ + macro(writeInt32BE) \ + macro(writeInt32LE) \ + macro(writeInt8) \ + macro(writeUInt16BE) \ + macro(writeUInt16LE) \ + macro(writeUInt32BE) \ + macro(writeUInt32LE) \ + macro(writeUInt8) \ + +#define WEBCORE_FOREACH_BUILTIN_FUNCTION_PRIVATE_GLOBAL_NAME(macro) \ + macro(assignDirectStream, readableStreamInternalsAssignDirectStream) \ + macro(consumeReadableStream, readableStreamConsumeReadableStream) \ + macro(createEmptyReadableStream, readableStreamCreateEmptyReadableStream) \ + macro(createFIFO, streamInternalsCreateFIFO) \ + macro(createNativeReadableStream, readableStreamCreateNativeReadableStream) \ + macro(readableStreamToArray, readableStreamReadableStreamToArray) \ + macro(readableStreamToArrayPublic, readableStreamReadableStreamToArrayPublic) \ + macro(readableStreamToBlob, readableStreamReadableStreamToBlob) \ + macro(readableStreamToJSON, readableStreamReadableStreamToJSON) \ + macro(readableStreamToText, readableStreamReadableStreamToText) \ + +#define DECLARE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \ + JSC::FunctionExecutable* codeName##Generator(JSC::VM&); + +WEBCORE_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR) +#undef DECLARE_BUILTIN_GENERATOR + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/WebCoreJSClientData.h b/src/bun.js/bindings/webcore/WebCoreJSClientData.h new file mode 100644 index 000000000..965f0bb98 --- /dev/null +++ b/src/bun.js/bindings/webcore/WebCoreJSClientData.h @@ -0,0 +1,3 @@ +#pragma once + +#include "BunClientData.h"
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp new file mode 100644 index 000000000..4c9660e26 --- /dev/null +++ b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2013-2021 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 "root.h" + +#include "WebCoreTypedArrayController.h" + +#include "JSDOMConvertBufferSource.h" + +#include "JSDOMGlobalObject.h" + +#include "JavaScriptCore/ArrayBuffer.h" + +#include "JavaScriptCore/JSArrayBuffer.h" + +namespace WebCore { + +WebCoreTypedArrayController::WebCoreTypedArrayController(bool allowAtomicsWait) + : m_allowAtomicsWait(allowAtomicsWait) +{ +} + +WebCoreTypedArrayController::~WebCoreTypedArrayController() = default; + +JSC::JSArrayBuffer* WebCoreTypedArrayController::toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer* buffer) +{ + return JSC::jsCast<JSC::JSArrayBuffer*>(WebCore::toJS(lexicalGlobalObject, JSC::jsCast<JSDOMGlobalObject*>(globalObject), buffer)); +} + +void WebCoreTypedArrayController::registerWrapper(JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer* native, JSC::JSArrayBuffer* wrapper) +{ + cacheWrapper(JSC::jsCast<JSDOMGlobalObject*>(globalObject)->world(), native, wrapper); +} + +bool WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread() +{ + return m_allowAtomicsWait; +} + +bool WebCoreTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::AbstractSlotVisitor& visitor, const char** reason) +{ + if (UNLIKELY(reason)) + *reason = "ArrayBuffer is opaque root"; + auto& wrapper = *JSC::jsCast<JSC::JSArrayBuffer*>(handle.slot()->asCell()); + return visitor.containsOpaqueRoot(wrapper.impl()); +} + +void WebCoreTypedArrayController::JSArrayBufferOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + auto& wrapper = *static_cast<JSC::JSArrayBuffer*>(handle.slot()->asCell()); + uncacheWrapper(*static_cast<DOMWrapperWorld*>(context), wrapper.impl(), &wrapper); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.h b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.h new file mode 100644 index 000000000..c689e019d --- /dev/null +++ b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013-2021 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. + */ + +#pragma once + +#include "JavaScriptCore/JSGlobalObject.h" +#include "JavaScriptCore/TypedArrayController.h" + +namespace WebCore { + +class WebCoreTypedArrayController : public JSC::TypedArrayController { +public: + WebCoreTypedArrayController(bool allowAtomicsWait); + virtual ~WebCoreTypedArrayController(); + + JSC::JSArrayBuffer* toJS(JSC::JSGlobalObject*, JSC::JSGlobalObject*, JSC::ArrayBuffer*) override; + void registerWrapper(JSC::JSGlobalObject*, ArrayBuffer*, JSC::JSArrayBuffer*) override; + bool isAtomicsWaitAllowedOnCurrentThread() override; + + JSC::WeakHandleOwner* wrapperOwner() { return &m_owner; } + +private: + class JSArrayBufferOwner : public JSC::WeakHandleOwner { + public: + bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, const char**) override; + void finalize(JSC::Handle<JSC::Unknown>, void* context) override; + }; + + JSArrayBufferOwner m_owner; + bool m_allowAtomicsWait; +}; + +} // namespace WebCore
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/WebSocket.cpp b/src/bun.js/bindings/webcore/WebSocket.cpp new file mode 100644 index 000000000..763668056 --- /dev/null +++ b/src/bun.js/bindings/webcore/WebSocket.cpp @@ -0,0 +1,1121 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2015-2016 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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 "WebSocket.h" +#include "headers.h" +// #include "Blob.h" +#include "CloseEvent.h" +// #include "ContentSecurityPolicy.h" +// #include "DOMWindow.h" +// #include "Document.h" +#include "Event.h" +#include "EventListener.h" +#include "EventNames.h" +// #include "Frame.h" +// #include "FrameLoader.h" +// #include "FrameLoaderClient.h" +// #include "InspectorInstrumentation.h" +// #include "Logging.h" +#include "MessageEvent.h" +// #include "MixedContentChecker.h" +// #include "ResourceLoadObserver.h" +// #include "ScriptController.h" +#include "ScriptExecutionContext.h" +// #include "SecurityOrigin.h" +// #include "SocketProvider.h" +// #include "ThreadableWebSocketChannel.h" +// #include "WebSocketChannel.h" +// #include "WorkerGlobalScope.h" +// #include "WorkerLoaderProxy.h" +// #include "WorkerThread.h" +#include <JavaScriptCore/ArrayBuffer.h> +#include <JavaScriptCore/ArrayBufferView.h> +#include <JavaScriptCore/ScriptCallStack.h> +#include <wtf/HashSet.h> +#include <wtf/HexNumber.h> +// #include <wtf/IsoMallocInlines.h> +#include <wtf/NeverDestroyed.h> +// #include <wtf/RunLoop.h> +#include <wtf/StdLibExtras.h> +#include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> + +#include <uws/src/App.h> + +// #if USE(WEB_THREAD) +// #include "WebCoreThreadRun.h" +// #endif +namespace WebCore { +WTF_MAKE_ISO_ALLOCATED_IMPL(WebSocket); + +static size_t getFramingOverhead(size_t payloadSize) +{ + static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header. + static const size_t hybiMaskingKeyLength = 4; // Every frame from client must have masking key. + static const size_t minimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; + static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0x10000; + size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength; + if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength) + overhead += 8; + else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength) + overhead += 2; + return overhead; +} + +const size_t maxReasonSizeInBytes = 123; + +static inline bool isValidProtocolCharacter(UChar character) +{ + // Hybi-10 says "(Subprotocol string must consist of) characters in the range U+0021 to U+007E not including + // separator characters as defined in [RFC2616]." + const UChar minimumProtocolCharacter = '!'; // U+0021. + const UChar maximumProtocolCharacter = '~'; // U+007E. + return character >= minimumProtocolCharacter && character <= maximumProtocolCharacter + && character != '"' && character != '(' && character != ')' && character != ',' && character != '/' + && !(character >= ':' && character <= '@') // U+003A - U+0040 (':', ';', '<', '=', '>', '?', '@'). + && !(character >= '[' && character <= ']') // U+005B - U+005D ('[', '\\', ']'). + && character != '{' && character != '}'; +} + +static bool isValidProtocolString(StringView protocol) +{ + if (protocol.isEmpty()) + return false; + for (auto codeUnit : protocol.codeUnits()) { + if (!isValidProtocolCharacter(codeUnit)) + return false; + } + return true; +} + +static String encodeProtocolString(const String& protocol) +{ + StringBuilder builder; + for (size_t i = 0; i < protocol.length(); i++) { + if (protocol[i] < 0x20 || protocol[i] > 0x7E) + builder.append("\\u", hex(protocol[i], 4)); + else if (protocol[i] == 0x5c) + builder.append("\\\\"); + else + builder.append(protocol[i]); + } + return builder.toString(); +} + +static String joinStrings(const Vector<String>& strings, const char* separator) +{ + StringBuilder builder; + for (size_t i = 0; i < strings.size(); ++i) { + if (i) + builder.append(separator); + builder.append(strings[i]); + } + return builder.toString(); +} + +static unsigned saturateAdd(unsigned a, unsigned b) +{ + if (std::numeric_limits<unsigned>::max() - a < b) + return std::numeric_limits<unsigned>::max(); + return a + b; +} + +ASCIILiteral WebSocket::subprotocolSeparator() +{ + return ", "_s; +} + +WebSocket::WebSocket(ScriptExecutionContext& context) + : ContextDestructionObserver(&context) + , m_subprotocol(emptyString()) + , m_extensions(emptyString()) +{ +} + +WebSocket::~WebSocket() +{ + + if (m_upgradeClient != nullptr) { + void* upgradeClient = m_upgradeClient; + if (m_isSecure) { + Bun__WebSocketHTTPSClient__cancel(upgradeClient); + } else { + Bun__WebSocketHTTPClient__cancel(upgradeClient); + } + } + + switch (m_connectedWebSocketKind) { + case ConnectedWebSocketKind::Client: { + Bun__WebSocketClient__finalize(this->m_connectedWebSocket.client); + break; + } + case ConnectedWebSocketKind::ClientSSL: { + Bun__WebSocketClientTLS__finalize(this->m_connectedWebSocket.clientSSL); + break; + } + case ConnectedWebSocketKind::Server: { + this->m_connectedWebSocket.server->end(None); + break; + } + case ConnectedWebSocketKind::ServerSSL: { + this->m_connectedWebSocket.serverSSL->end(None); + break; + } + default: { + break; + } + } +} + +ExceptionOr<Ref<WebSocket>> WebSocket::create(ScriptExecutionContext& context, const String& url) +{ + return create(context, url, Vector<String> {}); +} + +ExceptionOr<Ref<WebSocket>> WebSocket::create(ScriptExecutionContext& context, const String& url, const Vector<String>& protocols) +{ + if (url.isNull()) + return Exception { SyntaxError }; + + auto socket = adoptRef(*new WebSocket(context)); + // socket->suspendIfNeeded(); + + auto result = socket->connect(url, protocols); + // auto result = socket->connect(url, protocols); + + if (result.hasException()) + return result.releaseException(); + + return socket; +} + +ExceptionOr<Ref<WebSocket>> WebSocket::create(ScriptExecutionContext& context, const String& url, const String& protocol) +{ + return create(context, url, Vector<String> { 1, protocol }); +} + +ExceptionOr<void> WebSocket::connect(const String& url) +{ + return connect(url, Vector<String> {}); +} + +ExceptionOr<void> WebSocket::connect(const String& url, const String& protocol) +{ + return connect(url, Vector<String> { 1, protocol }); +} + +void WebSocket::failAsynchronously() +{ + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this] { + // We must block this connection. Instead of throwing an exception, we indicate this + // using the error event. But since this code executes as part of the WebSocket's + // constructor, we have to wait until the constructor has completed before firing the + // event; otherwise, users can't connect to the event. + this->dispatchErrorEventIfNeeded(); + // this->(); + // this->stop(); + // }); +} + +static String resourceName(const URL& url) +{ + auto path = url.path(); + auto result = makeString( + path, + path.isEmpty() ? "/" : "", + url.queryWithLeadingQuestionMark()); + ASSERT(!result.isEmpty()); + ASSERT(!result.contains(' ')); + return result; +} + +static String hostName(const URL& url, bool secure) +{ + ASSERT(url.protocolIs("wss") == secure); + if (url.port() && ((!secure && url.port().value() != 80) || (secure && url.port().value() != 443))) + return makeString(asASCIILowercase(url.host()), ':', url.port().value()); + return url.host().convertToASCIILowercase(); +} + +ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& protocols) +{ + LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); + m_url = URL { url }; + + ASSERT(scriptExecutionContext()); + auto& context = *scriptExecutionContext(); + + if (!m_url.isValid()) { + // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); + m_state = CLOSED; + return Exception { SyntaxError, makeString("Invalid url for WebSocket "_s, m_url.stringCenterEllipsizedToLength()) }; + } + + bool is_secure = m_url.protocolIs("wss"_s); + + if (!m_url.protocolIs("ws"_s) && !is_secure) { + // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); + m_state = CLOSED; + return Exception { SyntaxError, makeString("Wrong url scheme for WebSocket "_s, m_url.stringCenterEllipsizedToLength()) }; + } + if (m_url.hasFragmentIdentifier()) { + // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); + m_state = CLOSED; + return Exception { SyntaxError, makeString("URL has fragment component "_s, m_url.stringCenterEllipsizedToLength()) }; + } + + // ASSERT(context.contentSecurityPolicy()); + // auto& contentSecurityPolicy = *context.contentSecurityPolicy(); + + // contentSecurityPolicy.upgradeInsecureRequestIfNeeded(m_url, ContentSecurityPolicy::InsecureRequestType::Load); + + // if (!portAllowed(m_url)) { + // String message; + // if (m_url.port()) + // message = makeString("WebSocket port ", m_url.port().value(), " blocked"); + // else + // message = "WebSocket without port blocked"_s; + // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, message); + // failAsynchronously(); + // return {}; + // } + + // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. + // if (!context.shouldBypassMainWorldContentSecurityPolicy() && !contentSecurityPolicy.allowConnectToSource(m_url)) { + // m_state = CLOSED; + + // // FIXME: Should this be throwing an exception? + // return Exception { SecurityError }; + // } + + // FIXME: There is a disagreement about restriction of subprotocols between WebSocket API and hybi-10 protocol + // draft. The former simply says "only characters in the range U+0021 to U+007E are allowed," while the latter + // imposes a stricter rule: "the elements MUST be non-empty strings with characters as defined in [RFC2616], + // and MUST all be unique strings." + // + // Here, we throw SyntaxError if the given protocols do not meet the latter criteria. This behavior does not + // comply with WebSocket API specification, but it seems to be the only reasonable way to handle this conflict. + for (auto& protocol : protocols) { + if (!isValidProtocolString(protocol)) { + // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); + m_state = CLOSED; + return Exception { SyntaxError, makeString("Wrong protocol for WebSocket '"_s, encodeProtocolString(protocol), "'"_s) }; + } + } + HashSet<String> visited; + for (auto& protocol : protocols) { + if (!visited.add(protocol).isNewEntry) { + // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); + m_state = CLOSED; + return Exception { SyntaxError, makeString("WebSocket protocols contain duplicates:"_s, encodeProtocolString(protocol), "'"_s) }; + } + } + + // RunLoop::main().dispatch([targetURL = m_url.isolatedCopy(), mainFrameURL = context.url().isolatedCopy()]() { + // ResourceLoadObserver::shared().logWebSocketLoading(targetURL, mainFrameURL); + // }); + + // if (is<Document>(context)) { + // Document& document = downcast<Document>(context); + // RefPtr<Frame> frame = document.frame(); + // // FIXME: make the mixed content check equivalent to the non-document mixed content check currently in WorkerThreadableWebSocketChannel::Bridge::connect() + // if (!frame || !MixedContentChecker::canRunInsecureContent(*frame, document.securityOrigin(), m_url)) { + // failAsynchronously(); + // return { }; + // } + // } + + String protocolString; + if (!protocols.isEmpty()) + protocolString = joinStrings(protocols, subprotocolSeparator()); + + ZigString host = Zig::toZigString(m_url.host()); + auto resource = resourceName(m_url); + ZigString path = Zig::toZigString(resource); + ZigString clientProtocolString = Zig::toZigString(protocolString); + uint16_t port = is_secure ? 443 : 80; + if (auto userPort = m_url.port()) { + port = userPort.value(); + } + + m_isSecure = is_secure; + if (is_secure) { + us_socket_context_t* ctx = scriptExecutionContext()->webSocketContext<true>(); + RELEASE_ASSERT(ctx); + this->m_upgradeClient = Bun__WebSocketHTTPSClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString); + } else { + us_socket_context_t* ctx = scriptExecutionContext()->webSocketContext<false>(); + RELEASE_ASSERT(ctx); + this->m_upgradeClient = Bun__WebSocketHTTPClient__connect(scriptExecutionContext()->jsGlobalObject(), ctx, this, &host, port, &path, &clientProtocolString); + } + + if (this->m_upgradeClient == nullptr) { + // context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, ); + m_state = CLOSED; + return Exception { SyntaxError, "WebSocket connection failed"_s }; + } + + m_state = CONNECTING; + + // #if ENABLE(INTELLIGENT_TRACKING_PREVENTION) + // auto reportRegistrableDomain = [domain = RegistrableDomain(m_url).isolatedCopy()](auto& context) mutable { + // if (auto* frame = downcast<Document>(context).frame()) + // frame->loader().client().didLoadFromRegistrableDomain(WTFMove(domain)); + // }; + // if (is<Document>(context)) + // reportRegistrableDomain(context); + // else + // downcast<WorkerGlobalScope>(context).thread().workerLoaderProxy().postTaskToLoader(WTFMove(reportRegistrableDomain)); + // #endif + + // m_pendingActivity = makePendingActivity(*this); + + return {}; +} + +ExceptionOr<void> WebSocket::send(const String& message) +{ + LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.utf8().data()); + if (m_state == CONNECTING) + return Exception { InvalidStateError }; + // No exception is raised if the connection was once established but has subsequently been closed. + if (m_state == CLOSING || m_state == CLOSED) { + auto utf8 = message.utf8(StrictConversionReplacingUnpairedSurrogatesWithFFFD); + size_t payloadSize = utf8.length(); + m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payloadSize); + m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize)); + return {}; + } + + if (message.length() > 0) + this->sendWebSocketString(message); + + return {}; +} + +ExceptionOr<void> WebSocket::send(ArrayBuffer& binaryData) +{ + LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, &binaryData); + if (m_state == CONNECTING) + return Exception { InvalidStateError }; + if (m_state == CLOSING || m_state == CLOSED) { + unsigned payloadSize = binaryData.byteLength(); + m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payloadSize); + m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize)); + return {}; + } + char* data = static_cast<char*>(binaryData.data()); + size_t length = binaryData.byteLength(); + if (length > 0) + this->sendWebSocketData(data, length); + return {}; +} + +ExceptionOr<void> WebSocket::send(ArrayBufferView& arrayBufferView) +{ + LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, &arrayBufferView); + + if (m_state == CONNECTING) + return Exception { InvalidStateError }; + if (m_state == CLOSING || m_state == CLOSED) { + unsigned payloadSize = arrayBufferView.byteLength(); + m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payloadSize); + m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize)); + return {}; + } + + auto buffer = arrayBufferView.unsharedBuffer().get(); + char* baseAddress = reinterpret_cast<char*>(buffer->data()) + arrayBufferView.byteOffset(); + size_t length = arrayBufferView.byteLength(); + if (length > 0) + this->sendWebSocketData(baseAddress, length); + + return {}; +} + +// ExceptionOr<void> WebSocket::send(Blob& binaryData) +// { +// LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData.url().stringCenterEllipsizedToLength().utf8().data()); +// if (m_state == CONNECTING) +// return Exception { InvalidStateError }; +// if (m_state == CLOSING || m_state == CLOSED) { +// unsigned payloadSize = static_cast<unsigned>(binaryData.size()); +// m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payloadSize); +// m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFramingOverhead(payloadSize)); +// return {}; +// } +// m_bufferedAmount = saturateAdd(m_bufferedAmount, binaryData.size()); +// ASSERT(m_channel); +// m_channel->send(binaryData); +// return {}; +// } + +void WebSocket::sendWebSocketData(const char* baseAddress, size_t length) +{ + uWS::OpCode opCode = uWS::OpCode::BINARY; + + switch (m_connectedWebSocketKind) { + case ConnectedWebSocketKind::Client: { + Bun__WebSocketClient__writeBinaryData(this->m_connectedWebSocket.client, reinterpret_cast<const unsigned char*>(baseAddress), length); + // this->m_connectedWebSocket.client->send({ baseAddress, length }, opCode); + // this->m_bufferedAmount = this->m_connectedWebSocket.client->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ClientSSL: { + Bun__WebSocketClientTLS__writeBinaryData(this->m_connectedWebSocket.clientSSL, reinterpret_cast<const unsigned char*>(baseAddress), length); + break; + } + case ConnectedWebSocketKind::Server: { + this->m_connectedWebSocket.server->send({ baseAddress, length }, opCode); + this->m_bufferedAmount = this->m_connectedWebSocket.server->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ServerSSL: { + this->m_connectedWebSocket.serverSSL->send({ baseAddress, length }, opCode); + this->m_bufferedAmount = this->m_connectedWebSocket.serverSSL->getBufferedAmount(); + break; + } + default: { + RELEASE_ASSERT_NOT_REACHED(); + } + } +} + +void WebSocket::sendWebSocketString(const String& message) +{ + + switch (m_connectedWebSocketKind) { + case ConnectedWebSocketKind::Client: { + auto zigStr = Zig::toZigString(message); + Bun__WebSocketClient__writeString(this->m_connectedWebSocket.client, &zigStr); + // this->m_connectedWebSocket.client->send({ baseAddress, length }, opCode); + // this->m_bufferedAmount = this->m_connectedWebSocket.client->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ClientSSL: { + auto zigStr = Zig::toZigString(message); + Bun__WebSocketClientTLS__writeString(this->m_connectedWebSocket.clientSSL, &zigStr); + break; + } + case ConnectedWebSocketKind::Server: { + auto utf8 = message.utf8(StrictConversionReplacingUnpairedSurrogatesWithFFFD); + this->m_connectedWebSocket.server->send({ utf8.data(), utf8.length() }, uWS::OpCode::TEXT); + this->m_bufferedAmount = this->m_connectedWebSocket.server->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ServerSSL: { + auto utf8 = message.utf8(StrictConversionReplacingUnpairedSurrogatesWithFFFD); + this->m_connectedWebSocket.serverSSL->send({ utf8.data(), utf8.length() }, uWS::OpCode::TEXT); + this->m_bufferedAmount = this->m_connectedWebSocket.serverSSL->getBufferedAmount(); + break; + } + default: { + RELEASE_ASSERT_NOT_REACHED(); + } + } +} + +ExceptionOr<void> WebSocket::close(std::optional<unsigned short> optionalCode, const String& reason) +{ + + int code = optionalCode ? optionalCode.value() : static_cast<int>(0); + if (code == 0) + LOG(Network, "WebSocket %p close() without code and reason", this); + else { + LOG(Network, "WebSocket %p close() code=%d reason='%s'", this, code, reason.utf8().data()); + // if (!(code == WebSocketChannel::CloseEventCodeNormalClosure || (WebSocketChannel::CloseEventCodeMinimumUserDefined <= code && code <= WebSocketChannel::CloseEventCodeMaximumUserDefined))) + // return Exception { InvalidAccessError }; + if (reason.length() > maxReasonSizeInBytes) { + // scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "WebSocket close message is too long."_s); + return Exception { SyntaxError, "WebSocket close message is too long."_s }; + } + } + + if (m_state == CLOSING || m_state == CLOSED) + return {}; + if (m_state == CONNECTING) { + m_state = CLOSING; + if (m_upgradeClient != nullptr) { + void* upgradeClient = m_upgradeClient; + m_upgradeClient = nullptr; + if (m_isSecure) { + Bun__WebSocketHTTPSClient__cancel(upgradeClient); + } else { + Bun__WebSocketHTTPClient__cancel(upgradeClient); + } + } + return {}; + } + m_state = CLOSING; + switch (m_connectedWebSocketKind) { + case ConnectedWebSocketKind::Client: { + ZigString reasonZigStr = Zig::toZigString(reason); + Bun__WebSocketClient__close(this->m_connectedWebSocket.client, code, &reasonZigStr); + // this->m_bufferedAmount = this->m_connectedWebSocket.client->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ClientSSL: { + ZigString reasonZigStr = Zig::toZigString(reason); + Bun__WebSocketClientTLS__close(this->m_connectedWebSocket.clientSSL, code, &reasonZigStr); + // this->m_bufferedAmount = this->m_connectedWebSocket.clientSSL->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::Server: { + // this->m_connectedWebSocket.server->end(code, { utf8.data(), utf8.length() }); + // this->m_bufferedAmount = this->m_connectedWebSocket.server->getBufferedAmount(); + break; + } + case ConnectedWebSocketKind::ServerSSL: { + // this->m_connectedWebSocket.serverSSL->end(code, { utf8.data(), utf8.length() }); + // this->m_bufferedAmount = this->m_connectedWebSocket.serverSSL->getBufferedAmount(); + break; + } + default: { + break; + } + } + this->m_connectedWebSocketKind = ConnectedWebSocketKind::None; + + return {}; +} + +const URL& WebSocket::url() const +{ + return m_url; +} + +WebSocket::State WebSocket::readyState() const +{ + return m_state; +} + +unsigned WebSocket::bufferedAmount() const +{ + return saturateAdd(m_bufferedAmount, m_bufferedAmountAfterClose); +} + +String WebSocket::protocol() const +{ + return m_subprotocol; +} + +String WebSocket::extensions() const +{ + return m_extensions; +} + +String WebSocket::binaryType() const +{ + switch (m_binaryType) { + // case BinaryType::Blob: + // return "blob"_s; + case BinaryType::ArrayBuffer: + return "arraybuffer"_s; + } + ASSERT_NOT_REACHED(); + return String(); +} + +ExceptionOr<void> WebSocket::setBinaryType(const String& binaryType) +{ + // if (binaryType == "blob") { + // m_binaryType = BinaryType::Blob; + // return {}; + // } + if (binaryType == "arraybuffer") { + m_binaryType = BinaryType::ArrayBuffer; + return {}; + } + // scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, "'" + binaryType + "' is not a valid value for binaryType; binaryType remains unchanged."); + return Exception { SyntaxError, makeString("'"_s, binaryType, "' is not a valid value for binaryType; binaryType remains unchanged."_s) }; +} + +EventTargetInterface WebSocket::eventTargetInterface() const +{ + return WebSocketEventTargetInterfaceType; +} + +ScriptExecutionContext* WebSocket::scriptExecutionContext() const +{ + return ContextDestructionObserver::scriptExecutionContext(); +} + +// void WebSocket::contextDestroyed() +// { +// LOG(Network, "WebSocket %p contextDestroyed()", this); +// ASSERT(!m_channel); +// ASSERT(m_state == CLOSED); +// // ActiveDOMObject::contextDestroyed(); +// } + +// void WebSocket::suspend(ReasonForSuspension reason) +// { +// // if (!m_channel) +// // return; + +// // if (reason == ReasonForSuspension::BackForwardCache) { +// // // This will cause didClose() to be called. +// // m_channel->fail("WebSocket is closed due to suspension."_s); +// // return; +// // } + +// // m_channel->suspend(); +// } + +// void WebSocket::resume() +// { +// // if (m_channel) +// // m_channel->resume(); +// } + +// void WebSocket::stop() +// { +// if (m_channel) +// m_channel->disconnect(); +// m_channel = nullptr; +// m_state = CLOSED; +// // ActiveDOMObject::stop(); +// // m_pendingActivity = nullptr; +// } + +// const char* WebSocket::activeDOMObjectName() const +// { +// return "WebSocket"; +// } + +void WebSocket::didConnect() +{ + LOG(Network, "WebSocket %p didConnect()", this); + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this] { + if (m_state == CLOSED) + return; + if (m_state != CONNECTING) { + didClose(0, 0, emptyString()); + return; + } + m_state = OPEN; + + if (auto* context = scriptExecutionContext()) { + if (this->hasEventListeners("open"_s)) { + // the main reason for dispatching on a separate tick is to handle when you haven't yet attached an event listener + dispatchEvent(Event::create(eventNames().openEvent, Event::CanBubble::No, Event::IsCancelable::No)); + } else { + context->postTask([this, protectedThis = Ref { *this }](ScriptExecutionContext& context) { + ASSERT(scriptExecutionContext()); + + // m_subprotocol = m_channel->subprotocol(); + // m_extensions = m_channel->extensions(); + protectedThis->dispatchEvent(Event::create(eventNames().openEvent, Event::CanBubble::No, Event::IsCancelable::No)); + // }); + }); + } + } +} + +void WebSocket::didReceiveMessage(String&& message) +{ + LOG(Network, "WebSocket %p didReceiveMessage() Text message '%s'", this, message.utf8().data()); + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, message = WTFMove(message)]() mutable { + if (m_state != OPEN) + return; + + // if (UNLIKELY(InspectorInstrumentation::hasFrontends())) { + // if (auto* inspector = m_channel->channelInspector()) { + // auto utf8Message = message.utf8(); + // inspector->didReceiveWebSocketFrame(WebSocketChannelInspector::createFrame(utf8Message.dataAsUInt8Ptr(), utf8Message.length(), WebSocketFrame::OpCode::OpCodeText)); + // } + // } + + if (this->hasEventListeners("message"_s)) { + // the main reason for dispatching on a separate tick is to handle when you haven't yet attached an event listener + dispatchEvent(MessageEvent::create(WTFMove(message), m_url.string())); + return; + } + + if (auto* context = scriptExecutionContext()) { + + context->postTask([this, message_ = message, protectedThis = Ref { *this }](ScriptExecutionContext& context) { + ASSERT(scriptExecutionContext()); + protectedThis->dispatchEvent(MessageEvent::create(message_, protectedThis->m_url.string())); + }); + } + + // }); +} + +void WebSocket::didReceiveBinaryData(Vector<uint8_t>&& binaryData) +{ + LOG(Network, "WebSocket %p didReceiveBinaryData() %u byte binary message", this, static_cast<unsigned>(binaryData.size())); + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, binaryData = WTFMove(binaryData)]() mutable { + if (m_state != OPEN) + return; + + // if (UNLIKELY(InspectorInstrumentation::hasFrontends())) { + // if (auto* inspector = m_channel->channelInspector()) + // inspector->didReceiveWebSocketFrame(WebSocketChannelInspector::createFrame(binaryData.data(), binaryData.size(), WebSocketFrame::OpCode::OpCodeBinary)); + // } + + switch (m_binaryType) { + // case BinaryType::Blob: + // // FIXME: We just received the data from NetworkProcess, and are sending it back. This is inefficient. + // dispatchEvent(MessageEvent::create(Blob::create(scriptExecutionContext(), WTFMove(binaryData), emptyString()), SecurityOrigin::create(m_url)->toString())); + // break; + case BinaryType::ArrayBuffer: { + if (this->hasEventListeners("message"_s)) { + // the main reason for dispatching on a separate tick is to handle when you haven't yet attached an event listener + dispatchEvent(MessageEvent::create(ArrayBuffer::create(binaryData.data(), binaryData.size()), m_url.string())); + return; + } + + if (auto* context = scriptExecutionContext()) { + context->postTask([this, binaryData = binaryData, protectedThis = Ref { *this }](ScriptExecutionContext& context) { + ASSERT(scriptExecutionContext()); + protectedThis->dispatchEvent(MessageEvent::create(ArrayBuffer::create(binaryData.data(), binaryData.size()), m_url.string())); + }); + } + + break; + } + } + // }); +} + +void WebSocket::didReceiveMessageError(WTF::StringImpl::StaticStringImpl* reason) +{ + LOG(Network, "WebSocket %p didReceiveErrorMessage()", this); + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, reason = WTFMove(reason)] { + if (m_state == CLOSED) + return; + m_state = CLOSED; + if (auto* context = scriptExecutionContext()) { + context->postTask([this, reason, protectedThis = Ref { *this }](ScriptExecutionContext& context) { + ASSERT(scriptExecutionContext()); + // if (UNLIKELY(InspectorInstrumentation::hasFrontends())) { + // if (auto* inspector = m_channel->channelInspector()) + // inspector->didReceiveWebSocketFrameError(reason); + // } + + // FIXME: As per https://html.spec.whatwg.org/multipage/web-sockets.html#feedback-from-the-protocol:concept-websocket-closed, we should synchronously fire a close event. + dispatchEvent(CloseEvent::create(false, 0, WTF::String(reason))); + }); + } +} + +void WebSocket::didUpdateBufferedAmount(unsigned bufferedAmount) +{ + LOG(Network, "WebSocket %p didUpdateBufferedAmount() New bufferedAmount is %u", this, bufferedAmount); + if (m_state == CLOSED) + return; + m_bufferedAmount = bufferedAmount; +} + +void WebSocket::didStartClosingHandshake() +{ + LOG(Network, "WebSocket %p didStartClosingHandshake()", this); + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this] { + if (m_state == CLOSED) + return; + m_state = CLOSING; + // }); +} + +void WebSocket::didClose(unsigned unhandledBufferedAmount, unsigned short code, const String& reason) +{ + LOG(Network, "WebSocket %p didClose()", this); + if (this->m_connectedWebSocketKind == ConnectedWebSocketKind::None) + return; + + // queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, unhandledBufferedAmount, closingHandshakeCompletion, code, reason] { + // if (!m_channel) + // return; + + // if (UNLIKELY(InspectorInstrumentation::hasFrontends())) { + // if (auto* inspector = m_channel->channelInspector()) { + // WebSocketFrame closingFrame(WebSocketFrame::OpCodeClose, true, false, false); + // inspector->didReceiveWebSocketFrame(closingFrame); + // inspector->didCloseWebSocket(); + // } + // } + + bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && code != 0; // WebSocketChannel::CloseEventCodeAbnormalClosure; + m_state = CLOSED; + m_bufferedAmount = unhandledBufferedAmount; + ASSERT(scriptExecutionContext()); + this->m_connectedWebSocketKind = ConnectedWebSocketKind::None; + this->m_upgradeClient = nullptr; + + if (auto* context = scriptExecutionContext()) { + context->postTask([this, code, wasClean, reason, protectedThis = Ref { *this }](ScriptExecutionContext& context) { + ASSERT(scriptExecutionContext()); + protectedThis->dispatchEvent(CloseEvent::create(wasClean, code, reason)); + }); + } + + // m_pendingActivity = nullptr; + // }); +} + +// void WebSocket::didUpgradeURL() +// { +// ASSERT(m_url.protocolIs("ws")); +// m_url.setProtocol("wss"); +// } + +void WebSocket::dispatchErrorEventIfNeeded() +{ + if (m_dispatchedErrorEvent) + return; + + m_dispatchedErrorEvent = true; + + if (auto* context = scriptExecutionContext()) { + context->postTask([this, protectedThis = Ref { *this }](ScriptExecutionContext& context) { + ASSERT(scriptExecutionContext()); + protectedThis->dispatchEvent(Event::create(eventNames().errorEvent, Event::CanBubble::No, Event::IsCancelable::No)); + }); + } +} + +void WebSocket::didConnect(us_socket_t* socket, char* bufferedData, size_t bufferedDataSize) +{ + this->m_upgradeClient = nullptr; + if (m_isSecure) { + us_socket_context_t* ctx = (us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<true, false>(); + this->m_connectedWebSocket.clientSSL = Bun__WebSocketClientTLS__init(this, socket, ctx, this->scriptExecutionContext()->jsGlobalObject()); + this->m_connectedWebSocketKind = ConnectedWebSocketKind::ClientSSL; + } else { + us_socket_context_t* ctx = (us_socket_context_t*)this->scriptExecutionContext()->connnectedWebSocketContext<false, false>(); + this->m_connectedWebSocket.client = Bun__WebSocketClient__init(this, socket, ctx, this->scriptExecutionContext()->jsGlobalObject()); + this->m_connectedWebSocketKind = ConnectedWebSocketKind::Client; + } + + this->didConnect(); +} +void WebSocket::didFailWithErrorCode(int32_t code) +{ + if (m_state == CLOSED) + return; + + this->m_upgradeClient = nullptr; + this->m_connectedWebSocketKind = ConnectedWebSocketKind::None; + this->m_connectedWebSocket.client = nullptr; + + switch (code) { + // cancel + case 0: { + break; + } + // invalid_response + case 1: { + auto message = MAKE_STATIC_STRING_IMPL("Invalid response"); + didReceiveMessageError(message); + break; + } + // expected_101_status_code + case 2: { + auto message = MAKE_STATIC_STRING_IMPL("Expected 101 status code"); + didReceiveMessageError(message); + break; + } + // missing_upgrade_header + case 3: { + auto message = MAKE_STATIC_STRING_IMPL("Missing upgrade header"); + didReceiveMessageError(message); + break; + } + // missing_connection_header + case 4: { + auto message = MAKE_STATIC_STRING_IMPL("Missing connection header"); + didReceiveMessageError(message); + break; + } + // missing_websocket_accept_header + case 5: { + auto message = MAKE_STATIC_STRING_IMPL("Missing websocket accept header"); + didReceiveMessageError(message); + break; + } + // invalid_upgrade_header + case 6: { + auto message = MAKE_STATIC_STRING_IMPL("Invalid upgrade header"); + didReceiveMessageError(message); + break; + } + // invalid_connection_header + case 7: { + auto message = MAKE_STATIC_STRING_IMPL("Invalid connection header"); + didReceiveMessageError(message); + break; + } + // invalid_websocket_version + case 8: { + auto message = MAKE_STATIC_STRING_IMPL("Invalid websocket version"); + didReceiveMessageError(message); + break; + } + // mismatch_websocket_accept_header + case 9: { + auto message = MAKE_STATIC_STRING_IMPL("Mismatch websocket accept header"); + didReceiveMessageError(message); + break; + } + // missing_client_protocol + case 10: { + auto message = MAKE_STATIC_STRING_IMPL("Missing client protocol"); + didReceiveMessageError(message); + break; + } + // mismatch_client_protocol + case 11: { + auto message = MAKE_STATIC_STRING_IMPL("Mismatch client protocol"); + didReceiveMessageError(message); + break; + } + // timeout + case 12: { + auto message = MAKE_STATIC_STRING_IMPL("Timeout"); + didReceiveMessageError(message); + break; + } + // closed + case 13: { + auto message = MAKE_STATIC_STRING_IMPL("Closed by client"); + didReceiveMessageError(message); + break; + } + // failed_to_write + case 14: { + auto message = MAKE_STATIC_STRING_IMPL("Failed to write"); + didReceiveMessageError(message); + break; + } + // failed_to_connect + case 15: { + auto message = MAKE_STATIC_STRING_IMPL("Failed to connect"); + didReceiveMessageError(message); + break; + } + // headers_too_large + case 16: { + auto message = MAKE_STATIC_STRING_IMPL("Headers too large"); + didReceiveMessageError(message); + break; + } + // ended + case 17: { + auto message = MAKE_STATIC_STRING_IMPL("Closed by server"); + didReceiveMessageError(message); + break; + } + + // failed_to_allocate_memory + case 18: { + auto message = MAKE_STATIC_STRING_IMPL("Failed to allocate memory"); + didReceiveMessageError(message); + break; + } + // control_frame_is_fragmented + case 19: { + auto message = MAKE_STATIC_STRING_IMPL("Protocol error - control frame is fragmented"); + didReceiveMessageError(message); + break; + } + // invalid_control_frame + case 20: { + auto message = MAKE_STATIC_STRING_IMPL("Protocol error - invalid control frame"); + didReceiveMessageError(message); + break; + } + // compression_unsupported + case 21: { + auto message = MAKE_STATIC_STRING_IMPL("Compression not implemented yet"); + didReceiveMessageError(message); + break; + } + // unexpected_mask_from_server + case 22: { + auto message = MAKE_STATIC_STRING_IMPL("Protocol error - unexpected mask from server"); + didReceiveMessageError(message); + break; + } + // expected_control_frame + case 23: { + auto message = MAKE_STATIC_STRING_IMPL("Protocol error - expected control frame"); + didReceiveMessageError(message); + break; + } + // unsupported_control_frame + case 24: { + auto message = MAKE_STATIC_STRING_IMPL("Protocol error - unsupported control frame"); + didReceiveMessageError(message); + break; + } + // unexpected_opcode + case 25: { + auto message = MAKE_STATIC_STRING_IMPL("Protocol error - unexpected opcode"); + didReceiveMessageError(message); + break; + } + // invalid_utf8 + case 26: { + auto message = MAKE_STATIC_STRING_IMPL("Server sent invalid UTF8"); + didReceiveMessageError(message); + break; + } + } + + m_state = CLOSED; +} +} // namespace WebCore + +extern "C" void WebSocket__didConnect(WebCore::WebSocket* webSocket, us_socket_t* socket, char* bufferedData, size_t len) +{ + webSocket->didConnect(socket, bufferedData, len); +} +extern "C" void WebSocket__didCloseWithErrorCode(WebCore::WebSocket* webSocket, int32_t errorCode) +{ + webSocket->didFailWithErrorCode(errorCode); +} + +extern "C" void WebSocket__didReceiveText(WebCore::WebSocket* webSocket, bool clone, const ZigString* str) +{ + WTF::String wtf_str = Zig::toString(*str); + if (clone) { + wtf_str = wtf_str.isolatedCopy(); + } + + webSocket->didReceiveMessage(WTFMove(wtf_str)); +} +extern "C" void WebSocket__didReceiveBytes(WebCore::WebSocket* webSocket, uint8_t* bytes, size_t len) +{ + webSocket->didReceiveBinaryData({ bytes, len }); +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/WebSocket.h b/src/bun.js/bindings/webcore/WebSocket.h new file mode 100644 index 000000000..03c0d7709 --- /dev/null +++ b/src/bun.js/bindings/webcore/WebSocket.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2011 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +#pragma once + +#include "ContextDestructionObserver.h" +#include "EventTarget.h" +#include "ExceptionOr.h" +#include <wtf/URL.h> +#include <wtf/HashSet.h> +#include <wtf/Lock.h> + +namespace uWS { +template<bool, bool, typename> +struct WebSocket; +} + +namespace JSC { +class ArrayBuffer; +class ArrayBufferView; +} + +namespace WebCore { + +// class Blob; +class WebSocket final : public RefCounted<WebSocket>, public EventTargetWithInlineData, public ContextDestructionObserver { + WTF_MAKE_ISO_ALLOCATED(WebSocket); + +public: + static ASCIILiteral subprotocolSeparator(); + + static ExceptionOr<Ref<WebSocket>> create(ScriptExecutionContext&, const String& url); + static ExceptionOr<Ref<WebSocket>> create(ScriptExecutionContext&, const String& url, const String& protocol); + static ExceptionOr<Ref<WebSocket>> create(ScriptExecutionContext&, const String& url, const Vector<String>& protocols); + ~WebSocket(); + + enum State { + CONNECTING = 0, + OPEN = 1, + CLOSING = 2, + CLOSED = 3, + + }; + + ExceptionOr<void> connect(const String& url); + ExceptionOr<void> connect(const String& url, const String& protocol); + ExceptionOr<void> connect(const String& url, const Vector<String>& protocols); + + ExceptionOr<void> send(const String& message); + ExceptionOr<void> send(JSC::ArrayBuffer&); + ExceptionOr<void> send(JSC::ArrayBufferView&); + // ExceptionOr<void> send(Blob&); + + ExceptionOr<void> close(std::optional<unsigned short> code, const String& reason); + + const URL& url() const; + State readyState() const; + unsigned bufferedAmount() const; + + String protocol() const; + String extensions() const; + + String binaryType() const; + ExceptionOr<void> setBinaryType(const String&); + + ScriptExecutionContext* scriptExecutionContext() const final; + + using RefCounted::deref; + using RefCounted::ref; + void didConnect(); + void didClose(unsigned unhandledBufferedAmount, unsigned short code, const String& reason); + void didConnect(us_socket_t* socket, char* bufferedData, size_t bufferedDataSize); + void didFailWithErrorCode(int32_t code); + + void didReceiveMessage(String&& message); + void didReceiveData(const char* data, size_t length); + void didReceiveBinaryData(Vector<uint8_t>&&); + +private: + typedef union AnyWebSocket { + WebSocketClient* client; + WebSocketClientTLS* clientSSL; + uWS::WebSocket<false, true, WebCore::WebSocket*>* server; + uWS::WebSocket<true, true, WebCore::WebSocket*>* serverSSL; + } AnyWebSocket; + enum ConnectedWebSocketKind { + None, + Client, + ClientSSL, + Server, + ServerSSL + }; + + explicit WebSocket(ScriptExecutionContext&); + explicit WebSocket(ScriptExecutionContext&, const String& url); + + void dispatchErrorEventIfNeeded(); + + // void contextDestroyed() final; + // void suspend(ReasonForSuspension) final; + // void resume() final; + // void stop() final; + // const char* activeDOMObjectName() const final; + + EventTargetInterface eventTargetInterface() const final; + + void refEventTarget() final { ref(); } + void derefEventTarget() final { deref(); } + + void didReceiveMessageError(WTF::StringImpl::StaticStringImpl* reason); + void didUpdateBufferedAmount(unsigned bufferedAmount); + void didStartClosingHandshake(); + + void sendWebSocketString(const String& message); + void sendWebSocketData(const char* data, size_t length); + + void failAsynchronously(); + + enum class BinaryType { Blob, + ArrayBuffer }; + + State m_state { CONNECTING }; + URL m_url; + unsigned m_bufferedAmount { 0 }; + unsigned m_bufferedAmountAfterClose { 0 }; + BinaryType m_binaryType { BinaryType::ArrayBuffer }; + String m_subprotocol; + String m_extensions; + void* m_upgradeClient { nullptr }; + bool m_isSecure { false }; + AnyWebSocket m_connectedWebSocket { nullptr }; + ConnectedWebSocketKind m_connectedWebSocketKind { ConnectedWebSocketKind::None }; + + bool m_dispatchedErrorEvent { false }; + // RefPtr<PendingActivity<WebSocket>> m_pendingActivity; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/WebSocket.idl b/src/bun.js/bindings/webcore/WebSocket.idl new file mode 100644 index 000000000..4f65c90f3 --- /dev/null +++ b/src/bun.js/bindings/webcore/WebSocket.idl @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010, 2011 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER 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. + */ + +[ + ActiveDOMObject, + Exposed=(Window,Worker), + EnabledAtRuntime=WebSocketEnabled +] interface WebSocket : EventTarget { + [CallWith=CurrentScriptExecutionContext] constructor(USVString url, optional sequence<DOMString> protocols = []); + [CallWith=CurrentScriptExecutionContext] constructor(USVString url, DOMString protocol); + + readonly attribute USVString URL; // Lowercased .url is the one in the spec, but leaving .URL for compatibility reasons. + readonly attribute USVString url; + + const unsigned short CONNECTING = 0; + const unsigned short OPEN = 1; + const unsigned short CLOSING = 2; + const unsigned short CLOSED = 3; + readonly attribute unsigned short readyState; + + readonly attribute unsigned long bufferedAmount; + + attribute EventHandler onopen; + attribute EventHandler onmessage; + attribute EventHandler onerror; + attribute EventHandler onclose; + + readonly attribute DOMString? protocol; + readonly attribute DOMString? extensions; + + attribute DOMString binaryType; + + undefined send(ArrayBuffer data); + undefined send(ArrayBufferView data); + undefined send(Blob data); + undefined send(USVString data); + + undefined close(optional [Clamp] unsigned short code, optional USVString reason); +}; diff --git a/src/bun.js/bindings/webcore/WebSocketIdentifier.h b/src/bun.js/bindings/webcore/WebSocketIdentifier.h new file mode 100644 index 000000000..97884abd8 --- /dev/null +++ b/src/bun.js/bindings/webcore/WebSocketIdentifier.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 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 <wtf/ObjectIdentifier.h> + +namespace WebCore { + +enum WebSocketIdentifierType { }; +using WebSocketIdentifier = ObjectIdentifier<WebSocketIdentifierType>; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/WritableStream.cpp b/src/bun.js/bindings/webcore/WritableStream.cpp new file mode 100644 index 000000000..97d56b476 --- /dev/null +++ b/src/bun.js/bindings/webcore/WritableStream.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2021 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 "WritableStream.h" + +#include "JSWritableStream.h" +#include "JSWritableStreamSink.h" + +namespace WebCore { + +ExceptionOr<Ref<WritableStream>> WritableStream::create(JSC::JSGlobalObject& globalObject, std::optional<JSC::Strong<JSC::JSObject>>&& underlyingSink, std::optional<JSC::Strong<JSC::JSObject>>&& strategy) +{ + JSC::JSValue underlyingSinkValue = JSC::jsUndefined(); + if (underlyingSink) + underlyingSinkValue = underlyingSink->get(); + + JSC::JSValue strategyValue = JSC::jsUndefined(); + if (strategy) + strategyValue = strategy->get(); + + return create(globalObject, underlyingSinkValue, strategyValue); +} + +ExceptionOr<Ref<WritableStream>> WritableStream::create(JSC::JSGlobalObject& globalObject, JSC::JSValue underlyingSink, JSC::JSValue strategy) +{ + auto result = InternalWritableStream::createFromUnderlyingSink(*JSC::jsCast<JSDOMGlobalObject*>(&globalObject), underlyingSink, strategy); + if (result.hasException()) + return result.releaseException(); + + return adoptRef(*new WritableStream(result.releaseReturnValue())); +} + +ExceptionOr<Ref<WritableStream>> WritableStream::create(JSDOMGlobalObject& globalObject, Ref<WritableStreamSink>&& sink) +{ + return create(globalObject, toJSNewlyCreated(&globalObject, &globalObject, WTFMove(sink)), JSC::jsUndefined()); +} + +Ref<WritableStream> WritableStream::create(Ref<InternalWritableStream>&& internalWritableStream) +{ + return adoptRef(*new WritableStream(WTFMove(internalWritableStream))); +} + +WritableStream::WritableStream(Ref<InternalWritableStream>&& internalWritableStream) + : m_internalWritableStream(WTFMove(internalWritableStream)) +{ +} + +JSC::JSValue JSWritableStream::abort(JSC::JSGlobalObject& globalObject, JSC::CallFrame& callFrame) +{ + return wrapped().internalWritableStream().abort(globalObject, callFrame.argument(0)); +} + +JSC::JSValue JSWritableStream::close(JSC::JSGlobalObject& globalObject, JSC::CallFrame&) +{ + return wrapped().internalWritableStream().close(globalObject); +} + +JSC::JSValue JSWritableStream::getWriter(JSC::JSGlobalObject& globalObject, JSC::CallFrame&) +{ + return wrapped().internalWritableStream().getWriter(globalObject); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/WritableStream.h b/src/bun.js/bindings/webcore/WritableStream.h new file mode 100644 index 000000000..63a4b3377 --- /dev/null +++ b/src/bun.js/bindings/webcore/WritableStream.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 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. + */ + +#pragma once + +#include "root.h" + +#include "InternalWritableStream.h" +#include <JavaScriptCore/Strong.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + +class InternalWritableStream; +class WritableStreamSink; + +class WritableStream : public RefCounted<WritableStream> { +public: + static ExceptionOr<Ref<WritableStream>> create(JSC::JSGlobalObject&, std::optional<JSC::Strong<JSC::JSObject>>&&, std::optional<JSC::Strong<JSC::JSObject>>&&); + static ExceptionOr<Ref<WritableStream>> create(JSDOMGlobalObject&, Ref<WritableStreamSink>&&); + static Ref<WritableStream> create(Ref<InternalWritableStream>&&); + + ~WritableStream() = default; + + void lock() { m_internalWritableStream->lock(); } + bool locked() const { return m_internalWritableStream->locked(); } + + InternalWritableStream& internalWritableStream() { return m_internalWritableStream.get(); } + +private: + static ExceptionOr<Ref<WritableStream>> create(JSC::JSGlobalObject&, JSC::JSValue, JSC::JSValue); + explicit WritableStream(Ref<InternalWritableStream>&&); + + Ref<InternalWritableStream> m_internalWritableStream; +}; + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/WritableStream.idl b/src/bun.js/bindings/webcore/WritableStream.idl new file mode 100644 index 000000000..cd32d17f0 --- /dev/null +++ b/src/bun.js/bindings/webcore/WritableStream.idl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Canon Inc. + * Copyright (C) 2015 Igalia S.L. + * Copyright (C) 2020-2021 Apple Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions + * are required to be 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. + * 3. Neither the name of Canon Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CANON 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 CANON INC. AND 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. + */ + +[ + Exposed=*, + PrivateIdentifier, + PublicIdentifier, + SkipVTableValidation +] interface WritableStream { + // FIXME: Tighten parameter matching + [CallWith=CurrentGlobalObject] constructor(optional object underlyingSink, optional object strategy); + + readonly attribute boolean locked; + + [Custom, ReturnsOwnPromise] Promise<any> abort(optional any reason); + [Custom, ReturnsOwnPromise] Promise<any> close(); + [Custom] WritableStreamDefaultWriter getWriter(); +}; diff --git a/src/bun.js/bindings/webcore/WritableStreamSink.h b/src/bun.js/bindings/webcore/WritableStreamSink.h new file mode 100644 index 000000000..2caa86c39 --- /dev/null +++ b/src/bun.js/bindings/webcore/WritableStreamSink.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 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 "JSDOMPromiseDeferred.h" +#include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> + +namespace JSC { +class JSValue; +} + +namespace WebCore { + +class WritableStreamSink : public RefCounted<WritableStreamSink> { +public: + virtual ~WritableStreamSink() = default; + + virtual void write(ScriptExecutionContext&, JSC::JSValue, DOMPromiseDeferred<void>&&) = 0; + virtual void close() = 0; + virtual void error(String&&) = 0; +}; + +class SimpleWritableStreamSink : public WritableStreamSink { +public: + using WriteCallback = Function<ExceptionOr<void>(ScriptExecutionContext&, JSC::JSValue)>; + static Ref<SimpleWritableStreamSink> create(WriteCallback&& writeCallback) { return adoptRef(*new SimpleWritableStreamSink(WTFMove(writeCallback))); } + +private: + explicit SimpleWritableStreamSink(WriteCallback&&); + + void write(ScriptExecutionContext&, JSC::JSValue, DOMPromiseDeferred<void>&&) final; + void close() final { } + void error(String&&) final { } + + WriteCallback m_writeCallback; +}; + +inline SimpleWritableStreamSink::SimpleWritableStreamSink(WriteCallback&& writeCallback) + : m_writeCallback(WTFMove(writeCallback)) +{ +} + +inline void SimpleWritableStreamSink::write(ScriptExecutionContext& context, JSC::JSValue value, DOMPromiseDeferred<void>&& promise) +{ + promise.settle(m_writeCallback(context, value)); +} + +} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/config.h b/src/bun.js/bindings/webcore/config.h new file mode 100644 index 000000000..8d25cbc46 --- /dev/null +++ b/src/bun.js/bindings/webcore/config.h @@ -0,0 +1,6 @@ +#pragma once + +#ifndef WEBCORE_CONFIG +#define WEBCORE_CONFIG +#include "root.h" +#endif
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/weak_handle.cpp b/src/bun.js/bindings/webcore/weak_handle.cpp new file mode 100644 index 000000000..e210a5ba1 --- /dev/null +++ b/src/bun.js/bindings/webcore/weak_handle.cpp @@ -0,0 +1,21 @@ + +#include "weak_handle.h" +#include "JavaScriptCore/WeakHandleOwner.h" + +namespace JSC { +class SlotVisitor; +template<typename T> class Handle; + +// WeakHandleOwner::~WeakHandleOwner() +// { +// } + +// bool WeakHandleOwner::isReachableFromOpaqueRoots(Handle<Unknown>, void*, AbstractSlotVisitor&, const char**) +// { +// return false; +// } + +// void WeakHandleOwner::finalize(Handle<Unknown>, void*) +// { +// } +}
\ No newline at end of file diff --git a/src/bun.js/bindings/webcore/weak_handle.h b/src/bun.js/bindings/webcore/weak_handle.h new file mode 100644 index 000000000..22d6e702c --- /dev/null +++ b/src/bun.js/bindings/webcore/weak_handle.h @@ -0,0 +1,7 @@ +#pragma once + +#include "config.h" + +namespace JSC { + +} // namespace JSC |