AsyncGenerator.h 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /*
  2. * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Variant.h>
  9. #include <LibJS/Bytecode/Interpreter.h>
  10. #include <LibJS/Runtime/ExecutionContext.h>
  11. #include <LibJS/Runtime/Object.h>
  12. namespace JS {
  13. // 27.6.2 Properties of AsyncGenerator Instances, https://tc39.es/ecma262/#sec-properties-of-asyncgenerator-intances
  14. class AsyncGenerator final : public Object {
  15. JS_OBJECT(AsyncGenerator, Object);
  16. JS_DECLARE_ALLOCATOR(AsyncGenerator);
  17. public:
  18. enum class State {
  19. SuspendedStart,
  20. SuspendedYield,
  21. Executing,
  22. AwaitingReturn,
  23. Completed,
  24. };
  25. static ThrowCompletionOr<NonnullGCPtr<AsyncGenerator>> create(Realm&, Value, ECMAScriptFunctionObject*, NonnullOwnPtr<ExecutionContext>, NonnullOwnPtr<Bytecode::CallFrame>);
  26. virtual ~AsyncGenerator() override = default;
  27. void async_generator_enqueue(Completion, NonnullGCPtr<PromiseCapability>);
  28. ThrowCompletionOr<void> resume(VM&, Completion completion);
  29. void await_return();
  30. void complete_step(Completion, bool done, Realm* realm = nullptr);
  31. void drain_queue();
  32. State async_generator_state() const { return m_async_generator_state; }
  33. void set_async_generator_state(Badge<AsyncGeneratorPrototype>, State value);
  34. Optional<String> const& generator_brand() const { return m_generator_brand; }
  35. private:
  36. AsyncGenerator(Realm&, Object& prototype, NonnullOwnPtr<ExecutionContext>);
  37. virtual void visit_edges(Cell::Visitor&) override;
  38. void execute(VM&, Completion completion);
  39. ThrowCompletionOr<void> await(Value);
  40. // At the time of constructing an AsyncGenerator, we still need to point to an
  41. // execution context on the stack, but later need to 'adopt' it.
  42. State m_async_generator_state { State::SuspendedStart }; // [[AsyncGeneratorState]]
  43. NonnullOwnPtr<ExecutionContext> m_async_generator_context; // [[AsyncGeneratorContext]]
  44. Vector<AsyncGeneratorRequest> m_async_generator_queue; // [[AsyncGeneratorQueue]]
  45. Optional<String> m_generator_brand; // [[GeneratorBrand]]
  46. GCPtr<ECMAScriptFunctionObject> m_generating_function;
  47. Value m_previous_value;
  48. OwnPtr<Bytecode::CallFrame> m_frame;
  49. GCPtr<Promise> m_current_promise;
  50. };
  51. }