Skip to content

Commit

Permalink
Merge pull request #326 from polystat/fix_static_bug
Browse files Browse the repository at this point in the history
Fix static bug #325
  • Loading branch information
IngeniariusSoftware authored Aug 28, 2022
2 parents a39ce50 + 3ef9e02 commit 57b602c
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 85 deletions.
11 changes: 1 addition & 10 deletions project/src/transpiler/memory_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,9 @@ EOObject MemoryManager::GetEOObject() const {
return res;
}

void MemoryManager::RemoveAllUsed(std::vector<Variable> &all_local) {
size_t local_shift = 0;
size_t static_shift = 0;
std::reverse(std::begin(all_local), std::end(all_local));
void MemoryManager::RemoveAllUsed(const std::vector<Variable> &all_local) {
for (const auto &var : all_local) {
auto var_in_memory = find(variables_.begin(), variables_.end(), var);
if (var_in_memory->id->isStaticLocal()) {
static_shift += var_in_memory->size;
var_in_memory->position -= local_shift;
continue;
}
local_shift += var_in_memory->size;
pointer_ -= var_in_memory->size;
variables_.erase(var_in_memory);
}
Expand Down
2 changes: 1 addition & 1 deletion project/src/transpiler/memory_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class MemoryManager {

[[nodiscard]] EOObject GetEOObject() const;

void RemoveAllUsed(std::vector<Variable> &all_local);
void RemoveAllUsed(const std::vector<Variable> &all_local);

void SetExtEqGlob();

Expand Down
106 changes: 65 additions & 41 deletions project/src/transpiler/process_variables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,141 +46,163 @@ using std::vector;
extern UnitTranspiler transpiler;

void ProcessDeclStmt(size_t shift, vector<Variable> &all_local,
DeclStmt *decl_stmt);
DeclStmt *decl_stmt, bool process_only_static);

void ProcessForStmtLocalVariables(vector<Variable> &all_local, size_t shift,
ForStmt *for_stmt);
ForStmt *for_stmt, bool process_only_static);
void ProcessWhileStmtLocalVariables(vector<Variable> &all_local, size_t shift,
WhileStmt *while_stmt);
WhileStmt *while_stmt,
bool process_only_static);
void ProcessCaseStmtLocalVariables(vector<Variable> &all_local, size_t shift,
CaseStmt *case_stmt);
CaseStmt *case_stmt,
bool process_only_static);
void ProcessIfStmtLocalVariables(vector<Variable> &all_local, size_t shift,
IfStmt *if_stmt);
IfStmt *if_stmt, bool process_only_static);
void ProcessDefaultStmtLocalVariables(vector<Variable> &all_local, size_t shift,
DefaultStmt *default_stmt);
DefaultStmt *default_stmt,
bool process_only_static);
void ProcessSwitchStmtLocalVariables(vector<Variable> &all_local, size_t shift,
SwitchStmt *switch_stmt);
SwitchStmt *switch_stmt,
bool process_only_static);
void ProcessDoStmtLocalVariables(vector<Variable> &all_local, size_t shift,
DoStmt *do_stmt);
DoStmt *do_stmt, bool process_only_static);
void ProcessStmtLocalVariables(vector<Variable> &all_local, size_t shift,
Stmt *stmt) {
Stmt *stmt, bool process_only_static) {
Stmt::StmtClass stmt_class = stmt->getStmtClass();
if (stmt_class == Stmt::DeclStmtClass) {
auto *decl_stmt = dyn_cast<DeclStmt>(stmt);
ProcessDeclStmt(shift, all_local, decl_stmt);
ProcessDeclStmt(shift, all_local, decl_stmt, process_only_static);
} else if (stmt_class == Stmt::ForStmtClass) {
auto *for_stmt = dyn_cast<ForStmt>(stmt);
ProcessForStmtLocalVariables(all_local, shift, for_stmt);
ProcessForStmtLocalVariables(all_local, shift, for_stmt,
process_only_static);
} else if (stmt_class == Stmt::CompoundStmtClass) {
auto *compound_stmt = dyn_cast<CompoundStmt>(stmt);
ProcessFunctionLocalVariables(compound_stmt, all_local, shift);
ProcessFunctionLocalVariables(compound_stmt, all_local, shift,
process_only_static);
} else if (stmt_class == Stmt::WhileStmtClass) {
auto *while_stmt = dyn_cast<WhileStmt>(stmt);
ProcessWhileStmtLocalVariables(all_local, shift, while_stmt);
ProcessWhileStmtLocalVariables(all_local, shift, while_stmt,
process_only_static);
} else if (stmt_class == Stmt::SwitchStmtClass) {
auto *switch_stmt = dyn_cast<SwitchStmt>(stmt);
ProcessSwitchStmtLocalVariables(all_local, shift, switch_stmt);
ProcessSwitchStmtLocalVariables(all_local, shift, switch_stmt,
process_only_static);
} else if (stmt_class == Stmt::DoStmtClass) {
auto *do_stmt = dyn_cast<DoStmt>(stmt);
ProcessDoStmtLocalVariables(all_local, shift, do_stmt);
ProcessDoStmtLocalVariables(all_local, shift, do_stmt, process_only_static);
} else if (stmt_class == Stmt::CaseStmtClass) {
auto *case_stmt = dyn_cast<CaseStmt>(stmt);
ProcessCaseStmtLocalVariables(all_local, shift, case_stmt);
ProcessCaseStmtLocalVariables(all_local, shift, case_stmt,
process_only_static);
} else if (stmt_class == Stmt::DefaultStmtClass) {
auto *default_stmt = dyn_cast<DefaultStmt>(stmt);
ProcessDefaultStmtLocalVariables(all_local, shift, default_stmt);
ProcessDefaultStmtLocalVariables(all_local, shift, default_stmt,
process_only_static);
} else if (stmt_class == Stmt::IfStmtClass) {
auto *if_stmt = dyn_cast<IfStmt>(stmt);
ProcessIfStmtLocalVariables(all_local, shift, if_stmt);
ProcessIfStmtLocalVariables(all_local, shift, if_stmt, process_only_static);
}
}

