/* * Copyright (c) 2022, Linus Groh * Copyright (c) 2023, Luke Wilde * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace JS { // 27.6.2 Properties of AsyncGenerator Instances, https://tc39.es/ecma262/#sec-properties-of-asyncgenerator-intances class AsyncGenerator final : public Object { JS_OBJECT(AsyncGenerator, Object); GC_DECLARE_ALLOCATOR(AsyncGenerator); public: enum class State { SuspendedStart, SuspendedYield, Executing, AwaitingReturn, Completed, }; static GC::Ref create(Realm&, Variant, GC::Ref>, NonnullOwnPtr); virtual ~AsyncGenerator() override; void async_generator_enqueue(Completion, GC::Ref); ThrowCompletionOr resume(VM&, Completion completion); void await_return(); void complete_step(Completion, bool done, Realm* realm = nullptr); void drain_queue(); State async_generator_state() const { return m_async_generator_state; } void set_async_generator_state(Badge, State value); Optional const& generator_brand() const { return m_generator_brand; } void set_pending_completion(Completion const& completion) { m_pending_completion_value = completion.value(); m_pending_completion_type = completion.type(); } Value pending_completion_value() const { return m_pending_completion_value; } Completion::Type pending_completion_type() const { return m_pending_completion_type; } void set_pending_completion_type(Completion::Type completion_type) { m_pending_completion_type = completion_type; } void clear_pending_completion() { m_pending_completion_value = js_undefined(); m_pending_completion_type = Completion::Type::Normal; } private: AsyncGenerator(Realm&, Object* prototype, NonnullOwnPtr, GC::Ref); virtual void visit_edges(Cell::Visitor&) override; void execute(VM&, Completion completion); ThrowCompletionOr await(Value); // At the time of constructing an AsyncGenerator, we still need to point to an // execution context on the stack, but later need to 'adopt' it. State m_async_generator_state { State::SuspendedStart }; // [[AsyncGeneratorState]] NonnullOwnPtr m_async_generator_context; // [[AsyncGeneratorContext]] Vector m_async_generator_queue; // [[AsyncGeneratorQueue]] Optional m_generator_brand; // [[GeneratorBrand]] GC::Ref m_generating_executable; u32 m_yield_continuation { ExecutionContext::no_yield_continuation }; GC::Ptr m_current_promise; Value m_pending_completion_value { js_undefined() }; Completion::Type m_pending_completion_type { Completion::Type::Normal }; }; }