diff --git a/decompiler/pipeline/controlflowanalysis/loop_utility_methods.py b/decompiler/pipeline/controlflowanalysis/loop_utility_methods.py index de21e9beb..b09410053 100644 --- a/decompiler/pipeline/controlflowanalysis/loop_utility_methods.py +++ b/decompiler/pipeline/controlflowanalysis/loop_utility_methods.py @@ -230,14 +230,14 @@ def _requirement_without_reinitialization(ast: AbstractSyntaxTree, node: Abstrac return True -def _get_continue_nodes_with_equalizable_definition(loop_node: WhileLoopNode, continuation: AstInstruction) -> List[CodeNode]: +def _get_equalizable_last_definitions(loop_node: WhileLoopNode, continuation: AstInstruction) -> List[CodeNode]: """ - Finds code nodes of a while loop containing continue statements and a definition of the continuation instruction, which can be easily equalized. + Finds equalizable last definitions of the continuation instruction in the code nodes of a while loop containing continue statements. :param loop_node: While-loop to search in :param continuation: Instruction defining the for-loops modification :param variable_init: Instruction defining the for-loops declaration - :return: List of continue code nodes that has equalizable definitions, None if at least one continue node does not match the requirements + :return: List of equalizable last definitions, None if at least one continue node does not match the requirements """ equalizable_nodes = [] for code_node in ( @@ -247,16 +247,18 @@ def _get_continue_nodes_with_equalizable_definition(loop_node: WhileLoopNode, co return None if (last_definition_index := _get_last_definition_index_of(code_node, continuation.instruction.destination)) == -1: return None + else: + last_definition = code_node.instructions[last_definition_index] if not ( - isinstance(code_node.instructions[last_definition_index].value, Constant) - or _is_expression_simple_binary_operation(code_node.instructions[last_definition_index].value) + isinstance(last_definition.value, Constant) + or _is_expression_simple_binary_operation(last_definition.value) and _get_variable_in_binary_operation(continuation.instruction.value) - == _get_variable_in_binary_operation(code_node.instructions[last_definition_index].value) + == _get_variable_in_binary_operation(last_definition.value) ): return None _unify_binary_operation_in_assignment(continuation.instruction) - equalizable_nodes.append(code_node) + equalizable_nodes.append(last_definition) return equalizable_nodes @@ -295,7 +297,7 @@ def _unify_binary_operation_in_assignment(assignment: Assignment): assignment.substitute(assignment.value, BinaryOperation(OperationType.plus, [assignment.value.right, assignment.value.left])) -def _substract_continuation_from_last_definition(code_node: CodeNode, continuation: AstInstruction): +def _substract_continuation_from_last_definition(last_definition: Assignment, continuation: AstInstruction): """ Substracts the value of the continuation instruction from the last definition, which must be a simple binary operation or a constant, defining the same value as the continuation instruction in the given code node. @@ -304,7 +306,6 @@ def _substract_continuation_from_last_definition(code_node: CodeNode, continuati :param continuation: Instruction defining the for-loops modification :param variable_init: Instruction defining the for-loops declaration """ - last_definition = code_node.instructions[_get_last_definition_index_of(code_node, continuation.instruction.destination)] last_definition.substitute( last_definition.value, BinaryOperation(OperationType.minus, [last_definition.value, continuation.instruction.value.right]) ) diff --git a/decompiler/pipeline/controlflowanalysis/readability_based_refinement.py b/decompiler/pipeline/controlflowanalysis/readability_based_refinement.py index 3d640eac5..f979803c7 100644 --- a/decompiler/pipeline/controlflowanalysis/readability_based_refinement.py +++ b/decompiler/pipeline/controlflowanalysis/readability_based_refinement.py @@ -6,7 +6,7 @@ from decompiler.pipeline.controlflowanalysis.loop_utility_methods import ( AstInstruction, _find_continuation_instruction, - _get_continue_nodes_with_equalizable_definition, + _get_equalizable_last_definitions, _get_variable_initialisation, _initialization_reaches_loop_node, _is_single_instruction_loop_node, @@ -103,10 +103,10 @@ def run(self): continue if not self._force_for_loops and continuation.instruction.complexity > self._modification_max_complexity: continue - if (equalizable_continue_nodes := _get_continue_nodes_with_equalizable_definition(loop_node, continuation)) is None: + if (equalizable_last_definitions := _get_equalizable_last_definitions(loop_node, continuation)) is None: continue - for node in equalizable_continue_nodes: - _substract_continuation_from_last_definition(node, continuation) + for last_definition in equalizable_last_definitions: + _substract_continuation_from_last_definition(last_definition, continuation) self._replace_with_for_loop(loop_node, continuation, variable_init) break