void ProcessFunctionLocalVariables(const clang::CompoundStmt *CS,
std::vector<Variable> &all_local,
size_t shift) {
size_t shift, bool process_only_static) {
if (CS == nullptr) {
return;
}
for (auto *stmt : CS->body()) {
ProcessStmtLocalVariables(all_local, shift, stmt);
ProcessStmtLocalVariables(all_local, shift, stmt, process_only_static);
}
}
void ProcessDoStmtLocalVariables(vector<Variable> &all_local, size_t shift,
DoStmt *do_stmt) {
DoStmt *do_stmt, bool process_only_static) {
if (do_stmt == nullptr) {
return;
}
if (do_stmt->getBody() != nullptr &&
do_stmt->getBody()->getStmtClass() == Stmt::CompoundStmtClass) {
auto *compound_stmt = dyn_cast<CompoundStmt>(do_stmt->getBody());
ProcessFunctionLocalVariables(compound_stmt, all_local, shift);
ProcessFunctionLocalVariables(compound_stmt, all_local, shift,
process_only_static);
}
}
void ProcessSwitchStmtLocalVariables(vector<Variable> &all_local, size_t shift,
SwitchStmt *switch_stmt) {
SwitchStmt *switch_stmt,
bool process_only_static) {
if (switch_stmt == nullptr) {
return;
}
if (switch_stmt->getBody() != nullptr &&
switch_stmt->getBody()->getStmtClass() == Stmt::CompoundStmtClass) {
auto *compound_stmt = dyn_cast<CompoundStmt>(switch_stmt->getBody());
ProcessFunctionLocalVariables(compound_stmt, all_local, shift);
ProcessFunctionLocalVariables(compound_stmt, all_local, shift,
process_only_static);
}
}
void ProcessDefaultStmtLocalVariables(vector<Variable> &all_local, size_t shift,
DefaultStmt *default_stmt) {
DefaultStmt *default_stmt,
bool process_only_static) {
if (default_stmt == nullptr) {
return;
}
if (default_stmt->getSubStmt() != nullptr &&
default_stmt->getSubStmt()->getStmtClass() == Stmt::CompoundStmtClass) {
auto *compound_stmt = dyn_cast<CompoundStmt>(default_stmt->getSubStmt());
ProcessFunctionLocalVariables(compound_stmt, all_local, shift);
ProcessFunctionLocalVariables(compound_stmt, all_local, shift,
process_only_static);
} else if (default_stmt->getSubStmt() != nullptr &&
default_stmt->getSubStmt()->getStmtClass() ==
Stmt::DeclStmtClass) {
auto *decl_stmt = dyn_cast<DeclStmt>(default_stmt->getSubStmt());
ProcessDeclStmt(shift, all_local, decl_stmt);
ProcessDeclStmt(shift, all_local, decl_stmt, process_only_static);
}
}
void ProcessIfStmtLocalVariables(vector<Variable> &all_local, size_t shift,
IfStmt *if_stmt) {
IfStmt *if_stmt, bool process_only_static) {
if (if_stmt == nullptr) {
return;
}
if (if_stmt->getThen() != nullptr) {
ProcessStmtLocalVariables(all_local, shift, if_stmt->getThen());
ProcessStmtLocalVariables(all_local, shift, if_stmt->getThen(),
process_only_static);
}
if (if_stmt->getElse() != nullptr) {
ProcessStmtLocalVariables(all_local, shift, if_stmt->getElse());
ProcessStmtLocalVariables(all_local, shift, if_stmt->getElse(),
process_only_static);
}
}
void ProcessCaseStmtLocalVariables(vector<Variable> &all_local, size_t shift,
CaseStmt *case_stmt) {
CaseStmt *case_stmt,
bool process_only_static) {
if (case_stmt == nullptr || case_stmt->getSubStmt() == nullptr) {
return;
}
ProcessStmtLocalVariables(all_local, shift, case_stmt->getSubStmt());
ProcessStmtLocalVariables(all_local, shift, case_stmt->getSubStmt(),
process_only_static);
}
void ProcessWhileStmtLocalVariables(vector<Variable> &all_local, size_t shift,
WhileStmt *while_stmt) {
WhileStmt *while_stmt,
bool process_only_static) {
if (while_stmt == nullptr || while_stmt->getBody() == nullptr) {
return;
}
ProcessStmtLocalVariables(all_local, shift, while_stmt->getBody());
ProcessStmtLocalVariables(all_local, shift, while_stmt->getBody(),
process_only_static);
}
void ProcessForStmtLocalVariables(vector<Variable> &all_local, size_t shift,
ForStmt *for_stmt) {
ForStmt *for_stmt, bool process_only_static) {
if (for_stmt == nullptr) {
return;
}
if (for_stmt->getInit() != nullptr &&
for_stmt->getInit()->getStmtClass() == Stmt::DeclStmtClass) {
auto *decl_stmt = dyn_cast<DeclStmt>(for_stmt->getInit());
ProcessDeclStmt(shift, all_local, decl_stmt);
ProcessDeclStmt(shift, all_local, decl_stmt, process_only_static);
}
if (for_stmt->getBody() != nullptr) {
ProcessStmtLocalVariables(all_local, shift, for_stmt->getBody());
ProcessStmtLocalVariables(all_local, shift, for_stmt->getBody(),
process_only_static);
}
}

