From 211fd4fa06249f6d0205369903ec43dead337171 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Fri, 21 Mar 2025 03:40:45 -0800 Subject: [PATCH] deps: bump WebKit (#18349) --- cmake/tools/SetupWebKit.cmake | 2 +- .../webcore/SerializedScriptValue.cpp | 1 - src/bun.js/bindings/webcore/SharedBuffer.cpp | 683 ------------------ src/bun.js/bindings/webcore/SharedBuffer.h | 422 ----------- 4 files changed, 1 insertion(+), 1107 deletions(-) delete mode 100644 src/bun.js/bindings/webcore/SharedBuffer.cpp delete mode 100644 src/bun.js/bindings/webcore/SharedBuffer.h diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index d9db3e013f..0994ea7eae 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION 1b232942b0654e54e93dcf86bf6f5b581b37b1ae) + set(WEBKIT_VERSION 91bf2baced1b1309c7e05f19177c97fefec20976) endif() string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX) diff --git a/src/bun.js/bindings/webcore/SerializedScriptValue.cpp b/src/bun.js/bindings/webcore/SerializedScriptValue.cpp index 024ec3582b..38ec830717 100644 --- a/src/bun.js/bindings/webcore/SerializedScriptValue.cpp +++ b/src/bun.js/bindings/webcore/SerializedScriptValue.cpp @@ -62,7 +62,6 @@ // #include "JSWebCodecsEncodedVideoChunk.h" // #include "JSWebCodecsVideoFrame.h" #include "ScriptExecutionContext.h" -#include "SharedBuffer.h" // #include "WebCodecsEncodedVideoChunk.h" #include "WebCoreJSClientData.h" #include diff --git a/src/bun.js/bindings/webcore/SharedBuffer.cpp b/src/bun.js/bindings/webcore/SharedBuffer.cpp deleted file mode 100644 index ca3614f8ff..0000000000 --- a/src/bun.js/bindings/webcore/SharedBuffer.cpp +++ /dev/null @@ -1,683 +0,0 @@ -/* - * Copyright (C) 2006-2021 Apple Inc. All rights reserved. - * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. - * Copyright (C) 2015 Canon 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 "SharedBuffer.h" - -#include -#include -#include -#include -#include -#include -#include "headers-handwritten.h" - -namespace WebCore { - -Ref FragmentedSharedBuffer::create() -{ - return adoptRef(*new FragmentedSharedBuffer); -} - -Ref FragmentedSharedBuffer::create(const uint8_t* data, size_t size) -{ - return adoptRef(*new FragmentedSharedBuffer(data, size)); -} - -Ref FragmentedSharedBuffer::create(FileSystem::MappedFileData&& mappedFileData) -{ - return adoptRef(*new FragmentedSharedBuffer(WTFMove(mappedFileData))); -} - -Ref FragmentedSharedBuffer::create(Ref&& buffer) -{ - return adoptRef(*new FragmentedSharedBuffer(WTFMove(buffer))); -} - -Ref FragmentedSharedBuffer::create(Vector&& vector) -{ - return adoptRef(*new FragmentedSharedBuffer(WTFMove(vector))); -} - -Ref FragmentedSharedBuffer::create(DataSegment::Provider&& provider) -{ - return adoptRef(*new FragmentedSharedBuffer(WTFMove(provider))); -} - -FragmentedSharedBuffer::FragmentedSharedBuffer() = default; - -FragmentedSharedBuffer::FragmentedSharedBuffer(FileSystem::MappedFileData&& fileData) - : m_size(fileData.size()) -{ - m_segments.append({ 0, DataSegment::create(WTFMove(fileData)) }); -} - -FragmentedSharedBuffer::FragmentedSharedBuffer(DataSegment::Provider&& provider) - : m_size(provider.size()) -{ - m_segments.append({ 0, DataSegment::create(WTFMove(provider)) }); -} - -FragmentedSharedBuffer::FragmentedSharedBuffer(Ref&& buffer) -{ - append(WTFMove(buffer)); -} - -#if USE(GSTREAMER) -Ref FragmentedSharedBuffer::create(GstMappedOwnedBuffer& mappedBuffer) -{ - return adoptRef(*new FragmentedSharedBuffer(mappedBuffer)); -} - -FragmentedSharedBuffer::FragmentedSharedBuffer(GstMappedOwnedBuffer& mappedBuffer) - : m_size(mappedBuffer.size()) -{ - m_segments.append({ 0, DataSegment::create(&mappedBuffer) }); -} -#endif - -static Vector combineSegmentsData(const FragmentedSharedBuffer::DataSegmentVector& segments, size_t size) -{ - Vector combinedData; - combinedData.reserveInitialCapacity(size); - for (auto& segment : segments) - combinedData.append(std::span { segment.segment->data(), segment.segment->size() }); - ASSERT(combinedData.size() == size); - return combinedData; -} - -Ref FragmentedSharedBuffer::makeContiguous() const -{ - if (m_contiguous) - return Ref { *static_cast(const_cast(this)) }; - if (!m_segments.size()) - return SharedBuffer::create(); - if (m_segments.size() == 1) - return SharedBuffer::create(m_segments[0].segment.copyRef()); - auto combinedData = combineSegmentsData(m_segments, m_size); - return SharedBuffer::create(WTFMove(combinedData)); -} - -Vector FragmentedSharedBuffer::copyData() const -{ - Vector data; - data.reserveInitialCapacity(size()); - forEachSegment([&data](auto& span) { - data.unsafeAppendWithoutCapacityCheck(span.data(), span.size()); - }); - return data; -} - -Vector FragmentedSharedBuffer::takeData() -{ - if (m_segments.isEmpty()) - return {}; - - Vector combinedData; - if (hasOneSegment() && std::holds_alternative>(m_segments[0].segment->m_immutableData) && m_segments[0].segment->hasOneRef()) - combinedData = std::exchange(std::get>(const_cast(m_segments[0].segment.get()).m_immutableData), Vector()); - else - combinedData = combineSegmentsData(m_segments, m_size); - - clear(); - return combinedData; -} - -SharedBufferDataView FragmentedSharedBuffer::getSomeData(size_t position) const -{ - const DataSegmentVectorEntry* element = getSegmentForPosition(position); - return { element->segment.copyRef(), position - element->beginPosition }; -} - -Ref FragmentedSharedBuffer::getContiguousData(size_t position, size_t length) const -{ - if (position >= m_size) - return SharedBuffer::create(); - length = std::min(m_size - position, length); - const DataSegmentVectorEntry* element = getSegmentForPosition(position); - size_t offsetInSegment = position - element->beginPosition; - ASSERT(element->segment->size() > offsetInSegment); - if (element->segment->size() - offsetInSegment >= length) - return SharedBufferDataView { element->segment.copyRef(), offsetInSegment, length }.createSharedBuffer(); - Vector combinedData; - combinedData.reserveInitialCapacity(length); - combinedData.append(std::span { element->segment->data() + offsetInSegment, element->segment->size() - offsetInSegment }); - for (++element; combinedData.size() < length && element != m_segments.end(); element++) { - auto canCopy = std::min(length - combinedData.size(), element->segment->size()); - combinedData.append(std::span { element->segment->data(), canCopy }); - } - return SharedBuffer::create(WTFMove(combinedData)); -} - -const FragmentedSharedBuffer::DataSegmentVectorEntry* FragmentedSharedBuffer::getSegmentForPosition(size_t position) const -{ - RELEASE_ASSERT(position < m_size); - auto comparator = [](const size_t& position, const DataSegmentVectorEntry& entry) { - return position < entry.beginPosition; - }; - const DataSegmentVectorEntry* element = std::upper_bound(m_segments.begin(), m_segments.end(), position, comparator); - element--; // std::upper_bound gives a pointer to the element that is greater than position. We want the element just before that. - return element; -} - -String FragmentedSharedBuffer::toHexString() const -{ - StringBuilder stringBuilder; - forEachSegment([&](auto& segment) { - for (unsigned i = 0; i < segment.size(); ++i) - stringBuilder.append(pad('0', 2, hex(segment[i]))); - }); - return stringBuilder.toString(); -} - -RefPtr FragmentedSharedBuffer::tryCreateArrayBuffer() const -{ - auto arrayBuffer = ArrayBuffer::tryCreateUninitialized(static_cast(size()), 1); - if (!arrayBuffer) { - WTFLogAlways("SharedBuffer::tryCreateArrayBuffer Unable to create buffer. Requested size was %zu\n", size()); - return nullptr; - } - - size_t position = 0; - for (const auto& segment : m_segments) { - memcpy(static_cast(arrayBuffer->data()) + position, segment.segment->data(), segment.segment->size()); - position += segment.segment->size(); - } - - ASSERT(position == m_size); - ASSERT(internallyConsistent()); - return arrayBuffer; -} - -void FragmentedSharedBuffer::append(const FragmentedSharedBuffer& data) -{ - ASSERT(!m_contiguous); - m_segments.reserveCapacity(m_segments.size() + data.m_segments.size()); - for (const auto& element : data.m_segments) { - m_segments.unsafeAppendWithoutCapacityCheck(DataSegmentVectorEntry { m_size, element.segment.copyRef() }); - m_size += element.segment->size(); - } - ASSERT(internallyConsistent()); -} - -void FragmentedSharedBuffer::append(const uint8_t* data, size_t length) -{ - ASSERT(!m_contiguous); - m_segments.append({ m_size, DataSegment::create(Vector(std::span { data, length })) }); - m_size += length; - ASSERT(internallyConsistent()); -} - -void FragmentedSharedBuffer::append(Vector&& data) -{ - ASSERT(!m_contiguous); - auto dataSize = data.size(); - m_segments.append({ m_size, DataSegment::create(WTFMove(data)) }); - m_size += dataSize; - ASSERT(internallyConsistent()); -} - -void FragmentedSharedBuffer::clear() -{ - m_size = 0; - m_segments.clear(); - ASSERT(internallyConsistent()); -} - -Ref FragmentedSharedBuffer::copy() const -{ - if (m_contiguous) - return m_segments.size() ? SharedBuffer::create(m_segments[0].segment.copyRef()) : SharedBuffer::create(); - Ref clone = adoptRef(*new FragmentedSharedBuffer); - clone->m_size = m_size; - clone->m_segments.reserveInitialCapacity(m_segments.size()); - for (const auto& element : m_segments) - clone->m_segments.unsafeAppendWithoutCapacityCheck(DataSegmentVectorEntry { element.beginPosition, element.segment.copyRef() }); - ASSERT(clone->internallyConsistent()); - ASSERT(internallyConsistent()); - return clone; -} - -void FragmentedSharedBuffer::forEachSegment(const Function&)>& apply) const -{ - auto segments = m_segments; - for (auto& segment : segments) - segment.segment->iterate(apply); -} - -void DataSegment::iterate(const Function&)>& apply) const -{ -#if USE(FOUNDATION) - if (auto* data = std::get_if>(&m_immutableData)) - return iterate(data->get(), apply); -#endif - apply({ data(), size() }); -} - -void FragmentedSharedBuffer::forEachSegmentAsSharedBuffer(const Function&&)>& apply) const -{ - auto protectedThis = Ref { *this }; - for (auto& segment : m_segments) - apply(SharedBuffer::create(segment.segment.copyRef())); -} - -bool FragmentedSharedBuffer::startsWith(const std::span& prefix) const -{ - if (prefix.empty()) - return true; - - if (size() < prefix.size()) - return false; - - const uint8_t* prefixPtr = prefix.data(); - size_t remaining = prefix.size(); - for (auto& segment : m_segments) { - size_t amountToCompareThisTime = std::min(remaining, segment.segment->size()); - if (memcmp(prefixPtr, segment.segment->data(), amountToCompareThisTime)) - return false; - remaining -= amountToCompareThisTime; - if (!remaining) - return true; - prefixPtr += amountToCompareThisTime; - } - return false; -} - -Vector FragmentedSharedBuffer::read(size_t offset, size_t length) const -{ - Vector data; - if (offset >= size()) - return data; - auto remaining = std::min(length, size() - offset); - if (!remaining) - return data; - - data.reserveInitialCapacity(remaining); - auto* currentSegment = getSegmentForPosition(offset); - size_t offsetInSegment = offset - currentSegment->beginPosition; - size_t availableInSegment = std::min(currentSegment->segment->size() - offsetInSegment, remaining); - data.append(std::span { currentSegment->segment->data() + offsetInSegment, availableInSegment }); - - remaining -= availableInSegment; - - auto* afterLastSegment = end(); - - while (remaining && ++currentSegment != afterLastSegment) { - size_t lengthInSegment = std::min(currentSegment->segment->size(), remaining); - data.append(std::span { currentSegment->segment->data(), lengthInSegment }); - remaining -= lengthInSegment; - } - return data; -} - -void FragmentedSharedBuffer::copyTo(void* destination, size_t length) const -{ - return copyTo(destination, 0, length); -} - -void FragmentedSharedBuffer::copyTo(void* destination, size_t offset, size_t length) const -{ - ASSERT(length + offset <= size()); - if (offset >= size()) - return; - auto remaining = std::min(length, size() - offset); - if (!remaining) - return; - - auto segment = begin(); - if (offset >= segment->segment->size()) { - auto comparator = [](const size_t& position, const DataSegmentVectorEntry& entry) { - return position < entry.beginPosition; - }; - segment = std::upper_bound(segment, end(), offset, comparator); - segment--; // std::upper_bound gives a pointer to the segment that is greater than offset. We want the segment just before that. - } - auto destinationPtr = static_cast(destination); - - size_t positionInSegment = offset - segment->beginPosition; - size_t amountToCopyThisTime = std::min(remaining, segment->segment->size() - positionInSegment); - memcpy(destinationPtr, segment->segment->data() + positionInSegment, amountToCopyThisTime); - remaining -= amountToCopyThisTime; - if (!remaining) - return; - destinationPtr += amountToCopyThisTime; - - // If we reach here, there must be at least another segment available as we have content left to be fetched. - for (++segment; segment != end(); ++segment) { - size_t amountToCopyThisTime = std::min(remaining, segment->segment->size()); - memcpy(destinationPtr, segment->segment->data(), amountToCopyThisTime); - remaining -= amountToCopyThisTime; - if (!remaining) - return; - destinationPtr += amountToCopyThisTime; - } -} - -#if ASSERT_ENABLED -bool FragmentedSharedBuffer::internallyConsistent() const -{ - size_t position = 0; - for (const auto& element : m_segments) { - if (element.beginPosition != position) - return false; - position += element.segment->size(); - } - return position == m_size; -} -#endif // ASSERT_ENABLED - -#if !USE(CF) -void FragmentedSharedBuffer::hintMemoryNotNeededSoon() const -{ -} -#endif - -bool FragmentedSharedBuffer::operator==(const FragmentedSharedBuffer& other) const -{ - if (this == &other) - return true; - - if (m_size != other.m_size) - return false; - - auto thisIterator = begin(); - size_t thisOffset = 0; - auto otherIterator = other.begin(); - size_t otherOffset = 0; - - while (thisIterator != end() && otherIterator != other.end()) { - auto& thisSegment = thisIterator->segment.get(); - auto& otherSegment = otherIterator->segment.get(); - - if (&thisSegment == &otherSegment && !thisOffset && !otherOffset) { - ++thisIterator; - ++otherIterator; - continue; - } - - ASSERT(thisOffset <= thisSegment.size()); - ASSERT(otherOffset <= otherSegment.size()); - - size_t thisRemaining = thisSegment.size() - thisOffset; - size_t otherRemaining = otherSegment.size() - otherOffset; - size_t remaining = std::min(thisRemaining, otherRemaining); - - if (memcmp(thisSegment.data() + thisOffset, otherSegment.data() + otherOffset, remaining)) - return false; - - thisOffset += remaining; - otherOffset += remaining; - - if (thisOffset == thisSegment.size()) { - ++thisIterator; - thisOffset = 0; - } - - if (otherOffset == otherSegment.size()) { - ++otherIterator; - otherOffset = 0; - } - } - return true; -} - -SharedBuffer::SharedBuffer() -{ - m_contiguous = true; -} - -SharedBuffer::SharedBuffer(Ref&& segment) -{ - m_size = segment->size(); - m_segments.append({ 0, WTFMove(segment) }); - m_contiguous = true; -} - -SharedBuffer::SharedBuffer(Ref&& contiguousBuffer) -{ - ASSERT(contiguousBuffer->hasOneSegment() || contiguousBuffer->isEmpty()); - m_size = contiguousBuffer->size(); - if (contiguousBuffer->hasOneSegment()) - m_segments.append({ 0, contiguousBuffer->m_segments[0].segment.copyRef() }); - m_contiguous = true; -} - -SharedBuffer::SharedBuffer(FileSystem::MappedFileData&& data) - : FragmentedSharedBuffer(WTFMove(data)) -{ - m_contiguous = true; -} - -RefPtr SharedBuffer::createWithContentsOfFile(const String& filePath, FileSystem::MappedFileMode mappedFileMode, MayUseFileMapping mayUseFileMapping) -{ - if (mayUseFileMapping == MayUseFileMapping::Yes) { - bool mappingSuccess; - FileSystem::MappedFileData mappedFileData(filePath, mappedFileMode, mappingSuccess); - if (mappingSuccess) - return adoptRef(new SharedBuffer(WTFMove(mappedFileData))); - } - - auto buffer = FileSystem::readEntireFile(filePath); - if (!buffer) - return nullptr; - - return SharedBuffer::create(WTFMove(*buffer)); -} - -const uint8_t* SharedBuffer::data() const -{ - if (m_segments.isEmpty()) - return nullptr; - return m_segments[0].segment->data(); -} - -WTF::Persistence::Decoder SharedBuffer::decoder() const -{ - return { { data(), size() } }; -} - -Ref DataSegment::create(Vector&& data) -{ - data.shrinkToFit(); - return adoptRef(*new DataSegment(WTFMove(data))); -} - -#if USE(CF) -Ref DataSegment::create(RetainPtr&& data) -{ - return adoptRef(*new DataSegment(WTFMove(data))); -} -#endif - -#if USE(GLIB) -Ref DataSegment::create(GRefPtr&& data) -{ - return adoptRef(*new DataSegment(WTFMove(data))); -} -#endif - -#if USE(GSTREAMER) -Ref DataSegment::create(RefPtr&& data) -{ - return adoptRef(*new DataSegment(WTFMove(data))); -} -#endif - -Ref DataSegment::create(FileSystem::MappedFileData&& data) -{ - return adoptRef(*new DataSegment(WTFMove(data))); -} - -Ref DataSegment::create(Provider&& provider) -{ - return adoptRef(*new DataSegment(WTFMove(provider))); -} - -const uint8_t* DataSegment::data() const -{ - auto visitor = WTF::makeVisitor( - [](const Vector& data) -> const uint8_t* { return data.data(); }, -#if USE(CF) - [](const RetainPtr& data) -> const uint8_t* { return CFDataGetBytePtr(data.get()); }, -#endif -#if USE(GLIB) - [](const GRefPtr& data) -> const uint8_t* { return static_cast(g_bytes_get_data(data.get(), nullptr)); }, -#endif -#if USE(GSTREAMER) - [](const RefPtr& data) -> const uint8_t* { return data->data(); }, -#endif - [](const FileSystem::MappedFileData& data) -> const uint8_t* { return static_cast(data.span().data()); }, - [](const Provider& provider) -> const uint8_t* { return provider.data(); }); - return std::visit(visitor, m_immutableData); -} - -bool DataSegment::containsMappedFileData() const -{ - return std::holds_alternative(m_immutableData); -} - -size_t DataSegment::size() const -{ - auto visitor = WTF::makeVisitor( - [](const Vector& data) -> size_t { return data.size(); }, -#if USE(CF) - [](const RetainPtr& data) -> size_t { return CFDataGetLength(data.get()); }, -#endif -#if USE(GLIB) - [](const GRefPtr& data) -> size_t { return g_bytes_get_size(data.get()); }, -#endif -#if USE(GSTREAMER) - [](const RefPtr& data) -> size_t { return data->size(); }, -#endif - [](const FileSystem::MappedFileData& data) -> size_t { return data.span().size(); }, - [](const Provider& provider) -> size_t { return provider.size(); }); - return std::visit(visitor, m_immutableData); -} - -SharedBufferBuilder::SharedBufferBuilder(RefPtr&& buffer) -{ - if (!buffer) - return; - initialize(buffer.releaseNonNull()); -} - -SharedBufferBuilder& SharedBufferBuilder::operator=(RefPtr&& buffer) -{ - if (!buffer) { - m_buffer = nullptr; - return *this; - } - m_buffer = nullptr; - initialize(buffer.releaseNonNull()); - return *this; -} - -void SharedBufferBuilder::initialize(Ref&& buffer) -{ - ASSERT(!m_buffer); - // We do not want to take a reference to the SharedBuffer as all SharedBuffer should be immutable - // once created. - if (buffer->hasOneRef() && !buffer->isContiguous()) { - m_buffer = WTFMove(buffer); - return; - } - append(buffer); -} - -RefPtr SharedBufferBuilder::tryCreateArrayBuffer() const -{ - return m_buffer ? m_buffer->tryCreateArrayBuffer() : ArrayBuffer::tryCreate({}); -} - -Ref SharedBufferBuilder::take() -{ - return m_buffer ? m_buffer.releaseNonNull() : FragmentedSharedBuffer::create(); -} - -Ref SharedBufferBuilder::takeAsContiguous() -{ - return take()->makeContiguous(); -} - -RefPtr SharedBufferBuilder::takeAsArrayBuffer() -{ - if (!m_buffer) - return ArrayBuffer::tryCreate({}); - return take()->tryCreateArrayBuffer(); -} - -void SharedBufferBuilder::ensureBuffer() -{ - if (!m_buffer) - m_buffer = FragmentedSharedBuffer::create(); -} - -SharedBufferDataView::SharedBufferDataView(Ref&& segment, size_t positionWithinSegment, std::optional size) - : m_segment(WTFMove(segment)) - , m_positionWithinSegment(positionWithinSegment) - , m_size(size ? *size : m_segment->size() - positionWithinSegment) -{ - RELEASE_ASSERT(m_positionWithinSegment < m_segment->size()); - RELEASE_ASSERT(m_size <= m_segment->size() - m_positionWithinSegment); -} - -SharedBufferDataView::SharedBufferDataView(const SharedBufferDataView& other, size_t newSize) - : SharedBufferDataView(other.m_segment.copyRef(), other.m_positionWithinSegment, newSize) -{ -} - -Ref SharedBufferDataView::createSharedBuffer() const -{ - const Ref segment = m_segment; - return SharedBuffer::create(DataSegment::Provider { - [segment, data = data()]() { return data; }, - [size = size()]() { return size; } }); -} - -RefPtr utf8Buffer(const String& string) -{ - // Allocate a buffer big enough to hold all the characters. - const size_t length = string.length(); - if constexpr (String::MaxLength > std::numeric_limits::max() / 3) { - if (length > std::numeric_limits::max() / 3) - return nullptr; - } - - Vector buffer(length * 3); - WTF::Unicode::ConversionResult result; - if (length) { - if (string.is8Bit()) - result = WTF::Unicode::convert(string.span8(), spanReinterpretCast(buffer.mutableSpan())); - else - result = WTF::Unicode::convert(string.span16(), spanReinterpretCast(buffer.mutableSpan())); - } - - buffer.shrink(result.buffer.size()); - return SharedBuffer::create(WTFMove(buffer)); -} - -} // namespace WebCore diff --git a/src/bun.js/bindings/webcore/SharedBuffer.h b/src/bun.js/bindings/webcore/SharedBuffer.h deleted file mode 100644 index 9cffa0badd..0000000000 --- a/src/bun.js/bindings/webcore/SharedBuffer.h +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright (C) 2006-2021 Apple Inc. All rights reserved. - * Copyright (C) Research In Motion Limited 2009-2010. 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if USE(CF) -#include -#endif - -#if USE(GLIB) -#include -typedef struct _GBytes GBytes; -#endif - -#if USE(GSTREAMER) -#include "GStreamerCommon.h" -#endif - -#if USE(FOUNDATION) -OBJC_CLASS NSArray; -OBJC_CLASS NSData; -typedef struct OpaqueCMBlockBuffer *CMBlockBufferRef; -#endif - -namespace WTF { -namespace Persistence { -class Decoder; -} -} - -namespace WebCore { - -class SharedBuffer; -class SharedBufferDataView; - -// Data wrapped by a DataSegment should be immutable because it can be referenced by other objects. -// To modify or combine the data, allocate a new DataSegment. -class DataSegment : public ThreadSafeRefCounted { -public: - WEBCORE_EXPORT const uint8_t *data() const; - WEBCORE_EXPORT size_t size() const; - - WEBCORE_EXPORT static Ref create(Vector &&); - -#if USE(CF) - WEBCORE_EXPORT static Ref create(RetainPtr &&); -#endif -#if USE(GLIB) - WEBCORE_EXPORT static Ref create(GRefPtr &&); -#endif -#if USE(GSTREAMER) - WEBCORE_EXPORT static Ref create(RefPtr &&); -#endif - WEBCORE_EXPORT static Ref create(FileSystem::MappedFileData &&); - - struct Provider { - Function data; - Function size; - }; - - WEBCORE_EXPORT static Ref create(Provider &&); - -#if USE(FOUNDATION) - WEBCORE_EXPORT RetainPtr createNSData() const; -#endif - - WEBCORE_EXPORT bool containsMappedFileData() const; - -private: - void iterate(const Function &)> &apply) const; -#if USE(FOUNDATION) - void iterate(CFDataRef, const Function &)> &apply) const; -#endif - - explicit DataSegment(Vector &&data) - : m_immutableData(WTFMove(data)) - { - } -#if USE(CF) - explicit DataSegment(RetainPtr &&data) - : m_immutableData(WTFMove(data)) - { - } -#endif -#if USE(GLIB) - explicit DataSegment(GRefPtr &&data) - : m_immutableData(WTFMove(data)) - { - } -#endif -#if USE(GSTREAMER) - explicit DataSegment(RefPtr &&data) - : m_immutableData(WTFMove(data)) - { - } -#endif - explicit DataSegment(FileSystem::MappedFileData &&data) - : m_immutableData(WTFMove(data)) - { - } - explicit DataSegment(Provider &&provider) - : m_immutableData(WTFMove(provider)) - { - } - - std::variant, -#if USE(CF) - RetainPtr, -#endif -#if USE(GLIB) - GRefPtr, -#endif -#if USE(GSTREAMER) - RefPtr, -#endif - FileSystem::MappedFileData, - Provider> - m_immutableData; - friend class FragmentedSharedBuffer; - friend class SharedBuffer; // For createCFData -}; - -class FragmentedSharedBuffer : public ThreadSafeRefCounted { -public: - WEBCORE_EXPORT static Ref create(); - WEBCORE_EXPORT static Ref create(const uint8_t *, size_t); - static Ref create(const char *data, size_t size) { return create(reinterpret_cast(data), size); } - WEBCORE_EXPORT static Ref create(FileSystem::MappedFileData &&); - WEBCORE_EXPORT static Ref create(Ref &&); - WEBCORE_EXPORT static Ref create(Vector &&); - WEBCORE_EXPORT static Ref create(DataSegment::Provider &&); - -#if USE(FOUNDATION) - WEBCORE_EXPORT RetainPtr createNSDataArray() const; - WEBCORE_EXPORT static Ref create(NSData *); - WEBCORE_EXPORT RetainPtr createCMBlockBuffer() const; -#endif -#if USE(CF) - WEBCORE_EXPORT static Ref create(CFDataRef); -#endif - -#if USE(GLIB) - WEBCORE_EXPORT static Ref create(GBytes *); -#endif - -#if USE(GSTREAMER) - WEBCORE_EXPORT static Ref create(GstMappedOwnedBuffer &); -#endif - WEBCORE_EXPORT Vector copyData() const; - WEBCORE_EXPORT Vector read(size_t offset, size_t length) const; - - // Similar to copyData() but avoids copying and will take the data instead when it is safe (The FragmentedSharedBuffer is not shared). - Vector extractData(); - - WEBCORE_EXPORT RefPtr tryCreateArrayBuffer() const; - - size_t size() const { return m_size; } - bool isEmpty() const { return !size(); } - bool isContiguous() const { return m_contiguous; } - - WEBCORE_EXPORT Ref copy() const; - WEBCORE_EXPORT void copyTo(void *destination, size_t length) const; - WEBCORE_EXPORT void copyTo(void *destination, size_t offset, size_t length) const; - - WEBCORE_EXPORT void forEachSegment(const Function &)> &) const; - WEBCORE_EXPORT bool startsWith(const std::span &prefix) const; - WEBCORE_EXPORT void forEachSegmentAsSharedBuffer(const Function &&)> &) const; - - using DataSegment = WebCore::DataSegment; // To keep backward compatibility when using FragmentedSharedBuffer::DataSegment - - struct DataSegmentVectorEntry { - size_t beginPosition; - const Ref segment; - }; - using DataSegmentVector = Vector; - DataSegmentVector::const_iterator begin() const { return m_segments.begin(); } - DataSegmentVector::const_iterator end() const { return m_segments.end(); } - bool hasOneSegment() const { return m_segments.size() == 1; } - - // begin and end take O(1) time, this takes O(log(N)) time. - WEBCORE_EXPORT SharedBufferDataView getSomeData(size_t position) const; - WEBCORE_EXPORT Ref getContiguousData(size_t position, size_t length) const; - - WEBCORE_EXPORT String toHexString() const; - - void hintMemoryNotNeededSoon() const; - - WEBCORE_EXPORT bool operator==(const FragmentedSharedBuffer &) const; - bool operator!=(const FragmentedSharedBuffer &other) const { return !operator==(other); } - - WEBCORE_EXPORT Ref makeContiguous() const; - -protected: - friend class SharedBuffer; - - DataSegmentVector m_segments; - bool m_contiguous { false }; - - WEBCORE_EXPORT FragmentedSharedBuffer(); - explicit FragmentedSharedBuffer(const uint8_t *data, size_t size) { append(data, size); } - explicit FragmentedSharedBuffer(const char *data, size_t size) { append(data, size); } - explicit FragmentedSharedBuffer(Vector &&data) { append(WTFMove(data)); } - WEBCORE_EXPORT explicit FragmentedSharedBuffer(FileSystem::MappedFileData &&); - WEBCORE_EXPORT explicit FragmentedSharedBuffer(DataSegment::Provider &&); - WEBCORE_EXPORT explicit FragmentedSharedBuffer(Ref &&); -#if USE(CF) - WEBCORE_EXPORT explicit FragmentedSharedBuffer(CFDataRef); -#endif -#if USE(GLIB) - WEBCORE_EXPORT explicit FragmentedSharedBuffer(GBytes *); -#endif -#if USE(GSTREAMER) - WEBCORE_EXPORT explicit FragmentedSharedBuffer(GstMappedOwnedBuffer &); -#endif - size_t m_size { 0 }; - -private: - friend class SharedBufferBuilder; - WEBCORE_EXPORT void append(const FragmentedSharedBuffer &); - WEBCORE_EXPORT void append(const uint8_t *, size_t); - void append(std::span value) { append(value.data(), value.size()); } - void append(const char *data, size_t length) { append(reinterpret_cast(data), length); } - WEBCORE_EXPORT void append(Vector &&); -#if USE(FOUNDATION) - WEBCORE_EXPORT void append(NSData *); -#endif -#if USE(CF) - WEBCORE_EXPORT void append(CFDataRef); -#endif - - WEBCORE_EXPORT void clear(); - - // Combines all the segments into a Vector and returns that vector after clearing the FragmentedSharedBuffer. - WEBCORE_EXPORT Vector takeData(); - const DataSegmentVectorEntry *getSegmentForPosition(size_t position) const; - -#if ASSERT_ENABLED - bool internallyConsistent() const; -#endif -}; - -// A SharedBuffer is a FragmentedSharedBuffer that allows to directly access its content via the data() and related methods. -class SharedBuffer : public FragmentedSharedBuffer { -public: - template - static Ref create(Args &&...args) - { - if constexpr (!sizeof...(Args)) - return adoptRef(*new SharedBuffer()); - else if constexpr (sizeof...(Args) == 1 - && (std::is_same_v> && ...)) - return adoptRef(*new SharedBuffer(std::forward(args)...)); - else if constexpr (sizeof...(Args) == 1 - && (std::is_same_v, DataSegment> && ...)) - return adoptRef(*new SharedBuffer(std::forward(args)...)); - else { - auto buffer = FragmentedSharedBuffer::create(std::forward(args)...); - return adoptRef(*new SharedBuffer(WTFMove(buffer))); - } - } - - WEBCORE_EXPORT const uint8_t *data() const; - const char *dataAsCharPtr() const { return reinterpret_cast(data()); } - std::span dataAsSpanForContiguousData() const { return std::span(data(), isContiguous() ? size() : 0); } - WTF::Persistence::Decoder decoder() const; - - enum class MayUseFileMapping : bool { No, - Yes }; - WEBCORE_EXPORT static RefPtr createWithContentsOfFile(const String &filePath, FileSystem::MappedFileMode = FileSystem::MappedFileMode::Shared, MayUseFileMapping = MayUseFileMapping::Yes); - -#if USE(FOUNDATION) - WEBCORE_EXPORT RetainPtr createNSData() const; -#endif -#if USE(CF) - WEBCORE_EXPORT RetainPtr createCFData() const; -#endif -#if USE(GLIB) - WEBCORE_EXPORT GRefPtr createGBytes() const; -#endif - -private: - WEBCORE_EXPORT SharedBuffer(); - SharedBuffer(const DataSegment &segment) - : SharedBuffer(Ref { segment }) - { - } - WEBCORE_EXPORT explicit SharedBuffer(FileSystem::MappedFileData &&); - WEBCORE_EXPORT explicit SharedBuffer(Ref &&); - WEBCORE_EXPORT explicit SharedBuffer(Ref &&); - - WEBCORE_EXPORT static RefPtr createFromReadingFile(const String &filePath); -}; - -class SharedBufferBuilder { - WTF_MAKE_FAST_ALLOCATED; - -public: - SharedBufferBuilder() = default; - SharedBufferBuilder(SharedBufferBuilder &&) = default; - WEBCORE_EXPORT explicit SharedBufferBuilder(RefPtr &&); - explicit SharedBufferBuilder(Ref &&buffer) { initialize(WTFMove(buffer)); } - explicit SharedBufferBuilder(RefPtr &&buffer) - : SharedBufferBuilder(RefPtr { WTFMove(buffer) }) - { - } - explicit SharedBufferBuilder(Ref &&buffer) { initialize(WTFMove(buffer)); } - - template - SharedBufferBuilder(std::in_place_t, Args &&...args) - : m_buffer(FragmentedSharedBuffer::create(std::forward(args)...)) - { - } - - SharedBufferBuilder &operator=(SharedBufferBuilder &&) = default; - WEBCORE_EXPORT SharedBufferBuilder &operator=(RefPtr &&); - - template - void append(Args &&...args) - { - ensureBuffer(); - m_buffer->append(std::forward(args)...); - } - - explicit operator bool() const { return !isNull(); } - bool isNull() const { return !m_buffer; } - bool isEmpty() const { return m_buffer ? m_buffer->isEmpty() : true; } - - size_t size() const { return m_buffer ? m_buffer->size() : 0; } - - void reset() { m_buffer = nullptr; } - void empty() { m_buffer = FragmentedSharedBuffer::create(); } - - RefPtr get() const { return m_buffer; } - Ref copy() const { return m_buffer ? m_buffer->copy() : FragmentedSharedBuffer::create(); } - WEBCORE_EXPORT RefPtr tryCreateArrayBuffer() const; - - WEBCORE_EXPORT Ref take(); - WEBCORE_EXPORT Ref takeAsContiguous(); - WEBCORE_EXPORT RefPtr takeAsArrayBuffer(); - -private: - friend class ScriptBuffer; - friend class FetchBodyConsumer; - // Copy constructor should make a copy of the underlying SharedBuffer - // This is prevented by ScriptBuffer and FetchBodyConsumer classes (bug 234215) - // For now let the default constructor/operator take a reference to the - // SharedBuffer. - SharedBufferBuilder(const SharedBufferBuilder &) = default; - SharedBufferBuilder &operator=(const SharedBufferBuilder &) = default; - - WEBCORE_EXPORT void initialize(Ref &&); - WEBCORE_EXPORT void ensureBuffer(); - RefPtr m_buffer; -}; - -inline Vector FragmentedSharedBuffer::extractData() -{ - if (hasOneRef()) - return takeData(); - return copyData(); -} - -class SharedBufferDataView { -public: - WEBCORE_EXPORT SharedBufferDataView(Ref &&, size_t positionWithinSegment, std::optional newSize = std::nullopt); - WEBCORE_EXPORT SharedBufferDataView(const SharedBufferDataView &, size_t newSize); - size_t size() const { return m_size; } - const uint8_t *data() const { return m_segment->data() + m_positionWithinSegment; } - const char *dataAsCharPtr() const { return reinterpret_cast(data()); } - - WEBCORE_EXPORT Ref createSharedBuffer() const; -#if USE(FOUNDATION) - WEBCORE_EXPORT RetainPtr createNSData() const; -#endif -private: - const Ref m_segment; - const size_t m_positionWithinSegment; - const size_t m_size; -}; - -RefPtr utf8Buffer(const String &); - -} // namespace WebCore - -SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::SharedBuffer) -static bool isType(const WebCore::FragmentedSharedBuffer &buffer) { return buffer.isContiguous(); } -SPECIALIZE_TYPE_TRAITS_END()