diff --git a/src/h1/xsk/decompiler.cpp b/src/h1/xsk/decompiler.cpp index 939172c3..964e9858 100644 --- a/src/h1/xsk/decompiler.cpp +++ b/src/h1/xsk/decompiler.cpp @@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1787,26 +1787,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2413,7 +2425,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' diff --git a/src/h2/xsk/decompiler.cpp b/src/h2/xsk/decompiler.cpp index 5da0fd08..9ce527d3 100644 --- a/src/h2/xsk/decompiler.cpp +++ b/src/h2/xsk/decompiler.cpp @@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1787,26 +1787,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2413,7 +2425,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' diff --git a/src/iw5/xsk/decompiler.cpp b/src/iw5/xsk/decompiler.cpp index 6302c053..7dc8a3d7 100644 --- a/src/iw5/xsk/decompiler.cpp +++ b/src/iw5/xsk/decompiler.cpp @@ -1272,7 +1272,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); diff --git a/src/iw6/xsk/decompiler.cpp b/src/iw6/xsk/decompiler.cpp index f506ed8e..f906f217 100644 --- a/src/iw6/xsk/decompiler.cpp +++ b/src/iw6/xsk/decompiler.cpp @@ -1272,7 +1272,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1781,26 +1781,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2407,7 +2419,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' diff --git a/src/iw7/xsk/decompiler.cpp b/src/iw7/xsk/decompiler.cpp index 8a6ba22d..ade885ee 100644 --- a/src/iw7/xsk/decompiler.cpp +++ b/src/iw7/xsk/decompiler.cpp @@ -1272,7 +1272,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1781,26 +1781,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2407,7 +2419,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' diff --git a/src/iw8/xsk/decompiler.cpp b/src/iw8/xsk/decompiler.cpp index 4d5453c8..8069389d 100644 --- a/src/iw8/xsk/decompiler.cpp +++ b/src/iw8/xsk/decompiler.cpp @@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1818,26 +1818,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2444,7 +2456,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' diff --git a/src/s1/xsk/decompiler.cpp b/src/s1/xsk/decompiler.cpp index e246edcc..3d7ffa87 100644 --- a/src/s1/xsk/decompiler.cpp +++ b/src/s1/xsk/decompiler.cpp @@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1787,26 +1787,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2413,7 +2425,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' diff --git a/src/s2/xsk/decompiler.cpp b/src/s2/xsk/decompiler.cpp index b7253dd8..a5681fcc 100644 --- a/src/s2/xsk/decompiler.cpp +++ b/src/s2/xsk/decompiler.cpp @@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1794,26 +1794,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2420,7 +2432,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch' diff --git a/src/s4/xsk/decompiler.cpp b/src/s4/xsk/decompiler.cpp index aba03579..6d9f21c4 100644 --- a/src/s4/xsk/decompiler.cpp +++ b/src/s4/xsk/decompiler.cpp @@ -1278,7 +1278,7 @@ void decompiler::decompile_instruction(const instruction::ptr& inst) auto expr = ast::expr(std::move(stack_.top())); stack_.pop(); loc = expr.as_node->loc(); - for (auto i = std::stoul(inst->data[0]); i > 0; i++) + for (auto i = std::stoul(inst->data[0]); i > 0; i--) { auto node = std::move(stack_.top()); stack_.pop(); loc = node->loc(); @@ -1818,26 +1818,38 @@ void decompiler::decompile_statements(const ast::stmt_list::ptr& stmt) void decompiler::decompile_infinites(const ast::stmt_list::ptr& stmt) { - for (auto i = stmt->list.size() - 1; i > 0; i--) + if (stmt->list.size() == 0) return; + + for (std::int32_t i = stmt->list.size() - 1; i >= 0; i--) { if (stmt->list.at(i) == ast::kind::asm_jump_back) { auto break_loc = last_location_index(stmt, i) ? blocks_.back().loc_end : stmt->list.at(i + 1).loc().label(); auto start = find_location_index(stmt, stmt->list.at(i).as_jump_back->value); - if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) + if (i > 0 && stmt->list.at(i - 1).as_node->kind() == ast::kind::asm_jump_cond) // do-while { continue; } + else if (i == static_cast(start)) // empty loop + { + decompile_infinite(stmt, start, i); + i = stmt->list.size(); + } else if (stmt->list.at(start).as_node->kind() != ast::kind::asm_jump_cond) { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); } - else if (stmt->list.at(start).as_cond->value != break_loc) + else if (stmt->list.at(start).as_cond->value != break_loc) // cond belong to other stmt { decompile_infinite(stmt, start, i); - i = start; + i = stmt->list.size(); + } + else if (stmt->list.at(start).as_cond->value == break_loc) // not inf + { + decompile_loop(stmt, start, i); + i = stmt->list.size(); } } } @@ -2444,7 +2456,14 @@ void decompiler::decompile_switch(const ast::stmt_list::ptr& stmt, std::size_t s } } - end = find_location_index(stmt, end_loc) - 1; // update end; + end = find_location_index(stmt, end_loc); // update end + + // fix empty cases at end + if (stmt->list.at(end) == ast::kind::asm_endswitch) + end--; + + // TODO: fix more than 1 empty case at end + stmt->list.erase(stmt->list.begin() + start); // remove 'switch' stmt->list.erase(stmt->list.begin() + end); // remove 'endswitch'