Coverage Report

Created: 2026-05-16 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibJS/Runtime/WeakRef.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <LibJS/Runtime/WeakRef.h>
8
9
namespace JS {
10
11
JS_DEFINE_ALLOCATOR(WeakRef);
12
13
NonnullGCPtr<WeakRef> WeakRef::create(Realm& realm, Object& value)
14
0
{
15
0
    return realm.heap().allocate<WeakRef>(realm, value, realm.intrinsics().weak_ref_prototype());
16
0
}
17
18
NonnullGCPtr<WeakRef> WeakRef::create(Realm& realm, Symbol& value)
19
0
{
20
0
    return realm.heap().allocate<WeakRef>(realm, value, realm.intrinsics().weak_ref_prototype());
21
0
}
22
23
WeakRef::WeakRef(Object& value, Object& prototype)
24
0
    : Object(ConstructWithPrototypeTag::Tag, prototype)
25
0
    , WeakContainer(heap())
26
0
    , m_value(&value)
27
0
    , m_last_execution_generation(vm().execution_generation())
28
0
{
29
0
}
30
31
WeakRef::WeakRef(Symbol& value, Object& prototype)
32
0
    : Object(ConstructWithPrototypeTag::Tag, prototype)
33
0
    , WeakContainer(heap())
34
0
    , m_value(&value)
35
0
    , m_last_execution_generation(vm().execution_generation())
36
0
{
37
0
}
38
39
void WeakRef::remove_dead_cells(Badge<Heap>)
40
0
{
41
0
    if (m_value.visit([](Cell* cell) -> bool { return cell->state() == Cell::State::Live; }, [](Empty) -> bool { VERIFY_NOT_REACHED(); }))
42
0
        return;
43
44
0
    m_value = Empty {};
45
    // This is an optimization, we deregister from the garbage collector early (even if we were not garbage collected ourself yet)
46
    // to reduce the garbage collection overhead, which we can do because a cleared weak ref cannot be reused.
47
0
    WeakContainer::deregister();
48
0
}
49
50
void WeakRef::visit_edges(Visitor& visitor)
51
0
{
52
0
    Base::visit_edges(visitor);
53
54
0
    if (vm().execution_generation() == m_last_execution_generation) {
55
0
        auto* cell = m_value.visit([](Cell* cell) -> Cell* { return cell; }, [](Empty) -> Cell* { return nullptr; });
56
0
        visitor.visit(cell);
57
0
    }
58
0
}
59
60
}