Skip to content

Commit

Permalink
fix(arc): decompile original bugs & early return (#229)
Browse files Browse the repository at this point in the history
  • Loading branch information
xensik authored Nov 3, 2024
1 parent 9ab4470 commit f5c895f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 13 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ A utility to compile & decompile IW engine game scripts.
- **T7** *(Call of Duty: Black Ops III)* `PC` *(Decompiler)*
- **T8** *(Call of Duty: Black Ops 4)* ***\*WIP\****
- **T9** *(Call of Duty: Black Ops Cold War)* ***\*WIP\****
- **T10** *(Call of Duty: Black Ops 6)* ***\*WIP\****
- **JUP** *(Call of Duty: Modern Warfare III (2023)* ***\*WIP\****

## Usage
Expand Down
1 change: 1 addition & 0 deletions include/xsk/arc/common/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct locjmp
std::string cnt;
std::string brk;
bool is_dev;
bool is_switch;
};

// fordward decl for modules ref
Expand Down
2 changes: 1 addition & 1 deletion src/arc/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ auto compiler::emit_decl_function(decl_function const& func) -> void
emit_expr_parameters(*func.params);
emit_stmt_comp(*func.body);

if (scopes_.back().abort == scope::abort_none)
if (scopes_.back().abort == scope::abort_none || function_->labels.find(index_) != function_->labels.end())
emit_opcode(opcode::OP_End);

scopes_.pop_back();
Expand Down
40 changes: 28 additions & 12 deletions src/arc/decompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,15 @@ auto decompiler::decompile_ifelses(stmt_list& stm) -> void
}
else
{
decompile_ifelse(stm, i, j);
// fix treyarch compiler bug: breaks outside loops or switches
auto out_of_scope = stm.list.at(stm.list.size() - 1)->loc().begin.line < std::stol(stm.list.at(j)->as<stmt_jmp>().value.substr(4), 0, 16);

if (locs_.brk == "" && out_of_scope)
decompile_if(stm, i, j);
else
decompile_ifelse(stm, i, j);

//decompile_ifelse(stm, i, j);
}
}
else
Expand Down Expand Up @@ -1413,19 +1421,26 @@ auto decompiler::decompile_aborts(stmt_list& stm) -> void
}
else
{
// fix for treyarch compiler bug: nested switch break locs are not preserved
if (jmp != locs_.end)
// fix treyarch compiler bug: breaks outside loops or switches
if (locs_.brk == "")
{
auto j = find_location_index(stm, jmp);

if (stm.list.at(j)->is<stmt_break>())
{
stm.list.erase(stm.list.begin() + i);
stm.list.insert(stm.list.begin() + i, stmt_break::make(loc));

continue;
}
stm.list.erase(stm.list.begin() + i);
stm.list.insert(stm.list.begin() + i, stmt_break::make(loc));
}
// fix treyarch compiler bug: nested switch break locs are not preserved
else if (jmp != locs_.end && stm.list.at(find_location_index(stm, jmp))->is<stmt_break>())
{
stm.list.erase(stm.list.begin() + i);
stm.list.insert(stm.list.begin() + i, stmt_break::make(loc));
continue;
}
else if (locs_.is_switch && stm.list.at(stm.list.size() - 1)->is<stmt_switch>())
{
stm.list.erase(stm.list.begin() + i);
stm.list.insert(stm.list.begin() + i, stmt_break::make(loc));
continue;
}

std::cout << "WARNING: unresolved jump to '" + jmp + "', maybe incomplete for loop\n";
}
}
Expand Down Expand Up @@ -1853,6 +1868,7 @@ auto decompiler::decompile_switch(stmt_list& stm, usize begin, usize end) -> voi
auto save = locs_;
locs_.brk = last_location_index(stm, end) ? locs_.end : stm.list[end + 1]->label();
locs_.end = stm.list[begin]->as<stmt_jmp_switch>().value;
locs_.is_switch = true;

auto loc = stm.list[begin]->loc();
auto test = std::move(stm.list[begin]->as<stmt_jmp_switch>().test);
Expand Down

0 comments on commit f5c895f

Please sign in to comment.