mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 14:57:35 +00:00
LibJS+LibWeb: Make Uint8ClampedArray use TypedArray
Instead of being its own separate unrelated class. This automatically makes typed array properties available to it, as well as making it available to the runtime.
This commit is contained in:
parent
ba5da79617
commit
6af596d9e8
7 changed files with 36 additions and 129 deletions
|
@ -44,22 +44,29 @@ private:
|
|||
virtual void visit_edges(Visitor&) override;
|
||||
};
|
||||
|
||||
struct ClampedU8 {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class TypedArray : public TypedArrayBase {
|
||||
JS_OBJECT(TypedArray, TypedArrayBase);
|
||||
|
||||
using UnderlyingBufferDataType = Conditional<IsSame<ClampedU8, T>, u8, T>;
|
||||
|
||||
public:
|
||||
virtual bool put_by_index(u32 property_index, Value value) override
|
||||
{
|
||||
if (property_index >= m_array_length)
|
||||
return Base::put_by_index(property_index, value);
|
||||
|
||||
if constexpr (sizeof(T) < 4) {
|
||||
if constexpr (sizeof(UnderlyingBufferDataType) < 4) {
|
||||
auto number = value.to_i32(global_object());
|
||||
if (vm().exception())
|
||||
return {};
|
||||
if constexpr (IsSame<T, ClampedU8>)
|
||||
number = clamp(number, 0, 255);
|
||||
data()[property_index] = number;
|
||||
} else if constexpr (sizeof(T) == 4 || sizeof(T) == 8) {
|
||||
} else if constexpr (sizeof(UnderlyingBufferDataType) == 4 || sizeof(UnderlyingBufferDataType) == 8) {
|
||||
auto number = value.to_double(global_object());
|
||||
if (vm().exception())
|
||||
return {};
|
||||
|
@ -75,13 +82,13 @@ public:
|
|||
if (property_index >= m_array_length)
|
||||
return Base::get_by_index(property_index);
|
||||
|
||||
if constexpr (sizeof(T) < 4) {
|
||||
if constexpr (sizeof(UnderlyingBufferDataType) < 4) {
|
||||
return Value((i32)data()[property_index]);
|
||||
} else if constexpr (sizeof(T) == 4 || sizeof(T) == 8) {
|
||||
} else if constexpr (sizeof(UnderlyingBufferDataType) == 4 || sizeof(UnderlyingBufferDataType) == 8) {
|
||||
auto value = data()[property_index];
|
||||
if constexpr (IsFloatingPoint<T>) {
|
||||
if constexpr (IsFloatingPoint<UnderlyingBufferDataType>) {
|
||||
return Value((double)value);
|
||||
} else if constexpr (NumericLimits<T>::is_signed()) {
|
||||
} else if constexpr (NumericLimits<UnderlyingBufferDataType>::is_signed()) {
|
||||
if (value > NumericLimits<i32>::max() || value < NumericLimits<i32>::min())
|
||||
return Value((double)value);
|
||||
} else {
|
||||
|
@ -94,23 +101,23 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
Span<const T> data() const
|
||||
Span<const UnderlyingBufferDataType> data() const
|
||||
{
|
||||
return { reinterpret_cast<const T*>(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length };
|
||||
return { reinterpret_cast<const UnderlyingBufferDataType*>(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length };
|
||||
}
|
||||
Span<T> data()
|
||||
Span<UnderlyingBufferDataType> data()
|
||||
{
|
||||
return { reinterpret_cast<T*>(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length };
|
||||
return { reinterpret_cast<UnderlyingBufferDataType*>(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length };
|
||||
}
|
||||
|
||||
virtual size_t element_size() const override { return sizeof(T); };
|
||||
virtual size_t element_size() const override { return sizeof(UnderlyingBufferDataType); };
|
||||
|
||||
protected:
|
||||
TypedArray(u32 array_length, Object& prototype)
|
||||
: TypedArrayBase(prototype)
|
||||
{
|
||||
VERIFY(!Checked<u32>::multiplication_would_overflow(array_length, sizeof(T)));
|
||||
m_viewed_array_buffer = ArrayBuffer::create(global_object(), array_length * sizeof(T));
|
||||
VERIFY(!Checked<u32>::multiplication_would_overflow(array_length, sizeof(UnderlyingBufferDataType)));
|
||||
m_viewed_array_buffer = ArrayBuffer::create(global_object(), array_length * sizeof(UnderlyingBufferDataType));
|
||||
if (array_length)
|
||||
VERIFY(!data().is_null());
|
||||
m_array_length = array_length;
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <LibJS/Runtime/Error.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Uint8ClampedArray.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
Uint8ClampedArray* Uint8ClampedArray::create(GlobalObject& global_object, u32 length)
|
||||
{
|
||||
return global_object.heap().allocate<Uint8ClampedArray>(global_object, length, *global_object.array_prototype());
|
||||
}
|
||||
|
||||
Uint8ClampedArray::Uint8ClampedArray(u32 length, Object& prototype)
|
||||
: Object(prototype)
|
||||
, m_length(length)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
define_native_property(vm.names.length, length_getter, {});
|
||||
m_data = (u8*)calloc(m_length, 1);
|
||||
}
|
||||
|
||||
Uint8ClampedArray::~Uint8ClampedArray()
|
||||
{
|
||||
VERIFY(m_data);
|
||||
free(m_data);
|
||||
m_data = nullptr;
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_GETTER(Uint8ClampedArray::length_getter)
|
||||
{
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (StringView(this_object->class_name()) != "Uint8ClampedArray") {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "Uint8ClampedArray");
|
||||
return {};
|
||||
}
|
||||
return Value(static_cast<const Uint8ClampedArray*>(this_object)->length());
|
||||
}
|
||||
|
||||
bool Uint8ClampedArray::put_by_index(u32 property_index, Value value)
|
||||
{
|
||||
if (property_index >= m_length)
|
||||
return Base::put_by_index(property_index, value);
|
||||
auto number = value.to_i32(global_object());
|
||||
if (vm().exception())
|
||||
return {};
|
||||
m_data[property_index] = clamp(number, 0, 255);
|
||||
return true;
|
||||
}
|
||||
|
||||
Value Uint8ClampedArray::get_by_index(u32 property_index) const
|
||||
{
|
||||
if (property_index >= m_length)
|
||||
return Base::get_by_index(property_index);
|
||||
return Value((i32)m_data[property_index]);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class Uint8ClampedArray final : public Object {
|
||||
JS_OBJECT(Uint8ClampedArray, Object);
|
||||
|
||||
public:
|
||||
static Uint8ClampedArray* create(GlobalObject&, u32 length);
|
||||
|
||||
Uint8ClampedArray(u32 length, Object& prototype);
|
||||
virtual ~Uint8ClampedArray() override;
|
||||
|
||||
i32 length() const { return m_length; }
|
||||
|
||||
virtual bool put_by_index(u32 property_index, Value value) override;
|
||||
virtual Value get_by_index(u32 property_index) const override;
|
||||
|
||||
u8* data() { return m_data; }
|
||||
const u8* data() const { return m_data; }
|
||||
|
||||
private:
|
||||
JS_DECLARE_NATIVE_GETTER(length_getter);
|
||||
|
||||
u8* m_data { nullptr };
|
||||
u32 m_length { 0 };
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue