loom

Форк
0
/
FrameBody.cpp 
195 строк · 5.5 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2024 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo/loom
7
*/
8

9
#include "simodo/engine/FrameBody.h"
10
#include "simodo/variable/Module_interface.h"
11
#include "simodo/inout/format/fmt.h"
12

13
#include <cassert>
14

15
#if __cplusplus >= __cpp_2017
16
#include <filesystem>
17
namespace fs = std::filesystem;
18
#else
19
#include <experimental/filesystem>
20
namespace fs = std::filesystem::experimental;
21
#endif
22

23
namespace simodo::engine
24
{
25
    FrameBody::FrameBody(inout::Reporter_abstract & m, 
26
                    interpret::ModuleManagement_interface & mm,
27
                    const std::vector<std::string> & preload_module_names,
28
                    const std::string & initial_contracts_file,
29
                    const std::string & source_file)
30
        : _m(m)
31
        , _mm(mm)
32
        , _preload_module_names(preload_module_names)
33
        , _initial_contracts_file(initial_contracts_file)
34
        , _source_file(source_file)
35
    {
36
    }
37

38
    FrameBody::~FrameBody()
39
    {
40
        if (_inter)
41
            delete _inter;
42
    }
43

44
    const interpret::Interpret_interface & FrameBody::interpret() const
45
    {
46
        return *_inter;
47
    }
48

49
    bool FrameBody::prepare()
50
    {
51
        if (_stage >= Stage::Initialized)
52
            return true;
53

54
        _inter = _mm.interpret_factory().create();
55

56
        if (!_inter)
57
            return false;
58

59
        _inter->stack().startBoundary(interpret::BoundScope::Global, interpret::BOUNDARY_MARK_MODULE_FRAME);
60

61
        for(const std::string & module_name : _preload_module_names) {
62
            std::shared_ptr<variable::Module_interface> module = _mm.loadHardModule(module_name, _inter);
63
            if (!module)
64
                return false;
65

66
            _inter->stack().push({ inout::toU16(module_name), module->instantiate(module), inout::null_token_location,
67
                                    {{  {variable::SPEC_ORIGIN, variable::SPEC_ORIGIN_MODULE},
68
                                        {variable::SPEC_BUILTIN, true},
69
                                    }} });
70

71
            _inter->stack().addGlobal(_inter->stack().top());
72
        }
73

74
        if (!_initial_contracts_file.empty()) {
75
            _inter->addFile(_initial_contracts_file);
76
            _init_code = _mm.getCode(_initial_contracts_file, _inter->files());
77

78
            if (!_init_code)
79
                return false;
80
        }
81

82
        _inter->addFile(_source_file);
83
        _source_code = _mm.getCode(_source_file, _inter->files());
84

85
        if (!_source_code)
86
            return false;
87

88
        if (_init_code) {
89
            _code = _init_code;
90
        }
91
        else {
92
            _code = _source_code;
93
        }
94

95
        _stage = Stage::Prepared;
96

97
        return true;
98
    }
99

100
    loom::FiberStatus FrameBody::run(interpret::NextStepBehaviour mode)
101
    {
102
        if (_stage < Stage::Prepared || _stage == Stage::Completed || !_code)
103
            return loom::FiberStatus::Complete;
104

105
        /// \todo Переделать без goto
106
    WAIT_FIBER:
107
        if (_code == _source_code) {
108
            if (_stage != Stage::Running) {
109
                _stage = Stage::Running;
110
                _inter->stack().startBoundary(interpret::BoundScope::Global, interpret::BOUNDARY_MARK_MODULE_FRAME);
111
                _inter->logistics().setNextStepBehaviour(mode);
112
                _inter->addFlowLayer(*_code);
113
                _inter->loom().stretch(_inter->fiber());
114
            }
115
            else {
116
                _inter->logistics().setNextStepBehaviour(mode);
117
            }
118
        }
119
        else if (_stage == Stage::Prepared) {
120
            _stage = Stage::Initialized;
121
            _inter->addFlowLayer(*_code);
122
            _inter->loom().stretch(_inter->fiber());
123
        }
124
        else {
125
            _inter->logistics().setNextStepBehaviour(mode);
126
        }
127

128
        if (_inter->loom().paused())
129
            _inter->loom().resume();
130

131
        _busy = true;
132
        loom::FiberStatus fiber_status = _inter->loom().waitFiber(_inter->fiber());
133
        _busy = false;
134

135
        switch (fiber_status)
136
        {
137
        case loom::FiberStatus::Complete:
138
            if (_code == _init_code) {
139
                _code = _source_code;
140
                goto WAIT_FIBER;
141
            }
142
            _stage = Stage::Completed;
143
            break;
144
        
145
        default:
146
            break;
147
        }
148

149
        return fiber_status;
150
    }
151

152
    void FrameBody::cancel()
153
    {
154
        _inter->loom().stop();
155
    }
156

157
    void FrameBody::pause()
158
    {
159
        _inter->loom().pause();
160
    }
161

162
    inout::Reporter_abstract & FrameBody::reporter() const
163
    {
164
        return _m;
165
    }
166

167
    std::vector<loom::FiberStructure> FrameBody::fibers() const
168
    {
169
        return _inter->loom().fibers();
170
    }
171

172
    const loom::Fiber_interface * FrameBody::causer() const
173
    {
174
        return _inter->loom().causer();
175
    }
176

177
    inout::uri_set_t FrameBody::files() const
178
    {
179
        return _inter->files();
180
    }
181

182
    // ===============================================================================================
183
    // static ========================================================================================
184
    // ===============================================================================================
185

186
    std::string makeInitialContractFile(const std::string & loom_dir)
187
    {
188
        fs::path initial_contracts_path = fs::path(loom_dir)
189
                                / fs::path(engine::INITIAL_CONTRACTS_DIR) 
190
                                / fs::path(engine::INITIAL_CONTRACTS_FILE);
191

192
        return initial_contracts_path.lexically_normal().string();
193
    }
194

195
}
196

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.