decompiler support for tuples

This commit is contained in:
xensik 2022-07-17 13:49:31 +02:00
parent b8cc78d106
commit c44c54f815
20 changed files with 860 additions and 135 deletions

View File

@ -1338,7 +1338,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1607,7 +1607,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1783,6 +1783,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -1987,6 +1988,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3077,17 +3139,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3316,18 +3381,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1338,7 +1338,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1607,7 +1607,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1783,6 +1783,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -1987,6 +1988,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3077,17 +3139,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3316,18 +3381,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1332,7 +1332,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1601,7 +1601,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1777,6 +1777,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -1981,6 +1982,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3071,17 +3133,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3310,18 +3375,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1332,7 +1332,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1601,7 +1601,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1777,6 +1777,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -1981,6 +1982,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3071,17 +3133,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3310,18 +3375,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1332,7 +1332,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1601,7 +1601,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1777,6 +1777,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -1981,6 +1982,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3071,17 +3133,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3310,18 +3375,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1338,7 +1338,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1607,7 +1607,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1814,6 +1814,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -2018,6 +2019,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3114,17 +3176,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3353,18 +3418,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1338,7 +1338,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1607,7 +1607,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1783,6 +1783,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -1987,6 +1988,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3077,17 +3139,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3316,18 +3381,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1338,7 +1338,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1607,7 +1607,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1790,6 +1790,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -1994,6 +1995,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3084,17 +3146,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3323,18 +3388,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -1338,7 +1338,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
auto obj = ast::expr(std::move(stack_.top())); stack_.pop();
auto event = ast::expr(std::move(stack_.top())); stack_.pop();
loc = event.as_node->loc();
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj) , std::move(event));
auto stmt = std::make_unique<ast::stmt_endon>(loc, std::move(obj), std::move(event));
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1607,7 +1607,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst)
break;
case opcode::OP_ClearLocalVariableFieldCached0:
{
auto stmt = std::make_unique<ast::asm_clear>(loc,"0");
auto stmt = std::make_unique<ast::asm_clear>(loc, "0");
func_->stmt->list.push_back(ast::stmt(std::move(stmt)));
}
break;
@ -1814,6 +1814,7 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt)
decompile_switches(stmt);
decompile_ifelses(stmt);
decompile_aborts(stmt);
decompile_tuples(stmt);
}
void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt)
@ -2018,6 +2019,67 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& block)
}
}
void decompiler::decompile_tuples(const ast::stmt_list::ptr& block)
{
for (auto i = 1u; i < block->list.size(); i++)
{
if (block->list.at(i) == ast::kind::asm_clear)
{
auto j = i - 1;
auto found = false, done = false;
while (j >= 0 && block->list.at(j) == ast::kind::stmt_assign)
{
auto& expr = block->list.at(j).as_assign->expr;
if (expr != ast::kind::expr_assign_equal)
break;
if (!done)
{
if (expr.as_assign_equal->rvalue != ast::kind::expr_array)
break;
if (expr.as_assign_equal->rvalue.as_array->key != ast::kind::expr_integer)
break;
if (expr.as_assign_equal->rvalue.as_array->key.as_integer->value == "0")
done = true;
j--;
}
else
{
if (expr.as_assign_equal->lvalue == ast::kind::asm_create || expr.as_assign_equal->lvalue == ast::kind::asm_access)
found = true;
break;
}
}
if (found)
{
auto& stmt = block->list.at(j); // temp = expr;
auto new_expr = std::make_unique<ast::expr_tuple>(stmt.loc());
new_expr->temp = std::move(stmt.as_assign->expr.as_assign_equal->lvalue);
j++;
while (j < i)
{
new_expr->list.push_back(std::move(block->list.at(j).as_assign->expr.as_assign_equal->lvalue));
block->list.erase(block->list.begin() + j);
i--;
}
block->list.erase(block->list.begin() + j); // clear temp array
i--;
stmt.as_assign->expr.as_assign_equal->lvalue = ast::expr(std::move(new_expr));
}
}
}
}
void decompiler::decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end)
{
block blk;
@ -3114,17 +3176,20 @@ void decompiler::process_expr(ast::expr& expr, const block::ptr& blk)
case ast::kind::expr_add_array:
process_expr_add_array(expr.as_add_array, blk);
break;
case ast::kind::expr_array:
process_array_variable(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_field_variable(expr.as_field, blk);
break;
case ast::kind::expr_size:
process_expr_size(expr.as_size, blk);
break;
case ast::kind::expr_tuple:
process_expr_tuple(expr.as_tuple, blk);
break;
case ast::kind::expr_array:
process_expr_array(expr.as_array, blk);
break;
case ast::kind::expr_field:
process_expr_field(expr.as_field, blk);
break;
case ast::kind::expr_identifier:
process_local_variable(expr.as_identifier, blk);
process_expr_local(expr.as_identifier, blk);
break;
case ast::kind::expr_vector:
process_expr_vector(expr.as_vector, blk);
@ -3353,18 +3418,28 @@ void decompiler::process_expr_size(const ast::expr_size::ptr& expr, const block:
process_expr(expr->obj, blk);
}
void decompiler::process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk)
{
process_expr(expr->temp, blk);
for (auto& entry : expr->list)
{
process_expr(entry, blk);
}
}
void decompiler::process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk)
{
process_expr(expr->key, blk);
process_expr(expr->obj, blk);
}
void decompiler::process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk)
void decompiler::process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk)
{
process_expr(expr->obj, blk);
}
void decompiler::process_local_variable(const ast::expr_identifier::ptr&, const block::ptr&)
void decompiler::process_expr_local(const ast::expr_identifier::ptr&, const block::ptr&)
{
return;
}

