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));
const auto count = std::stoul(inst->data[0]);
const auto numerical = inst->data.back() == "i";
script_->align(4);
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 (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);
}
@ -705,12 +706,13 @@ void assembler::align_instruction(const instruction::ptr& inst)
script_->seek(4);
const auto count = std::stoul(inst->data[0]);
const auto numerical = inst->data.back() == "i";
for (auto i = 0u; i < count; i++)
{
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);
}
@ -792,12 +794,13 @@ void assembler::process_instruction(const instruction::ptr& inst)
case opcode::OP_EndSwitch:
{
const auto count = std::stoul(inst->data[0]);
const auto numerical = inst->data.back() == "i";
for (auto i = 0u; i < count; i++)
{
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]);
}

View File

@ -656,6 +656,7 @@ void compiler::emit_stmt_switch(const ast::stmt_switch::ptr& stmt)
std::vector<std::string> data;
data.push_back(utils::string::va("%d", stmt->stmt->list.size()));
bool numerical = false;
bool has_default = false;
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;
if (case_->label == ast::kind::expr_integer)
{
numerical = true;
auto loc = insert_label();
data.push_back("case");
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();
data.push_back(numerical ? "i" : "s");
insert_label(jmptable_loc);
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()));
{
std::uint32_t totalcase = std::stoul(inst->data[0]);
auto numerical = inst->data.back() == "i";
auto index = 0;
for (auto casenum = 0u; casenum < totalcase; casenum++)
{
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;
}
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
auto casenum = std::atol(stmt->list.at(end).as_asm_endswitch->count.data());
auto data = stmt->list.at(end).as_asm_endswitch->data;
auto numerical = data.back() == "i";
auto idx = 0;
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_idx = find_location_index(stmt, loc_str);
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);
list->is_case = true;
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>();
inst->data.push_back(utils::string::va("%i", count));
@ -579,6 +580,7 @@ void disassembler::disassemble_end_switch(const instruction::ptr& inst)
}
else
{
numerical = true;
inst->data.push_back("case");
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->data.push_back((numerical) ? "i" : "s");
}
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()));
{
std::uint32_t totalcase = std::stoul(inst->data[0]);
auto numerical = inst->data.back() == "i";
auto index = 0;
for (auto casenum = 0u; casenum < totalcase; casenum++)
{
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;
}
else if (inst->data[1 + index] == "default")