Serenity Operating System
at master 75 lines 2.8 kB view raw
1/* 2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <AK/Assertions.h> 11#include <AK/Concepts.h> 12#include <AK/Function.h> 13#include <AK/Span.h> 14#include <AK/Vector.h> 15#include <LibJS/Runtime/Completion.h> 16#include <LibJS/Runtime/GlobalObject.h> 17#include <LibJS/Runtime/Object.h> 18#include <LibJS/Runtime/VM.h> 19 20namespace JS { 21 22class Array : public Object { 23 JS_OBJECT(Array, Object); 24 25public: 26 static ThrowCompletionOr<NonnullGCPtr<Array>> create(Realm&, u64 length, Object* prototype = nullptr); 27 static NonnullGCPtr<Array> create_from(Realm&, Vector<Value> const&); 28 29 // Non-standard but equivalent to CreateArrayFromList. 30 template<typename T> 31 static NonnullGCPtr<Array> create_from(Realm& realm, ReadonlySpan<T> elements, Function<Value(T const&)> map_fn) 32 { 33 auto values = MarkedVector<Value> { realm.heap() }; 34 values.ensure_capacity(elements.size()); 35 for (auto const& element : elements) 36 values.append(map_fn(element)); 37 38 return Array::create_from(realm, values); 39 } 40 41 // Non-standard but equivalent to CreateArrayFromList. 42 template<typename T, FallibleFunction<T const&> Callback> 43 static ThrowCompletionOr<NonnullGCPtr<Array>> try_create_from(VM& vm, Realm& realm, ReadonlySpan<T> elements, Callback map_fn) 44 { 45 auto values = MarkedVector<Value> { realm.heap() }; 46 TRY_OR_THROW_OOM(vm, values.try_ensure_capacity(elements.size())); 47 48 for (auto const& element : elements) 49 TRY_OR_THROW_OOM(vm, values.try_append(TRY(map_fn(element)))); 50 51 return Array::create_from(realm, values); 52 } 53 54 virtual ~Array() override = default; 55 56 virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override; 57 virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override; 58 virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&) override; 59 virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override; 60 61 [[nodiscard]] bool length_is_writable() const { return m_length_writable; }; 62 63protected: 64 explicit Array(Object& prototype); 65 66private: 67 ThrowCompletionOr<bool> set_length(PropertyDescriptor const&); 68 69 bool m_length_writable { true }; 70}; 71 72ThrowCompletionOr<double> compare_array_elements(VM&, Value x, Value y, FunctionObject* comparefn); 73ThrowCompletionOr<MarkedVector<Value>> sort_indexed_properties(VM&, Object const&, size_t length, Function<ThrowCompletionOr<double>(Value, Value)> const& sort_compare, bool skip_holes); 74 75}