t6: fix switch type bug

This commit is contained in:
xensik 2022-05-02 14:30:54 +02:00
parent 37205b6345
commit 405e2b7046
4 changed files with 21 additions and 6 deletions

View File

@ -465,6 +465,7 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode)); script_->write<std::uint8_t>(static_cast<std::uint8_t>(inst->opcode));
const auto count = std::stoul(inst->data[0]); const auto count = std::stoul(inst->data[0]);
const auto numerical = inst->data.back() == "i";
script_->align(4); script_->align(4);
script_->write<std::uint32_t>(count); script_->write<std::uint32_t>(count);
@ -473,7 +474,7 @@ void assembler::assemble_end_switch(const instruction::ptr& inst)
{ {
if (inst->data[1 + (3 * i)] == "case") if (inst->data[1 + (3 * i)] == "case")
{ {
if (utils::string::is_number(inst->data[1 + (3 * i) + 1])) if (numerical /*&& utils::string::is_number(inst->data[1 + (3 * i) + 1])*/)
{ {
script_->write<uint32_t>((std::stoi(inst->data[1 + (3 * i) + 1]) & 0xFFFFFF) + 0x800000); script_->write<uint32_t>((std::stoi(inst->data[1 + (3 * i) + 1]) & 0xFFFFFF) + 0x800000);
} }
@ -705,12 +706,13 @@ void assembler::align_instruction(const instruction::ptr& inst)
script_->seek(4); script_->seek(4);
const auto count = std::stoul(inst->data[0]); const auto count = std::stoul(inst->data[0]);
const auto numerical = inst->data.back() == "i";
for (auto i = 0u; i < count; i++) for (auto i = 0u; i < count; i++)
{ {
if (inst->data[1 + (3 * i)] == "case") if (inst->data[1 + (3 * i)] == "case")
{ {
if (!utils::string::is_number(inst->data[1 + (3 * i) + 1])) if (!numerical /*|| !utils::string::is_number(inst->data[1 + (3 * i) + 1])*/)
{ {
add_string_reference(inst->data[1 + (3 * i) + 1], string_type::literal, script_->pos() + 2); add_string_reference(inst->data[1 + (3 * i) + 1], string_type::literal, script_->pos() + 2);
} }
@ -792,12 +794,13 @@ void assembler::process_instruction(const instruction::ptr& inst)
case opcode::OP_EndSwitch: case opcode::OP_EndSwitch:
{ {
const auto count = std::stoul(inst->data[0]); const auto count = std::stoul(inst->data[0]);
const auto numerical = inst->data.back() == "i";
for (auto i = 0u; i < count; i++) for (auto i = 0u; i < count; i++)
{ {
if (inst->data[1 + (3 * i)] == "case") if (inst->data[1 + (3 * i)] == "case")
{ {
if (!utils::string::is_number(inst->data[1 + (3 * i) + 1])) if (!numerical /*|| !utils::string::is_number(inst->data[1 + (3 * i) + 1])*/)
{ {
process_string(inst->data[1 + (3 * i) + 1]); process_string(inst->data[1 + (3 * i) + 1]);
} }

View File

@ -656,6 +656,7 @@ void compiler::emit_stmt_switch(const ast::stmt_switch::ptr& stmt)
std::vector<std::string> data; std::vector<std::string> data;
data.push_back(utils::string::va("%d", stmt->stmt->list.size())); data.push_back(utils::string::va("%d", stmt->stmt->list.size()));
bool numerical = false;
bool has_default = false; bool has_default = false;
for (auto i = 0u; i < stmt->stmt->list.size(); i++) for (auto i = 0u; i < stmt->stmt->list.size(); i++)
@ -672,6 +673,7 @@ void compiler::emit_stmt_switch(const ast::stmt_switch::ptr& stmt)
auto& case_ = entry.as_case; auto& case_ = entry.as_case;
if (case_->label == ast::kind::expr_integer) if (case_->label == ast::kind::expr_integer)
{ {
numerical = true;
auto loc = insert_label(); auto loc = insert_label();
data.push_back("case"); data.push_back("case");
data.push_back(case_->label.as_integer->value); data.push_back(case_->label.as_integer->value);
@ -713,6 +715,7 @@ void compiler::emit_stmt_switch(const ast::stmt_switch::ptr& stmt)
} }
blocks_.pop_back(); blocks_.pop_back();
data.push_back(numerical ? "i" : "s");
insert_label(jmptable_loc); insert_label(jmptable_loc);
emit_opcode(opcode::OP_EndSwitch, data); emit_opcode(opcode::OP_EndSwitch, data);
@ -2432,12 +2435,14 @@ void compiler::print_instruction(const instruction::ptr& inst)
output_->write_string(utils::string::va("%s", inst->data[0].data())); output_->write_string(utils::string::va("%s", inst->data[0].data()));
{ {
std::uint32_t totalcase = std::stoul(inst->data[0]); std::uint32_t totalcase = std::stoul(inst->data[0]);
auto numerical = inst->data.back() == "i";
auto index = 0; auto index = 0;
for (auto casenum = 0u; casenum < totalcase; casenum++) for (auto casenum = 0u; casenum < totalcase; casenum++)
{ {
if (inst->data[1 + index] == "case") if (inst->data[1 + index] == "case")
{ {
output_->write_string(utils::string::va(", %s, \"%s\", %s", inst->data[1 + index].data(), inst->data[1 + index + 1].data(), inst->data[1 + index + 2].data())); auto fmt = numerical ? ", %s, %s, %s"s : ", %s, \"%s\", %s"s;
output_->write_string(utils::string::va(fmt, inst->data[1 + index].data(), inst->data[1 + index + 1].data(), inst->data[1 + index + 2].data()));
index += 3; index += 3;
} }
else if (inst->data[1 + index] == "default") else if (inst->data[1 + index] == "default")

View File

@ -1881,6 +1881,7 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
// collect cases // collect cases
auto casenum = std::atol(stmt->list.at(end).as_asm_endswitch->count.data()); auto casenum = std::atol(stmt->list.at(end).as_asm_endswitch->count.data());
auto data = stmt->list.at(end).as_asm_endswitch->data; auto data = stmt->list.at(end).as_asm_endswitch->data;
auto numerical = data.back() == "i";
auto idx = 0; auto idx = 0;
for (auto i = 0; i < casenum; i++) for (auto i = 0; i < casenum; i++)
@ -1890,7 +1891,7 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s
auto loc_str = data.at(idx + 2); auto loc_str = data.at(idx + 2);
auto loc_idx = find_location_index(stmt, loc_str); auto loc_idx = find_location_index(stmt, loc_str);
auto loc_pos = location(&filename_, std::stol(loc_str.substr(4), 0, 16)); auto loc_pos = location(&filename_, std::stol(loc_str.substr(4), 0, 16));
auto value = ast::expr(std::make_unique<ast::expr_string>(loc_pos, data.at(idx + 1))); auto value = numerical ? ast::expr(std::make_unique<ast::expr_integer>(loc_pos, data.at(idx + 1))) : ast::expr(std::make_unique<ast::expr_string>(loc_pos, data.at(idx + 1)));
auto list = std::make_unique<ast::stmt_list>(loc); auto list = std::make_unique<ast::stmt_list>(loc);
list->is_case = true; list->is_case = true;
auto case_stmt = ast::stmt(std::make_unique<ast::stmt_case>(loc_pos, std::move(value), std::move(list))); auto case_stmt = ast::stmt(std::make_unique<ast::stmt_case>(loc_pos, std::move(value), std::move(list)));

View File

@ -560,6 +560,7 @@ void disassembler::disassemble_end_switch(const instruction::ptr& inst)
} }
} }
auto numerical = false;
const auto count = script_->read<std::uint32_t>(); const auto count = script_->read<std::uint32_t>();
inst->data.push_back(utils::string::va("%i", count)); inst->data.push_back(utils::string::va("%i", count));
@ -579,6 +580,7 @@ void disassembler::disassemble_end_switch(const instruction::ptr& inst)
} }
else else
{ {
numerical = true;
inst->data.push_back("case"); inst->data.push_back("case");
inst->data.push_back(utils::string::va("%i", (value - 0x800000) & 0xFFFFFF)); inst->data.push_back(utils::string::va("%i", (value - 0x800000) & 0xFFFFFF));
} }
@ -591,6 +593,8 @@ void disassembler::disassemble_end_switch(const instruction::ptr& inst)
inst->size += 8; inst->size += 8;
} }
inst->data.push_back((numerical) ? "i" : "s");
} }
void disassembler::disassemble_devblock(const instruction::ptr& inst) void disassembler::disassemble_devblock(const instruction::ptr& inst)
@ -658,12 +662,14 @@ void disassembler::print_instruction(const instruction::ptr& inst)
output_->write_string(utils::string::va("%s", inst->data[0].data())); output_->write_string(utils::string::va("%s", inst->data[0].data()));
{ {
std::uint32_t totalcase = std::stoul(inst->data[0]); std::uint32_t totalcase = std::stoul(inst->data[0]);
auto numerical = inst->data.back() == "i";
auto index = 0; auto index = 0;
for (auto casenum = 0u; casenum < totalcase; casenum++) for (auto casenum = 0u; casenum < totalcase; casenum++)
{ {
if (inst->data[1 + index] == "case") if (inst->data[1 + index] == "case")
{ {
output_->write_string(utils::string::va(", %s, \"%s\", %s", inst->data[1 + index].data(), inst->data[1 + index + 1].data(), inst->data[1 + index + 2].data())); auto fmt = numerical ? ", %s, %s, %s"s : ", %s, \"%s\", %s"s;
output_->write_string(utils::string::va(fmt, inst->data[1 + index].data(), inst->data[1 + index + 1].data(), inst->data[1 + index + 2].data()));
index += 3; index += 3;
} }
else if (inst->data[1 + index] == "default") else if (inst->data[1 + index] == "default")