Iterator.h 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
  3. * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
  4. * Copyright (c) 2023-2024, Tim Flynn <trflynn89@ladybird.org>
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #pragma once
  9. #include <AK/Function.h>
  10. #include <AK/Optional.h>
  11. #include <LibJS/Runtime/Completion.h>
  12. #include <LibJS/Runtime/Object.h>
  13. #include <LibJS/Runtime/Value.h>
  14. namespace JS {
  15. // 7.4.1 Iterator Records, https://tc39.es/ecma262/#sec-iterator-records
  16. class IteratorRecord final : public Object {
  17. JS_OBJECT(IteratorRecord, Object);
  18. GC_DECLARE_ALLOCATOR(IteratorRecord);
  19. public:
  20. IteratorRecord(Realm& realm, GC::Ptr<Object> iterator, Value next_method, bool done)
  21. : Object(ConstructWithoutPrototypeTag::Tag, realm)
  22. , iterator(iterator)
  23. , next_method(next_method)
  24. , done(done)
  25. {
  26. }
  27. GC::Ptr<Object> iterator; // [[Iterator]]
  28. Value next_method; // [[NextMethod]]
  29. bool done { false }; // [[Done]]
  30. private:
  31. virtual void visit_edges(Cell::Visitor&) override;
  32. virtual bool is_iterator_record() const override { return true; }
  33. };
  34. template<>
  35. inline bool Object::fast_is<IteratorRecord>() const { return is_iterator_record(); }
  36. class Iterator : public Object {
  37. JS_OBJECT(Iterator, Object);
  38. GC_DECLARE_ALLOCATOR(Iterator);
  39. public:
  40. static GC::Ref<Iterator> create(Realm&, Object& prototype, GC::Ref<IteratorRecord> iterated);
  41. IteratorRecord const& iterated() const { return m_iterated; }
  42. private:
  43. Iterator(Object& prototype, GC::Ref<IteratorRecord> iterated);
  44. explicit Iterator(Object& prototype);
  45. virtual void visit_edges(Cell::Visitor&) override;
  46. GC::Ref<IteratorRecord> m_iterated; // [[Iterated]]
  47. };
  48. enum class IteratorHint {
  49. Sync,
  50. Async,
  51. };
  52. enum class PrimitiveHandling {
  53. IterateStringPrimitives,
  54. RejectPrimitives,
  55. };
  56. ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator_direct(VM&, Object&);
  57. ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator_from_method(VM&, Value, GC::Ref<FunctionObject>);
  58. ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator(VM&, Value, IteratorHint);
  59. ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator_flattenable(VM&, Value, PrimitiveHandling);
  60. ThrowCompletionOr<GC::Ref<Object>> iterator_next(VM&, IteratorRecord&, Optional<Value> = {});
  61. ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result);
  62. ThrowCompletionOr<Value> iterator_value(VM&, Object& iterator_result);
  63. ThrowCompletionOr<GC::Ptr<Object>> iterator_step(VM&, IteratorRecord&);
  64. ThrowCompletionOr<Optional<Value>> iterator_step_value(VM&, IteratorRecord&);
  65. Completion iterator_close(VM&, IteratorRecord const&, Completion);
  66. Completion async_iterator_close(VM&, IteratorRecord const&, Completion);
  67. GC::Ref<Object> create_iterator_result_object(VM&, Value, bool done);
  68. ThrowCompletionOr<GC::MarkedVector<Value>> iterator_to_list(VM&, IteratorRecord&);
  69. ThrowCompletionOr<void> setter_that_ignores_prototype_properties(VM&, Value this_, Object const& home, PropertyKey const& property, Value value);
  70. using IteratorValueCallback = Function<Optional<Completion>(Value)>;
  71. Completion get_iterator_values(VM&, Value iterable, IteratorValueCallback callback);
  72. }