From a286f52fedd37e6f9728c4c8cb97550ad1f1ef08 Mon Sep 17 00:00:00 2001 From: xensik Date: Fri, 9 Sep 2022 22:56:57 +0200 Subject: [PATCH] t6 clean code --- src/t6/xsk/assembler.cpp | 133 +++++-------- src/t6/xsk/assembler.hpp | 1 - src/t6/xsk/compiler.cpp | 53 +++-- src/t6/xsk/decompiler.cpp | 383 +++++++++++++++++------------------- src/t6/xsk/decompiler.hpp | 2 +- src/t6/xsk/disassembler.cpp | 68 +++---- src/t6/xsk/disassembler.hpp | 1 - src/t6/xsk/lexer.cpp | 6 +- src/t6/xsk/resolver.cpp | 4 +- src/t6/xsk/t6.cpp | 4 +- 10 files changed, 297 insertions(+), 358 deletions(-) diff --git a/src/t6/xsk/assembler.cpp b/src/t6/xsk/assembler.cpp index 0d2cd33b..e235e231 100644 --- a/src/t6/xsk/assembler.cpp +++ b/src/t6/xsk/assembler.cpp @@ -23,7 +23,7 @@ auto assembler::output() -> std::vector void assembler::assemble(const std::string&, std::vector&) { - throw error("assemble from source unimplemented!"); + throw error("assemble from source not implemented!"); } void assembler::assemble(const std::string& file, assembly::ptr& data) @@ -75,7 +75,7 @@ void assembler::assemble(const std::string& file, assembly::ptr& data) header_.cseg_size = script_->pos() - header_.cseg_offset; - header_.source_crc = 0; // calcule_crc(); + header_.source_crc = 0; // assemble exports header_.exports_offset = script_->pos(); @@ -215,18 +215,20 @@ void assembler::assemble_function(const function::ptr& func) assemble_instruction(inst); } - export_ref obj; - obj.checksum = 0; // calculate_checksum(); - obj.offset = func->index; - obj.name = func->name; - obj.params = func->params; - obj.flags = func->flags; - exports_.push_back(obj); + export_ref entry; + entry.checksum = 0; + entry.offset = func->index; + entry.name = func->name; + entry.params = func->params; + entry.flags = func->flags; + exports_.push_back(entry); } void assembler::assemble_instruction(const instruction::ptr& inst) { - switch (opcode(inst->opcode)) + script_->write(static_cast(inst->opcode)); + + switch (static_cast(inst->opcode)) { case opcode::OP_End: case opcode::OP_Return: @@ -310,31 +312,25 @@ void assembler::assemble_instruction(const instruction::ptr& inst) case opcode::OP_ThreadObject: case opcode::OP_EvalLocalVariable: case opcode::OP_EvalLocalVariableRef: - script_->write(static_cast(inst->opcode)); break; case opcode::OP_GetByte: case opcode::OP_GetNegByte: - script_->write(static_cast(inst->opcode)); script_->write(static_cast(std::stoi(inst->data[0]))); break; case opcode::OP_GetUnsignedShort: case opcode::OP_GetNegUnsignedShort: - script_->write(static_cast(inst->opcode)); script_->align(2); script_->write(static_cast(std::stoi(inst->data[0]))); break; case opcode::OP_GetInteger: - script_->write(static_cast(inst->opcode)); script_->align(4); script_->write(std::stoi(inst->data[0])); break; case opcode::OP_GetFloat: - script_->write(static_cast(inst->opcode)); script_->align(4); script_->write(std::stof(inst->data[0])); break; case opcode::OP_GetVector: - script_->write(static_cast(inst->opcode)); script_->align(4); script_->write(std::stof(inst->data[0])); script_->write(std::stof(inst->data[1])); @@ -342,25 +338,20 @@ void assembler::assemble_instruction(const instruction::ptr& inst) break; case opcode::OP_GetString: case opcode::OP_GetIString: - script_->write(static_cast(inst->opcode)); script_->align(2); script_->write(0); break; case opcode::OP_GetAnimation: - script_->write(static_cast(inst->opcode)); script_->align(4); script_->write(0); break; case opcode::OP_WaitTillMatch: - script_->write(static_cast(inst->opcode)); script_->write(static_cast(std::stoi(inst->data[0]))); break; case opcode::OP_VectorConstant: - script_->write(static_cast(inst->opcode)); script_->write(static_cast(std::stoi(inst->data[0]))); break; case opcode::OP_GetHash: - script_->write(static_cast(inst->opcode)); script_->align(4); script_->write(static_cast(std::stoul(inst->data[0], 0, 16))); break; @@ -372,13 +363,11 @@ void assembler::assemble_instruction(const instruction::ptr& inst) case opcode::OP_EvalLocalArrayRefCached: case opcode::OP_SafeSetWaittillVariableFieldCached: case opcode::OP_EvalLocalVariableRefCached: - script_->write(static_cast(inst->opcode)); script_->write(static_cast(std::stoi(inst->data[0]))); break; case opcode::OP_EvalFieldVariable: case opcode::OP_EvalFieldVariableRef: case opcode::OP_ClearFieldVariable: - script_->write(static_cast(inst->opcode)); script_->align(2); script_->write(0); break; @@ -386,11 +375,9 @@ void assembler::assemble_instruction(const instruction::ptr& inst) case opcode::OP_ScriptMethodCallPointer: case opcode::OP_ScriptThreadCallPointer: case opcode::OP_ScriptMethodThreadCallPointer: - script_->write(static_cast(inst->opcode)); script_->write(static_cast(std::stoi(inst->data[0]))); break; case opcode::OP_GetFunction: - script_->write(static_cast(inst->opcode)); script_->align(4); script_->write(0); break; @@ -400,7 +387,6 @@ void assembler::assemble_instruction(const instruction::ptr& inst) case opcode::OP_ScriptMethodCall: case opcode::OP_ScriptThreadCall: case opcode::OP_ScriptMethodThreadCall: - script_->write(static_cast(inst->opcode)); script_->write(0); script_->align(4); script_->write(0); @@ -411,6 +397,7 @@ void assembler::assemble_instruction(const instruction::ptr& inst) case opcode::OP_JumpOnTrueExpr: case opcode::OP_Jump: case opcode::OP_JumpBack: + case opcode::OP_DevblockBegin: assemble_jump(inst); break; case opcode::OP_Switch: @@ -419,18 +406,13 @@ void assembler::assemble_instruction(const instruction::ptr& inst) case opcode::OP_EndSwitch: assemble_end_switch(inst); break; - case opcode::OP_DevblockBegin: - case opcode::OP_DevblockEnd: - assemble_devblock(inst); - break; default: - throw asm_error(utils::string::va("Unhandled opcode 0x%X at index '%04X'!", inst->opcode, inst->index)); + throw asm_error(utils::string::va("unhandled opcode 0x%X at index '%04X'!", inst->opcode, inst->index)); } } void assembler::assemble_localvars(const instruction::ptr& inst) { - script_->write(static_cast(inst->opcode)); script_->write(static_cast(inst->data.size())); for (auto i = 0u; i < inst->data.size(); i++) @@ -442,8 +424,6 @@ void assembler::assemble_localvars(const instruction::ptr& inst) void assembler::assemble_jump(const instruction::ptr& inst) { - script_->write(static_cast(inst->opcode)); - const auto addr = static_cast(resolve_label(inst->data[0]) - inst->index - inst->size); script_->align(2); @@ -452,8 +432,6 @@ void assembler::assemble_jump(const instruction::ptr& inst) void assembler::assemble_switch(const instruction::ptr& inst) { - script_->write(static_cast(inst->opcode)); - const std::int32_t addr = ((resolve_label(inst->data[0]) + 4) & 0xFFFFFFFC) - inst->index - inst->size; script_->align(4); @@ -462,8 +440,6 @@ void assembler::assemble_switch(const instruction::ptr& inst) void assembler::assemble_end_switch(const instruction::ptr& inst) { - script_->write(static_cast(inst->opcode)); - const auto count = std::stoul(inst->data[0]); const auto numerical = inst->data.back() == "i"; @@ -495,25 +471,19 @@ void assembler::assemble_end_switch(const instruction::ptr& inst) script_->write(addr); } + else + { + throw asm_error("invalid switch case '" + inst->data[1 + (3 * i)] + "'!"); + } } } -void assembler::assemble_devblock(const instruction::ptr& inst) -{ - script_->write(static_cast(inst->opcode)); - - const auto addr = static_cast(resolve_label(inst->data[0]) - inst->index - inst->size); - - script_->align(2); - script_->write(addr); -} - void assembler::align_instruction(const instruction::ptr& inst) { inst->size = opcode_size(inst->opcode); script_->seek(1); - switch (opcode(inst->opcode)) + switch (static_cast(inst->opcode)) { case opcode::OP_End: case opcode::OP_Return: @@ -641,16 +611,18 @@ void assembler::align_instruction(const instruction::ptr& inst) script_->seek(4); break; case opcode::OP_SafeCreateLocalVariables: + { script_->seek(1); + + for (auto i = 0u; i < inst->data.size(); i++) { - for (auto i = 0u; i < inst->data.size(); i++) - { - inst->size += script_->align(2) + 2; - add_string_reference(inst->data[i], string_type::canonical, script_->pos()); - script_->seek(2); - } + inst->size += script_->align(2) + 2; + add_string_reference(inst->data[i], string_type::canonical, script_->pos()); + script_->seek(2); } + break; + } case opcode::OP_RemoveLocalVariables: case opcode::OP_EvalLocalVariableCached: case opcode::OP_EvalLocalArrayRefCached: @@ -693,6 +665,7 @@ void assembler::align_instruction(const instruction::ptr& inst) case opcode::OP_JumpOnTrueExpr: case opcode::OP_Jump: case opcode::OP_JumpBack: + case opcode::OP_DevblockBegin: inst->size += script_->align(2); script_->seek(2); break; @@ -721,15 +694,11 @@ void assembler::align_instruction(const instruction::ptr& inst) inst->size += 8; script_->seek(8); } + + break; } - break; - case opcode::OP_DevblockBegin: - case opcode::OP_DevblockEnd: - inst->size += script_->align(2); - script_->seek(2); - break; default: - throw asm_error(utils::string::va("Unhandled opcode 0x%X at index '%04X'!", inst->opcode, inst->index)); + throw asm_error(utils::string::va("unhandled opcode 0x%X at index '%04X'!", inst->opcode, inst->index)); } } @@ -755,7 +724,7 @@ void assembler::process_function(const function::ptr& func) void assembler::process_instruction(const instruction::ptr& inst) { - switch (opcode(inst->opcode)) + switch (static_cast(inst->opcode)) { case opcode::OP_GetString: case opcode::OP_GetIString: @@ -771,8 +740,9 @@ void assembler::process_instruction(const instruction::ptr& inst) { process_string(entry); } - } + break; + } case opcode::OP_EvalFieldVariable: case opcode::OP_EvalFieldVariableRef: case opcode::OP_ClearFieldVariable: @@ -806,8 +776,9 @@ void assembler::process_instruction(const instruction::ptr& inst) } } } - } + break; + } default: break; } @@ -815,15 +786,15 @@ void assembler::process_instruction(const instruction::ptr& inst) auto assembler::resolve_label(const std::string& name) -> std::int32_t { - for (const auto& func : labels_) + for (const auto& entry : labels_) { - if (func.second == name) + if (entry.second == name) { - return func.first; + return entry.first; } } - throw asm_error("Couldn't resolve label address of '" + name + "'!"); + throw asm_error("couldn't resolve label address of '" + name + "'!"); } auto assembler::string_offset(const std::string& name) -> std::uint16_t @@ -842,7 +813,7 @@ void assembler::add_string_reference(const std::string& str, string_type type, s { for (auto& entry : stringtables_) { - if (entry.name == str && entry.type == std::uint8_t(type)) + if (entry.name == str && entry.type == static_cast(type)) { entry.refs.push_back(ref); return; @@ -863,13 +834,13 @@ void assembler::add_import_reference(const std::vector& data, std:: } } - import_ref n; - n.space = data[0]; - n.name = data[1]; - n.params = static_cast(std::stoi(data[2])); - n.flags = static_cast(std::stoi(data[3])); - n.refs.push_back(ref); - imports_.push_back(std::move(n)); + import_ref new_entry; + new_entry.space = data[0]; + new_entry.name = data[1]; + new_entry.params = static_cast(std::stoi(data[2])); + new_entry.flags = static_cast(std::stoi(data[3])); + new_entry.refs.push_back(ref); + imports_.push_back(std::move(new_entry)); } void assembler::add_anim_reference(const std::vector& data, std::uint32_t ref) @@ -883,10 +854,10 @@ void assembler::add_anim_reference(const std::vector& data, std::ui } } - animtree_ref n; - n.name = data[0]; - n.anims.push_back({ data[1], ref }); - animtrees_.push_back(std::move(n)); + animtree_ref new_entry; + new_entry.name = data[0]; + new_entry.anims.push_back({ data[1], ref }); + animtrees_.push_back(std::move(new_entry)); } } // namespace xsk::arc::t6 diff --git a/src/t6/xsk/assembler.hpp b/src/t6/xsk/assembler.hpp index 73f1b62d..e4b3dc78 100644 --- a/src/t6/xsk/assembler.hpp +++ b/src/t6/xsk/assembler.hpp @@ -33,7 +33,6 @@ private: void assemble_jump(const instruction::ptr& inst); void assemble_switch(const instruction::ptr& inst); void assemble_end_switch(const instruction::ptr& inst); - void assemble_devblock(const instruction::ptr& inst); void process_string(const std::string& data); void process_function(const function::ptr& func); void process_instruction(const instruction::ptr& inst); diff --git a/src/t6/xsk/compiler.cpp b/src/t6/xsk/compiler.cpp index e1f6a8dc..0734b00a 100644 --- a/src/t6/xsk/compiler.cpp +++ b/src/t6/xsk/compiler.cpp @@ -69,9 +69,8 @@ auto compiler::parse_buffer(const std::string& file, char* data, size_t size) -> auto compiler::parse_file(const std::string& file) -> ast::program::ptr { auto data = resolver::file_data(file); - auto result = parse_buffer(file, std::get<1>(data), std::get<2>(data)); - return result; + return parse_buffer(file, std::get<1>(data), std::get<2>(data)); } void compiler::compile_program(const ast::program::ptr& program) @@ -1250,16 +1249,16 @@ void compiler::emit_expr_call_function(const ast::expr_function::ptr& expr, bool emit_expr_arguments(expr->args); auto argcount = utils::string::va("%d", expr->args->list.size()); - auto flags = developer_thread_ ? std::uint8_t(import_flags::developer) : 0; + auto flags = developer_thread_ ? static_cast(import_flags::developer) : 0; switch (expr->mode) { case ast::call::mode::normal: - flags |= std::uint8_t(import_flags::func_call); + flags |= static_cast(import_flags::func_call); emit_opcode(opcode::OP_ScriptFunctionCall, { expr->path->value, expr->name->value, argcount, utils::string::va("%d", flags) }); break; case ast::call::mode::thread: - flags |= std::uint8_t(import_flags::func_call_thread); + flags |= static_cast(import_flags::func_call_thread); emit_opcode(opcode::OP_ScriptThreadCall, { expr->path->value, expr->name->value, argcount, utils::string::va("%d", flags) }); break; default: @@ -1339,16 +1338,16 @@ void compiler::emit_expr_method_function(const ast::expr_function::ptr& expr, co emit_expr(obj); auto argcount = utils::string::va("%d", expr->args->list.size()); - auto flags = developer_thread_ ? std::uint8_t(import_flags::developer) : 0; + auto flags = developer_thread_ ? static_cast(import_flags::developer) : 0; switch (expr->mode) { case ast::call::mode::normal: - flags |= std::uint8_t(import_flags::meth_call); + flags |= static_cast(import_flags::meth_call); emit_opcode(opcode::OP_ScriptMethodCall, { expr->path->value, expr->name->value, argcount, utils::string::va("%d", flags) }); break; case ast::call::mode::thread: - flags |= std::uint8_t(import_flags::meth_call_thread); + flags |= static_cast(import_flags::meth_call_thread); emit_opcode(opcode::OP_ScriptMethodThreadCall, { expr->path->value, expr->name->value, argcount, utils::string::va("%d", flags) }); break; default: @@ -1519,9 +1518,9 @@ void compiler::emit_expr_reference(const ast::expr_reference::ptr& expr) // TODO: resolve import calls path - auto flags = developer_thread_ ? std::uint8_t(import_flags::developer) : 0; + auto flags = developer_thread_ ? static_cast(import_flags::developer) : 0; - flags |= std::uint8_t(import_flags::func_reference); + flags |= static_cast(import_flags::func_reference); emit_opcode(opcode::OP_GetFunction, { expr->path->value, expr->name->value, "0", utils::string::va("%d", flags) }); } @@ -1633,7 +1632,7 @@ void compiler::emit_expr_field_ref(const ast::expr_field::ptr& expr, bool set) void compiler::emit_expr_local_ref(const ast::expr_identifier::ptr& expr, bool set) { - const auto itr = constants_.find(expr->value); + const auto& itr = constants_.find(expr->value); if (itr != constants_.end()) { @@ -1724,17 +1723,12 @@ void compiler::emit_expr_field(const ast::expr_field::ptr& expr) void compiler::emit_expr_local(const ast::expr_identifier::ptr& expr) { // is constant ( should only allow: string, loc string, number, vector) - const auto itr = constants_.find(expr->value); + const auto& itr = constants_.find(expr->value); if (itr != constants_.end()) - { - const auto& value = itr->second; - emit_expr(value); - return; - } - - // is local var - emit_opcode(opcode::OP_EvalLocalVariableCached, variable_access(expr)); + emit_expr(itr->second); + else + emit_opcode(opcode::OP_EvalLocalVariableCached, variable_access(expr)); } void compiler::emit_expr_object(const ast::expr& expr) @@ -2277,6 +2271,7 @@ void compiler::process_expr_parameters(const ast::expr_parameters::ptr& expr) void compiler::variable_register(const std::string& name) { auto found = false; + for (std::size_t i = 0; i < local_stack_.size(); i++) { if (local_stack_[i] == name) @@ -2286,10 +2281,7 @@ void compiler::variable_register(const std::string& name) } } - if (!found) - { - local_stack_.push_back(name); - } + if (!found) local_stack_.push_back(name); } auto compiler::variable_access(const ast::expr_identifier::ptr& name) -> std::string @@ -2332,13 +2324,12 @@ auto compiler::is_constant_condition(const ast::expr& expr) -> bool auto compiler::create_label() -> std::string { label_idx_++; - auto name = utils::string::va("loc_%d", label_idx_); - return name; + return utils::string::va("loc_%d", label_idx_); } auto compiler::insert_label() -> std::string { - const auto itr = function_->labels.find(index_); + const auto& itr = function_->labels.find(index_); if (itr != function_->labels.end()) { @@ -2348,20 +2339,20 @@ auto compiler::insert_label() -> std::string { label_idx_++; auto name = utils::string::va("loc_%d", label_idx_); - function_->labels.insert({index_, name}); + function_->labels.insert({ index_, name }); return name; } } void compiler::insert_label(const std::string& name) { - const auto itr = function_->labels.find(index_); + const auto& itr = function_->labels.find(index_); if (itr != function_->labels.end()) { for (auto& inst : function_->instructions) { - switch (opcode(inst->opcode)) + switch (static_cast(inst->opcode)) { case opcode::OP_JumpOnFalse: case opcode::OP_JumpOnTrue: @@ -2415,7 +2406,7 @@ void compiler::print_instruction(const instruction::ptr& inst) { output_->write_string(utils::string::va("\t\t%s(", resolver::opcode_name(inst->opcode).data())); - switch (opcode(inst->opcode)) + switch (static_cast(inst->opcode)) { case opcode::OP_GetHash: case opcode::OP_GetString: diff --git a/src/t6/xsk/decompiler.cpp b/src/t6/xsk/decompiler.cpp index 7401b6a4..d8bdeca9 100644 --- a/src/t6/xsk/decompiler.cpp +++ b/src/t6/xsk/decompiler.cpp @@ -102,7 +102,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto loc = location(&filename_, inst->index); - switch (opcode(inst->opcode)) + switch (static_cast(inst->opcode)) { case opcode::OP_End: { @@ -115,8 +115,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto expr = ast::expr(std::make_unique()); auto stmt = ast::stmt(std::make_unique(loc, std::move(expr))); func_->stmt->list.push_back(std::move(stmt)); - } break; + } case opcode::OP_Return: { retnum_++; @@ -129,53 +129,53 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto stmt = ast::stmt(std::make_unique(expr.loc(), std::move(expr))); func_->stmt->list.push_back(std::move(stmt)); - } break; + } case opcode::OP_GetUndefined: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetZero: { auto node = std::make_unique(loc, "0"); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetByte: case opcode::OP_GetUnsignedShort: case opcode::OP_GetInteger: { auto node = std::make_unique(loc, inst->data[0]); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetNegByte: case opcode::OP_GetNegUnsignedShort: { auto node = std::make_unique(loc, "-" + inst->data[0]); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetFloat: { auto node = std::make_unique(loc, inst->data[0]); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetString: { auto node = std::make_unique(loc, inst->data[0]); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetIString: { auto node = std::make_unique(loc, inst->data[0]); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetVector: { auto x = ast::expr(std::make_unique(loc, inst->data[0])); @@ -183,36 +183,36 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto z = ast::expr(std::make_unique(loc, inst->data[2])); auto node = std::make_unique(loc, std::move(x), std::move(y), std::move(z)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetLevel: case opcode::OP_GetLevelObject: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetAnim: case opcode::OP_GetAnimObject: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetSelf: case opcode::OP_GetSelfObject: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetGame: case opcode::OP_GetGameRef: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetAnimation: { bool found = false; @@ -237,60 +237,53 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto node = std::make_unique(loc, inst->data[1]); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetFunction: { auto path = std::make_unique(loc, inst->data[0]); auto name = std::make_unique(loc, inst->data[1]); auto node = std::make_unique(loc, std::move(path), std::move(name)); stack_.push(std::move(node)); + break; } - break; - case opcode::OP_CreateLocalVariable: - throw decomp_error("unhandled opcode " + resolver::opcode_name(inst->opcode)); - break; case opcode::OP_SafeCreateLocalVariables: { for (const auto& entry : inst->data) - { locals_.insert(locals_.begin(), entry); - } + + break; } - break; - case opcode::OP_RemoveLocalVariables: - throw decomp_error("unhandled opcode " + resolver::opcode_name(inst->opcode)); - break; case opcode::OP_EvalLocalVariableCached: { auto node = std::make_unique(loc, locals_.at(std::stoi(inst->data[0]))); stack_.push(std::move(node)); - } break; + } case opcode::OP_EvalArray: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); auto key = ast::expr(std::move(stack_.top())); stack_.pop(); auto node = std::make_unique(key.loc(), std::move(obj), std::move(key)); stack_.push(std::move(node)); - } break; + } case opcode::OP_EvalLocalArrayRefCached: { auto key = ast::expr(std::move(stack_.top())); stack_.pop(); auto obj = ast::expr(std::make_unique(loc, locals_.at(std::stoi(inst->data[0])))); auto node = std::make_unique(key.loc(), std::move(obj), std::move(key)); stack_.push(std::move(node)); - } break; + } case opcode::OP_EvalArrayRef: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); auto key = ast::expr(std::move(stack_.top())); stack_.pop(); auto node = std::make_unique(key.loc(), std::move(obj), std::move(key)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ClearArray: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -301,14 +294,14 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto expr = ast::expr(std::make_unique(loc, std::move(lvalue), std::move(rvalue))); auto stmt = ast::stmt(std::make_unique(loc, std::move(expr))); func_->stmt->list.push_back(std::move(stmt)); - } break; + } case opcode::OP_EmptyArray: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_EvalFieldVariable: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -316,8 +309,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto field = std::make_unique(loc, inst->data[0]); auto stmt = std::make_unique(loc, std::move(obj), std::move(field)); stack_.push(std::move(stmt)); - } break; + } case opcode::OP_EvalFieldVariableRef: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -325,35 +318,32 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto field = std::make_unique(loc, inst->data[0]); auto stmt = std::make_unique(loc, std::move(obj), std::move(field)); stack_.push(std::move(stmt)); - } break; + } case opcode::OP_ClearFieldVariable: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); loc = obj.as_node->loc(); - auto field = std::make_unique(loc, inst->data[0]); - auto expr = ast::expr(std::make_unique(loc, std::move(obj), std::move(field))); + auto name = std::make_unique(loc, inst->data[0]); + auto field = ast::expr(std::make_unique(loc, std::move(obj), std::move(name))); auto undef = ast::expr(std::make_unique(loc)); - auto e = ast::expr(std::make_unique(loc, std::move(expr), std::move(undef))); - func_->stmt->list.push_back(ast::stmt(std::make_unique(loc, std::move(e)))); + auto expr = ast::expr(std::make_unique(loc, std::move(field), std::move(undef))); + auto stmt = ast::stmt(std::make_unique(loc, std::move(expr))); + func_->stmt->list.push_back(std::move(stmt)); + break; } - break; - case opcode::OP_SafeSetVariableFieldCached: - throw decomp_error("unhandled opcode " + resolver::opcode_name(inst->opcode)); - break; case opcode::OP_SafeSetWaittillVariableFieldCached: { auto node = std::make_unique(loc, locals_.at(std::stoi(inst->data[0]))); stack_.push(std::move(node)); - } break; + } case opcode::OP_ClearParams: { if (in_waittill_) { auto args = std::make_unique(loc); - auto var = std::move(stack_.top()); - stack_.pop(); + auto var = std::move(stack_.top()); stack_.pop(); while (var->kind() != ast::kind::stmt_waittill) { @@ -370,30 +360,25 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) func_->stmt->list.push_back(ast::stmt(std::move(var))); } + break; } - break; - case opcode::OP_CheckClearParams: - break; case opcode::OP_EvalLocalVariableRefCached: { auto node = std::make_unique(loc, locals_.at(std::stoi(inst->data[0]))); stack_.push(std::move(node)); - } break; + } case opcode::OP_SetVariableField: { - auto lvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); - - auto rvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = rvalue.as_node->loc(); - auto e = ast::expr(std::make_unique(loc, std::move(lvalue), std::move(rvalue))); - auto stmt = std::make_unique(loc, std::move(e)); - func_->stmt->list.push_back(ast::stmt(std::move(stmt))); - } + auto expr = ast::expr(std::make_unique(loc, std::move(lvalue), std::move(rvalue))); + auto stmt = ast::stmt(std::make_unique(loc, std::move(expr))); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_CallBuiltin: { auto args = std::make_unique(loc); @@ -413,8 +398,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto func = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(func)); stack_.push(std::move(node)); - } break; + } case opcode::OP_CallBuiltinMethod: { auto args = std::make_unique(loc); @@ -434,51 +419,49 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(obj) ,std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Wait: { auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.loc(); auto stmt = ast::stmt(std::make_unique(loc, std::move(expr))); func_->stmt->list.push_back(std::move(stmt)); - } break; + } case opcode::OP_WaitTillFrameEnd: { auto stmt = ast::stmt(std::make_unique(loc)); func_->stmt->list.push_back(std::move(stmt)); - } break; + } case opcode::OP_PreScriptCall: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptFunctionCall: { auto args = std::make_unique(loc); auto path = std::make_unique(loc, inst->data[0]); auto name = std::make_unique(loc, inst->data[1]); - auto var = std::move(stack_.top()); - stack_.pop(); + auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); while (var->kind() != ast::kind::asm_prescriptcall) { args->list.push_back(std::move(var)); - var = std::move(stack_.top()); - stack_.pop(); + var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } auto call = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptFunctionCallPointer: { auto args = std::make_unique(loc); @@ -498,8 +481,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(func), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptMethodCall: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -522,8 +505,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(obj) ,std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptMethodCallPointer: { auto args = std::make_unique(loc); @@ -544,31 +527,29 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(func), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(obj), std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptThreadCall: { auto args = std::make_unique(loc); auto path = std::make_unique(loc, inst->data[0]); auto name = std::make_unique(loc, inst->data[1]); - auto var = std::move(stack_.top()); - stack_.pop(); + auto var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); while (var->kind() != ast::kind::asm_prescriptcall) { args->list.push_back(std::move(var)); - var = std::move(stack_.top()); - stack_.pop(); + var = std::move(stack_.top()); stack_.pop(); loc = var->loc(); } auto call = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::thread)); auto node = std::make_unique(loc, std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptThreadCallPointer: { auto args = std::make_unique(loc); @@ -588,8 +569,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(func), std::move(args), ast::call::mode::thread)); auto node = std::make_unique(loc, std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptMethodThreadCall: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -612,8 +593,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::thread)); auto node = std::make_unique(loc, std::move(obj) ,std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ScriptMethodThreadCallPointer: { auto args = std::make_unique(loc); @@ -634,125 +615,116 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(func), std::move(args), ast::call::mode::thread)); auto node = std::make_unique(loc, std::move(obj), std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_DecTop: { auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); - auto stmt = std::make_unique(expr.loc(), std::move(expr)); - func_->stmt->list.push_back(ast::stmt(std::move(stmt))); + auto stmt = ast::stmt(std::make_unique(expr.loc(), std::move(expr))); + func_->stmt->list.push_back(std::move(stmt)); + break; } - break; - case opcode::OP_CastFieldObject: - case opcode::OP_CastBool: - break; case opcode::OP_BoolNot: { - auto lvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); auto expr = std::make_unique(loc, std::move(lvalue)); stack_.push(std::move(expr)); - } break; + } case opcode::OP_BoolComplement: { - auto lvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); auto expr = std::make_unique(loc, std::move(lvalue)); stack_.push(std::move(expr)); - } break; + } case opcode::OP_JumpOnTrue: { - auto lvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); if (inst->index > resolve_label(inst->data[0])) { - auto expr = std::make_unique(loc, std::move(lvalue), inst->data[0]); - func_->stmt->list.push_back(ast::stmt(std::move(expr))); + auto stmt = ast::stmt(std::make_unique(loc, std::move(lvalue), inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); } else { - auto e_not = ast::expr(std::make_unique(loc, std::move(lvalue))); - auto expr = std::make_unique(loc, std::move(e_not), inst->data[0]); - func_->stmt->list.push_back(ast::stmt(std::move(expr))); + auto expr = ast::expr(std::make_unique(loc, std::move(lvalue))); + auto stmt = ast::stmt(std::make_unique(loc, std::move(expr), inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); } - } break; + } case opcode::OP_JumpOnFalse: { - auto lvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); if (inst->index > resolve_label(inst->data[0])) { - auto e_not = ast::expr(std::make_unique(loc, std::move(lvalue))); - auto expr = std::make_unique(loc, std::move(e_not), inst->data[0]); - func_->stmt->list.push_back(ast::stmt(std::move(expr))); + auto expr = ast::expr(std::make_unique(loc, std::move(lvalue))); + auto stmt = ast::stmt(std::make_unique(loc, std::move(expr), inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); } else { - auto expr = std::make_unique(loc, std::move(lvalue), inst->data[0]); - func_->stmt->list.push_back(ast::stmt(std::move(expr))); + auto stmt = ast::stmt(std::make_unique(loc, std::move(lvalue), inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); } - } break; + } case opcode::OP_JumpOnTrueExpr: { - auto lvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); auto expr = std::make_unique(loc, std::move(lvalue), inst->data[0]); stack_.push(std::move(expr)); expr_labels_.push_back(inst->data[0]); - } break; + } case opcode::OP_JumpOnFalseExpr: { - auto lvalue = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); auto expr = std::make_unique(loc, std::move(lvalue), inst->data[0]); stack_.push(std::move(expr)); expr_labels_.push_back(inst->data[0]); - } break; + } case opcode::OP_Jump: { - auto expr = std::make_unique(loc, inst->data[0]); - func_->stmt->list.push_back(ast::stmt(std::move(expr))); + auto stmt = ast::stmt(std::make_unique(loc, inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); if (stack_.size() != 0) tern_labels_.push_back(inst->data[0]); - } break; + } case opcode::OP_JumpBack: { - auto expr = std::make_unique(loc, inst->data[0]); - func_->stmt->list.push_back(ast::stmt(std::move(expr))); - } + auto stmt = ast::stmt(std::make_unique(loc, inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_Inc: { auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); auto node = ast::expr(std::make_unique(loc, std::move(lvalue), false)); - auto stmt = std::make_unique(loc, std::move(node)); - func_->stmt->list.push_back(ast::stmt(std::move(stmt))); - } + auto stmt = ast::stmt(std::make_unique(loc, std::move(node))); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_Dec: { auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); auto node = ast::expr(std::make_unique(loc, std::move(lvalue), false)); - auto stmt = std::make_unique(loc, std::move(node)); - func_->stmt->list.push_back(ast::stmt(std::move(stmt))); - } + auto stmt = ast::stmt(std::make_unique(loc, std::move(node))); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_Bit_Or: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -760,8 +732,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Bit_Xor: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -769,8 +741,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Bit_And: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -778,8 +750,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Equal: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -787,8 +759,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_NotEqual: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -796,8 +768,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_LessThan: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -805,8 +777,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GreaterThan: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -814,8 +786,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_LessThanOrEqualTo: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -823,8 +795,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GreaterThanOrEqualTo: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -832,8 +804,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ShiftLeft: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -841,8 +813,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_ShiftRight: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -850,8 +822,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Plus: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -859,8 +831,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Minus: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -868,8 +840,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Multiply: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -877,8 +849,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Divide: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -886,8 +858,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Modulus: { auto rvalue = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -895,16 +867,16 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue), std::move(rvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_SizeOf: { auto lvalue = ast::expr(std::move(stack_.top())); stack_.pop(); loc = lvalue.as_node->loc(); auto node = std::make_unique(loc, std::move(lvalue)); stack_.push(std::move(node)); - } break; + } case opcode::OP_WaitTillMatch: { auto args = std::make_unique(loc); @@ -919,10 +891,10 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) args->list.push_back(std::move(node)); } - auto stmt = std::make_unique(loc, std::move(obj), std::move(expr), std::move(args)); - func_->stmt->list.push_back(ast::stmt(std::move(stmt))); - } + auto stmt = ast::stmt(std::make_unique(loc, std::move(obj), std::move(expr), std::move(args))); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_WaitTill: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -932,8 +904,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto stmt = std::make_unique(loc, std::move(obj) , std::move(event), std::move(args)); stack_.push(std::move(stmt)); in_waittill_ = true; - } break; + } case opcode::OP_Notify: { auto obj = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -949,43 +921,42 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = var->loc(); } - auto stmt = std::make_unique(loc, std::move(obj), std::move(event), std::move(args)); - func_->stmt->list.push_back(ast::stmt(std::move(stmt))); - } + auto stmt = ast::stmt(std::make_unique(loc, std::move(obj), std::move(event), std::move(args))); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_EndOn: { 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(loc, std::move(obj) , std::move(event)); - func_->stmt->list.push_back(ast::stmt(std::move(stmt))); - } + auto stmt = ast::stmt(std::make_unique(loc, std::move(obj) , std::move(event))); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_VoidCodePos: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_Switch: { - auto expr = ast::expr(std::move(stack_.top())); - stack_.pop(); + auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - auto sw = std::make_unique(loc, std::move(expr), inst->data[0]); - func_->stmt->list.push_back(ast::stmt(std::move(sw))); - } + auto stmt = ast::stmt(std::make_unique(loc, std::move(expr), inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_EndSwitch: { auto count = inst->data[0]; inst->data.erase(inst->data.begin()); auto data = inst->data; - auto end = std::make_unique(loc, data, count); - func_->stmt->list.push_back(ast::stmt(std::move(end))); - } + auto stmt = ast::stmt(std::make_unique(loc, data, count)); + func_->stmt->list.push_back(std::move(stmt)); break; + } case opcode::OP_Vector: { auto x = ast::expr(std::move(stack_.top())); stack_.pop(); @@ -994,22 +965,22 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = z.as_node->loc(); auto node = std::make_unique(loc, std::move(x), std::move(y), std::move(z)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetHash: { auto node = std::make_unique(loc, inst->data[0]); stack_.push(std::move(node)); - } break; + } case opcode::OP_RealWait: { auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.loc(); auto stmt = ast::stmt(std::make_unique(loc, std::move(expr))); func_->stmt->list.push_back(std::move(stmt)); - } break; + } case opcode::OP_VectorConstant: { auto flags = static_cast(std::stoi(inst->data[0])); @@ -1018,16 +989,16 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto z = ast::expr(std::make_unique(loc, (flags & 0x02) ? "1" : (flags & 0x01) ? "-1" : "0")); auto node = std::make_unique(loc, std::move(x), std::move(y), std::move(z)); stack_.push(std::move(node)); - } break; + } case opcode::OP_IsDefined: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_VectorScale: { auto arg1 = std::move(stack_.top()); stack_.pop(); @@ -1035,126 +1006,126 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) loc = arg2->loc(); auto node = std::make_unique(loc, std::move(arg1), std::move(arg2)); stack_.push(std::move(node)); - } break; + } case opcode::OP_AnglesToUp: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_AnglesToRight: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_AnglesToForward: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_AngleClamp180: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_VectorToAngles: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_Abs: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetTime: { auto node = std::make_unique(loc); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvar: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvarInt: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvarFloat: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvarVector: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvarColorRed: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvarColorGreen: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvarColorBlue: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_GetDvarColorAlpha: { auto arg = std::move(stack_.top()); stack_.pop(); loc = arg->loc(); auto node = std::make_unique(loc, std::move(arg)); stack_.push(std::move(node)); - } break; + } case opcode::OP_FirstArrayKey: { auto args = std::make_unique(loc); @@ -1166,8 +1137,8 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(call)); stack_.push(std::move(node)); - } break; + } case opcode::OP_NextArrayKey: { auto args = std::make_unique(loc); @@ -1181,26 +1152,30 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) auto call = ast::call(std::make_unique(loc, std::move(path), std::move(name), std::move(args), ast::call::mode::normal)); auto node = std::make_unique(loc, std::move(call)); stack_.push(std::move(node)); - } break; - case opcode::OP_ProfileStart: - case opcode::OP_ProfileStop: - throw decomp_error("unhandled opcode " + resolver::opcode_name(inst->opcode)); + } + case opcode::OP_DevblockBegin: + { + auto stmt = ast::stmt(std::make_unique(loc, inst->data[0])); + func_->stmt->list.push_back(std::move(stmt)); + break; + } + case opcode::OP_CheckClearParams: + case opcode::OP_CastFieldObject: + case opcode::OP_CastBool: case opcode::OP_SafeDecTop: break; + case opcode::OP_CreateLocalVariable: + case opcode::OP_RemoveLocalVariables: + case opcode::OP_SafeSetVariableFieldCached: + case opcode::OP_ProfileStart: + case opcode::OP_ProfileStop: case opcode::OP_Nop: case opcode::OP_Abort: case opcode::OP_Object: case opcode::OP_ThreadObject: case opcode::OP_EvalLocalVariable: case opcode::OP_EvalLocalVariableRef: - throw decomp_error("unhandled opcode " + resolver::opcode_name(inst->opcode)); - case opcode::OP_DevblockBegin: - { - auto stmt = ast::stmt(std::make_unique(loc, inst->data[0])); - func_->stmt->list.push_back(std::move(stmt)); - } - break; case opcode::OP_DevblockEnd: default: throw decomp_error("unhandled opcode " + resolver::opcode_name(inst->opcode)); @@ -1209,12 +1184,12 @@ void decompiler::decompile_instruction(const instruction::ptr& inst, bool last) void decompiler::decompile_expressions(const instruction::ptr& inst) { - const auto itr = labels_.find(inst->index); + const auto& itr = labels_.find(inst->index); if (itr == labels_.end()) return; - for (auto& expr : expr_labels_) + for (const auto& expr : expr_labels_) { if (expr == itr->second) { @@ -1241,7 +1216,7 @@ void decompiler::decompile_expressions(const instruction::ptr& inst) } } - for (auto& tern : tern_labels_) + for (const auto& tern : tern_labels_) { if (tern == itr->second) { @@ -1306,12 +1281,12 @@ void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { - decompile_infinite(stmt, start, i); + decompile_inf(stmt, start, i); i = stmt->list.size(); } else if (stmt->list.at(start).as_cond->value != break_loc) { - decompile_infinite(stmt, start, i); + decompile_inf(stmt, start, i); i = stmt->list.size(); } else if (stmt->list.at(start).as_cond->value == break_loc) @@ -1470,6 +1445,10 @@ void decompiler::decompile_aborts(const ast::stmt_list::ptr& stmt) auto new_stmt = ast::stmt(std::make_unique(loc)); stmt->list.insert(stmt->list.begin() + i, std::move(new_stmt)); } + else + { + std::cout << "WARNING: unresolved jump to '" + jump_loc + "', maybe incomplete for loop\n"; + } } } } @@ -1488,7 +1467,7 @@ void decompiler::decompile_devblocks(const ast::stmt_list::ptr& stmt) if (i + 1 < stmt->list.size()) { - if (stmt->list.at(i+1) == ast::kind::asm_dev && stmt->list.at(i+1).as_asm_dev->value == stmt->list.at(i).as_asm_dev->value) + if (stmt->list.at(i + 1) == ast::kind::asm_dev && stmt->list.at(i + 1).as_asm_dev->value == stmt->list.at(i).as_asm_dev->value) { stmt->list.erase(stmt->list.begin() + i + 1); } @@ -1619,7 +1598,7 @@ void decompiler::decompile_ifelse(const ast::stmt_list::ptr& stmt, std::size_t b stmt->list.insert(stmt->list.begin() + begin, std::move(new_stmt)); } -void decompiler::decompile_infinite(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end) +void decompiler::decompile_inf(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end) { block blk; blk.loc_break = last_location_index(stmt, end) ? blocks_.back().loc_end : stmt->list.at(end + 1).loc().label(); @@ -2107,7 +2086,7 @@ auto decompiler::resolve_label(const std::string& name) -> std::uint32_t } } - throw decomp_error("Couldn't resolve label address of '" + name + "'!"); + throw decomp_error("couldn't resolve label address of '" + name + "'!"); } void decompiler::process_thread(const ast::decl_thread::ptr& thread) diff --git a/src/t6/xsk/decompiler.hpp b/src/t6/xsk/decompiler.hpp index 40622d52..58f9ff3b 100644 --- a/src/t6/xsk/decompiler.hpp +++ b/src/t6/xsk/decompiler.hpp @@ -40,7 +40,7 @@ private: void decompile_devblocks(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_infinite(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end); + void decompile_inf(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end); void decompile_loop(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end); void decompile_while(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end); void decompile_dowhile(const ast::stmt_list::ptr& stmt, std::size_t begin, std::size_t end); diff --git a/src/t6/xsk/disassembler.cpp b/src/t6/xsk/disassembler.cpp index 780c2034..38b2be4b 100644 --- a/src/t6/xsk/disassembler.cpp +++ b/src/t6/xsk/disassembler.cpp @@ -230,9 +230,6 @@ void disassembler::disassemble(const std::string& file, std::vectorlabels = labels_; labels_.clear(); } - - // fixup list ... - // profile list ... } void disassembler::disassemble_function(const function::ptr& func) @@ -274,7 +271,7 @@ void disassembler::disassemble_function(const function::ptr& func) void disassembler::disassemble_instruction(const instruction::ptr& inst) { - switch (opcode(inst->opcode)) + switch (static_cast(inst->opcode)) { case opcode::OP_End: case opcode::OP_Return: @@ -438,6 +435,7 @@ void disassembler::disassemble_instruction(const instruction::ptr& inst) case opcode::OP_JumpOnTrueExpr: case opcode::OP_Jump: case opcode::OP_JumpBack: + case opcode::OP_DevblockBegin: disassemble_jump(inst); break; case opcode::OP_Switch: @@ -446,11 +444,8 @@ void disassembler::disassemble_instruction(const instruction::ptr& inst) case opcode::OP_EndSwitch: disassemble_end_switch(inst); break; - case opcode::OP_DevblockBegin: - disassemble_devblock(inst); - break; default: - throw disasm_error(utils::string::va("Unhandled opcode 0x%X at index '%04X'!", inst->opcode, inst->index)); + throw disasm_error(utils::string::va("unhandled opcode 0x%X at index '%04X'!", inst->opcode, inst->index)); } } @@ -458,10 +453,16 @@ void disassembler::disassemble_string(const instruction::ptr& inst) { inst->size += script_->align(2); - const auto& entry = string_refs_.at(script_->pos()); + const auto& entry = string_refs_.find(script_->pos()); - inst->data.push_back(entry->name); - script_->seek(2); + if (entry != string_refs_.end()) + { + inst->data.push_back(entry->second->name); + script_->seek(2); + return; + } + + throw disasm_error(utils::string::va("string reference not found at index '%04X'!", inst->index)); } void disassembler::disassemble_animation(const instruction::ptr& inst) @@ -469,20 +470,24 @@ void disassembler::disassemble_animation(const instruction::ptr& inst) inst->size += script_->align(4); const auto ref = script_->pos(); - const auto& entry = anim_refs_.at(ref); + const auto& entry = anim_refs_.find(ref); - inst->data.push_back(entry->name); - - for (const auto& anim : entry->anims) + if (entry != anim_refs_.end()) { - if (anim.ref == ref) + inst->data.push_back(entry->second->name); + + for (const auto& anim : entry->second->anims) { - inst->data.push_back(anim.name); - break; + if (anim.ref == ref) + { + inst->data.push_back(anim.name); + script_->seek(4); + return; + } } } - script_->seek(4); + throw disasm_error(utils::string::va("animation reference not found at index '%04X'!", inst->index)); } void disassembler::disassemble_localvars(const instruction::ptr& inst) @@ -501,17 +506,23 @@ void disassembler::disassemble_import(const instruction::ptr& inst) inst->size += script_->align(4); script_->seek(4); - const auto& entry = import_refs_.at(inst->index); + const auto& entry = import_refs_.find(inst->index); - inst->data.push_back(entry->space); - inst->data.push_back(entry->name); + if (entry != import_refs_.end()) + { + inst->data.push_back(entry->second->space); + inst->data.push_back(entry->second->name); + return; + } + + throw disasm_error(utils::string::va("import reference not found at index '%04X'!", inst->index)); } void disassembler::disassemble_jump(const instruction::ptr& inst) { inst->size += script_->align(2); - const auto addr = inst->index + inst->size + script_->read(); + const auto addr = script_->read() + script_->pos(); const auto label = utils::string::va("loc_%X", addr); inst->data.push_back(label); @@ -597,17 +608,6 @@ void disassembler::disassemble_end_switch(const instruction::ptr& inst) inst->data.push_back((numerical) ? "i" : "s"); } -void disassembler::disassemble_devblock(const instruction::ptr& inst) -{ - inst->size += script_->align(2); - - const auto addr = inst->index + inst->size + script_->read(); - const auto label = utils::string::va("loc_%X", addr); - - inst->data.push_back(label); - labels_.insert({ addr, label }); -} - void disassembler::print_function(const function::ptr& func) { output_->write_string("\n"); diff --git a/src/t6/xsk/disassembler.hpp b/src/t6/xsk/disassembler.hpp index fe8af3bc..66587c39 100644 --- a/src/t6/xsk/disassembler.hpp +++ b/src/t6/xsk/disassembler.hpp @@ -40,7 +40,6 @@ private: void disassemble_jump(const instruction::ptr& inst); void disassemble_switch(const instruction::ptr& inst); void disassemble_end_switch(const instruction::ptr& inst); - void disassemble_devblock(const instruction::ptr& inst); void print_function(const function::ptr& func); void print_instruction(const instruction::ptr& inst); }; diff --git a/src/t6/xsk/lexer.cpp b/src/t6/xsk/lexer.cpp index ba6ff8d8..1ba54a56 100644 --- a/src/t6/xsk/lexer.cpp +++ b/src/t6/xsk/lexer.cpp @@ -709,7 +709,7 @@ lex_number: if (last == '\'' || buffer_.length <= 0) throw comp_error(loc_, "invalid octal literal"); - return parser::make_INTEGER(xsk::utils::string::oct_to_dec(buffer_.data), loc_); + return parser::make_INTEGER(utils::string::oct_to_dec(buffer_.data), loc_); } else if (curr == 'b') { @@ -743,7 +743,7 @@ lex_number: if (last == '\'' || buffer_.length < 3) throw comp_error(loc_, "invalid binary literal"); - return parser::make_INTEGER(xsk::utils::string::bin_to_dec(buffer_.data), loc_); + return parser::make_INTEGER(utils::string::bin_to_dec(buffer_.data), loc_); } else if (curr == 'x') { @@ -777,7 +777,7 @@ lex_number: if (last == '\'' || buffer_.length < 3) throw comp_error(loc_, "invalid hexadecimal literal"); - return parser::make_INTEGER(xsk::utils::string::hex_to_dec(buffer_.data), loc_); + return parser::make_INTEGER(utils::string::hex_to_dec(buffer_.data), loc_); } throw error("UNEXPECTED LEXER INTERNAL ERROR!"); diff --git a/src/t6/xsk/resolver.cpp b/src/t6/xsk/resolver.cpp index d2e2b143..8b240d4a 100644 --- a/src/t6/xsk/resolver.cpp +++ b/src/t6/xsk/resolver.cpp @@ -39,7 +39,7 @@ auto resolver::opcode_id(const std::string& name) -> std::uint8_t return itr->second; } - throw error(utils::string::va("Couldn't resolve opcode id for name '%s'!", name.data())); + throw error(utils::string::va("couldn't resolve opcode id for name '%s'!", name.data())); } auto resolver::opcode_name(std::uint8_t id) -> std::string @@ -51,7 +51,7 @@ auto resolver::opcode_name(std::uint8_t id) -> std::string return std::string(itr->second); } - throw error(utils::string::va("Couldn't resolve opcode name for id '0x%hhX'!", id)); + throw error(utils::string::va("couldn't resolve opcode name for id '0x%hhX'!", id)); } auto resolver::dvar_name(std::uint32_t id) -> std::string diff --git a/src/t6/xsk/t6.cpp b/src/t6/xsk/t6.cpp index cfa9d859..738d4d16 100644 --- a/src/t6/xsk/t6.cpp +++ b/src/t6/xsk/t6.cpp @@ -11,7 +11,7 @@ namespace xsk::arc::t6 auto opcode_size(std::uint8_t id) -> std::uint32_t { - switch (opcode(id)) + switch (static_cast(id)) { case opcode::OP_End: case opcode::OP_Return: @@ -145,7 +145,7 @@ auto opcode_size(std::uint8_t id) -> std::uint32_t case opcode::OP_GetVector: return 13; default: - throw std::runtime_error("Couldn't resolve instruction size for " + std::to_string(id)); + throw error("couldn't resolve instruction size for " + std::to_string(id)); } }