Coverage Report

Created: 2025-11-02 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibJS/Runtime/AsyncGenerator.h
Line
Count
Source
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
8
#pragma once
9
10
#include <AK/Variant.h>
11
#include <LibJS/Bytecode/Interpreter.h>
12
#include <LibJS/Runtime/AsyncGeneratorRequest.h>
13
#include <LibJS/Runtime/ExecutionContext.h>
14
#include <LibJS/Runtime/Object.h>
15
16
namespace JS {
17
18
// 27.6.2 Properties of AsyncGenerator Instances, https://tc39.es/ecma262/#sec-properties-of-asyncgenerator-intances
19
class AsyncGenerator final : public Object {
20
    JS_OBJECT(AsyncGenerator, Object);
21
    JS_DECLARE_ALLOCATOR(AsyncGenerator);
22
23
public:
24
    enum class State {
25
        SuspendedStart,
26
        SuspendedYield,
27
        Executing,
28
        AwaitingReturn,
29
        Completed,
30
    };
31
32
    static ThrowCompletionOr<NonnullGCPtr<AsyncGenerator>> create(Realm&, Value, ECMAScriptFunctionObject*, NonnullOwnPtr<ExecutionContext>);
33
34
    virtual ~AsyncGenerator() override;
35
36
    void async_generator_enqueue(Completion, NonnullGCPtr<PromiseCapability>);
37
    ThrowCompletionOr<void> resume(VM&, Completion completion);
38
    void await_return();
39
    void complete_step(Completion, bool done, Realm* realm = nullptr);
40
    void drain_queue();
41
42
0
    State async_generator_state() const { return m_async_generator_state; }
43
    void set_async_generator_state(Badge<AsyncGeneratorPrototype>, State value);
44
45
0
    Optional<String> const& generator_brand() const { return m_generator_brand; }
46
47
private:
48
    AsyncGenerator(Realm&, Object& prototype, NonnullOwnPtr<ExecutionContext>);
49
50
    virtual void visit_edges(Cell::Visitor&) override;
51
52
    void execute(VM&, Completion completion);
53
    ThrowCompletionOr<void> await(Value);
54
55
    // At the time of constructing an AsyncGenerator, we still need to point to an
56
    // execution context on the stack, but later need to 'adopt' it.
57
    State m_async_generator_state { State::SuspendedStart };   // [[AsyncGeneratorState]]
58
    NonnullOwnPtr<ExecutionContext> m_async_generator_context; // [[AsyncGeneratorContext]]
59
    Vector<AsyncGeneratorRequest> m_async_generator_queue;     // [[AsyncGeneratorQueue]]
60
    Optional<String> m_generator_brand;                        // [[GeneratorBrand]]
61
62
    GCPtr<ECMAScriptFunctionObject> m_generating_function;
63
    Value m_previous_value;
64
    GCPtr<Promise> m_current_promise;
65
};
66
67
}