diff --git a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp index 2d6866b24e..ab3ade8854 100644 --- a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp +++ b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include namespace JS::Bytecode { @@ -306,10 +308,13 @@ Value new_function(VM& vm, FunctionExpression const& function_node, Optional put_by_value(VM& vm, Value base, Value property_key_value, Value value, Op::PropertyKind kind) { // OPTIMIZATION: Fast path for simple Int32 indexes in array-like objects. - if (base.is_object() && property_key_value.is_int32() && property_key_value.as_i32() >= 0) { + if ((kind == Op::PropertyKind::KeyValue || kind == Op::PropertyKind::DirectKeyValue) + && base.is_object() && property_key_value.is_int32() && property_key_value.as_i32() >= 0) { auto& object = base.as_object(); auto* storage = object.indexed_properties().storage(); auto index = static_cast(property_key_value.as_i32()); + + // For "non-typed arrays": if (storage && storage->is_simple_storage() && !object.may_interfere_with_indexed_property_access() @@ -320,6 +325,20 @@ ThrowCompletionOr put_by_value(VM& vm, Value base, Value property_key_valu return {}; } } + + // For typed arrays: + if (object.is_typed_array()) { + auto& typed_array = static_cast(object); + auto canonical_index = CanonicalIndex { CanonicalIndex::Type::Index, index }; + switch (typed_array.kind()) { +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \ + case TypedArrayBase::Kind::ClassName: \ + return integer_indexed_element_set(typed_array, canonical_index, value); + JS_ENUMERATE_TYPED_ARRAYS +#undef __JS_ENUMERATE + } + return {}; + } } auto property_key = kind != Op::PropertyKind::Spread ? TRY(property_key_value.to_property_key(vm)) : PropertyKey {}; diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index 6a7a2d6e3c..f0ef451cbb 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -32,6 +32,13 @@ public: Number, }; + enum class Kind { +#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \ + ClassName, + JS_ENUMERATE_TYPED_ARRAYS +#undef __JS_ENUMERATE + }; + using IntrinsicConstructor = NonnullGCPtr (Intrinsics::*)(); u32 array_length() const { return m_array_length; } @@ -48,6 +55,7 @@ public: virtual size_t element_size() const = 0; virtual DeprecatedFlyString const& element_name() const = 0; + virtual Kind kind() const = 0; // 25.1.2.6 IsUnclampedIntegerElementType ( type ), https://tc39.es/ecma262/#sec-isunclampedintegerelementtype virtual bool is_unclamped_integer_element_type() const = 0; @@ -472,6 +480,7 @@ ThrowCompletionOr compare_typed_array_elements(VM&, Value x, Value y, Fu static ThrowCompletionOr> create(Realm&, u32 length); \ static NonnullGCPtr create(Realm&, u32 length, ArrayBuffer& buffer); \ virtual DeprecatedFlyString const& element_name() const override; \ + virtual Kind kind() const override { return Kind::ClassName; } \ \ protected: \ ClassName(Object& prototype, u32 length, ArrayBuffer& array_buffer); \