• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ArkScript-lang / Ark / 28806973608

06 Jul 2026 04:30PM UTC coverage: 94.366%. First build
28806973608

Pull #695

github

web-flow
Merge 61bb29818 into a68b04545
Pull Request #695: Fix leak in closures with circular references

242 of 248 new or added lines in 4 files covered. (97.58%)

10335 of 10952 relevant lines covered (94.37%)

989351.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.83
/src/arkreactor/VM/Value/Closure.cpp
1
#include <Ark/VM/Value/Closure.hpp>
2

3
#include <Ark/VM/Value/ClosureScope.hpp>
4
#include <Ark/VM/VM.hpp>
5

6
#include <ranges>
7

8
namespace Ark::internal
9
{
10
    Closure::Closure(const ClosureScope& scope, const PageAddr_t pa) noexcept :
693✔
11
        m_scope(std::make_shared<ClosureScope>(scope)),
693✔
12
        m_page_addr(pa)
693✔
13
    {}
1,386✔
14

15
    Closure::Closure(const Closure& closure, const PageAddr_t pa) noexcept :
3,262✔
16
        m_page_addr(pa)
3,262✔
17
    {
3,262✔
18
        if (std::holds_alternative<shared_t>(closure.m_scope))
3,262✔
19
            m_scope = weak_t(std::get<shared_t>(closure.m_scope));
3,262✔
20
        else
NEW
21
            m_scope = closure.m_scope;
×
22
    }
3,262✔
23

24
    ClosureScope& Closure::refScope() const noexcept
11,506✔
25
    {
11,506✔
26
        if (std::holds_alternative<shared_t>(m_scope))
11,506✔
27
            return *std::get<shared_t>(m_scope);
8,244✔
28
        return *std::get<weak_t>(m_scope).lock();
3,262✔
29
    }
11,506✔
30

31
    bool Closure::hasFieldEndingWith(const std::string& end, const VM& vm) const
1✔
32
    {
1✔
33
        return std::ranges::any_of(std::ranges::views::keys(scopePtr()->m_data), [&vm, &end](const auto& id) {
2✔
34
            return end.ends_with(":" + vm.m_state.m_symbols[id]);
1✔
35
        });
36
    }
37

38
    std::string Closure::toString(VM& vm) const noexcept
3✔
39
    {
3✔
40
        if (m_is_printing)
3✔
NEW
41
            return fmt::format("Ref(Closure@{})", m_page_addr);
×
42
        m_is_printing = true;
3✔
43

44
        ClosureScope* scope_ptr = scopePtr();
3✔
45
        std::string out = "(";
3✔
46
        for (std::size_t i = 0, end = scope_ptr->m_data.size(); i < end; ++i)
8✔
47
        {
48
            auto& [id, value] = scope_ptr->m_data[i];
20✔
49
            if (i != 0)
5✔
50
                out += ' ';
2✔
51

52
            out += '.' + vm.m_state.m_symbols[id] + '=';
5✔
53
            if (value.valueType() == ValueType::Closure && value.closure().scopePtr() == scope_ptr)
5✔
54
                out += fmt::format("Ref(Closure@{})", m_page_addr);
1✔
55
            else
56
                out += value.toString(vm);
8✔
57
        }
5✔
58
        m_is_printing = false;
3✔
59
        return out + ")";
3✔
60
    }
3✔
61

62
    bool operator==(const Closure& A, const Closure& B) noexcept
25✔
63
    {
25✔
64
        // they do not come from the same closure builder
65
        if (A.m_page_addr != B.m_page_addr)
25✔
66
            return false;
2✔
67
        // pointers are identical, we are dealing with the same object
68
        if (A.scopePtr() == B.scopePtr())
23✔
69
            return true;
15✔
70

71
        return *A.scopePtr() == *B.scopePtr();
8✔
72
    }
25✔
73
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc