diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-16 11:45:35 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-17 08:59:23 +0000 |
commit | 552906b0f222c5d5dd11b9fd73829d510980461a (patch) | |
tree | 3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/third_party/blink/renderer/core/typed_arrays | |
parent | 1b05827804eaf047779b597718c03e7d38344261 (diff) | |
download | qtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz |
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/typed_arrays')
25 files changed, 615 insertions, 1329 deletions
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn b/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn index 760dd95702e..4823bc8e45a 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn +++ b/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn @@ -6,15 +6,8 @@ import("//third_party/blink/renderer/core/core.gni") blink_core_sources("typed_arrays") { sources = [ - "array_buffer/array_buffer.cc", - "array_buffer/array_buffer.h", "array_buffer/array_buffer_contents.cc", "array_buffer/array_buffer_contents.h", - "array_buffer/array_buffer_view.cc", - "array_buffer/array_buffer_view.h", - "array_buffer/array_piece.cc", - "array_buffer/array_piece.h", - "array_buffer/typed_array.h", "array_buffer_view_helpers.h", "dom_array_buffer.cc", "dom_array_buffer.h", diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.cc deleted file mode 100644 index b35dac95a1e..00000000000 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2009 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 COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * 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 "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" - -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h" - -namespace blink { - -bool ArrayBuffer::Transfer(ArrayBufferContents& result) { - DCHECK(!IsShared()); - scoped_refptr<ArrayBuffer> keep_alive(this); - - if (is_detached_) { - result.Detach(); - return false; - } - - if (!contents_.Data()) { - // We transfer an empty ArrayBuffer, we can just allocate an empty content. - result = ArrayBufferContents(contents_.BackingStore()); - return true; - } - - bool all_views_are_detachable = true; - for (ArrayBufferView* i = first_view_; i; i = i->next_view_) { - if (!i->IsDetachable()) - all_views_are_detachable = false; - } - - if (all_views_are_detachable) { - contents_.Transfer(result); - - while (first_view_) { - ArrayBufferView* current = first_view_; - RemoveView(current); - current->Detach(); - } - - is_detached_ = true; - } else { - // TODO(https://crbug.com/763038): See original bug at - // https://crbug.com/254728. Copying the buffer instead of transferring is - // not spec compliant but was added for a WebAudio bug fix. The only time - // this branch is taken is when attempting to transfer an AudioBuffer's - // channel data ArrayBuffer. - contents_.CopyTo(result); - if (!result.Data()) - return false; - } - - return true; -} - -bool ArrayBuffer::ShareContentsWith(ArrayBufferContents& result) { - DCHECK(IsShared()); - scoped_refptr<ArrayBuffer> keep_alive(this); - - if (!contents_.BackingStore()) { - result.Detach(); - return false; - } - - contents_.ShareWith(result); - return true; -} - -bool ArrayBuffer::ShareNonSharedForInternalUse(ArrayBufferContents& result) { - DCHECK(!IsShared()); - scoped_refptr<ArrayBuffer> keep_alive(this); - - if (!contents_.BackingStore()) { - result.Detach(); - return false; - } - - contents_.ShareNonSharedForInternalUse(result); - return true; -} - -void ArrayBuffer::AddView(ArrayBufferView* view) { - view->buffer_ = this; - view->prev_view_ = nullptr; - view->next_view_ = first_view_; - if (first_view_) - first_view_->prev_view_ = view; - first_view_ = view; -} - -void ArrayBuffer::RemoveView(ArrayBufferView* view) { - DCHECK_EQ(this, view->buffer_.get()); - if (view->next_view_) - view->next_view_->prev_view_ = view->prev_view_; - if (view->prev_view_) - view->prev_view_->next_view_ = view->next_view_; - if (first_view_ == view) - first_view_ = view->next_view_; - view->prev_view_ = view->next_view_ = nullptr; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h deleted file mode 100644 index ca488c6ca95..00000000000 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2009 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 COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * 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 THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_ - -#include "base/allocator/partition_allocator/oom.h" -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/ref_counted.h" - -namespace blink { - -class ArrayBuffer; -class ArrayBufferView; - -class CORE_EXPORT ArrayBuffer : public RefCounted<ArrayBuffer> { - USING_FAST_MALLOC(ArrayBuffer); - - public: - static inline scoped_refptr<ArrayBuffer> Create(size_t num_elements, - size_t element_byte_size); - static inline scoped_refptr<ArrayBuffer> Create(ArrayBuffer*); - static inline scoped_refptr<ArrayBuffer> Create(const void* source, - size_t byte_length); - static inline scoped_refptr<ArrayBuffer> Create(ArrayBufferContents&); - - static inline scoped_refptr<ArrayBuffer> CreateOrNull( - size_t num_elements, - size_t element_byte_size); - - // Only for use by DOMArrayBuffer::CreateUninitializedOrNull(). - static inline scoped_refptr<ArrayBuffer> CreateUninitializedOrNull( - size_t num_elements, - size_t element_byte_size); - - static inline scoped_refptr<ArrayBuffer> CreateShared( - size_t num_elements, - size_t element_byte_size); - static inline scoped_refptr<ArrayBuffer> CreateShared(const void* source, - size_t byte_length); - - inline void* Data(); - inline const void* Data() const; - inline void* DataShared(); - inline const void* DataShared() const; - inline void* DataMaybeShared(); - inline const void* DataMaybeShared() const; - inline size_t ByteLengthAsSizeT() const; - // This function is deprecated and should not be used. Use {ByteLengthAsSizeT} - // instead. - inline unsigned ByteLengthAsUnsigned() const; - - void AddView(ArrayBufferView*); - void RemoveView(ArrayBufferView*); - - bool Transfer(ArrayBufferContents&); - bool ShareContentsWith(ArrayBufferContents&); - // Documentation see DOMArrayBuffer. - bool ShareNonSharedForInternalUse(ArrayBufferContents&); - bool IsDetached() const { return is_detached_; } - bool IsShared() const { return contents_.IsShared(); } - ArrayBufferContents* Content() { return &contents_; } - ~ArrayBuffer() = default; - - protected: - inline explicit ArrayBuffer(ArrayBufferContents&); - - private: - static inline scoped_refptr<ArrayBuffer> Create( - size_t num_elements, - size_t element_byte_size, - ArrayBufferContents::InitializationPolicy); - static inline scoped_refptr<ArrayBuffer> CreateOrNull( - size_t num_elements, - size_t element_byte_size, - ArrayBufferContents::InitializationPolicy); - static inline scoped_refptr<ArrayBuffer> CreateShared( - size_t num_elements, - size_t element_byte_size, - ArrayBufferContents::InitializationPolicy); - - ArrayBufferContents contents_; - ArrayBufferView* first_view_; - bool is_detached_; -}; - -scoped_refptr<ArrayBuffer> ArrayBuffer::Create(size_t num_elements, - size_t element_byte_size) { - return Create(num_elements, element_byte_size, - ArrayBufferContents::kZeroInitialize); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBuffer* other) { - // TODO(binji): support creating a SharedArrayBuffer by copying another - // ArrayBuffer? - DCHECK(!other->IsShared()); - return ArrayBuffer::Create(other->Data(), other->ByteLengthAsSizeT()); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::Create(const void* source, - size_t byte_length) { - ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kNotShared, - ArrayBufferContents::kDontInitialize); - if (UNLIKELY(!contents.Data())) - OOM_CRASH(); - scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents)); - memcpy(buffer->Data(), source, byte_length); - return buffer; -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBufferContents& contents) { - CHECK(contents.DataLength() == 0 || contents.DataMaybeShared()); - return base::AdoptRef(new ArrayBuffer(contents)); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(size_t num_elements, - size_t element_byte_size) { - return CreateOrNull(num_elements, element_byte_size, - ArrayBufferContents::kZeroInitialize); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateUninitializedOrNull( - size_t num_elements, - size_t element_byte_size) { - return CreateOrNull(num_elements, element_byte_size, - ArrayBufferContents::kDontInitialize); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::Create( - size_t num_elements, - size_t element_byte_size, - ArrayBufferContents::InitializationPolicy policy) { - ArrayBufferContents contents(num_elements, element_byte_size, - ArrayBufferContents::kNotShared, policy); - if (UNLIKELY(!contents.Data())) - OOM_CRASH(); - return base::AdoptRef(new ArrayBuffer(contents)); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull( - size_t num_elements, - size_t element_byte_size, - ArrayBufferContents::InitializationPolicy policy) { - ArrayBufferContents contents(num_elements, element_byte_size, - ArrayBufferContents::kNotShared, policy); - if (!contents.Data()) - return nullptr; - return base::AdoptRef(new ArrayBuffer(contents)); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(size_t num_elements, - size_t element_byte_size) { - return CreateShared(num_elements, element_byte_size, - ArrayBufferContents::kZeroInitialize); -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(const void* source, - size_t byte_length) { - ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared, - ArrayBufferContents::kDontInitialize); - CHECK(contents.DataShared()); - scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents)); - memcpy(buffer->DataShared(), source, byte_length); - return buffer; -} - -scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared( - size_t num_elements, - size_t element_byte_size, - ArrayBufferContents::InitializationPolicy policy) { - ArrayBufferContents contents(num_elements, element_byte_size, - ArrayBufferContents::kShared, policy); - CHECK(contents.DataShared()); - return base::AdoptRef(new ArrayBuffer(contents)); -} - -ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents) - : first_view_(nullptr), is_detached_(false) { - if (contents.IsShared()) - contents.ShareWith(contents_); - else - contents.Transfer(contents_); -} - -void* ArrayBuffer::Data() { - return contents_.Data(); -} - -const void* ArrayBuffer::Data() const { - return contents_.Data(); -} - -void* ArrayBuffer::DataShared() { - return contents_.DataShared(); -} - -const void* ArrayBuffer::DataShared() const { - return contents_.DataShared(); -} - -void* ArrayBuffer::DataMaybeShared() { - return contents_.DataMaybeShared(); -} - -const void* ArrayBuffer::DataMaybeShared() const { - return contents_.DataMaybeShared(); -} - -size_t ArrayBuffer::ByteLengthAsSizeT() const { - return contents_.DataLength(); -} - -// This function is deprecated and should not be used. Use {ByteLengthAsSizeT} -// instead. -unsigned ArrayBuffer::ByteLengthAsUnsigned() const { - // TODO(dtapuska): Revisit this cast. ArrayBufferContents - // uses size_t for storing data. Whereas ArrayBuffer IDL is - // only uint32_t based. - return base::checked_cast<unsigned>(contents_.DataLength()); -} -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_ diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h index 2e871b20c1e..cce802e4fc9 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h @@ -65,11 +65,13 @@ class CORE_EXPORT ArrayBufferContents { InitializationPolicy); ArrayBufferContents(void* data, size_t length, DataDeleter deleter); ArrayBufferContents(ArrayBufferContents&&) = default; + ArrayBufferContents(const ArrayBufferContents&) = default; explicit ArrayBufferContents(std::shared_ptr<v8::BackingStore> backing_store) : backing_store_(std::move(backing_store)) {} ~ArrayBufferContents(); + ArrayBufferContents& operator=(const ArrayBufferContents&) = default; ArrayBufferContents& operator=(ArrayBufferContents&&) = default; void Detach(); @@ -112,8 +114,6 @@ class CORE_EXPORT ArrayBufferContents { static void* AllocateMemoryWithFlags(size_t, InitializationPolicy, int); std::shared_ptr<v8::BackingStore> backing_store_; - - DISALLOW_COPY_AND_ASSIGN(ArrayBufferContents); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc index c7fd17dd203..3ce5bfe15b8 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc +++ b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc @@ -10,7 +10,15 @@ namespace blink { class ArrayBufferContentsTest : public testing::Test {}; -TEST_F(ArrayBufferContentsTest, AllocationFail) { +#if defined(ADDRESS_SANITIZER) +#define DISABLE_ON_ASAN(test_name) DISABLED_##test_name +#else +#define DISABLE_ON_ASAN(test_name) test_name +#endif // defined(ADDRESS_SANITIZER) + +// Disable on ASAN to avoid crashing on failed allocations, see +// https://crbug.com/1038741. +TEST_F(ArrayBufferContentsTest, DISABLE_ON_ASAN(AllocationFail)) { // This should be an amount of memory that cannot be allocated. size_t length = sizeof(size_t) == 4 ? 0x4fffffff : 0x8000000000; size_t element_byte_size = 1; diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.cc deleted file mode 100644 index eee63083591..00000000000 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2009 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 COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * 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 "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h" - -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" - -namespace blink { - -ArrayBufferView::ArrayBufferView(scoped_refptr<ArrayBuffer> buffer, - size_t byte_offset) - : byte_offset_(byte_offset), - is_detachable_(true), - buffer_(std::move(buffer)), - prev_view_(nullptr), - next_view_(nullptr) { - base_address_ = - buffer_ ? (static_cast<char*>(buffer_->DataMaybeShared()) + byte_offset_) - : nullptr; - if (buffer_) - buffer_->AddView(this); -} - -ArrayBufferView::~ArrayBufferView() { - if (buffer_) - buffer_->RemoveView(this); -} - -void ArrayBufferView::Detach() { - buffer_ = nullptr; - base_address_ = nullptr; - byte_offset_ = 0; -} - -const char* ArrayBufferView::TypeName() { - switch (GetType()) { - case kTypeInt8: - return "Int8"; - break; - case kTypeUint8: - return "UInt8"; - break; - case kTypeUint8Clamped: - return "UInt8Clamped"; - break; - case kTypeInt16: - return "Int16"; - break; - case kTypeUint16: - return "UInt16"; - break; - case kTypeInt32: - return "Int32"; - break; - case kTypeUint32: - return "Uint32"; - break; - case kTypeBigInt64: - return "BigInt64"; - break; - case kTypeBigUint64: - return "BigUint64"; - break; - case kTypeFloat32: - return "Float32"; - break; - case kTypeFloat64: - return "Float64"; - break; - case kTypeDataView: - return "DataView"; - break; - } - NOTREACHED(); - return "Unknown"; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h deleted file mode 100644 index bd9f580236a..00000000000 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2009 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 COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * 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 THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_VIEW_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_VIEW_H_ - -#include <limits.h> -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/ref_counted.h" - -namespace blink { - -class CORE_EXPORT ArrayBufferView : public RefCounted<ArrayBufferView> { - USING_FAST_MALLOC(ArrayBuffer); - - public: - enum ViewType { - kTypeInt8, - kTypeUint8, - kTypeUint8Clamped, - kTypeInt16, - kTypeUint16, - kTypeInt32, - kTypeUint32, - kTypeFloat32, - kTypeFloat64, - kTypeBigInt64, - kTypeBigUint64, - kTypeDataView - }; - virtual ViewType GetType() const = 0; - const char* TypeName(); - - ArrayBuffer* Buffer() const { return buffer_.get(); } - - void* BaseAddress() const { - DCHECK(!IsShared()); - return base_address_; - } - void* BaseAddressMaybeShared() const { return base_address_; } - - size_t ByteOffset() const { return byte_offset_; } - - virtual size_t ByteLengthAsSizeT() const = 0; - virtual unsigned TypeSize() const = 0; - - void SetDetachable(bool flag) { is_detachable_ = flag; } - bool IsDetachable() const { return is_detachable_; } - bool IsShared() const { return buffer_ ? buffer_->IsShared() : false; } - - virtual ~ArrayBufferView(); - - protected: - ArrayBufferView(scoped_refptr<ArrayBuffer>, size_t byte_offset); - - virtual void Detach(); - - // This is the address of the ArrayBuffer's storage, plus the byte offset. - void* base_address_; - - size_t byte_offset_; - bool is_detachable_; - - private: - friend class ArrayBuffer; - scoped_refptr<ArrayBuffer> buffer_; - ArrayBufferView* prev_view_; - ArrayBufferView* next_view_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_VIEW_H_ diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc deleted file mode 100644 index abfaeadf6c1..00000000000 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h" - -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h" -#include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" - -namespace blink { - -ArrayPiece::ArrayPiece() { - InitNull(); -} - -ArrayPiece::ArrayPiece(ArrayBuffer* buffer) { - InitWithArrayBuffer(buffer); -} - -ArrayPiece::ArrayPiece(ArrayBufferView* buffer) { - InitWithArrayBufferView(buffer); -} - -bool ArrayPiece::IsNull() const { - return is_null_; -} - -bool ArrayPiece::IsDetached() const { - return is_detached_; -} - -void* ArrayPiece::Data() const { - DCHECK(!IsNull()); - return data_; -} - -unsigned char* ArrayPiece::Bytes() const { - return static_cast<unsigned char*>(Data()); -} - -size_t ArrayPiece::ByteLengthAsSizeT() const { - DCHECK(!IsNull()); - return byte_length_; -} - -void ArrayPiece::InitWithArrayBuffer(ArrayBuffer* buffer) { - if (buffer) { - InitWithData(buffer->Data(), buffer->ByteLengthAsSizeT()); - is_detached_ = buffer->IsDetached(); - } else { - InitNull(); - } -} - -void ArrayPiece::InitWithArrayBufferView(ArrayBufferView* buffer) { - if (buffer) { - InitWithData(buffer->BaseAddress(), buffer->ByteLengthAsSizeT()); - is_detached_ = buffer->Buffer() ? buffer->Buffer()->IsDetached() : true; - } else { - InitNull(); - } -} - -void ArrayPiece::InitWithData(void* data, size_t byte_length) { - byte_length_ = byte_length; - data_ = data; - is_null_ = false; - is_detached_ = false; -} - -void ArrayPiece::InitNull() { - byte_length_ = 0; - data_ = nullptr; - is_null_ = true; - is_detached_ = false; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h deleted file mode 100644 index 6a542ba716b..00000000000 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_PIECE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_PIECE_H_ - -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class ArrayBuffer; -class ArrayBufferView; - -// This class is for passing around un-owned bytes as a pointer + length. -// It supports implicit conversion from several other data types. -// -// ArrayPiece has the concept of being "null". This is different from an empty -// byte range. It is invalid to call methods other than isNull() on such -// instances. -// -// IMPORTANT: The data contained by ArrayPiece is NOT OWNED, so caution must be -// taken to ensure it is kept alive. -class CORE_EXPORT ArrayPiece { - DISALLOW_NEW(); - - public: - // Constructs a "null" ArrayPiece object. - ArrayPiece(); - - // Constructs an ArrayPiece from the given ArrayBuffer. If the input is a - // nullptr, then the constructed instance will be isNull(). - ArrayPiece(ArrayBuffer*); - ArrayPiece(ArrayBufferView*); - - bool IsNull() const; - bool IsDetached() const; - void* Data() const; - unsigned char* Bytes() const; - size_t ByteLengthAsSizeT() const; - - protected: - void InitWithArrayBuffer(ArrayBuffer*); - void InitWithArrayBufferView(ArrayBufferView*); - void InitWithData(void* data, size_t byte_length); - - private: - void InitNull(); - - void* data_; - size_t byte_length_; - bool is_null_; - bool is_detached_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_PIECE_H_ diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h deleted file mode 100644 index e44982bdd9e..00000000000 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2010 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: - * 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 COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * 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 THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_TYPED_ARRAY_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_TYPED_ARRAY_H_ - -#include <limits> -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h" -#include "third_party/blink/renderer/platform/wtf/math_extras.h" - -namespace blink { - -template <typename T, bool clamped = false> -class TypedArray : public ArrayBufferView { - public: - typedef T ValueType; - - static inline scoped_refptr<TypedArray<T, clamped>> Create(size_t length); - static inline scoped_refptr<TypedArray<T, clamped>> Create(const T* array, - size_t length); - static inline scoped_refptr<TypedArray<T, clamped>> - Create(scoped_refptr<ArrayBuffer>, size_t byte_offset, size_t length); - - T* Data() const { return static_cast<T*>(BaseAddress()); } - - T* DataMaybeShared() const { - return static_cast<T*>(BaseAddressMaybeShared()); - } - - size_t length() const { return length_; } - - size_t ByteLengthAsSizeT() const final { return length_ * sizeof(T); } - - unsigned TypeSize() const final { return sizeof(T); } - - inline void Set(size_t index, double value); - - inline void Set(size_t index, uint64_t value); - - ArrayBufferView::ViewType GetType() const override; - - TypedArray(scoped_refptr<ArrayBuffer> buffer, - size_t byte_offset, - size_t length) - : ArrayBufferView(std::move(buffer), byte_offset), length_(length) {} - - // Invoked by the indexed getter. Does not perform range checks; caller - // is responsible for doing so and returning undefined as necessary. - T Item(size_t index) const { - SECURITY_DCHECK(index < length_); - return Data()[index]; - } - - private: - void Detach() final { - ArrayBufferView::Detach(); - length_ = 0; - } - - size_t length_; -}; - -template <typename T, bool clamped> -scoped_refptr<TypedArray<T, clamped>> TypedArray<T, clamped>::Create( - size_t length) { - scoped_refptr<ArrayBuffer> buffer = ArrayBuffer::Create(length, sizeof(T)); - return Create(std::move(buffer), 0, length); -} - -template <typename T, bool clamped> -scoped_refptr<TypedArray<T, clamped>> TypedArray<T, clamped>::Create( - const T* array, - size_t length) { - auto a = Create(length); - if (a) { - std::memcpy(a->Data(), array, a->ByteLengthAsSizeT()); - } - return a; -} - -namespace { -// Helper to verify that a given sub-range of an ArrayBuffer is within range. -template <typename T> -bool VerifySubRange(const ArrayBuffer* buffer, - size_t byte_offset, - size_t num_elements) { - if (!buffer) - return false; - if (sizeof(T) > 1 && byte_offset % sizeof(T)) - return false; - if (byte_offset > buffer->ByteLengthAsSizeT()) - return false; - size_t remaining_elements = - (buffer->ByteLengthAsSizeT() - byte_offset) / sizeof(T); - if (num_elements > remaining_elements) - return false; - return true; -} -} // namespace - -template <typename T, bool clamped> -scoped_refptr<TypedArray<T, clamped>> TypedArray<T, clamped>::Create( - scoped_refptr<ArrayBuffer> buffer, - size_t byte_offset, - size_t length) { - CHECK(VerifySubRange<T>(buffer.get(), byte_offset, length)); - return base::AdoptRef( - new TypedArray<T, clamped>(std::move(buffer), byte_offset, length)); -} - -template <typename T, bool clamped> -inline void TypedArray<T, clamped>::Set(size_t index, double value) { - if (index >= length_) - return; - if (std::isnan(value)) // Clamp NaN to 0 - value = 0; - // The double cast is necessary to get the correct wrapping - // for out-of-range values with Int32Array and Uint32Array. - Data()[index] = static_cast<T>(static_cast<int64_t>(value)); -} - -template <> -inline void TypedArray<uint8_t, true>::Set(size_t index, double value) { - if (index >= length_) { - return; - } - if (std::isnan(value) || value < 0) { - value = 0; - } else if (value > 255) { - value = 255; - } - - Data()[index] = static_cast<unsigned char>(lrint(value)); -} - -template <> -inline void TypedArray<float, false>::Set(size_t index, double value) { - if (index >= length_) - return; - Data()[index] = static_cast<float>(value); -} - -template <> -inline void TypedArray<double, false>::Set(size_t index, double value) { - if (index >= length_) - return; - Data()[index] = value; -} - -template <> -inline void TypedArray<int64_t, false>::Set(size_t index, uint64_t value) { - if (index >= length_) - return; - Data()[index] = static_cast<int64_t>(value); -} - -template <> -inline void TypedArray<uint64_t, false>::Set(size_t index, uint64_t value) { - if (index >= length_) - return; - Data()[index] = value; -} - -template <> -inline void TypedArray<int64_t, false>::Set(size_t index, double value) { - // This version of {Set} is not supposed to be used for a TypedArray of type - // int64_t. - NOTREACHED(); -} - -template <> -inline void TypedArray<uint64_t, false>::Set(size_t index, double value) { - // This version of {Set} is not supposed to be used for a TypedArray of type - // uint64_t. - NOTREACHED(); -} - -template <typename T, bool clamped> -inline void TypedArray<T, clamped>::Set(size_t index, uint64_t value) { - // This version of {Set} is only supposed to be used for a TypedArrays of type - // int64_t or uint64_t. - NOTREACHED(); -} - -#define FOREACH_VIEW_TYPE(V) \ - V(int8_t, kTypeInt8) \ - V(int16_t, kTypeInt16) \ - V(int32_t, kTypeInt32) \ - V(uint8_t, kTypeUint8) \ - V(uint16_t, kTypeUint16) \ - V(uint32_t, kTypeUint32) \ - V(float, kTypeFloat32) \ - V(double, kTypeFloat64) \ - V(int64_t, kTypeBigInt64) \ - V(uint64_t, kTypeBigUint64) - -#define GET_TYPE(c_type, view_type) \ - template <> \ - inline ArrayBufferView::ViewType TypedArray<c_type, false>::GetType() \ - const { \ - return ArrayBufferView::view_type; \ - } - -FOREACH_VIEW_TYPE(GET_TYPE) - -#undef GET_TYPE -#undef FOREACH_VIEW_TYPE - -template <> -inline ArrayBufferView::ViewType TypedArray<uint8_t, true>::GetType() const { - return ArrayBufferView::kTypeUint8Clamped; -} - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_TYPED_ARRAY_H_ diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h index e6bcd90342b..5fa03cb3550 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_VIEW_HELPERS_H_ #include <type_traits> + #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/type_traits.h" @@ -13,105 +14,119 @@ namespace blink { // A wrapper template type that is used to ensure that a TypedArray is not -// backed by a SharedArrayBuffer. -// -// Typically this is used as an annotation on C++ functions that are called by -// the bindings layer, e.g.: +// backed by a SharedArrayBuffer. It is usable like a smart pointer. // // void Foo(NotShared<DOMUint32Array> param) { -// DOMUint32Array* array = param.View(); +// size_t length = param->lengthAsSizeT(); // ... // } template <typename T> class NotShared { + DISALLOW_NEW(); static_assert(WTF::IsSubclass<typename std::remove_const<T>::type, DOMArrayBufferView>::value, "NotShared<T> must have T as subclass of DOMArrayBufferView"); - STACK_ALLOCATED(); public: using TypedArrayType = T; NotShared() = default; - - explicit NotShared(T* typedArray) : typed_array_(typedArray) { - DCHECK(!(typedArray && typedArray->View()->IsShared())); + NotShared(const NotShared<T>& other) = default; + // Allow implicit upcasts if U inherits from T. + template <typename U, std::enable_if_t<std::is_base_of<T, U>::value, int> = 0> + NotShared(const NotShared<U>& other) : typed_array_(other.Get()) {} + + explicit NotShared(std::nullptr_t) {} + explicit NotShared(T* typed_array) : typed_array_(typed_array) { + DCHECK(!typed_array || !typed_array->IsShared()); } - NotShared(const NotShared& other) = default; - template <typename U> - NotShared(const NotShared<U>& other) : typed_array_(other.View()) {} template <typename U> - NotShared(const Member<U>& other) { - DCHECK(!other->View()->IsShared()); - typed_array_ = other.Get(); + explicit NotShared(const Member<U>& other) : typed_array_(other.Get()) { + DCHECK(!other || !other->IsShared()); } NotShared& operator=(const NotShared& other) = default; template <typename U> NotShared& operator=(const NotShared<U>& other) { - typed_array_ = other.View(); + typed_array_ = static_cast<T*>(other.Get()); return *this; } - T* View() const { return typed_array_.Get(); } + // |View()| is a legacy API and deprecated. Use Get() instead. + T* View() const { return GetRaw(); } + T* Get() const { return GetRaw(); } + void Clear() { typed_array_ = nullptr; } - bool operator!() const { return !typed_array_; } - explicit operator bool() const { return !!typed_array_; } + // Returns true if this object represents IDL null. + bool IsNull() const { return !GetRaw(); } + + explicit operator bool() const { return GetRaw(); } + T* operator->() const { return GetRaw(); } + T& operator*() const { return *GetRaw(); } + + void Trace(Visitor* visitor) { visitor->Trace(typed_array_); } private: - // Must use an untraced member here since this object may be constructed on a - // thread without a ThreadState (e.g. an Audio worklet). It is safe in that - // case because the pointed-to ArrayBuffer is being kept alive another way - // (e.g. CrossThreadPersistent). - // - // TODO(binji): update to using Member, see crbug.com/710295. - UntracedMember<T> typed_array_; + T* GetRaw() const { return typed_array_; } + + Member<T> typed_array_; }; -// A wrapper template type that specifies that a TypedArray may be backed by a -// SharedArrayBuffer. -// -// Typically this is used as an annotation on C++ functions that are called by -// the bindings layer, e.g.: +// A wrapper template type that specifies that a TypedArray *may* be backed by +// a SharedArrayBuffer. It is usable like a smart pointer. // // void Foo(MaybeShared<DOMUint32Array> param) { -// DOMUint32Array* array = param.View(); +// DOMArrayBuffer* buffer = param->buffer(); // ... // } template <typename T> class MaybeShared { + DISALLOW_NEW(); static_assert(WTF::IsSubclass<typename std::remove_const<T>::type, DOMArrayBufferView>::value, "MaybeShared<T> must have T as subclass of DOMArrayBufferView"); - STACK_ALLOCATED(); public: using TypedArrayType = T; MaybeShared() = default; - - explicit MaybeShared(T* typedArray) : typed_array_(typedArray) {} MaybeShared(const MaybeShared& other) = default; + // Allow implicit upcasts if U inherits from T. + template <typename U, std::enable_if_t<std::is_base_of<T, U>::value, int> = 0> + MaybeShared(const MaybeShared<U>& other) : typed_array_(other.Get()) {} + + explicit MaybeShared(std::nullptr_t) {} + // [AllowShared] array buffer view may be a view of non-shared array buffer, + // so we don't check if the buffer is SharedArrayBuffer or not. + // https://heycam.github.io/webidl/#AllowShared + explicit MaybeShared(T* typed_array) : typed_array_(typed_array) {} template <typename U> - MaybeShared(const MaybeShared<U>& other) : typed_array_(other.View()) {} - template <typename U> - MaybeShared(const Member<U>& other) { - typed_array_ = other.Get(); - } + explicit MaybeShared(const Member<U>& other) : typed_array_(other.Get()) {} MaybeShared& operator=(const MaybeShared& other) = default; template <typename U> MaybeShared& operator=(const MaybeShared<U>& other) { - typed_array_ = other.View(); + typed_array_ = static_cast<T*>(other.Get()); return *this; } - T* View() const { return typed_array_.Get(); } + // |View()| is a legacy API and deprecated. Use Get() instead. + T* View() const { return GetRaw(); } + T* Get() const { return GetRaw(); } + void Clear() { typed_array_ = nullptr; } - bool operator!() const { return !typed_array_; } - explicit operator bool() const { return !!typed_array_; } + // Returns true if this object represents IDL null. + bool IsNull() const { return !GetRaw(); } + + explicit operator bool() const { return GetRaw(); } + T* operator->() const { return GetRaw(); } + T& operator*() const { return *GetRaw(); } + + void Trace(Visitor* visitor) { visitor->Trace(typed_array_); } private: + T* GetRaw() const { return typed_array_; } + Member<T> typed_array_; }; diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc index bbd0fe285f5..17fcf0f9034 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc @@ -44,11 +44,21 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate, DOMArrayBuffer* to_transfer = this; if (!IsDetachable(isolate)) { to_transfer = - DOMArrayBuffer::Create(Buffer()->Data(), Buffer()->ByteLengthAsSizeT()); + DOMArrayBuffer::Create(Content()->Data(), ByteLengthAsSizeT()); } - if (!to_transfer->Buffer()->Transfer(result)) + if (IsDetached()) { + result.Detach(); return false; + } + + if (!Content()->Data()) { + // We transfer an empty ArrayBuffer, we can just allocate an empty content. + result = ArrayBufferContents(Content()->BackingStore()); + } else { + Content()->Transfer(result); + Detach(); + } Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles; v8::HandleScope handle_scope(isolate); @@ -60,17 +70,30 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate, return true; } +DOMArrayBuffer* DOMArrayBuffer::CreateOrNull(size_t num_elements, + size_t element_byte_size) { + ArrayBufferContents contents(num_elements, element_byte_size, + ArrayBufferContents::kNotShared, + ArrayBufferContents::kZeroInitialize); + if (!contents.Data()) { + return nullptr; + } + return Create(std::move(contents)); +} + DOMArrayBuffer* DOMArrayBuffer::CreateUninitializedOrNull( size_t num_elements, size_t element_byte_size) { - scoped_refptr<ArrayBuffer> buffer = - ArrayBuffer::CreateUninitializedOrNull(num_elements, element_byte_size); - if (!buffer) + ArrayBufferContents contents(num_elements, element_byte_size, + ArrayBufferContents::kNotShared, + ArrayBufferContents::kDontInitialize); + if (!contents.Data()) { return nullptr; - return Create(std::move(buffer)); + } + return Create(std::move(contents)); } -v8::Local<v8::Object> DOMArrayBuffer::Wrap( +v8::Local<v8::Value> DOMArrayBuffer::Wrap( v8::Isolate* isolate, v8::Local<v8::Object> creation_context) { DCHECK(!DOMDataStore::ContainsWrapper(this, isolate)); @@ -80,10 +103,9 @@ v8::Local<v8::Object> DOMArrayBuffer::Wrap( v8::Local<v8::ArrayBuffer> wrapper; { v8::Context::Scope context_scope(creation_context->CreationContext()); - wrapper = - v8::ArrayBuffer::New(isolate, Buffer()->Content()->BackingStore()); + wrapper = v8::ArrayBuffer::New(isolate, Content()->BackingStore()); - wrapper->Externalize(Buffer()->Content()->BackingStore()); + wrapper->Externalize(Content()->BackingStore()); } return AssociateWithWrapper(isolate, wrapper_type_info, wrapper); @@ -96,14 +118,14 @@ DOMArrayBuffer* DOMArrayBuffer::Create( ArrayBufferContents::kDontInitialize); uint8_t* data = static_cast<uint8_t*>(contents.Data()); if (UNLIKELY(!data)) - OOM_CRASH(); + OOM_CRASH(shared_buffer->size()); for (const auto& span : *shared_buffer) { memcpy(data, span.data(), span.size()); data += span.size(); } - return Create(ArrayBuffer::Create(contents)); + return Create(std::move(contents)); } DOMArrayBuffer* DOMArrayBuffer::Create( @@ -116,14 +138,14 @@ DOMArrayBuffer* DOMArrayBuffer::Create( ArrayBufferContents::kDontInitialize); uint8_t* ptr = static_cast<uint8_t*>(contents.Data()); if (UNLIKELY(!ptr)) - OOM_CRASH(); + OOM_CRASH(size); for (const auto& span : data) { memcpy(ptr, span.data(), span.size()); ptr += span.size(); } - return Create(ArrayBuffer::Create(contents)); + return Create(std::move(contents)); } DOMArrayBuffer* DOMArrayBuffer::Slice(size_t begin, size_t end) const { diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h index 9ba70628af2..00ba385dafc 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h @@ -5,9 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_H_ +#include "base/allocator/partition_allocator/oom.h" #include "base/containers/span.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" +#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -17,29 +18,43 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase { DEFINE_WRAPPERTYPEINFO(); public: - static DOMArrayBuffer* Create(scoped_refptr<ArrayBuffer> buffer) { - return MakeGarbageCollected<DOMArrayBuffer>(std::move(buffer)); + static DOMArrayBuffer* Create(ArrayBufferContents contents) { + return MakeGarbageCollected<DOMArrayBuffer>(std::move(contents)); } static DOMArrayBuffer* Create(size_t num_elements, size_t element_byte_size) { - return Create(ArrayBuffer::Create(num_elements, element_byte_size)); + ArrayBufferContents contents(num_elements, element_byte_size, + ArrayBufferContents::kNotShared, + ArrayBufferContents::kZeroInitialize); + if (UNLIKELY(!contents.Data())) { + OOM_CRASH(num_elements * element_byte_size); + } + return Create(std::move(contents)); } static DOMArrayBuffer* Create(const void* source, size_t byte_length) { - return Create(ArrayBuffer::Create(source, byte_length)); - } - static DOMArrayBuffer* Create(ArrayBufferContents& contents) { - return Create(ArrayBuffer::Create(contents)); + ArrayBufferContents contents(byte_length, 1, + ArrayBufferContents::kNotShared, + ArrayBufferContents::kDontInitialize); + if (UNLIKELY(!contents.Data())) { + OOM_CRASH(byte_length); + } + memcpy(contents.Data(), source, byte_length); + return Create(std::move(contents)); } + static DOMArrayBuffer* Create(scoped_refptr<SharedBuffer>); static DOMArrayBuffer* Create(const Vector<base::span<const char>>&); + static DOMArrayBuffer* CreateOrNull(size_t num_elements, + size_t element_byte_size); + // Only for use by XMLHttpRequest::responseArrayBuffer, // Internals::serializeObject, and // FetchDataLoaderAsArrayBuffer::OnStateChange. static DOMArrayBuffer* CreateUninitializedOrNull(size_t num_elements, size_t element_byte_size); - explicit DOMArrayBuffer(scoped_refptr<ArrayBuffer> buffer) - : DOMArrayBufferBase(std::move(buffer)) {} + explicit DOMArrayBuffer(ArrayBufferContents contents) + : DOMArrayBufferBase(std::move(contents)) {} DOMArrayBuffer* Slice(size_t begin, size_t end) const; @@ -53,11 +68,16 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase { // for e.g. WebAudio which uses a separate thread for processing the // ArrayBuffer while at the same time exposing a NonShared Float32Array. bool ShareNonSharedForInternalUse(ArrayBufferContents& result) { - return Buffer()->ShareNonSharedForInternalUse(result); + if (!Content()->BackingStore()) { + result.Detach(); + return false; + } + Content()->ShareNonSharedForInternalUse(result); + return true; } - v8::Local<v8::Object> Wrap(v8::Isolate*, - v8::Local<v8::Object> creation_context) override; + v8::Local<v8::Value> Wrap(v8::Isolate*, + v8::Local<v8::Object> creation_context) override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h index 150510b93c2..e99cce60dd7 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_BASE_H_ #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" +#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -16,38 +16,41 @@ class CORE_EXPORT DOMArrayBufferBase : public ScriptWrappable { public: ~DOMArrayBufferBase() override = default; - const ArrayBuffer* Buffer() const { return buffer_.get(); } - ArrayBuffer* Buffer() { return buffer_.get(); } + const ArrayBufferContents* Content() const { return &contents_; } + ArrayBufferContents* Content() { return &contents_; } - const void* Data() const { return Buffer()->Data(); } - void* Data() { return Buffer()->Data(); } + const void* Data() const { return contents_.Data(); } + void* Data() { return contents_.Data(); } - size_t ByteLengthAsSizeT() const { return Buffer()->ByteLengthAsSizeT(); } + const void* DataMaybeShared() const { return contents_.DataMaybeShared(); } + void* DataMaybeShared() { return contents_.DataMaybeShared(); } + + size_t ByteLengthAsSizeT() const { return contents_.DataLength(); } // This function is deprecated and should not be used. Use {ByteLengthAsSizeT} // instead. unsigned DeprecatedByteLengthAsUnsigned() const { - size_t size = ByteLengthAsSizeT(); - CHECK_LE(size, static_cast<size_t>(std::numeric_limits<unsigned>::max())); - return static_cast<unsigned>(size); + return base::checked_cast<unsigned>(contents_.DataLength()); } - bool IsDetached() const { return Buffer()->IsDetached(); } - bool IsShared() const { return Buffer()->IsShared(); } + bool IsDetached() const { return is_detached_; } + + void Detach() { is_detached_ = true; } - v8::Local<v8::Object> Wrap(v8::Isolate*, - v8::Local<v8::Object> creation_context) override { + bool IsShared() const { return contents_.IsShared(); } + + v8::Local<v8::Value> Wrap(v8::Isolate*, + v8::Local<v8::Object> creation_context) override { NOTREACHED(); return v8::Local<v8::Object>(); } protected: - explicit DOMArrayBufferBase(scoped_refptr<ArrayBuffer> buffer) - : buffer_(std::move(buffer)) { - DCHECK(buffer_); - } + explicit DOMArrayBufferBase(ArrayBufferContents contents) + : contents_(std::move(contents)) {} - scoped_refptr<ArrayBuffer> buffer_; + ArrayBufferContents contents_; + bool is_detached_ = false; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h index 132367b7cfa..3b863d46da5 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h @@ -6,7 +6,6 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_VIEW_H_ #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -17,33 +16,32 @@ class CORE_EXPORT DOMArrayBufferView : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - typedef ArrayBufferView::ViewType ViewType; - static const ViewType kTypeInt8 = ArrayBufferView::kTypeInt8; - static const ViewType kTypeUint8 = ArrayBufferView::kTypeUint8; - static const ViewType kTypeUint8Clamped = ArrayBufferView::kTypeUint8Clamped; - static const ViewType kTypeInt16 = ArrayBufferView::kTypeInt16; - static const ViewType kTypeUint16 = ArrayBufferView::kTypeUint16; - static const ViewType kTypeInt32 = ArrayBufferView::kTypeInt32; - static const ViewType kTypeUint32 = ArrayBufferView::kTypeUint32; - static const ViewType kTypeFloat32 = ArrayBufferView::kTypeFloat32; - static const ViewType kTypeFloat64 = ArrayBufferView::kTypeFloat64; - static const ViewType kTypeDataView = ArrayBufferView::kTypeDataView; + enum ViewType { + kTypeInt8, + kTypeUint8, + kTypeUint8Clamped, + kTypeInt16, + kTypeUint16, + kTypeInt32, + kTypeUint32, + kTypeFloat32, + kTypeFloat64, + kTypeBigInt64, + kTypeBigUint64, + kTypeDataView + }; ~DOMArrayBufferView() override = default; DOMArrayBuffer* buffer() const { DCHECK(!IsShared()); - if (!dom_array_buffer_) - dom_array_buffer_ = DOMArrayBuffer::Create(View()->Buffer()); - + DCHECK(dom_array_buffer_); return static_cast<DOMArrayBuffer*>(dom_array_buffer_.Get()); } DOMSharedArrayBuffer* BufferShared() const { DCHECK(IsShared()); - if (!dom_array_buffer_) - dom_array_buffer_ = DOMSharedArrayBuffer::Create(View()->Buffer()); - + DCHECK(dom_array_buffer_); return static_cast<DOMSharedArrayBuffer*>(dom_array_buffer_.Get()); } @@ -54,59 +52,102 @@ class CORE_EXPORT DOMArrayBufferView : public ScriptWrappable { return buffer(); } - const ArrayBufferView* View() const { return buffer_view_.get(); } - ArrayBufferView* View() { return buffer_view_.get(); } + virtual ViewType GetType() const = 0; + + const char* TypeName() { + switch (GetType()) { + case kTypeInt8: + return "Int8"; + break; + case kTypeUint8: + return "UInt8"; + break; + case kTypeUint8Clamped: + return "UInt8Clamped"; + break; + case kTypeInt16: + return "Int16"; + break; + case kTypeUint16: + return "UInt16"; + break; + case kTypeInt32: + return "Int32"; + break; + case kTypeUint32: + return "Uint32"; + break; + case kTypeBigInt64: + return "BigInt64"; + break; + case kTypeBigUint64: + return "BigUint64"; + break; + case kTypeFloat32: + return "Float32"; + break; + case kTypeFloat64: + return "Float64"; + break; + case kTypeDataView: + return "DataView"; + break; + } + } + + void* BaseAddress() const { + DCHECK(!IsShared()); + return BaseAddressMaybeShared(); + } - ViewType GetType() const { return View()->GetType(); } - const char* TypeName() { return View()->TypeName(); } - void* BaseAddress() const { return View()->BaseAddress(); } - size_t byteOffsetAsSizeT() const { return View()->ByteOffset(); } + size_t byteOffsetAsSizeT() const { + return !IsDetached() ? raw_byte_offset_ : 0; + } // This function is deprecated and should not be used. Use {byteOffsetAsSizeT} // instead. unsigned deprecatedByteOffsetAsUnsigned() const { - return base::checked_cast<unsigned>(View()->ByteOffset()); + return base::checked_cast<unsigned>(byteOffsetAsSizeT()); } - size_t byteLengthAsSizeT() const { return View()->ByteLengthAsSizeT(); } + virtual size_t byteLengthAsSizeT() const = 0; // This function is deprecated and should not be used. Use {byteLengthAsSizeT} // instead. unsigned deprecatedByteLengthAsUnsigned() const { - return base::checked_cast<unsigned>(View()->ByteLengthAsSizeT()); + return base::checked_cast<unsigned>(byteLengthAsSizeT()); } - unsigned TypeSize() const { return View()->TypeSize(); } - void SetDetachable(bool flag) { return View()->SetDetachable(flag); } - bool IsShared() const { return View()->IsShared(); } + virtual unsigned TypeSize() const = 0; + bool IsShared() const { return dom_array_buffer_->IsShared(); } void* BaseAddressMaybeShared() const { - return View()->BaseAddressMaybeShared(); + return !IsDetached() ? raw_base_address_ : nullptr; } - v8::Local<v8::Object> Wrap(v8::Isolate*, - v8::Local<v8::Object> creation_context) override { + v8::Local<v8::Value> Wrap(v8::Isolate*, + v8::Local<v8::Object> creation_context) override { NOTREACHED(); return v8::Local<v8::Object>(); } - void Trace(blink::Visitor* visitor) override { + void Trace(Visitor* visitor) override { visitor->Trace(dom_array_buffer_); ScriptWrappable::Trace(visitor); } protected: - explicit DOMArrayBufferView(scoped_refptr<ArrayBufferView> buffer_view) - : buffer_view_(std::move(buffer_view)) { - DCHECK(buffer_view_); - } - DOMArrayBufferView(scoped_refptr<ArrayBufferView> buffer_view, - DOMArrayBufferBase* dom_array_buffer) - : buffer_view_(std::move(buffer_view)), - dom_array_buffer_(dom_array_buffer) { - DCHECK(buffer_view_); + DOMArrayBufferView(DOMArrayBufferBase* dom_array_buffer, size_t byte_offset) + : raw_byte_offset_(byte_offset), dom_array_buffer_(dom_array_buffer) { DCHECK(dom_array_buffer_); - DCHECK_EQ(dom_array_buffer_->Buffer(), buffer_view_->Buffer()); + raw_base_address_ = + static_cast<char*>(dom_array_buffer_->DataMaybeShared()) + byte_offset; } + bool IsDetached() const { return dom_array_buffer_->IsDetached(); } + private: - scoped_refptr<ArrayBufferView> buffer_view_; + // The raw_* fields may be stale after Detach. Use getters instead. + // This is the address of the ArrayBuffer's storage, plus the byte offset. + void* raw_base_address_; + size_t raw_byte_offset_; + mutable Member<DOMArrayBufferBase> dom_array_buffer_; }; diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc index 3118f4ab3cf..6e47cd45906 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc @@ -9,19 +9,81 @@ namespace blink { DOMArrayPiece::DOMArrayPiece( - const ArrayBufferOrArrayBufferView& array_buffer_or_view, - InitWithUnionOption option) { + const ArrayBufferOrArrayBufferView& array_buffer_or_view) { if (array_buffer_or_view.IsArrayBuffer()) { DOMArrayBuffer* array_buffer = array_buffer_or_view.GetAsArrayBuffer(); - InitWithArrayBuffer(array_buffer->Buffer()); + InitWithArrayBuffer(array_buffer); } else if (array_buffer_or_view.IsArrayBufferView()) { DOMArrayBufferView* array_buffer_view = array_buffer_or_view.GetAsArrayBufferView().View(); - InitWithArrayBufferView(array_buffer_view->View()); - } else if (array_buffer_or_view.IsNull() && - option == kAllowNullPointToNullWithZeroSize) { - InitWithData(nullptr, 0); - } // Otherwise, leave the obejct as null. + InitWithArrayBufferView(array_buffer_view); + } +} +/////////////////////////////////////////////////////// +DOMArrayPiece::DOMArrayPiece() { + InitNull(); +} + +DOMArrayPiece::DOMArrayPiece(DOMArrayBuffer* buffer) { + InitWithArrayBuffer(buffer); +} + +DOMArrayPiece::DOMArrayPiece(DOMArrayBufferView* buffer) { + InitWithArrayBufferView(buffer); +} + +bool DOMArrayPiece::IsNull() const { + return is_null_; +} + +bool DOMArrayPiece::IsDetached() const { + return is_detached_; +} + +void* DOMArrayPiece::Data() const { + DCHECK(!IsNull()); + return data_; +} + +unsigned char* DOMArrayPiece::Bytes() const { + return static_cast<unsigned char*>(Data()); +} + +size_t DOMArrayPiece::ByteLengthAsSizeT() const { + DCHECK(!IsNull()); + return byte_length_; +} + +void DOMArrayPiece::InitWithArrayBuffer(DOMArrayBuffer* buffer) { + if (buffer) { + InitWithData(buffer->Data(), buffer->ByteLengthAsSizeT()); + is_detached_ = buffer->IsDetached(); + } else { + InitNull(); + } +} + +void DOMArrayPiece::InitWithArrayBufferView(DOMArrayBufferView* buffer) { + if (buffer) { + InitWithData(buffer->BaseAddress(), buffer->byteLengthAsSizeT()); + is_detached_ = buffer->buffer() ? buffer->buffer()->IsDetached() : true; + } else { + InitNull(); + } +} + +void DOMArrayPiece::InitWithData(void* data, size_t byte_length) { + byte_length_ = byte_length; + data_ = data; + is_null_ = false; + is_detached_ = false; +} + +void DOMArrayPiece::InitNull() { + byte_length_ = 0; + data_ = nullptr; + is_null_ = true; + is_detached_ = false; } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h index 41d75f19b25..a1752b68a8b 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h @@ -5,51 +5,54 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_PIECE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_PIECE_H_ -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h" +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" -#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" namespace blink { class ArrayBufferOrArrayBufferView; +class DOMArrayBufferView; // This class is for passing around un-owned bytes as a pointer + length. // It supports implicit conversion from several other data types. // -// ArrayPiece has the concept of being "null". This is different from an empty -// byte range. It is invalid to call methods other than isNull() on such +// DOMArrayPiece has the concept of being "null". This is different from an +// empty byte range. It is invalid to call methods other than isNull() on such // instances. // -// IMPORTANT: The data contained by ArrayPiece is NOT OWNED, so caution must be -// taken to ensure it is kept alive. -class CORE_EXPORT DOMArrayPiece : public ArrayPiece { +// IMPORTANT: The data contained by DOMArrayPiece is NOT OWNED, so caution must +// be taken to ensure it is kept alive. +class CORE_EXPORT DOMArrayPiece { DISALLOW_NEW(); public: - enum InitWithUnionOption { - // Initialize this object as "null" when initialized with an union which - // holds null. - kTreatNullAsNull, - // Initialize this object so this points to null pointer with zero size - // when initialized with an union which holds null. - kAllowNullPointToNullWithZeroSize, - }; - - DOMArrayPiece() = default; - DOMArrayPiece(DOMArrayBuffer* buffer) : ArrayPiece(buffer->Buffer()) {} - DOMArrayPiece(DOMArrayBufferView* view) : ArrayPiece(view->View()) {} - DOMArrayPiece(const ArrayBufferOrArrayBufferView&, - InitWithUnionOption = kTreatNullAsNull); + DOMArrayPiece(); + DOMArrayPiece(DOMArrayBuffer* buffer); + DOMArrayPiece(DOMArrayBufferView* view); + DOMArrayPiece(const ArrayBufferOrArrayBufferView&); bool operator==(const DOMArrayBuffer& other) const { return ByteLengthAsSizeT() == other.ByteLengthAsSizeT() && memcmp(Data(), other.Data(), ByteLengthAsSizeT()) == 0; } - bool operator==(const DOMArrayBufferView& other) const { - return ByteLengthAsSizeT() == other.byteLengthAsSizeT() && - memcmp(Data(), other.BaseAddress(), ByteLengthAsSizeT()) == 0; - } + bool IsNull() const; + bool IsDetached() const; + void* Data() const; + unsigned char* Bytes() const; + size_t ByteLengthAsSizeT() const; + + private: + void InitWithArrayBuffer(DOMArrayBuffer*); + void InitWithArrayBufferView(DOMArrayBufferView*); + void InitWithData(void* data, size_t byte_length); + + void InitNull(); + + void* data_; + size_t byte_length_; + bool is_null_; + bool is_detached_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc index 0530327a8d6..50e4017caef 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc @@ -6,54 +6,21 @@ #include "base/numerics/checked_math.h" #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h" #include "third_party/blink/renderer/platform/bindings/dom_data_store.h" namespace blink { -namespace { - -class DataView final : public ArrayBufferView { - public: - static scoped_refptr<DataView> Create(ArrayBuffer* buffer, - unsigned byte_offset, - size_t byte_length) { - base::CheckedNumeric<uint32_t> checked_max = byte_offset; - checked_max += byte_length; - CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLengthAsUnsigned()); - return base::AdoptRef(new DataView(buffer, byte_offset, byte_length)); - } - - size_t ByteLengthAsSizeT() const override { return byte_length_; } - ViewType GetType() const override { return kTypeDataView; } - unsigned TypeSize() const override { return 1; } - - protected: - void Detach() override { - ArrayBufferView::Detach(); - byte_length_ = 0; - } - - private: - DataView(ArrayBuffer* buffer, unsigned byte_offset, size_t byte_length) - : ArrayBufferView(buffer, byte_offset), byte_length_(byte_length) {} - - size_t byte_length_; -}; - -} // anonymous namespace - DOMDataView* DOMDataView::Create(DOMArrayBufferBase* buffer, - unsigned byte_offset, - unsigned byte_length) { - scoped_refptr<DataView> data_view = - DataView::Create(buffer->Buffer(), byte_offset, byte_length); - return MakeGarbageCollected<DOMDataView>(data_view, buffer); + size_t byte_offset, + size_t byte_length) { + base::CheckedNumeric<size_t> checked_max = byte_offset; + checked_max += byte_length; + CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLengthAsSizeT()); + return MakeGarbageCollected<DOMDataView>(buffer, byte_offset, byte_length); } -v8::Local<v8::Object> DOMDataView::Wrap( - v8::Isolate* isolate, - v8::Local<v8::Object> creation_context) { +v8::Local<v8::Value> DOMDataView::Wrap(v8::Isolate* isolate, + v8::Local<v8::Object> creation_context) { DCHECK(!DOMDataStore::ContainsWrapper(this, isolate)); const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo(); diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h index caf0986e44f..e3618412f6d 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h @@ -17,15 +17,30 @@ class CORE_EXPORT DOMDataView final : public DOMArrayBufferView { typedef char ValueType; static DOMDataView* Create(DOMArrayBufferBase*, - unsigned byte_offset, - unsigned byte_length); + size_t byte_offset, + size_t byte_length); - DOMDataView(scoped_refptr<ArrayBufferView> data_view, - DOMArrayBufferBase* dom_array_buffer) - : DOMArrayBufferView(std::move(data_view), dom_array_buffer) {} + DOMDataView(DOMArrayBufferBase* dom_array_buffer, + size_t byte_offset, + size_t byte_length) + : DOMArrayBufferView(dom_array_buffer, byte_offset), + raw_byte_length_(byte_length) {} - v8::Local<v8::Object> Wrap(v8::Isolate*, - v8::Local<v8::Object> creation_context) override; + v8::Local<v8::Value> Wrap(v8::Isolate*, + v8::Local<v8::Object> creation_context) override; + + size_t byteLengthAsSizeT() const final { + return !IsDetached() ? raw_byte_length_ : 0; + } + + // DOMDataView is a byte array, therefore each field has size 1. + unsigned TypeSize() const final { return 1; } + + DOMArrayBufferView::ViewType GetType() const final { return kTypeDataView; } + + private: + // It may be stale after Detach. Use ByteLengthAsSizeT instead. + size_t raw_byte_length_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc index a2fabac3409..720f112b53d 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc @@ -8,15 +8,15 @@ namespace blink { -v8::Local<v8::Object> DOMSharedArrayBuffer::Wrap( +v8::Local<v8::Value> DOMSharedArrayBuffer::Wrap( v8::Isolate* isolate, v8::Local<v8::Object> creation_context) { DCHECK(!DOMDataStore::ContainsWrapper(this, isolate)); const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo(); v8::Local<v8::SharedArrayBuffer> wrapper = - v8::SharedArrayBuffer::New(isolate, Buffer()->Content()->BackingStore()); - wrapper->Externalize(Buffer()->Content()->BackingStore()); + v8::SharedArrayBuffer::New(isolate, Content()->BackingStore()); + wrapper->Externalize(Content()->BackingStore()); return AssociateWithWrapper(isolate, wrapper_type_info, wrapper); } diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h index 3a05a54c204..a504cf95640 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h @@ -5,8 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_SHARED_ARRAY_BUFFER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_SHARED_ARRAY_BUFFER_H_ +#include "base/allocator/partition_allocator/oom.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h" +#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h" namespace blink { @@ -15,32 +16,47 @@ class CORE_EXPORT DOMSharedArrayBuffer final : public DOMArrayBufferBase { DEFINE_WRAPPERTYPEINFO(); public: - static DOMSharedArrayBuffer* Create(scoped_refptr<ArrayBuffer> buffer) { - DCHECK(buffer->IsShared()); - return MakeGarbageCollected<DOMSharedArrayBuffer>(std::move(buffer)); + static DOMSharedArrayBuffer* Create(ArrayBufferContents contents) { + DCHECK(contents.IsShared()); + return MakeGarbageCollected<DOMSharedArrayBuffer>(std::move(contents)); } + static DOMSharedArrayBuffer* Create(unsigned num_elements, unsigned element_byte_size) { - return Create(ArrayBuffer::CreateShared(num_elements, element_byte_size)); + ArrayBufferContents contents(num_elements, element_byte_size, + ArrayBufferContents::kShared, + ArrayBufferContents::kZeroInitialize); + if (UNLIKELY(!contents.DataShared())) { + OOM_CRASH(num_elements * element_byte_size); + } + return Create(std::move(contents)); } + static DOMSharedArrayBuffer* Create(const void* source, unsigned byte_length) { - return Create(ArrayBuffer::CreateShared(source, byte_length)); - } - static DOMSharedArrayBuffer* Create(ArrayBufferContents& contents) { - DCHECK(contents.IsShared()); - return Create(ArrayBuffer::Create(contents)); + ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared, + ArrayBufferContents::kDontInitialize); + if (UNLIKELY(!contents.DataShared())) { + OOM_CRASH(byte_length); + } + memcpy(contents.DataShared(), source, byte_length); + return Create(std::move(contents)); } - explicit DOMSharedArrayBuffer(scoped_refptr<ArrayBuffer> buffer) - : DOMArrayBufferBase(std::move(buffer)) {} + explicit DOMSharedArrayBuffer(ArrayBufferContents contents) + : DOMArrayBufferBase(std::move(contents)) {} bool ShareContentsWith(ArrayBufferContents& result) { - return Buffer()->ShareContentsWith(result); + if (!Content()->BackingStore()) { + result.Detach(); + return false; + } + Content()->ShareWith(result); + return true; } - v8::Local<v8::Object> Wrap(v8::Isolate*, - v8::Local<v8::Object> creation_context) override; + v8::Local<v8::Value> Wrap(v8::Isolate*, + v8::Local<v8::Object> creation_context) override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc index 83efea3440d..6f76592e633 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc @@ -20,8 +20,8 @@ namespace blink { -template <typename TypedArray, typename V8TypedArray> -v8::Local<v8::Object> DOMTypedArray<TypedArray, V8TypedArray>::Wrap( +template <typename T, typename V8TypedArray, bool clamped> +v8::Local<v8::Value> DOMTypedArray<T, V8TypedArray, clamped>::Wrap( v8::Isolate* isolate, v8::Local<v8::Object> creation_context) { DCHECK(!DOMDataStore::ContainsWrapper(this, isolate)); @@ -68,34 +68,24 @@ DEFINE_DOMTYPEDARRAY_TRAITS(DOMBigUint64Array, V8BigUint64Array); DEFINE_DOMTYPEDARRAY_TRAITS(DOMFloat32Array, V8Float32Array); DEFINE_DOMTYPEDARRAY_TRAITS(DOMFloat64Array, V8Float64Array); -template <typename TypedArray, typename V8TypedArray> +template <typename T, typename V8TypedArray, bool clamped> const WrapperTypeInfo* -DOMTypedArray<TypedArray, V8TypedArray>::GetWrapperTypeInfo() const { +DOMTypedArray<T, V8TypedArray, clamped>::GetWrapperTypeInfo() const { return DOMTypedArrayTraits< - DOMTypedArray<TypedArray, V8TypedArray>>::Type::GetWrapperTypeInfo(); + DOMTypedArray<T, V8TypedArray, clamped>>::Type::GetWrapperTypeInfo(); } +template class CORE_TEMPLATE_EXPORT DOMTypedArray<int8_t, v8::Int8Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<int16_t, v8::Int16Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<int32_t, v8::Int32Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint8_t, v8::Uint8Array>; template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int8_t>, v8::Int8Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int16_t>, v8::Int16Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int32_t>, v8::Int32Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint8_t>, v8::Uint8Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint8_t, /*clamped=*/true>, v8::Uint8ClampedArray>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint16_t>, v8::Uint16Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint32_t>, v8::Uint32Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int64_t>, v8::BigInt64Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint64_t>, v8::BigUint64Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<float>, v8::Float32Array>; -template class CORE_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<double>, v8::Float64Array>; + DOMTypedArray<uint8_t, v8::Uint8ClampedArray, /*clamped=*/true>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint16_t, v8::Uint16Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint32_t, v8::Uint32Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<int64_t, v8::BigInt64Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint64_t, v8::BigUint64Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<float, v8::Float32Array>; +template class CORE_TEMPLATE_EXPORT DOMTypedArray<double, v8::Float64Array>; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h index a52b5a5f7f2..8ca51f82b14 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h @@ -6,7 +6,6 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_TYPED_ARRAY_H_ #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" #include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -14,114 +13,165 @@ namespace blink { -template <typename TypedArray, typename V8TypedArray> +namespace { +// Helper to verify that a given sub-range of an ArrayBuffer is within range. +template <typename T> +bool VerifySubRange(const DOMArrayBufferBase* buffer, + size_t byte_offset, + size_t num_elements) { + if (!buffer) + return false; + if (sizeof(T) > 1 && byte_offset % sizeof(T)) + return false; + if (byte_offset > buffer->ByteLengthAsSizeT()) + return false; + size_t remaining_elements = + (buffer->ByteLengthAsSizeT() - byte_offset) / sizeof(T); + if (num_elements > remaining_elements) + return false; + return true; +} +} // namespace + +template <typename T, typename V8TypedArray, bool clamped = false> class DOMTypedArray final : public DOMArrayBufferView { - typedef DOMTypedArray<TypedArray, V8TypedArray> ThisType; + typedef DOMTypedArray<T, V8TypedArray, clamped> ThisType; DECLARE_WRAPPERTYPEINFO(); public: - typedef typename TypedArray::ValueType ValueType; - - static ThisType* Create(scoped_refptr<TypedArray> buffer_view) { - return MakeGarbageCollected<ThisType>(std::move(buffer_view)); + typedef T ValueType; + static ThisType* Create(DOMArrayBufferBase* buffer, + size_t byte_offset, + size_t length) { + CHECK(VerifySubRange<ValueType>(buffer, byte_offset, length)); + return MakeGarbageCollected<ThisType>(buffer, byte_offset, length); } + static ThisType* Create(size_t length) { - return Create(TypedArray::Create(length)); + DOMArrayBuffer* buffer = DOMArrayBuffer::Create(length, sizeof(ValueType)); + return Create(buffer, 0, length); } + static ThisType* Create(const ValueType* array, size_t length) { - return Create(TypedArray::Create(array, length)); - } - static ThisType* Create(scoped_refptr<ArrayBuffer> buffer, - size_t byte_offset, - size_t length) { - return Create(TypedArray::Create(std::move(buffer), byte_offset, length)); - } - static ThisType* Create(DOMArrayBufferBase* buffer, - size_t byte_offset, - size_t length) { - scoped_refptr<TypedArray> buffer_view = - TypedArray::Create(buffer->Buffer(), byte_offset, length); - return MakeGarbageCollected<ThisType>(std::move(buffer_view), buffer); + DOMArrayBuffer* buffer = + DOMArrayBuffer::Create(array, length * sizeof(ValueType)); + return Create(buffer, 0, length); } static ThisType* CreateOrNull(size_t length) { - scoped_refptr<ArrayBuffer> buffer = - ArrayBuffer::CreateOrNull(length, sizeof(ValueType)); + DOMArrayBuffer* buffer = + DOMArrayBuffer::CreateOrNull(length, sizeof(ValueType)); return buffer ? Create(std::move(buffer), 0, length) : nullptr; } static ThisType* CreateUninitializedOrNull(size_t length) { - scoped_refptr<ArrayBuffer> buffer = - ArrayBuffer::CreateOrNull(length, sizeof(ValueType)); - return buffer ? Create(std::move(buffer), 0, length) : nullptr; + DOMArrayBuffer* buffer = + DOMArrayBuffer::CreateUninitializedOrNull(length, sizeof(ValueType)); + return buffer ? Create(buffer, 0, length) : nullptr; } - explicit DOMTypedArray(scoped_refptr<TypedArray> buffer_view) - : DOMArrayBufferView(std::move(buffer_view)) {} - DOMTypedArray(scoped_refptr<TypedArray> buffer_view, - DOMArrayBufferBase* dom_array_buffer) - : DOMArrayBufferView(std::move(buffer_view), dom_array_buffer) {} + DOMTypedArray(DOMArrayBufferBase* dom_array_buffer, + size_t byte_offset, + size_t length) + : DOMArrayBufferView(dom_array_buffer, byte_offset), + raw_length_(length) {} - const TypedArray* View() const { - return static_cast<const TypedArray*>(DOMArrayBufferView::View()); - } - TypedArray* View() { - return static_cast<TypedArray*>(DOMArrayBufferView::View()); + ValueType* Data() const { return static_cast<ValueType*>(BaseAddress()); } + + ValueType* DataMaybeShared() const { + return reinterpret_cast<ValueType*>(BaseAddressMaybeShared()); } - ValueType* Data() const { return View()->Data(); } - ValueType* DataMaybeShared() const { return View()->DataMaybeShared(); } - size_t lengthAsSizeT() const { return View()->length(); } - // This function is deprecated and should not be used. Use {lengthAsSizeT} - // instead. - unsigned deprecatedLengthAsUnsigned() const { - return base::checked_cast<unsigned>(View()->length()); + size_t lengthAsSizeT() const { return !IsDetached() ? raw_length_ : 0; } + + size_t byteLengthAsSizeT() const final { + return lengthAsSizeT() * sizeof(ValueType); } + + unsigned TypeSize() const final { return sizeof(ValueType); } + + DOMArrayBufferView::ViewType GetType() const override; + // Invoked by the indexed getter. Does not perform range checks; caller // is responsible for doing so and returning undefined as necessary. - ValueType Item(size_t index) const { return View()->Item(index); } + ValueType Item(size_t index) const { + SECURITY_DCHECK(index < lengthAsSizeT()); + return Data()[index]; + } - v8::Local<v8::Object> Wrap(v8::Isolate*, - v8::Local<v8::Object> creation_context) override; + v8::Local<v8::Value> Wrap(v8::Isolate*, + v8::Local<v8::Object> creation_context) override; + + private: + // It may be stale after Detach. Use lengthAsSizeT() instead. + size_t raw_length_; }; +#define FOREACH_VIEW_TYPE(V) \ + V(int8_t, v8::Int8Array, kTypeInt8) \ + V(int16_t, v8::Int16Array, kTypeInt16) \ + V(int32_t, v8::Int32Array, kTypeInt32) \ + V(uint8_t, v8::Uint8Array, kTypeUint8) \ + V(uint16_t, v8::Uint16Array, kTypeUint16) \ + V(uint32_t, v8::Uint32Array, kTypeUint32) \ + V(float, v8::Float32Array, kTypeFloat32) \ + V(double, v8::Float64Array, kTypeFloat64) \ + V(int64_t, v8::BigInt64Array, kTypeBigInt64) \ + V(uint64_t, v8::BigUint64Array, kTypeBigUint64) + +#define GET_TYPE(c_type, v8_type, view_type) \ + template <> \ + inline DOMArrayBufferView::ViewType \ + DOMTypedArray<c_type, v8_type, false>::GetType() const { \ + return DOMArrayBufferView::view_type; \ + } + +FOREACH_VIEW_TYPE(GET_TYPE) + +#undef GET_TYPE +#undef FOREACH_VIEW_TYPE + +template <> +inline DOMArrayBufferView::ViewType +DOMTypedArray<uint8_t, v8::Uint8ClampedArray, true>::GetType() const { + return DOMArrayBufferView::kTypeUint8Clamped; +} + extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int8_t>, v8::Int8Array>; + DOMTypedArray<int8_t, v8::Int8Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int16_t>, v8::Int16Array>; + DOMTypedArray<int16_t, v8::Int16Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int32_t>, v8::Int32Array>; + DOMTypedArray<int32_t, v8::Int32Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint8_t>, v8::Uint8Array>; + DOMTypedArray<uint8_t, v8::Uint8Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint8_t, /*clamped=*/true>, v8::Uint8ClampedArray>; + DOMTypedArray<uint8_t, v8::Uint8ClampedArray, /*clamped=*/true>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint16_t>, v8::Uint16Array>; + DOMTypedArray<uint16_t, v8::Uint16Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint32_t>, v8::Uint32Array>; + DOMTypedArray<uint32_t, v8::Uint32Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<int64_t>, v8::BigInt64Array>; + DOMTypedArray<int64_t, v8::BigInt64Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<uint64_t>, v8::BigUint64Array>; + DOMTypedArray<uint64_t, v8::BigUint64Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<float>, v8::Float32Array>; + DOMTypedArray<float, v8::Float32Array>; extern template class CORE_EXTERN_TEMPLATE_EXPORT - DOMTypedArray<TypedArray<double>, v8::Float64Array>; - -typedef DOMTypedArray<TypedArray<int8_t>, v8::Int8Array> DOMInt8Array; -typedef DOMTypedArray<TypedArray<int16_t>, v8::Int16Array> DOMInt16Array; -typedef DOMTypedArray<TypedArray<int32_t>, v8::Int32Array> DOMInt32Array; -typedef DOMTypedArray<TypedArray<uint8_t>, v8::Uint8Array> DOMUint8Array; -typedef DOMTypedArray<TypedArray<uint8_t, /*clamped=*/true>, - v8::Uint8ClampedArray> + DOMTypedArray<double, v8::Float64Array>; + +typedef DOMTypedArray<int8_t, v8::Int8Array> DOMInt8Array; +typedef DOMTypedArray<int16_t, v8::Int16Array> DOMInt16Array; +typedef DOMTypedArray<int32_t, v8::Int32Array> DOMInt32Array; +typedef DOMTypedArray<uint8_t, v8::Uint8Array> DOMUint8Array; +typedef DOMTypedArray<uint8_t, v8::Uint8ClampedArray, /*clamped=*/true> DOMUint8ClampedArray; -typedef DOMTypedArray<TypedArray<uint16_t>, v8::Uint16Array> DOMUint16Array; -typedef DOMTypedArray<TypedArray<uint32_t>, v8::Uint32Array> DOMUint32Array; -typedef DOMTypedArray<TypedArray<int64_t>, v8::BigInt64Array> DOMBigInt64Array; -typedef DOMTypedArray<TypedArray<uint64_t>, v8::BigUint64Array> - DOMBigUint64Array; -typedef DOMTypedArray<TypedArray<float>, v8::Float32Array> DOMFloat32Array; -typedef DOMTypedArray<TypedArray<double>, v8::Float64Array> DOMFloat64Array; +typedef DOMTypedArray<uint16_t, v8::Uint16Array> DOMUint16Array; +typedef DOMTypedArray<uint32_t, v8::Uint32Array> DOMUint32Array; +typedef DOMTypedArray<int64_t, v8::BigInt64Array> DOMBigInt64Array; +typedef DOMTypedArray<uint64_t, v8::BigUint64Array> DOMBigUint64Array; +typedef DOMTypedArray<float, v8::Float32Array> DOMFloat32Array; +typedef DOMTypedArray<double, v8::Float64Array> DOMFloat64Array; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h index de71e231b1e..6bcd117e894 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h @@ -6,23 +6,31 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_FLEXIBLE_ARRAY_BUFFER_VIEW_H_ #include "base/macros.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" #include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { +// FlexibleArrayBufferView is a performance hack to avoid overhead to +// instantiate DOMArrayBufferView and DOMArrayBuffer when the contents are +// very small. Otherwise, FlexibleArrayBufferView is a thin wrapper to +// DOMArrayBufferView. class CORE_EXPORT FlexibleArrayBufferView { STACK_ALLOCATED(); public: - FlexibleArrayBufferView() : small_data_(nullptr), small_length_(0) {} - - void SetFull(DOMArrayBufferView* full) { full_ = full; } - void SetSmall(void* data, uint32_t length) { - small_data_ = data; - small_length_ = length; + FlexibleArrayBufferView() = default; + FlexibleArrayBufferView(const FlexibleArrayBufferView&) = default; + FlexibleArrayBufferView(FlexibleArrayBufferView&&) = default; + FlexibleArrayBufferView(v8::Local<v8::ArrayBufferView> array_buffer_view) { + SetContents(array_buffer_view); } + ~FlexibleArrayBufferView() = default; + + FlexibleArrayBufferView& operator=(const FlexibleArrayBufferView&) = delete; + FlexibleArrayBufferView& operator=(FlexibleArrayBufferView&&) = delete; void Clear() { full_ = nullptr; @@ -30,7 +38,21 @@ class CORE_EXPORT FlexibleArrayBufferView { small_length_ = 0; } - bool IsEmpty() const { return !full_ && !small_data_; } + void SetContents(v8::Local<v8::ArrayBufferView> array_buffer_view) { + DCHECK(IsNull()); + size_t size = array_buffer_view->ByteLength(); + if (size <= sizeof small_buffer_) { + array_buffer_view->CopyContents(small_buffer_, size); + small_data_ = small_buffer_; + small_length_ = size; + } else { + full_ = V8ArrayBufferView::ToImpl(array_buffer_view); + } + } + + // Returns true if this object represents IDL null. + bool IsNull() const { return !full_ && !small_data_; } + bool IsFull() const { return full_; } DOMArrayBufferView* Full() const { @@ -42,28 +64,35 @@ class CORE_EXPORT FlexibleArrayBufferView { // temporary storage that is only valid during the life-time of the // FlexibleArrayBufferView object. void* BaseAddressMaybeOnStack() const { - DCHECK(!IsEmpty()); + DCHECK(!IsNull()); return IsFull() ? full_->BaseAddressMaybeShared() : small_data_; } - unsigned ByteOffset() const { - DCHECK(!IsEmpty()); - return IsFull() ? full_->deprecatedByteOffsetAsUnsigned() : 0; + size_t ByteLengthAsSizeT() const { + DCHECK(!IsNull()); + return IsFull() ? full_->byteLengthAsSizeT() : small_length_; } - unsigned ByteLength() const { - DCHECK(!IsEmpty()); - return IsFull() ? full_->deprecatedByteLengthAsUnsigned() : small_length_; + unsigned DeprecatedByteLengthAsUnsigned() const { + DCHECK(!IsNull()); + return IsFull() ? base::checked_cast<unsigned>(full_->byteLengthAsSizeT()) + : base::checked_cast<unsigned>(small_length_); } - operator bool() const { return !IsEmpty(); } + // TODO(crbug.com/1050474): Remove this cast operator and make the callsites + // explicitly call IsNull(). + operator bool() const { return !IsNull(); } private: - Member<DOMArrayBufferView> full_; - - void* small_data_; - uint32_t small_length_; - DISALLOW_COPY_AND_ASSIGN(FlexibleArrayBufferView); + DOMArrayBufferView* full_ = nullptr; + + // If the contents of the given v8::ArrayBufferView are small enough to fit + // within |small_buffer_|, the contents are directly copied into + // |small_buffer_| to which accesses are much faster than to a maybe-shared + // buffer in a DOMArrayBufferView. + void* small_data_ = nullptr; // Non null iff |small_buffer_| is used + size_t small_length_ = 0; // The size actually used of |small_buffer_| + uint8_t small_buffer_[64]; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h index cad257296ac..bafb6f282a1 100644 --- a/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h +++ b/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h @@ -6,40 +6,43 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_TYPED_FLEXIBLE_ARRAY_BUFFER_VIEW_H_ #include "base/macros.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h" #include "third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h" namespace blink { -template <typename TypedArray> +template <typename ValueType, bool clamped = false> class TypedFlexibleArrayBufferView final : public FlexibleArrayBufferView { STACK_ALLOCATED(); public: - using ValueType = typename TypedArray::ValueType; - - TypedFlexibleArrayBufferView() : FlexibleArrayBufferView() {} + TypedFlexibleArrayBufferView() = default; + TypedFlexibleArrayBufferView(const TypedFlexibleArrayBufferView&) = default; + TypedFlexibleArrayBufferView(TypedFlexibleArrayBufferView&&) = default; + TypedFlexibleArrayBufferView(v8::Local<v8::ArrayBufferView> array_buffer_view) + : FlexibleArrayBufferView(array_buffer_view) {} + ~TypedFlexibleArrayBufferView() = default; ValueType* DataMaybeOnStack() const { return static_cast<ValueType*>(BaseAddressMaybeOnStack()); } - unsigned length() const { - DCHECK_EQ(ByteLength() % sizeof(ValueType), 0u); - return ByteLength() / sizeof(ValueType); + size_t lengthAsSizeT() const { + DCHECK_EQ(ByteLengthAsSizeT() % sizeof(ValueType), 0u); + return ByteLengthAsSizeT() / sizeof(ValueType); } - - private: - DISALLOW_COPY_AND_ASSIGN(TypedFlexibleArrayBufferView); }; -using FlexibleFloat32ArrayView = - TypedFlexibleArrayBufferView<TypedArray<float>>; -using FlexibleInt32ArrayView = - TypedFlexibleArrayBufferView<TypedArray<int32_t>>; -using FlexibleUint32ArrayView = - TypedFlexibleArrayBufferView<TypedArray<uint32_t>>; +using FlexibleInt8Array = TypedFlexibleArrayBufferView<int8_t>; +using FlexibleInt16Array = TypedFlexibleArrayBufferView<int16_t>; +using FlexibleInt32Array = TypedFlexibleArrayBufferView<int32_t>; +using FlexibleUint8Array = TypedFlexibleArrayBufferView<uint8_t>; +using FlexibleUint8ClampedArray = TypedFlexibleArrayBufferView<uint8_t, true>; +using FlexibleUint16Array = TypedFlexibleArrayBufferView<uint16_t>; +using FlexibleUint32Array = TypedFlexibleArrayBufferView<uint32_t>; +using FlexibleBigInt64Array = TypedFlexibleArrayBufferView<int64_t>; +using FlexibleBigUint64Array = TypedFlexibleArrayBufferView<uint64_t>; +using FlexibleFloat32Array = TypedFlexibleArrayBufferView<float>; +using FlexibleFloat64Array = TypedFlexibleArrayBufferView<double>; } // namespace blink |