finish decompiler loop statements

This commit is contained in:
xensik 2022-07-19 13:50:12 +02:00
parent 0527d294ed
commit 0fc0834a83
9 changed files with 369 additions and 126 deletions

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1884,17 +1877,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1909,7 +1932,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -1984,6 +2007,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1884,17 +1877,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1909,7 +1932,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -1984,6 +2007,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1878,17 +1871,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1903,7 +1926,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -1978,6 +2001,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1878,17 +1871,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1903,7 +1926,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -1978,6 +2001,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1878,17 +1871,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1903,7 +1926,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -1978,6 +2001,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1915,17 +1908,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1940,7 +1963,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -2015,6 +2038,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1884,17 +1877,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1909,7 +1932,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -1984,6 +2007,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1891,17 +1884,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1916,7 +1939,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -1991,6 +2014,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}

View File

@ -72,13 +72,6 @@ void decompiler::decompile_function(const function::ptr& func)
// remove last return
stmt->list.pop_back();
// hotfix empty else block at func end
if (stmt->list.size() > 0 && stmt->list.back() == ast::kind::asm_jump)
{
if (stmt->list.back().as_jump->value == blk.loc_end)
stmt->list.pop_back();
}
blocks_.push_back(blk);
decompile_statements(stmt);
@ -1915,17 +1908,47 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
// if block is a loop check break, continue
if (stmt->list.at(j).as_jump->value == blocks_.back().loc_continue)
{
// last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
// check for if/else or if/continue
if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::stmt_return)
{
// block ends with a return, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (j - i > 1 && stmt->list.at(j - 1) == ast::kind::asm_jump)
{
if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_break)
{
// block ends with a break, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j - 1).as_jump->value == blocks_.back().loc_continue)
{
// if { break/return } else { continue } at loop block end
if (j - i > 2 && (stmt->list.at(j - 2) == ast::kind::asm_jump || stmt->list.at(j - 2) == ast::kind::stmt_return))
{
decompile_if(stmt, i, j);
}
else
{
// block ends with a continue, so jump belows to if/else
decompile_ifelse(stmt, i, j);
}
}
else
{
// jump belows to if/continue
decompile_if(stmt, i, j);
}
}
else
{ // last if/else inside a loop still trigger this :(
decompile_if(stmt, i, j);
}
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_break)
{
decompile_if(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == blocks_.back().loc_end)
{
decompile_ifelse(stmt, i, j);
}
else if (stmt->list.at(j).as_jump->value == entry.as_cond->value)
{
if (find_location_reference(stmt, i + 1, j, entry.as_cond->value))
@ -1940,7 +1963,7 @@ void decompiler::decompile_ifelses(const ast::stmt_list::ptr& stmt)
}
else
{
decompile_ifelse(stmt, i, j); // TODO: if else block is empty, convert it to only if!
decompile_ifelse(stmt, i, j);
}
}
else if (stmt->list.at(j) == ast::kind::stmt_return && stmt->list.at(j).as_return->expr == ast::kind::null)
@ -2015,6 +2038,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
auto stmt = ast::stmt(std::make_unique<ast::stmt_break>(loc));
block->list.insert(block->list.begin() + i, std::move(stmt));
}
else
{
printf("WARNING: unresolved jump to '%s', maybe incomplete for loop\n", jump_loc.data());
}
}
}
}