Expand All @@ -200,7 +222,7 @@ void ProcessCompoundStatementLocalVariables(const clang::CompoundStmt *CS,
Decl::Kind decl_kind = decl->getKind();
if (decl_kind == Decl::Var) {
auto *var_decl = dyn_cast<VarDecl>(decl);
if (var_decl != nullptr) {
if (var_decl != nullptr && !var_decl->isStaticLocal()) {
all_local.push_back(transpiler.glob_.GetVarById(var_decl));
}
}
Expand All @@ -220,7 +242,7 @@ void ProcessCompoundStatementLocalVariables(const clang::CompoundStmt *CS,
Decl::Kind decl_kind = decl->getKind();
if (decl_kind == Decl::Var) {
auto *var_decl = dyn_cast<VarDecl>(decl);
if (var_decl != nullptr) {
if (var_decl != nullptr && !var_decl->isStaticLocal()) {
all_local.push_back(transpiler.glob_.GetVarById(var_decl));
}
}
Expand All @@ -231,7 +253,7 @@ void ProcessCompoundStatementLocalVariables(const clang::CompoundStmt *CS,
}

void ProcessDeclStmt(size_t shift, vector<Variable> &all_local,
DeclStmt *decl_stmt) {
DeclStmt *decl_stmt, bool process_only_static) {
if (decl_stmt == nullptr) {
return;
}
Expand All @@ -240,7 +262,9 @@ void ProcessDeclStmt(size_t shift, vector<Variable> &all_local,
if (decl_kind == Decl::Var) {
auto *var_decl = dyn_cast<VarDecl>(decl);
if (var_decl != nullptr) {
all_local.push_back(ProcessVariable(var_decl, "local-start", shift));
if (var_decl->isStaticLocal() == process_only_static) {
all_local.push_back(ProcessVariable(var_decl, "local-start", shift));
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion project/src/transpiler/process_variables.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

void ProcessFunctionLocalVariables(const clang::CompoundStmt* CS,
std::vector<Variable>& all_local,
size_t shift);
size_t shift, bool process_only_static);

void ProcessCompoundStatementLocalVariables(const clang::CompoundStmt* CS,
std::vector<Variable>& all_local);
Expand Down
44 changes: 40 additions & 4 deletions project/src/transpiler/transpile_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,16 @@ EOObject GetFunctionBody(const clang::FunctionDecl *FD) {
return EOObject(EOObjectType::EO_EMPTY);
}
size_t shift = transpiler.glob_.GetFreeSpacePointer();
vector<Variable> all_static_local;
ProcessFunctionLocalVariables(func_body, all_static_local, shift, true);
shift = transpiler.glob_.GetFreeSpacePointer();
size_t param_memory_size = GetParamMemorySize(FD->parameters());
vector<Variable> all_param = ProcessFunctionParams(FD->parameters(), shift);
vector<EOObject> all_types = PrecessRecordTypes(func_body);

vector<Variable> all_local;
ProcessFunctionLocalVariables(func_body, all_local,
shift + param_memory_size);
ProcessFunctionLocalVariables(func_body, all_local, shift + param_memory_size,
false);
EOObject func_body_eo = EOObject(EOObjectType::EO_EMPTY);
EOObject local_start("plus", "local-start");
local_start.nested.emplace_back("param-start");
Expand Down Expand Up @@ -598,9 +602,20 @@ EOObject GetSwitchEOObject(const SwitchStmt *p_stmt) {
eq_obj.nested.push_back(GetStmtEOObject(case_stmt->getLHS()));
cond_obj.nested.push_back(
GetCaseCondEOObject(all_cases, switch_expr_object, 0));
if_obj.nested.push_back(cond_obj);
if (nested != nullptr &&
nested->getStmtClass() == Stmt::DefaultStmtClass) {
EOObject always_true_obj{"or"};
always_true_obj.nested.push_back(cond_obj);
always_true_obj.nested.emplace_back("TRUE", EOObjectType::EO_LITERAL);
if_obj.nested.push_back(always_true_obj);
const auto *def_stmt = dyn_cast<DefaultStmt>(nested);
nested = def_stmt->getSubStmt();
} else {
if_obj.nested.push_back(cond_obj);
}
EOObject buffer_obj{"seq"};
if (nested != nullptr) {
if (nested != nullptr &&
nested->getStmtClass() != Stmt::DefaultStmtClass) {
buffer_obj.nested.push_back(GetStmtEOObject(nested));
}
auto tmp = stmt;
Expand All @@ -614,6 +629,27 @@ EOObject GetSwitchEOObject(const SwitchStmt *p_stmt) {
buffer_obj.nested.emplace_back("TRUE", EOObjectType::EO_LITERAL);
if_obj.nested.push_back(buffer_obj);
seq_object.nested.push_back(if_obj);

if (nested != nullptr &&
nested->getStmtClass() == Stmt::DefaultStmtClass) {
const auto *default_stmt = dyn_cast<DefaultStmt>(nested);
EOObject buffer_obj_def{"seq"};
if (default_stmt->getSubStmt() != nullptr) {
buffer_obj_def.nested.push_back(
GetStmtEOObject(default_stmt->getSubStmt()));
}
auto tmp_def = stmt;
tmp_def++;
while (tmp_def != end &&
(*tmp_def)->getStmtClass() != Stmt::CaseStmtClass &&
(*tmp_def)->getStmtClass() != Stmt::DefaultStmtClass) {
buffer_obj_def.nested.push_back(GetStmtEOObject(*tmp_def));
tmp_def++;
}
buffer_obj_def.nested.push_back(set_flag_object);
buffer_obj_def.nested.emplace_back("TRUE", EOObjectType::EO_LITERAL);
seq_object.nested.push_back(buffer_obj_def);
}
} else if ((*stmt)->getStmtClass() == Stmt::DefaultStmtClass) {
const auto *default_stmt = dyn_cast<DefaultStmt>(*stmt);
EOObject buffer_obj{"seq"};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,22 @@ void op10() {

void test_switch() {
switch (x) {
case 1:
op1();
break;
case 2:
case 3:
op23();
break;
case 4:
op4();
case 5:
op5();
break;
case 6:
default:
op10();
break;
case 1:
op1();
break;
case 2:
case 3:
op23();
break;
case 4:
op4();
case 5:
op5();
break;
case 6:
default:
op10();
break;
}
}

Expand Down
Loading

1 comment on commit 57b602c

@0pdd
Copy link
Member

@0pdd 0pdd commented on 57b602c Aug 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to retrieve PDD puzzles from the code base and submit them to github. If you think that it's a bug on our side, please submit it to yegor256/0pdd:

set -x && set -e && set -o pipefail && cd /tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ && pdd -v -f /tmp/20220828-3508-1egkir9 [1]: + set -e + set -o pipefail + cd /tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ + pdd -v -f...

Please, copy and paste this stack trace to GitHub:

UserError
set -x && set -e && set -o pipefail && cd /tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ && pdd -v -f /tmp/20220828-3508-1egkir9 [1]:
+ set -e
+ set -o pipefail
+ cd /tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ
+ pdd -v -f /tmp/20220828-3508-1egkir9

My version is 0.21.3
Ruby version is 2.7.5 at x86_64-linux
Reading from root dir /tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ
/tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ/project/scripts/data/skips/test.txt is a binary file (0 bytes)
/tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ/project/tests/in_progress/for_main/.gitkeep is a binary file (0 bytes)
/tmp/0pdd20220828-13-l0g5pe/Z2l0QGdpdGh1Yi5jb206cG9seXN0YXQvYzJlby5naXQ/result/eo/c2eo/src/.gitkeep is a binary file (0 bytes)
Reading .gitignore ...
Reading .gitattributes ...
Reading Dockerfile ...
Reading .rultor.yml ...
Reading project/CMakeLists.txt ...
Reading project/scripts/build_c2eo.py ...
Reading project/scripts/build_eo.py ...
Reading project/scripts/code_lines.py ...
Reading project/scripts/c2eo-all.py ...
Reading project/scripts/clang_tidy.py ...
Reading project/scripts/compile.py ...
Reading project/scripts/readme.md ...
Reading project/scripts/clean_before_transpilation.py ...
Reading project/scripts/tools.py ...
Reading project/scripts/update-release.py ...
Reading project/scripts/test.py ...
Reading project/scripts/transpile.py ...
Reading project/scripts/codecov.py ...
Reading project/scripts/data/settings.yml ...
Reading project/scripts/data/meta/run.sh.txt ...
Reading project/scripts/data/meta/plug.txt ...
Reading project/scripts/data/skips/gcc.txt ...
Reading project/scripts/data/skips/testcuite.txt ...
ERROR: project/scripts/data/skips/testcuite.txt; PDD::Error at project/scripts/data/skips/testcuite.txt:1: TODO found, but puzzle can't be parsed, most probably because TODO is not followed by a puzzle marker, as this page explains: https://github.com/cqfn/pdd#how-to-format
If you can't understand the cause of this issue or you don't know how to fix it, please submit a GitHub issue, we will try to help you: https://github.com/cqfn/pdd/issues. This tool is still in its beta version and we will appreciate your feedback. Here is where you can find more documentation: https://github.com/cqfn/pdd/blob/master/README.md.
Exit code is 1

/app/objects/git_repo.rb:73:in `rescue in block in xml'
/app/objects/git_repo.rb:70:in `block in xml'
/app/vendor/ruby-2.7.5/lib/ruby/2.7.0/tempfile.rb:291:in `open'
/app/objects/git_repo.rb:69:in `xml'
/app/objects/puzzles.rb:41:in `deploy'
/app/objects/jobs/job.rb:38:in `proceed'
/app/objects/jobs/job_starred.rb:32:in `proceed'
/app/objects/jobs/job_recorded.rb:31:in `proceed'
/app/objects/jobs/job_emailed.rb:33:in `proceed'
/app/objects/jobs/job_commiterrors.rb:33:in `proceed'
/app/objects/jobs/job_detached.rb:48:in `exclusive'
/app/objects/jobs/job_detached.rb:36:in `block in proceed'
/app/objects/jobs/job_detached.rb:36:in `fork'
/app/objects/jobs/job_detached.rb:36:in `proceed'
/app/0pdd.rb:518:in `process_request'
/app/0pdd.rb:355:in `block in <top (required)>'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1686:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1686:in `block in compile!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1023:in `block (3 levels) in route!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1042:in `route_eval'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1023:in `block (2 levels) in route!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1071:in `block in process_route'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1069:in `catch'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1069:in `process_route'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1021:in `block in route!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1018:in `each'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1018:in `route!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1140:in `block in dispatch!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `block in invoke'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `catch'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `invoke'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1135:in `dispatch!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:949:in `block in call!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `block in invoke'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `catch'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1112:in `invoke'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:949:in `call!'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:938:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-protection-2.2.2/lib/rack/protection/xss_header.rb:18:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-protection-2.2.2/lib/rack/protection/path_traversal.rb:16:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-protection-2.2.2/lib/rack/protection/json_csrf.rb:26:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-protection-2.2.2/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-protection-2.2.2/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-protection-2.2.2/lib/rack/protection/frame_options.rb:31:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-2.2.4/lib/rack/logger.rb:17:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-2.2.4/lib/rack/common_logger.rb:38:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:255:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:248:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-2.2.4/lib/rack/head.rb:12:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-2.2.4/lib/rack/method_override.rb:24:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:218:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1993:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1553:in `block in call'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1769:in `synchronize'
/app/vendor/bundle/ruby/2.7.0/gems/sinatra-2.2.2/lib/sinatra/base.rb:1553:in `call'
/app/vendor/bundle/ruby/2.7.0/gems/rack-2.2.4/lib/rack/handler/webrick.rb:95:in `service'
/app/vendor/ruby-2.7.5/lib/ruby/2.7.0/webrick/httpserver.rb:140:in `service'
/app/vendor/ruby-2.7.5/lib/ruby/2.7.0/webrick/httpserver.rb:96:in `run'
/app/vendor/ruby-2.7.5/lib/ruby/2.7.0/webrick/server.rb:307:in `block in start_thread'

Please sign in to comment.