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

ArkScript-lang / Ark / 14600096568

22 Apr 2025 04:42PM UTC coverage: 81.034% (+0.6%) from 80.417%
14600096568

Pull #530

github

web-flow
Merge 77531b0d0 into 32828a045
Pull Request #530: Feat/inst locations

238 of 388 new or added lines in 20 files covered. (61.34%)

8 existing lines in 3 files now uncovered.

6396 of 7893 relevant lines covered (81.03%)

78911.84 hits per line

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

68.99
/src/arkreactor/VM/State.cpp
1
#include <Ark/VM/State.hpp>
2

3
#include <Ark/Constants.hpp>
4
#include <Ark/Files.hpp>
5
#include <Ark/Compiler/Welder.hpp>
6

7
#ifdef _MSC_VER
8
#    pragma warning(push)
9
#    pragma warning(disable : 4996)
10
#endif
11

12
#include <Proxy/Picosha2.hpp>
13
#include <Ark/Compiler/BytecodeReader.hpp>
14
#include <fmt/core.h>
15
#include <fmt/color.h>
16

17
namespace Ark
18
{
19
    State::State(const std::vector<std::filesystem::path>& libenv) noexcept :
352✔
20
        m_debug_level(0),
176✔
21
        m_libenv(libenv),
176✔
22
        m_filename(ARK_NO_NAME_FILE)
176✔
23
    {}
352✔
24

25
    bool State::feed(const std::string& bytecode_filename)
79✔
26
    {
79✔
27
        if (!Utils::fileExists(bytecode_filename))
79✔
28
            return false;
×
29

30
        return feed(Utils::readFileAsBytes(bytecode_filename));
79✔
31
    }
79✔
32

33
    bool State::feed(const bytecode_t& bytecode)
83✔
34
    {
83✔
35
        BytecodeReader bcr;
83✔
36
        bcr.feed(bytecode);
83✔
37
        if (!bcr.checkMagic())
83✔
38
            return false;
×
39

40
        m_bytecode = bytecode;
83✔
41

42
        try
43
        {
44
            configure(bcr);
83✔
45
            return true;
83✔
46
        }
×
47
        catch (const std::exception& e)  // FIXME I don't like this shit
48
        {
49
            fmt::println("{}", e.what());
×
50
            return false;
×
51
        }
×
52
    }
83✔
53

54
    bool State::compile(const std::string& file, const std::string& output, const uint16_t features) const
172✔
55
    {
172✔
56
        Welder welder(m_debug_level, m_libenv, features);
172✔
57
        for (auto& p : m_binded)
190✔
58
            welder.registerSymbol(p.first);
18✔
59

60
        if (!welder.computeASTFromFile(file))
172✔
61
            return false;
×
62
        if (!welder.generateBytecode())
113✔
63
            return false;
×
64

65
        const std::string destination = output.empty() ? (file.substr(0, file.find_last_of('.')) + ".arkc") : output;
79✔
66
        if (!welder.saveBytecodeToFile(destination))
79✔
67
            return false;
×
68

69
        return true;
79✔
70
    }
172✔
71

72
    bool State::doFile(const std::string& file, const uint16_t features)
172✔
73
    {
172✔
74
        if (!Utils::fileExists(file))
172✔
75
        {
76
            fmt::print(fmt::fg(fmt::color::red), "Can not find file '{}'\n", file);
×
77
            return false;
×
78
        }
79
        m_filename = file;
172✔
80

81
        const bytecode_t bytecode = Utils::readFileAsBytes(file);
172✔
82
        BytecodeReader bcr;
172✔
83
        bcr.feed(bytecode);
172✔
84
        if (!bcr.checkMagic())  // couldn't read magic number, it's a source file
172✔
85
        {
86
            // check if it's in the arkscript cache
87
            const std::string short_filename = (std::filesystem::path(file)).filename().string();
172✔
88
            const std::string filename = short_filename.substr(0, short_filename.find_last_of('.')) + ".arkc";
172✔
89
            const std::filesystem::path directory = (std::filesystem::path(file)).parent_path() / ARK_CACHE_DIRNAME;
172✔
90
            const std::string path = (directory / filename).string();
172✔
91

92
            if (!exists(directory))  // create ark cache directory
172✔
93
                create_directory(directory);
13✔
94

95
            if (compile(file, path, features) && feed(path))
172✔
96
                return true;
79✔
97
        }
172✔
98
        else if (feed(bytecode))  // it's a bytecode file
×
99
            return true;
×
100
        return false;
×
101
    }
265✔
102

103
    bool State::doString(const std::string& code, const uint16_t features)
4✔
104
    {
4✔
105
        Welder welder(m_debug_level, m_libenv, features);
4✔
106
        for (auto& p : m_binded)
8✔
107
            welder.registerSymbol(p.first);
4✔
108

109
        if (!welder.computeASTFromString(code))
4✔
110
            return false;
×
111
        if (!welder.generateBytecode())
4✔
112
            return false;
×
113
        return feed(welder.bytecode());
4✔
114
    }
4✔
115

116
    void State::loadFunction(const std::string& name, const Value::ProcType function) noexcept
4✔
117
    {
4✔
118
        m_binded[name] = Value(function);
4✔
119
    }
4✔
120

121
    void State::setArgs(const std::vector<std::string>& args) noexcept
9✔
122
    {
9✔
123
        Value val(ValueType::List);
9✔
124
        std::ranges::transform(args, std::back_inserter(val.list()), [](const std::string& arg) {
9✔
125
            return Value(arg);
×
126
        });
127

128
        m_binded[std::string(internal::Language::SysArgs)] = val;
9✔
129
        m_binded[std::string(internal::Language::SysPlatform)] = Value(ARK_PLATFORM_NAME);
9✔
130
    }
9✔
131

132
    void State::setDebug(const unsigned level) noexcept
×
133
    {
×
134
        m_debug_level = level;
×
135
    }
×
136

137
    void State::setLibDirs(const std::vector<std::filesystem::path>& libenv) noexcept
×
138
    {
×
139
        m_libenv = libenv;
×
140
    }
×
141

142
    void State::configure(const BytecodeReader& bcr)
83✔
143
    {
83✔
144
        using namespace internal;
145

146
        const auto [major, minor, patch] = bcr.version();
83✔
147
        if (major != ARK_VERSION_MAJOR)
83✔
148
        {
149
            std::string str_version = std::to_string(major) + "." +
×
150
                std::to_string(minor) + "." +
×
151
                std::to_string(patch);
×
152
            throwStateError(fmt::format("Compiler and VM versions don't match: got {} while running {}", str_version, ARK_VERSION));
×
153
        }
×
154

155
        const auto bytecode_hash = bcr.sha256();
83✔
156

157
        std::vector<unsigned char> hash(picosha2::k_digest_size);
83✔
158
        picosha2::hash256(m_bytecode.begin() + bytecode::HeaderSize + picosha2::k_digest_size, m_bytecode.end(), hash);
83✔
159
        // checking integrity
160
        for (std::size_t j = 0; j < picosha2::k_digest_size; ++j)
2,739✔
161
        {
162
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
163
            if (hash[j] != bytecode_hash[j])
2,656✔
164
                throwStateError("Integrity check failed");
×
165
#endif
166
        }
2,656✔
167

168
        const auto syms = bcr.symbols();
83✔
169
        const auto vals = bcr.values(syms);
83✔
170
        const auto files = bcr.filenames(vals);
83✔
171
        const auto inst_locs = bcr.instLocations(files);
83✔
172
        const auto [pages, _] = bcr.code(inst_locs);
166✔
173

174
        m_symbols = syms.symbols;
83✔
175
        m_constants = vals.values;
83✔
176
        m_filenames = files.filenames;
83✔
177
        m_inst_locations = inst_locs.locations;
83✔
178
        m_pages = pages;
83✔
179
    }
83✔
180

181
    void State::reset() noexcept
×
182
    {
×
183
        m_symbols.clear();
×
184
        m_constants.clear();
×
NEW
185
        m_filenames.clear();
×
NEW
186
        m_inst_locations.clear();
×
187
        m_pages.clear();
×
188
        m_binded.clear();
×
189
    }
×
190
}
191

192
#ifdef _MSC_VER
193
#    pragma warning(pop)
194
#endif
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