/* * Copyright (c) 2021, Ali Mohammad Pur * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace JS { class GeneratorObject : public Object { JS_OBJECT(GeneratorObject, Object); GC_DECLARE_ALLOCATOR(GeneratorObject); public: static ThrowCompletionOr> create(Realm&, Value, ECMAScriptFunctionObject*, NonnullOwnPtr); virtual ~GeneratorObject() override = default; void visit_edges(Cell::Visitor&) override; ThrowCompletionOr resume(VM&, Value value, Optional const& generator_brand); ThrowCompletionOr resume_abrupt(VM&, JS::Completion abrupt_completion, Optional const& generator_brand); enum class GeneratorState { SuspendedStart, SuspendedYield, Executing, Completed, }; GeneratorState generator_state() const { return m_generator_state; } void set_generator_state(GeneratorState generator_state) { m_generator_state = generator_state; } protected: GeneratorObject(Realm&, Object& prototype, NonnullOwnPtr, Optional generator_brand = {}); ThrowCompletionOr validate(VM&, Optional const& generator_brand); virtual ThrowCompletionOr execute(VM&, JS::Completion const& completion); private: NonnullOwnPtr m_execution_context; GC::Ptr m_generating_function; Value m_previous_value; GeneratorState m_generator_state { GeneratorState::SuspendedStart }; Optional m_generator_brand; }; }