From 0b086c759a658a02cf7edb05e74ffac1d0a8b41d Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Wed, 2 Dec 2020 12:11:21 +0000 Subject: LibJS: Move TypedArray length getter to prototype --- Libraries/LibJS/Runtime/TypedArray.cpp | 6 --- Libraries/LibJS/Runtime/TypedArray.h | 50 +++++++++------------- Libraries/LibJS/Runtime/TypedArrayPrototype.cpp | 24 +++++++++++ Libraries/LibJS/Runtime/TypedArrayPrototype.h | 3 ++ .../TypedArray/TypedArray.prototype.length.js | 10 +++++ 5 files changed, 58 insertions(+), 35 deletions(-) create mode 100644 Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.length.js (limited to 'Libraries/LibJS') diff --git a/Libraries/LibJS/Runtime/TypedArray.cpp b/Libraries/LibJS/Runtime/TypedArray.cpp index 58b9eba1c3..a27023f9cd 100644 --- a/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Libraries/LibJS/Runtime/TypedArray.cpp @@ -46,12 +46,6 @@ namespace JS { : Object(*global_object.typed_array_prototype()) \ { \ } \ - void PrototypeName::initialize(GlobalObject& global_object) \ - { \ - auto& vm = this->vm(); \ - Object::initialize(global_object); \ - define_property(vm.names.length, Value(0), Attribute::Configurable); \ - } \ PrototypeName::~PrototypeName() { } \ \ ConstructorName::ConstructorName(GlobalObject& global_object) \ diff --git a/Libraries/LibJS/Runtime/TypedArray.h b/Libraries/LibJS/Runtime/TypedArray.h index d78f89c554..e7f98dfba8 100644 --- a/Libraries/LibJS/Runtime/TypedArray.h +++ b/Libraries/LibJS/Runtime/TypedArray.h @@ -32,9 +32,25 @@ namespace JS { +class TypedArrayBase : public Object { + JS_OBJECT(TypedArrayBase, Object); + +public: + u32 length() const { return m_length; } + +protected: + TypedArrayBase(u32 length, Object& prototype) + : Object(prototype) + , m_length(length) + { + } + + u32 m_length { 0 }; +}; + template -class TypedArray : public Object { - JS_OBJECT(TypedArray, Object); +class TypedArray : public TypedArrayBase { + JS_OBJECT(TypedArray, TypedArrayBase); public: virtual ~TypedArray() override @@ -44,8 +60,6 @@ public: m_data = nullptr; } - i32 length() const { return m_length; } - virtual bool put_by_index(u32 property_index, Value value) override { if (property_index >= m_length) @@ -94,37 +108,17 @@ public: protected: TypedArray(u32 length, Object& prototype) - : Object(prototype) - , m_length(length) + : TypedArrayBase(length, prototype) { - auto& vm = this->vm(); - // FIXME: This belongs to TypedArray.prototype - define_native_property(vm.names.length, length_getter, nullptr); m_data = (T*)calloc(m_length, sizeof(T)); } private: virtual bool is_typed_array() const final { return true; } - JS_DECLARE_NATIVE_GETTER(length_getter); - T* m_data { nullptr }; - u32 m_length { 0 }; }; -template -inline JS_DEFINE_NATIVE_GETTER(TypedArray::length_getter) -{ - auto* this_object = vm.this_value(global_object).to_object(global_object); - if (!this_object) - return {}; - if (!this_object->is_typed_array()) { - vm.throw_exception(global_object, ErrorType::NotA, "TypedArray"); - return {}; - } - return Value(static_cast(this_object)->length()); -} - #define JS_DECLARE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type) \ class ClassName : public TypedArray { \ JS_OBJECT(ClassName, TypedArray); \ @@ -139,7 +133,6 @@ inline JS_DEFINE_NATIVE_GETTER(TypedArray::length_getter) \ public: \ PrototypeName(GlobalObject&); \ - virtual void initialize(GlobalObject&) override; \ virtual ~PrototypeName() override; \ }; \ class ConstructorName final : public TypedArrayConstructor { \ @@ -157,9 +150,8 @@ inline JS_DEFINE_NATIVE_GETTER(TypedArray::length_getter) virtual bool has_constructor() const override { return true; } \ }; -#undef __JS_ENUMERATE -#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \ - JS_DECLARE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType); +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \ + JS_DECLARE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type); JS_ENUMERATE_TYPED_ARRAYS #undef __JS_ENUMERATE diff --git a/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index cb398e2ba1..80547d3bfe 100644 --- a/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -25,6 +25,7 @@ */ #include +#include #include namespace JS { @@ -36,11 +37,34 @@ TypedArrayPrototype::TypedArrayPrototype(GlobalObject& global_object) void TypedArrayPrototype::initialize(GlobalObject& object) { + auto& vm = this->vm(); Object::initialize(object); + // FIXME: This should be an accessor property + define_native_property(vm.names.length, length_getter, nullptr, Attribute::Configurable); } TypedArrayPrototype::~TypedArrayPrototype() { } +static TypedArrayBase* typed_array_from(VM& vm, GlobalObject& global_object) +{ + auto* this_object = vm.this_value(global_object).to_object(global_object); + if (!this_object) + return nullptr; + if (!this_object->is_typed_array()) { + vm.throw_exception(global_object, ErrorType::NotA, "TypedArray"); + return nullptr; + } + return static_cast(this_object); +} + +JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::length_getter) +{ + auto typed_array = typed_array_from(vm, global_object); + if (!typed_array) + return {}; + return Value(typed_array->length()); +} + } diff --git a/Libraries/LibJS/Runtime/TypedArrayPrototype.h b/Libraries/LibJS/Runtime/TypedArrayPrototype.h index 1ef6b368f8..108ac5352b 100644 --- a/Libraries/LibJS/Runtime/TypedArrayPrototype.h +++ b/Libraries/LibJS/Runtime/TypedArrayPrototype.h @@ -37,6 +37,9 @@ public: explicit TypedArrayPrototype(GlobalObject&); virtual void initialize(GlobalObject&) override; virtual ~TypedArrayPrototype() override; + +private: + JS_DECLARE_NATIVE_GETTER(length_getter); }; } diff --git a/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.length.js b/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.length.js new file mode 100644 index 0000000000..bbe85a2bf1 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/TypedArray/TypedArray.prototype.length.js @@ -0,0 +1,10 @@ +// Update when more typed arrays get added +const TYPED_ARRAYS = [Uint8Array, Uint16Array, Uint32Array, Int8Array, Int16Array, Int32Array]; + +test("basic functionality", () => { + TYPED_ARRAYS.forEach(T => { + const typedArray = new T(42); + expect(Object.hasOwnProperty(typedArray, "length")).toBeFalse(); + expect(typedArray.length).toBe(42); + }); +}); -- cgit v1.2.3