Fix removal of double-length conditional instructions (PBS entry signal).

pull/16/head
Jonathan G Rennison 7 years ago
parent a2a8f7f7b7
commit f10c32de53

@ -844,6 +844,16 @@ static uint32 GetDualInstructionInitialValue(TraceRestrictItem item)
}
}
template <typename T> T InstructionIteratorNext(T iter)
{
return IsTraceRestrictDoubleItem(*iter) ? iter + 2 : iter + 1;
}
template <typename T> void InstructionIteratorAdvance(T &iter)
{
iter = InstructionIteratorNext(iter);
}
CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &items, uint32 offset, bool shallow_mode)
{
TraceRestrictItem old_item = *TraceRestrictProgram::InstructionAt(items, offset);
@ -861,10 +871,10 @@ CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &ite
uint32 recursion_depth = 1;
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
std::vector<TraceRestrictItem>::iterator remove_end = InstructionIteratorNext(remove_start);
// iterate until matching end block found
for (; remove_end != items.end(); ++remove_end) {
for (; remove_end != items.end(); InstructionIteratorAdvance(remove_end)) {
TraceRestrictItem current_item = *remove_end;
if (IsTraceRestrictConditional(current_item)) {
if (GetTraceRestrictCondFlags(current_item) == 0) {
@ -873,8 +883,13 @@ CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &ite
recursion_depth--;
if (recursion_depth == 0) {
if (remove_whole_block) {
// inclusively remove up to here
++remove_end;
if (shallow_mode) {
// must erase endif first, as it is later in the vector
items.erase(remove_end, InstructionIteratorNext(remove_end));
} else {
// inclusively remove up to here
InstructionIteratorAdvance(remove_end);
}
break;
} else {
// exclusively remove up to here
@ -897,27 +912,18 @@ CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &ite
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_SHALLOW_REMOVE_IF_ELIF);
}
}
} else if (IsTraceRestrictDoubleItem(current_item)) {
// this is a double-item, jump over the next item as well
++remove_end;
}
}
if (recursion_depth != 0) return CMD_ERROR; // ran off the end
if (shallow_mode) {
// must erase endif first, as it is later in the vector
if (remove_whole_block) items.erase(remove_end - 1);
items.erase(remove_start);
items.erase(remove_start, InstructionIteratorNext(remove_start));
} else {
items.erase(remove_start, remove_end);
}
} else {
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
std::vector<TraceRestrictItem>::iterator remove_end = InstructionIteratorNext(remove_start);
if (IsTraceRestrictDoubleItem(old_item)) {
// this is a double-item, remove the next item as well
++remove_end;
}
items.erase(remove_start, remove_end);
}
return CommandCost();

Loading…
Cancel
Save