t6 disassemble discard align and #include fix

This commit is contained in:
xensik 2022-02-21 20:44:37 +01:00
parent 613c033b24
commit 5504bef189
4 changed files with 69 additions and 36 deletions

View File

@ -101,6 +101,8 @@ void compiler::compile_program(const ast::program::ptr& program)
{
emit_declaration(declaration);
}
std::reverse(assembly_->includes.begin(), assembly_->includes.end());
}
void compiler::emit_include(const ast::include::ptr& include)
@ -1247,10 +1249,10 @@ void compiler::emit_expr_call_pointer(const ast::expr_pointer::ptr& expr)
void compiler::emit_expr_call_function(const ast::expr_function::ptr& expr)
{
bool found = false;
if(expr->path->value != "")
if (expr->path->value != "")
{
bool found = false;
for (const auto& entry : assembly_->includes)
{
if (entry == expr->path->value)
@ -1259,11 +1261,11 @@ void compiler::emit_expr_call_function(const ast::expr_function::ptr& expr)
break;
}
}
}
if(!found)
{
assembly_->includes.push_back(expr->path->value);
if (!found)
{
assembly_->includes.push_back(expr->path->value);
}
}
// TODO: resolve import calls path
@ -1323,10 +1325,10 @@ void compiler::emit_expr_method_pointer(const ast::expr_pointer::ptr& expr, cons
void compiler::emit_expr_method_function(const ast::expr_function::ptr& expr, const ast::expr& obj)
{
bool found = false;
if(expr->path->value != "")
if (expr->path->value != "")
{
bool found = false;
for (const auto& entry : assembly_->includes)
{
if (entry == expr->path->value)
@ -1335,11 +1337,11 @@ void compiler::emit_expr_method_function(const ast::expr_function::ptr& expr, co
break;
}
}
}
if(!found)
{
assembly_->includes.push_back(expr->path->value);
if (!found)
{
assembly_->includes.push_back(expr->path->value);
}
}
// TODO: resolve import calls path
@ -1512,10 +1514,10 @@ void compiler::emit_expr_getnextarraykey(const ast::expr_getnextarraykey::ptr& e
void compiler::emit_expr_reference(const ast::expr_reference::ptr& expr)
{
bool found = false;
if(expr->path->value != "")
if (expr->path->value != "")
{
bool found = false;
for (const auto& entry : assembly_->includes)
{
if (entry == expr->path->value)
@ -1524,11 +1526,11 @@ void compiler::emit_expr_reference(const ast::expr_reference::ptr& expr)
break;
}
}
}
if(!found)
{
assembly_->includes.push_back(expr->path->value);
if (!found)
{
assembly_->includes.push_back(expr->path->value);
}
}
// TODO: resolve import calls path
@ -1834,9 +1836,7 @@ void compiler::emit_expr_animation(const ast::expr_animation::ptr& expr)
throw comp_error(expr->loc(), "trying to use animation without specified using animtree");
}
auto& tree = animtrees_.back();
emit_opcode(opcode::OP_GetAnimation, { tree.name, expr->value });
emit_opcode(opcode::OP_GetAnimation, { animtrees_.back(), expr->value });
}
void compiler::emit_expr_istring(const ast::expr_istring::ptr& expr)
@ -2394,6 +2394,7 @@ void compiler::insert_label(const std::string& name)
case opcode::OP_Jump:
case opcode::OP_JumpBack:
case opcode::OP_Switch:
case opcode::OP_DevblockBegin:
if (inst->data[0] == name)
inst->data[0] = itr->second;
break;

View File

@ -21,7 +21,7 @@ class compiler : public arc::compiler
std::vector<std::string> local_stack_;
std::vector<std::string> local_functions_;
std::vector<include_t> includes_;
std::vector<animtree_t> animtrees_;
std::vector<std::string> animtrees_;
std::unordered_map<std::string, ast::expr> constants_;
std::vector<block> blocks_;
bool can_break_;

View File

@ -29,6 +29,14 @@ void decompiler::decompile(const std::string& file, const assembly::ptr& data)
filename_ = file;
program_ = std::make_unique<ast::program>();
std::reverse(data->includes.begin(), data->includes.end());
for (const auto& inc : data->includes)
{
auto include = std::make_unique<ast::include>(std::make_unique<ast::expr_path>(inc));
program_->includes.push_back(std::move(include));
}
for (const auto& func : data->functions)
{
auto name = std::make_unique<ast::expr_identifier>(func->name);

View File

@ -40,7 +40,7 @@ void disassembler::disassemble(const std::string& file, std::vector<std::uint8_t
script_ = std::make_unique<utils::byte_buffer>(data);
assembly_ = std::make_unique<assembly>();
std::memset(&header_, 0 ,sizeof(header_));
std::memset(&header_, 0, sizeof(header_));
exports_.clear();
imports_.clear();
strings_.clear();
@ -191,19 +191,25 @@ void disassembler::disassemble(const std::string& file, std::vector<std::uint8_t
if (i < exports_.size() - 1)
{
entry->size = (exports_[i+1]->offset - entry->offset) - 4;
entry->size = (exports_[i+1]->offset - entry->offset);
auto end_pos = entry->offset + entry->size;
auto end_pos = entry->offset + entry->size - 4;
for (auto j = 1; j < 4; j++)
script_->pos(end_pos);
if (script_->read<std::uint32_t>() == 0)
{
script_->pos(end_pos - j);
auto op = script_->read<std::uint8_t>();
entry->size -= 4;
for (auto j = 1; j < 4; j++)
{
script_->pos(end_pos - j);
auto op = script_->read<std::uint8_t>();
if (op <= 0x01) break;
if (op == '\x00' || op == '\x01')
break;
else
entry->size--;
}
}
}
else
@ -243,13 +249,31 @@ void disassembler::disassemble_function(const function::ptr& func)
inst->opcode = script_->read<std::uint8_t>();
inst->size = opcode_size(inst->opcode);
if (size < 4 && inst->opcode >= std::uint8_t(opcode::OP_Count))
{
func->instructions.pop_back();
break;
}
this->disassemble_instruction(inst);
size -= inst->size;
}
for (auto i = func->instructions.size() - 1; i >= 1; i--)
{
auto& inst = func->instructions.at(i);
auto& last = func->instructions.at(i-1);
if (labels_.contains(inst->index))
break;
if (inst->opcode <= 0x01 && (last->opcode > 0x01))
break;
func->instructions.pop_back();
}
}
void disassembler::disassemble_instruction(const instruction::ptr& inst)
{
switch (opcode(inst->opcode))