4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo/loom
9
#include "simodo/module/ModuleManagement.h"
10
#include "simodo/interpret/Interpret.h"
11
#include "simodo/inout/convert/functions.h"
12
#include "simodo/inout/format/fmt.h"
17
constexpr int BUFFER_SIZE = 1024;
19
namespace simodo::module
21
bool ModuleManagement::debug(const inout::uri_set_t & files)
25
std::unique_lock<std::mutex> locking(_debug_condition_mutex);
27
done = _debug_condition.wait_for(locking, std::chrono::seconds(_timeout)) == std::cv_status::no_timeout;
29
_debug_condition.wait(locking);
31
const loom::Fiber_interface * causer = _loom.causer();
32
std::vector<loom::FiberStructure> fibers = _loom.fibers();
34
if (done && !causer) {
40
_m.reportInformation(inout::fmt("Остановка программы произошла из-за нити %1")
41
.arg(getFiberName(findFiberStructure(fibers,causer))));
44
assert(_loom.paused());
46
_m.reportInformation(inout::fmt("Программа работала дольше %1 сек и была остановлена")
49
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
51
_m.reportInformation(inout::fmt("Индексы исходных файлов:"));
52
for(size_t i=0; i < files.size(); ++i)
53
_m.reportInformation(std::to_string(i) + ". " + files[i]);
55
_m.reportInformation(inout::fmt("Структура нитей (name/no, status, (file,line,host,op), need_delete, waiting_for_no, error? causer?):"));
57
fibers = _loom.fibers();
60
for(const loom::FiberStructure & fs : fibers) {
61
if (fs.p_parent == nullptr)
62
printFiberBranch(fibers, fs, causer);
64
if (fs.status == loom::FiberStatus::Paused) {
65
interpret::Interpret_interface * p_interpret = dynamic_cast<interpret::Interpret_interface *>(fs.p_fiber);
66
if (p_interpret && p_interpret->errors()) {
73
if (_resume && !errors) {
83
///////////////////////////////////////////////////////////////////////////////
86
void ModuleManagement::printFiberBranch(
87
const std::vector<loom::FiberStructure> & fibers,
88
const loom::FiberStructure & fs,
89
const loom::Fiber_interface * causer,
92
std::string info, err;
93
interpret::Interpret_interface * p_interpret = nullptr;
95
if (fs.status == loom::FiberStatus::Flow)
98
p_interpret = dynamic_cast<interpret::Interpret_interface *>(fs.p_fiber);
101
info = getInfo(p_interpret->lookupOperationNode());
102
err = p_interpret->errors() ? ", error" : "";
108
if (fs.p_fiber == causer)
111
char buffer[BUFFER_SIZE];
113
snprintf(buffer, BUFFER_SIZE,
114
"%s> %s, %s, %s, %s, %s%s",
115
std::string(depth,'-').c_str(),
116
getFiberName(fs).c_str(),
117
loom::getFiberStatusName(fs.status),
119
(fs.need_delete ? "yes" : "no"),
120
fs.p_waiting_for ? getFiberName(findFiberStructure(fibers,fs.p_waiting_for)).c_str() : "-",
123
_m.reportInformation(buffer);
126
if (fs.status == loom::FiberStatus::Paused || fs.status == loom::FiberStatus::Delayed)
127
if (_need_full_debug_info || fs.p_fiber == causer)
128
printCallStack(*p_interpret);
130
for(const loom::FiberStructure & child : fibers)
131
if (child.p_parent == fs.p_fiber)
132
printFiberBranch(fibers, child, causer, depth+1);
135
void ModuleManagement::printCallStack(const interpret::Interpret_interface & interp) const
137
std::vector<interpret::boundary_index_t> frames = interp.stack().getFunctionBounds();
139
for(size_t i=0; i < frames.size(); ++i) {
140
interpret::boundary_index_t fi = frames[i];
141
auto [begin, end] = interp.stack().boundaryLowAndTop(fi);
142
interpret::name_index_t function_index = begin - 1;
143
const variable::Variable function_variable = function_index >= interp.stack().index_over_top()
144
? variable::error_variable()
145
: interp.stack().variable(function_index);
149
const ast::Node * p_node = interp.lookupOperationNode(0,frames[i]);
152
text = inout::fmt("\tcalled from %1:").arg(getInfo(p_node));
153
else if (function_variable.type() == variable::ValueType::Ref) {
154
text = inout::fmt("\tcall point is out, formal call location: (f:%1, l:%2):")
155
.arg(function_variable.location().uri_index())
156
.arg(function_variable.location().range().start().line()+1);
159
text = inout::fmt("\tcall point is out");
161
_m.reportInformation(text);
165
if (function_variable.origin().value().isFunction()) {
166
variable::FunctionWrapper function(function_variable);
167
const variable::Variable & return_type = function.getReturnDeclarationVariable();
168
variable::VariableSetWrapper declarations = function.getArgumentDeclarationVariables();
170
text += "\tfn " + inout::toU8(function_variable.origin().name())
172
for(size_t i=0; i < declarations.size(); ++i) {
176
text += variable::getValueTypeName(declarations[i].type());
178
if (!declarations[i].name().empty())
179
text += " " + inout::toU8(declarations[i].name());
182
if (return_type.type() != variable::ValueType::Null)
183
text += " -> " + variable::getValueTypeName(return_type.type());
186
text += "\t<root module>";
188
_m.reportInformation(text);
190
printLocals(interp, fi);
194
void ModuleManagement::printLocals(const interpret::Interpret_interface & causer,
195
interpret::boundary_index_t frame_index) const
197
std::vector<interpret::boundary_index_t> frames = causer.stack().getFunctionBounds();
199
assert(!frames.empty());
201
if (frame_index > frames.front())
202
frame_index = frames.front();
204
std::vector<interpret::name_index_t> locals = causer.stack().getFrameLocals(frame_index);
206
for(interpret::name_index_t i : locals) {
207
const variable::Variable & v = causer.stack().variable(i);
209
_m.reportInformation("\t\t" + inout::toU8(v.origin().name()) + " = " + inout::toU8(variable::toString(v.origin().value())));
213
std::string ModuleManagement::getInfo(const ast::Node * p) const
218
info = "f:" + std::to_string(int(p->token().location().uri_index())) + ", "
219
+ "l:" + std::to_string(p->token().location().range().start().line()+1) + ", "
220
+ "h:" + inout::toU8(p->host()) + ", "
221
+ "o:" + std::to_string(int(p->operation()));
225
return "(" + info + ")";
228
std::string ModuleManagement::getFiberName(const loom::FiberStructure & fs) const
231
return std::to_string(int(fs.no));
233
return fs.name + "/" + std::to_string(int(fs.no));
236
const loom::FiberStructure &ModuleManagement::findFiberStructure(const std::vector<loom::FiberStructure> & fibers, const loom::Fiber_interface * p_fiber) const
238
static const loom::FiberStructure none {nullptr,nullptr,false,loom::FiberStatus::Complete,0,{}};
240
auto const it = std::find_if(fibers.begin(), fibers.end(), [p_fiber](const loom::FiberStructure & fs){
241
return fs.p_fiber == p_fiber;
244
if (it == fibers.end())