blob: 452a6d2c75ded5d0299bdae5276c3381b9cbeaa8 [file] [log] [blame]
// 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_DOM_TYPED_ARRAY_H_
#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/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"
#include "v8/include/v8.h"
namespace blink {
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->ByteLength())
return false;
size_t remaining_elements = (buffer->ByteLength() - 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<T, V8TypedArray, clamped> ThisType;
DECLARE_WRAPPERTYPEINFO();
public:
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) {
DOMArrayBuffer* buffer = DOMArrayBuffer::Create(length, sizeof(ValueType));
return Create(buffer, 0, length);
}
static ThisType* Create(const ValueType* array, size_t length) {
DOMArrayBuffer* buffer =
DOMArrayBuffer::Create(array, length * sizeof(ValueType));
return Create(buffer, 0, length);
}
static ThisType* CreateOrNull(size_t length) {
DOMArrayBuffer* buffer =
DOMArrayBuffer::CreateOrNull(length, sizeof(ValueType));
return buffer ? Create(std::move(buffer), 0, length) : nullptr;
}
static ThisType* CreateUninitializedOrNull(size_t length) {
DOMArrayBuffer* buffer =
DOMArrayBuffer::CreateUninitializedOrNull(length, sizeof(ValueType));
return buffer ? Create(buffer, 0, length) : nullptr;
}
DOMTypedArray(DOMArrayBufferBase* dom_array_buffer,
size_t byte_offset,
size_t length)
: DOMArrayBufferView(dom_array_buffer, byte_offset),
raw_length_(length) {}
ValueType* Data() const { return static_cast<ValueType*>(BaseAddress()); }
ValueType* DataMaybeShared() const {
return reinterpret_cast<ValueType*>(BaseAddressMaybeShared());
}
size_t length() const { return !IsDetached() ? raw_length_ : 0; }
size_t byteLength() const final { return length() * 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 {
SECURITY_DCHECK(index < length());
return Data()[index];
}
v8::Local<v8::Value> Wrap(v8::Isolate*,
v8::Local<v8::Object> creation_context) override;
v8::MaybeLocal<v8::Value> WrapV2(ScriptState*) override;
private:
// It may be stale after Detach. Use length() 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<int8_t, v8::Int8Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<int16_t, v8::Int16Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<int32_t, v8::Int32Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<uint8_t, v8::Uint8Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<uint8_t, v8::Uint8ClampedArray, /*clamped=*/true>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<uint16_t, v8::Uint16Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<uint32_t, v8::Uint32Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<int64_t, v8::BigInt64Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<uint64_t, v8::BigUint64Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
DOMTypedArray<float, v8::Float32Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
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<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
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_TYPED_ARRAY_H_