View File

@ -34,6 +34,7 @@ private:
void decompile_switches(const ast::stmt_list::ptr& stmt);
void decompile_ifelses(const ast::stmt_list::ptr& stmt);
void decompile_aborts(const ast::stmt_list::ptr& stmt);
void decompile_tuples(const ast::stmt_list::ptr& stmt);
void decompile_if(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
void decompile_last_ifelse(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end);
@ -89,9 +90,10 @@ private:
void process_expr_arguments(const ast::expr_arguments::ptr& expr, const block::ptr& blk);
void process_expr_add_array(const ast::expr_add_array::ptr& expr, const block::ptr& blk);
void process_expr_size(const ast::expr_size::ptr& expr, const block::ptr& blk);
void process_array_variable(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_field_variable(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_local_variable(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_tuple(const ast::expr_tuple::ptr& expr, const block::ptr& blk);
void process_expr_array(const ast::expr_array::ptr& expr, const block::ptr& blk);
void process_expr_field(const ast::expr_field::ptr& expr, const block::ptr& blk);
void process_expr_local(const ast::expr_identifier::ptr& expr, const block::ptr& blk);
void process_expr_vector(const ast::expr_vector::ptr& vec, const block::ptr& blk);
void process_var_create(ast::expr& expr, const block::ptr& blk, bool fromstmt = false);
void process_var_access(ast::expr& expr, const block::ptr& blk);

View File

@ -206,6 +206,9 @@ expr_field::expr_field(const location& loc, expr obj, expr_identifier::ptr field
expr_array::expr_array(expr obj, expr key) : node(kind::expr_array), obj(std::move(obj)), key(std::move(key)) {}
expr_array::expr_array(const location& loc, expr obj, expr key) : node(kind::expr_array, loc), obj(std::move(obj)), key(std::move(key)) {}
expr_tuple::expr_tuple() : node(kind::expr_tuple) {}
expr_tuple::expr_tuple(const location& loc) : node(kind::expr_tuple, loc) {}
expr_reference::expr_reference(expr_path::ptr path, expr_identifier::ptr name) : node(kind::expr_reference), path(std::move(path)), name(std::move(name)) {}
expr_reference::expr_reference(const location& loc, expr_path::ptr path, expr_identifier::ptr name) : node(kind::expr_reference, loc), path(std::move(path)), name(std::move(name)) {}
@ -606,6 +609,19 @@ auto expr_array::print() const -> std::string
return obj.print() + "[" + key.print() + "]";
}
auto expr_tuple::print() const -> std::string
{
std::string data = "[";
for (const auto& entry : list)
{
data += " " + entry.print();
data += (&entry != &list.back()) ? "," : " ";
}
return data += "]";
}
auto expr_reference::print() const -> std::string
{
return path->print() + "::" + name->print();
@ -1576,6 +1592,7 @@ expr::~expr()
case kind::expr_size: as_size.~unique_ptr(); return;
case kind::expr_field: as_field.~unique_ptr(); return;
case kind::expr_array: as_array.~unique_ptr(); return;
case kind::expr_tuple: as_tuple.~unique_ptr(); return;
case kind::expr_reference: as_reference.~unique_ptr(); return;
case kind::expr_arguments: as_arguments.~unique_ptr(); return;
case kind::expr_parameters: as_parameters.~unique_ptr(); return;

View File

@ -33,6 +33,7 @@ enum class kind
expr_size,
expr_field,
expr_array,
expr_tuple,
expr_reference,
expr_istrue,
expr_isdefined,
@ -152,6 +153,7 @@ struct expr_paren;
struct expr_size;
struct expr_field;
struct expr_array;
struct expr_tuple;
struct expr_reference;
struct expr_istrue;
struct expr_isdefined;
@ -292,6 +294,7 @@ union expr
std::unique_ptr<expr_size> as_size;
std::unique_ptr<expr_field> as_field;
std::unique_ptr<expr_array> as_array;
std::unique_ptr<expr_tuple> as_tuple;
std::unique_ptr<expr_reference> as_reference;
std::unique_ptr<expr_istrue> as_istrue;
std::unique_ptr<expr_isdefined> as_isdefined;
@ -718,6 +721,18 @@ struct expr_array : public node
friend bool operator==(const expr_array& lhs, const expr_array& rhs);
};
struct expr_tuple : public node
{
using ptr = std::unique_ptr<expr_tuple>;
std::vector<expr> list;
ast::expr temp;
expr_tuple();
expr_tuple(const location& loc);
auto print() const -> std::string override;
};
struct expr_reference : public node
{
using ptr = std::unique_ptr<expr_reference>;