fix decompiler bugs (inf loops, waittillmatch)
This commit is contained in:
parent
0ddfafd98e
commit
cb531e7f1f
@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1787,26 +1787,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2413,7 +2425,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1787,26 +1787,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2413,7 +2425,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
@ -1272,7 +1272,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
|
@ -1272,7 +1272,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1781,26 +1781,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2407,7 +2419,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
@ -1272,7 +1272,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1781,26 +1781,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2407,7 +2419,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1818,26 +1818,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2444,7 +2456,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1787,26 +1787,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2413,7 +2425,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1794,26 +1794,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2420,7 +2432,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
|
||||
auto expr = ast::expr(std::move(stack_.top())); stack_.pop();
|
||||
loc = expr.as_node->loc();
|
||||
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i++)
|
||||
for (auto i = std::stoul(inst->data[0]); i > 0; i--)
|
||||
{
|
||||
auto node = std::move(stack_.top()); stack_.pop();
|
||||
loc = node->loc();
|
||||
@ -1818,26 +1818,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
|
||||
|
||||
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
|
||||
{
|
||||
for (auto i = stmt->list.size() - 1; i > 0; i--)
|
||||
if (stmt->list.size() == 0) return;
|
||||
|
||||
for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if (stmt->list.at(i) == ast::kind::asm_jump_back)
|
||||
{
|
||||
auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label();
|
||||
auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value);
|
||||
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond)
|
||||
if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (i == static_cast<std::int32_t>(start)) // empty loop
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond)
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc)
|
||||
else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt
|
||||
{
|
||||
decompile_infinite(stmt, start, i);
|
||||
i = start;
|
||||
i = stmt->list.size();
|
||||
}
|
||||
else if (stmt->list.at(start).as_cond->value == break_loc) // not inf
|
||||
{
|
||||
decompile_loop(stmt, start, i);
|
||||
i = stmt->list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2444,7 +2456,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
|
||||
}
|
||||
}
|
||||
|
||||
end = find_location_index(stmt, end_loc) - 1; // update end;
|
||||
end = find_location_index(stmt, end_loc); // update end
|
||||
|
||||
// fix empty cases at end
|
||||
if (stmt->list.at(end) == ast::kind::asm_endswitch)
|
||||
end--;
|
||||
|
||||
// TODO: fix more than 1 empty case at end
|
||||
|
||||
stmt->list.erase(stmt->list.begin() + start); // remove 'switch'
|
||||
stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user