diff --git a/Userland/Libraries/LibJS/CMakeLists.txt b/Userland/Libraries/LibJS/CMakeLists.txt index 86a78ff059..6bf8f45258 100644 --- a/Userland/Libraries/LibJS/CMakeLists.txt +++ b/Userland/Libraries/LibJS/CMakeLists.txt @@ -82,7 +82,6 @@ set(SOURCES Runtime/TypedArray.cpp Runtime/TypedArrayConstructor.cpp Runtime/TypedArrayPrototype.cpp - Runtime/Uint8ClampedArray.cpp Runtime/VM.cpp Runtime/Value.cpp Runtime/WithScope.cpp diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 7914f42003..3d5737ec85 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -54,14 +54,15 @@ __JS_ENUMERATE(TypeError, type_error, TypeErrorPrototype, TypeErrorConstructor, void) \ __JS_ENUMERATE(URIError, uri_error, URIErrorPrototype, URIErrorConstructor, void) -#define JS_ENUMERATE_TYPED_ARRAYS \ - __JS_ENUMERATE(Uint8Array, uint8_array, Uint8ArrayPrototype, Uint8ArrayConstructor, u8) \ - __JS_ENUMERATE(Uint16Array, uint16_array, Uint16ArrayPrototype, Uint16ArrayConstructor, u16) \ - __JS_ENUMERATE(Uint32Array, uint32_array, Uint32ArrayPrototype, Uint32ArrayConstructor, u32) \ - __JS_ENUMERATE(Int8Array, int8_array, Int8ArrayPrototype, Int8ArrayConstructor, i8) \ - __JS_ENUMERATE(Int16Array, int16_array, Int16ArrayPrototype, Int16ArrayConstructor, i16) \ - __JS_ENUMERATE(Int32Array, int32_array, Int32ArrayPrototype, Int32ArrayConstructor, i32) \ - __JS_ENUMERATE(Float32Array, float32_array, Float32ArrayPrototype, Float32ArrayConstructor, float) \ +#define JS_ENUMERATE_TYPED_ARRAYS \ + __JS_ENUMERATE(Uint8Array, uint8_array, Uint8ArrayPrototype, Uint8ArrayConstructor, u8) \ + __JS_ENUMERATE(Uint8ClampedArray, uint8_clamped_array, Uint8ClampedArrayPrototype, Uint8ClampedArrayConstructor, ClampedU8) \ + __JS_ENUMERATE(Uint16Array, uint16_array, Uint16ArrayPrototype, Uint16ArrayConstructor, u16) \ + __JS_ENUMERATE(Uint32Array, uint32_array, Uint32ArrayPrototype, Uint32ArrayConstructor, u32) \ + __JS_ENUMERATE(Int8Array, int8_array, Int8ArrayPrototype, Int8ArrayConstructor, i8) \ + __JS_ENUMERATE(Int16Array, int16_array, Int16ArrayPrototype, Int16ArrayConstructor, i16) \ + __JS_ENUMERATE(Int32Array, int32_array, Int32ArrayPrototype, Int32ArrayConstructor, i32) \ + __JS_ENUMERATE(Float32Array, float32_array, Float32ArrayPrototype, Float32ArrayConstructor, float) \ __JS_ENUMERATE(Float64Array, float64_array, Float64ArrayPrototype, Float64ArrayConstructor, double) #define JS_ENUMERATE_ITERATOR_PROTOTYPES \ @@ -131,7 +132,6 @@ class Shape; class Statement; class Symbol; class Token; -class Uint8ClampedArray; class VM; class Value; enum class DeclarationKind; @@ -146,6 +146,9 @@ class ProxyConstructor; class TypedArrayConstructor; class TypedArrayPrototype; +// Tag type used to differentiate between u8 as used by Uint8Array and u8 as used by Uint8ClampedArray. +struct ClampedU8; + #define __JS_ENUMERATE(ClassName, snake_name, ConstructorName, PrototypeName, ArrayType) \ class ClassName; \ class ConstructorName; \ diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index 30bcc0f246..49a9f2ce10 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -44,22 +44,29 @@ private: virtual void visit_edges(Visitor&) override; }; +struct ClampedU8 { +}; + template class TypedArray : public TypedArrayBase { JS_OBJECT(TypedArray, TypedArrayBase); + using UnderlyingBufferDataType = Conditional, 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) + 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) { + if constexpr (IsFloatingPoint) { return Value((double)value); - } else if constexpr (NumericLimits::is_signed()) { + } else if constexpr (NumericLimits::is_signed()) { if (value > NumericLimits::max() || value < NumericLimits::min()) return Value((double)value); } else { @@ -94,23 +101,23 @@ public: } } - Span data() const + Span data() const { - return { reinterpret_cast(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length }; + return { reinterpret_cast(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length }; } - Span data() + Span data() { - return { reinterpret_cast(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length }; + return { reinterpret_cast(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::multiplication_would_overflow(array_length, sizeof(T))); - m_viewed_array_buffer = ArrayBuffer::create(global_object(), array_length * sizeof(T)); + VERIFY(!Checked::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; diff --git a/Userland/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp b/Userland/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp deleted file mode 100644 index f801c90dfd..0000000000 --- a/Userland/Libraries/LibJS/Runtime/Uint8ClampedArray.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include - -namespace JS { - -Uint8ClampedArray* Uint8ClampedArray::create(GlobalObject& global_object, u32 length) -{ - return global_object.heap().allocate(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(global_object, ErrorType::NotA, "Uint8ClampedArray"); - return {}; - } - return Value(static_cast(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]); -} - -} diff --git a/Userland/Libraries/LibJS/Runtime/Uint8ClampedArray.h b/Userland/Libraries/LibJS/Runtime/Uint8ClampedArray.h deleted file mode 100644 index a9480096c7..0000000000 --- a/Userland/Libraries/LibJS/Runtime/Uint8ClampedArray.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2020, Andreas Kling - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include - -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 }; -}; - -} diff --git a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp index 72fc832e64..b315645c44 100644 --- a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp +++ b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp @@ -856,7 +856,7 @@ void generate_implementation(const IDL::Interface& interface) #include #include #include -#include +#include #include #include #include @@ -1200,7 +1200,7 @@ void generate_prototype_implementation(const IDL::Interface& interface) #include #include #include -#include +#include #include #include #include diff --git a/Userland/Libraries/LibWeb/HTML/ImageData.cpp b/Userland/Libraries/LibWeb/HTML/ImageData.cpp index b44bb247a2..e9044829ed 100644 --- a/Userland/Libraries/LibWeb/HTML/ImageData.cpp +++ b/Userland/Libraries/LibWeb/HTML/ImageData.cpp @@ -5,7 +5,7 @@ */ #include -#include +#include #include namespace Web::HTML { @@ -26,7 +26,7 @@ RefPtr ImageData::create_with_size(JS::GlobalObject& global_object, i auto data_handle = JS::make_handle(data); - auto bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::RGBA8888, Gfx::IntSize(width, height), 1, width * sizeof(u32), (u32*)data->data()); + auto bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::RGBA8888, Gfx::IntSize(width, height), 1, width * sizeof(u32), data->data().data()); if (!bitmap) return nullptr; return adopt_ref(*new ImageData(bitmap.release_nonnull(), move(data_handle)));