/* * Copyright (c) 2020, Andreas Kling * Copyright (c) 2020-2022, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include namespace JS { class Array : public Object { JS_OBJECT(Array, Object); public: static ThrowCompletionOr> create(Realm&, u64 length, Object* prototype = nullptr); static NonnullGCPtr create_from(Realm&, Vector const&); // Non-standard but equivalent to CreateArrayFromList. template static NonnullGCPtr create_from(Realm& realm, ReadonlySpan elements, Function map_fn) { auto values = MarkedVector { realm.heap() }; values.ensure_capacity(elements.size()); for (auto const& element : elements) values.append(map_fn(element)); return Array::create_from(realm, values); } // Non-standard but equivalent to CreateArrayFromList. template Callback> static ThrowCompletionOr> try_create_from(VM& vm, Realm& realm, ReadonlySpan elements, Callback map_fn) { auto values = MarkedVector { realm.heap() }; TRY_OR_THROW_OOM(vm, values.try_ensure_capacity(elements.size())); for (auto const& element : elements) TRY_OR_THROW_OOM(vm, values.try_append(TRY(map_fn(element)))); return Array::create_from(realm, values); } virtual ~Array() override = default; virtual ThrowCompletionOr> internal_get_own_property(PropertyKey const&) const override; virtual ThrowCompletionOr internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override; virtual ThrowCompletionOr internal_delete(PropertyKey const&) override; virtual ThrowCompletionOr> internal_own_property_keys() const override; [[nodiscard]] bool length_is_writable() const { return m_length_writable; }; protected: explicit Array(Object& prototype); private: ThrowCompletionOr set_length(PropertyDescriptor const&); bool m_length_writable { true }; }; ThrowCompletionOr compare_array_elements(VM&, Value x, Value y, FunctionObject* comparefn); ThrowCompletionOr> sort_indexed_properties(VM&, Object const&, size_t length, Function(Value, Value)> const& sort_compare, bool skip_holes); }