t6: fix switch type bug
This commit is contained in:
parent
37205b6345
commit
405e2b7046
@ -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]);
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
|
@ -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)));
|
||||||
|
@ -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")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user