Iterator.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
  3. * Copyright (c) 2022-2023, Linus Groh <linusg@serenityos.org>
  4. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.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. JS_DECLARE_ALLOCATOR(IteratorRecord);
  19. public:
  20. IteratorRecord(Realm& realm, GCPtr<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. GCPtr<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. JS_DECLARE_ALLOCATOR(Iterator);
  39. public:
  40. static NonnullGCPtr<Iterator> create(Realm&, Object& prototype, NonnullGCPtr<IteratorRecord> iterated);
  41. IteratorRecord const& iterated() const { return m_iterated; }
  42. private:
  43. Iterator(Object& prototype, NonnullGCPtr<IteratorRecord> iterated);
  44. explicit Iterator(Object& prototype);
  45. virtual void visit_edges(Cell::Visitor&) override;
  46. NonnullGCPtr<IteratorRecord> m_iterated; // [[Iterated]]
  47. };
  48. enum class IteratorHint {
  49. Sync,
  50. Async,
  51. };
  52. enum class StringHandling {
  53. IterateStrings,
  54. RejectStrings,
  55. };
  56. ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_from_method(VM&, Value, NonnullGCPtr<FunctionObject>);
  57. ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator(VM&, Value, IteratorHint);
  58. ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_direct(VM&, Object&);
  59. ThrowCompletionOr<NonnullGCPtr<IteratorRecord>> get_iterator_flattenable(VM&, Value, StringHandling);
  60. ThrowCompletionOr<NonnullGCPtr<Object>> iterator_next(VM&, IteratorRecord const&, Optional<Value> = {});
  61. ThrowCompletionOr<GCPtr<Object>> iterator_step(VM&, IteratorRecord const&);
  62. ThrowCompletionOr<Optional<Value>> iterator_step_value(VM&, IteratorRecord&);
  63. ThrowCompletionOr<bool> iterator_complete(VM&, Object& iterator_result);
  64. ThrowCompletionOr<Value> iterator_value(VM&, Object& iterator_result);
  65. Completion iterator_close(VM&, IteratorRecord const&, Completion);
  66. Completion async_iterator_close(VM&, IteratorRecord const&, Completion);
  67. NonnullGCPtr<Object> create_iterator_result_object(VM&, Value, bool done);
  68. ThrowCompletionOr<MarkedVector<Value>> iterator_to_list(VM&, IteratorRecord&);
  69. using IteratorValueCallback = Function<Optional<Completion>(Value)>;
  70. Completion get_iterator_values(VM&, Value iterable, IteratorValueCallback callback);
  71. }