diff --git a/__init__.py b/__init__.py index 7c43afacd..356458f86 100644 --- a/__init__.py +++ b/__init__.py @@ -22,9 +22,10 @@ def decompile(bv: BinaryView, function: Function): """Decompile the target mlil_function.""" decompiler = Decompiler.from_raw(bv) options = Options.from_gui() - task = decompiler.decompile(function, options) + task, code = decompiler.decompile(function, task_options=options) show_html_report( - f"decompile {task.name}", DecoratedCode.generate_html_from_code(task.code, task.options.getstring("code-generator.style_plugin")) + f"decompile {task.name}", + DecoratedCode.generate_html_from_code(code, options.getstring("code-generator.style_plugin")), ) diff --git a/decompile.py b/decompile.py index 971129f21..739e57d0a 100755 --- a/decompile.py +++ b/decompile.py @@ -2,7 +2,8 @@ """Main decompiler Interface.""" from __future__ import annotations -from typing import Dict, List, Optional, Tuple +from dataclasses import dataclass +from typing import Collection, Optional from decompiler.backend.codegenerator import CodeGenerator from decompiler.frontend import BinaryninjaFrontend, Frontend @@ -40,33 +41,49 @@ def from_raw(cls, data, frontend: Frontend = BinaryninjaFrontend) -> Decompiler: """Create a decompiler instance from existing frontend instance (e.g. a binaryninja view).""" return cls(frontend.from_raw(data)) - def decompile(self, function: str, task_options: Optional[Options] = None) -> DecompilerTask: - """Decompile the target function.""" - # Sanity check to ensure task_options is populated - if task_options is None: - task_options = Decompiler.create_options() - # Start decompiling - pipeline = DecompilerPipeline.from_strings(task_options.getlist("pipeline.cfg_stages"), task_options.getlist("pipeline.ast_stages")) - task = self._frontend.create_task(function, task_options) - pipeline.run(task) - task.code = self._backend.generate([task]) - return task - - def decompile_all(self, task_options: Optional[Options] = None) -> str: - """Decompile all functions in the binary""" - tasks = list() - # Sanity check to ensure task_options is populated + def decompile_all(self, function_ids: Collection[object] | None = None, task_options: Options | None = None) -> Result: + """ + Decompile a collection of functions specified by their identifiers. + + :param function_ids: A collection of function identifiers to decompile. If None, decompiles all functions. + :param task_options: Options for the decompilation tasks. If None, default options are used. + :return: A Result object containing decompiled tasks and generated code. + """ + if function_ids is None: # decompile all functions when none are specified + function_ids = self._frontend.get_all_function_names() if task_options is None: task_options = Decompiler.create_options() - # Start decompiling + pipeline = DecompilerPipeline.from_strings(task_options.getlist("pipeline.cfg_stages"), task_options.getlist("pipeline.ast_stages")) - functions = self._frontend.get_all_function_names() - for function in functions: - task = self._frontend.create_task(function, task_options) - pipeline.run(task) + + tasks = [] + for func_id in function_ids: + task = DecompilerTask(str(func_id), func_id, task_options) tasks.append(task) + + self._frontend.lift(task) + pipeline.run(task) + code = self._backend.generate(tasks) - return code + + return Decompiler.Result(tasks, code) + + def decompile(self, function_id: object, task_options: Options | None = None) -> tuple[DecompilerTask, str]: + """ + Decompile a specific function specified by its identifier. + This method servers as a shorthand for decompiling a single function and simply delegates to decompile_all. + + :param function_id: The identifier of the function to decompile. + :param task_options: Options for the decompilation task. If None, default options are used. + :return: A tuple containing the DecompilerTask object and the generated code. + """ + result = self.decompile_all([function_id], task_options) + return result.tasks[0], result.code + + @dataclass + class Result: + tasks: list[DecompilerTask] + code: str """When invoked as a script, run the commandline interface.""" diff --git a/decompiler/backend/codegenerator.py b/decompiler/backend/codegenerator.py index ebb31c61c..075832898 100644 --- a/decompiler/backend/codegenerator.py +++ b/decompiler/backend/codegenerator.py @@ -37,12 +37,23 @@ def generate(self, tasks: Iterable[DecompilerTask], run_cleanup: bool = True): def generate_function(self, task: DecompilerTask) -> str: """Generate C-Code for the function described in the given DecompilerTask.""" - return self.TEMPLATE.substitute( - return_type=task.function_return_type, - name=task.name, - parameters=", ".join( - map(lambda param: CExpressionGenerator.format_variables_declaration(param.type, [param.name]), task.function_parameters) - ), - local_declarations=LocalDeclarationGenerator.from_task(task) if not task.failed else "", - function_body=CodeVisitor(task).visit(task.syntax_tree.root) if not task.failed else task.failure_message, - ) + if task.failed: + return self.generate_failure_message(task) + else: + return self.TEMPLATE.substitute( + return_type=task.function_return_type, + name=task.name, + parameters=", ".join( + map(lambda param: CExpressionGenerator.format_variables_declaration(param.type, [param.name]), task.function_parameters) + ), + local_declarations=LocalDeclarationGenerator.from_task(task), + function_body=CodeVisitor(task).visit(task.syntax_tree.root), + ) + + @staticmethod + def generate_failure_message(task: DecompilerTask): + """Returns the message to be shown for a failed task.""" + msg = f"Failed to decompile {task.name}" + if origin := task.failure_origin: # checks if the string is empty (should never be None when this method is called) + msg += f" due to error during {origin}." + return msg diff --git a/decompiler/frontend/binaryninja/frontend.py b/decompiler/frontend/binaryninja/frontend.py index e84697fc7..dd0b9ebe5 100644 --- a/decompiler/frontend/binaryninja/frontend.py +++ b/decompiler/frontend/binaryninja/frontend.py @@ -3,14 +3,10 @@ from __future__ import annotations import logging -from typing import List, Optional, Tuple, Union -from binaryninja import BinaryView, Function, load +import binaryninja +from binaryninja import BinaryView from binaryninja.types import SymbolType -from decompiler.structures.graphs.cfg import ControlFlowGraph -from decompiler.structures.pseudo.complextypes import ComplexTypeMap -from decompiler.structures.pseudo.expressions import Variable -from decompiler.structures.pseudo.typing import Type from decompiler.task import DecompilerTask from decompiler.util.options import Options @@ -20,72 +16,6 @@ from .tagging import CompilerIdiomsTagging -class FunctionObject: - """Wrapper class for dealing with Binaryninja Functions""" - - def __init__(self, function: Function): - self._function = function - self._lifter = BinaryninjaLifter() - self._name = self._lifter.lift(self._function.symbol).name - - @classmethod - def get(cls, bv: BinaryView, identifier: Union[str, Function]) -> FunctionObject: - """Get a function object from the given identifier.""" - if isinstance(identifier, Function): - return cls(identifier) - if isinstance(identifier, str): - return cls.from_string(bv, identifier) - raise ValueError(f"Could not parse function identifier of type {type(identifier)}.") - - @classmethod - def from_string(cls, bv: BinaryView, function_name: str) -> FunctionObject: - """Given a function identifier, locate Function object in BinaryView""" - if (function := cls._resolve_by_identifier_name(bv, function_name)) is not None: - return cls(function) - if (function := cls._resolve_by_address(bv, function_name)) is not None: - return cls(function) - raise RuntimeError(f"Frontend could not resolve function '{function_name}'") - - @property - def function(self) -> Function: - """Function object""" - return self._function - - @property - def name(self) -> str: - """Name of function object""" - return self._name - - @property - def return_type(self) -> Type: - """Lifted return type of function""" - return self._lifter.lift(self._function.type.return_value) - - @property - def params(self) -> List[Variable]: - """Lifted function parameters""" - return [self._lifter.lift(param) for param in self._function.type.parameters] - - @staticmethod - def _resolve_by_identifier_name(bv: BinaryView, function_name: str) -> Optional[Function]: - """ - Iterate BinaryView.functions and compare matching names. - - note: we take this approach since bv.get_functions_by_name() may return wrong functions. - """ - return next(filter(lambda f: f.name == function_name, bv.functions), None) - - @staticmethod - def _resolve_by_address(bv: BinaryView, hex_str: str) -> Optional[Function]: - """Get Function object by hex address or 'sub_
'""" - try: - hex_address = hex_str[4:] if hex_str.startswith("sub_") else hex_str - address = int(hex_address, 16) - return bv.get_function_at(address) - except ValueError: - logging.info(f"{hex_str} does not contain hex value") - - class BinaryninjaFrontend(Frontend): """Frontend implementation for binaryninja.""" @@ -114,7 +44,7 @@ def __init__(self, bv: BinaryView): def from_path(cls, path: str, options: Options): """Create a frontend object by invoking binaryninja on the given sample.""" file_options = {"analysis.limits.maxFunctionSize": options.getint("binaryninja.max_function_size")} - if (bv := load(path, options=file_options)) is not None: + if (bv := binaryninja.load(path, options=file_options)) is not None: return cls(bv) raise RuntimeError("Failed to create binary view") @@ -123,30 +53,34 @@ def from_raw(cls, view: BinaryView): """Create a binaryninja frontend instance based on an initialized binary view.""" return cls(view) - def create_task(self, function_identifier: Union[str, Function], options: Options) -> DecompilerTask: - """Create a task from the given function identifier.""" - function = FunctionObject.get(self._bv, function_identifier) - tagging = CompilerIdiomsTagging(self._bv, function.function.start, options) - tagging.run() + def lift(self, task: DecompilerTask): + """ + Lifts data from binaryninja into the specified Decompiler task. + The function to be lifted is identified by the function identifier of the decompiler task (task.function_identifier). + + :param task: Decompiler task to lift data into. + """ + if task.failed: + return + try: - cfg, complex_types = self._extract_cfg(function.function, options) - task = DecompilerTask( - function.name, - cfg, - function_return_type=function.return_type, - function_parameters=function.params, - options=options, - complex_types=complex_types, - ) + function = self._get_binninja_function(task.function_identifier) + lifter, parser = self._create_lifter_parser(task.options) + + task.function_return_type = lifter.lift(function.return_type) + task.function_parameters = [lifter.lift(param_type) for param_type in function.type.parameters] + + tagging = CompilerIdiomsTagging(self._bv, function.start, task.options) + tagging.run() + + task.cfg = parser.parse(function) + task.complex_types = parser.complex_types except Exception as e: - task = DecompilerTask( - function.name, None, function_return_type=function.return_type, function_parameters=function.params, options=options - ) - task.fail(origin="CFG creation") - logging.error(f"Failed to decompile {task.name}, error during CFG creation: {e}") - if options.getboolean("pipeline.debug", fallback=False): + task.fail("Function lifting") + logging.exception(f"Failed to decompile {task.name}, error during function lifting") + + if task.options.getboolean("pipeline.debug", fallback=False): raise e - return task def get_all_function_names(self): """Returns the entire list of all function names in the binary. Ignores blacklisted functions and imported functions.""" @@ -159,9 +93,63 @@ def get_all_function_names(self): functions.append(function.name) return functions - def _extract_cfg(self, function: Function, options: Options) -> Tuple[ControlFlowGraph, ComplexTypeMap]: - """Extract a control flow graph utilizing the parser and fixing it afterwards.""" + def _get_binninja_function(self, function_identifier: object) -> binaryninja.function.Function: + """ + Retrieves the Binary Ninja function based on the provided function identifier. + + :param function_identifier: An object representing the identifier of the function. + :return: The Binary Ninja function object corresponding to the provided identifier. + :raises ValueError: If the function identifier is of an unsupported type. + :raises RuntimeError: If Binary Ninja frontend could not resolve the function. + """ + function: binaryninja.function.Function | None + match function_identifier: + case str(): + function = self._get_binninja_function_from_string(function_identifier) + case binaryninja.function.Function(): + function = function_identifier + case _: + raise ValueError(f"BNinja frontend can't handle function identifier of type {type(function_identifier)}") + + if function is None: + raise RuntimeError(f"BNinja frontend could not resolve function with identifier '{function_identifier}'") + + if function.analysis_skipped: + raise RuntimeError( + f"BNinja skipped function analysis for function '{function.name}' with reason '{function.analysis_skip_reason.name}'" + ) + + return function + + def _get_binninja_function_from_string(self, function_name: str) -> binaryninja.function.Function | None: + """Given a function string identifier, locate Function object in BinaryView""" + if (function := self._resolve_by_identifier_name(function_name)) is not None: + return function + if (function := self._resolve_by_address(function_name)) is not None: + return function + + return None + + def _resolve_by_identifier_name(self, function_name: str) -> binaryninja.function.Function | None: + """ + Iterate BinaryView.functions and compare matching names. + + note: we take this approach since bv.get_functions_by_name() may return wrong functions. + """ + return next(filter(lambda f: f.name == function_name, self._bv.functions), None) + + def _resolve_by_address(self, hex_str: str) -> binaryninja.function.Function | None: + """Get Function object by hex address or 'sub_'""" + try: + hex_address = hex_str[4:] if hex_str.startswith("sub_") else hex_str + address = int(hex_address, 16) + return self._bv.get_function_at(address) + except ValueError: + logging.info(f"{hex_str} does not contain hex value") + + def _create_lifter_parser(self, options: Options) -> tuple[BinaryninjaLifter, BinaryninjaParser]: report_threshold = options.getint("lifter.report_threshold", fallback=3) no_masks = options.getboolean("lifter.no_bit_masks", fallback=True) - parser = BinaryninjaParser(BinaryninjaLifter(no_masks, bv=function.view), report_threshold) - return parser.parse(function), parser.complex_types + lifter = BinaryninjaLifter(no_masks, bv=self._bv) + parser = BinaryninjaParser(lifter, report_threshold) + return lifter, parser diff --git a/decompiler/frontend/frontend.py b/decompiler/frontend/frontend.py index c5b57d8fd..8cde53a9c 100644 --- a/decompiler/frontend/frontend.py +++ b/decompiler/frontend/frontend.py @@ -33,8 +33,13 @@ def from_path(cls, path: str, options: Options) -> Frontend: """ @abstractmethod - def create_task(self, function_identifier: str, options: Options) -> DecompilerTask: - """Create a task from the given function identifier.""" + def lift(self, task: DecompilerTask): + """ + Lifts data from the fronted into the specified Decompiler task. + The function to be lifted is identified by the function identifier of the decompiler task (task.function_identifier). + + :param task: Decompiler task to lift data into. + """ @abstractmethod def get_all_function_names(self) -> List[str]: diff --git a/decompiler/pipeline/controlflowanalysis/loop_name_generator.py b/decompiler/pipeline/controlflowanalysis/loop_name_generator.py index 0d9590d6f..16e0f5a42 100644 --- a/decompiler/pipeline/controlflowanalysis/loop_name_generator.py +++ b/decompiler/pipeline/controlflowanalysis/loop_name_generator.py @@ -117,7 +117,7 @@ def run(self, task: DecompilerTask): for_loop_names: List[str] = task.options.getlist("loop-name-generator.for_loop_variable_names", fallback=[]) if rename_while_loops: - WhileLoopVariableRenamer(task._ast).rename() + WhileLoopVariableRenamer(task.ast).rename() if for_loop_names: - ForLoopVariableRenamer(task._ast, for_loop_names).rename() + ForLoopVariableRenamer(task.ast, for_loop_names).rename() diff --git a/decompiler/pipeline/controlflowanalysis/restructuring.py b/decompiler/pipeline/controlflowanalysis/restructuring.py index 949e3e41c..869cc0abf 100644 --- a/decompiler/pipeline/controlflowanalysis/restructuring.py +++ b/decompiler/pipeline/controlflowanalysis/restructuring.py @@ -53,8 +53,8 @@ def run(self, task: DecompilerTask): assert len(self.t_cfg) == 1, f"The Transition Graph can only have one node after the restructuring." self.asforest.set_current_root(self.t_cfg.root.ast) assert (roots := len(self.asforest.get_roots)) == 1, f"After the restructuring the forest should have one root, but it has {roots}!" - task._ast = AbstractSyntaxTree.from_asforest(self.asforest, self.asforest.current_root) - task._cfg = None + task.ast = AbstractSyntaxTree.from_asforest(self.asforest, self.asforest.current_root) + task.cfg = None def restructure_cfg(self) -> None: """ diff --git a/decompiler/pipeline/controlflowanalysis/variable_name_generation.py b/decompiler/pipeline/controlflowanalysis/variable_name_generation.py index 8627c93da..10876adb1 100644 --- a/decompiler/pipeline/controlflowanalysis/variable_name_generation.py +++ b/decompiler/pipeline/controlflowanalysis/variable_name_generation.py @@ -1,7 +1,7 @@ import re from abc import ABC, abstractmethod from enum import Enum -from typing import Dict, List, Optional, Set +from typing import Dict, List, Optional from decompiler.pipeline.stage import PipelineStage from decompiler.structures.ast.ast_nodes import ConditionNode, LoopNode @@ -75,9 +75,9 @@ class RenamingScheme(ABC): def __init__(self, task: DecompilerTask) -> None: """Collets all needed variables for renaming + filters already renamed + function arguments out""" - collector = VariableCollector(task._ast.condition_map) - collector.visit_ast(task._ast) - self._params: List[Variable] = task._function_parameters + collector = VariableCollector(task.ast.condition_map) + collector.visit_ast(task.ast) + self._params: List[Variable] = task.function_parameters self._loop_vars: List[Variable] = collector.get_loop_variables() self._variables: List[Variable] = list(filter(self._filter_variables, collector.get_variables())) diff --git a/decompiler/task.py b/decompiler/task.py index 66a725db4..9bad50ad9 100644 --- a/decompiler/task.py +++ b/decompiler/task.py @@ -1,113 +1,60 @@ """Module describing tasks to be handled by the decompiler pipleline.""" -from typing import Dict, List, Optional +from dataclasses import dataclass, field +from typing import List from decompiler.structures.ast.syntaxtree import AbstractSyntaxTree from decompiler.structures.graphs.cfg import ControlFlowGraph +from decompiler.structures.pseudo import Integer from decompiler.structures.pseudo.complextypes import ComplexTypeMap from decompiler.structures.pseudo.expressions import Variable -from decompiler.structures.pseudo.typing import Integer, Type +from decompiler.structures.pseudo.typing import Type from decompiler.util.options import Options +# We set eq=False, so that tasks are only equal when they are the very same instance +@dataclass(eq=False) class DecompilerTask: """Represents a task for the decompiler pipeline.""" - def __init__( - self, - name: str, - cfg: ControlFlowGraph = None, - ast: Optional[AbstractSyntaxTree] = None, - options: Optional[Options] = None, - function_return_type: Type = Integer(32), - function_parameters: Optional[List[Variable]] = None, - complex_types: Optional[ComplexTypeMap] = None, - ): - """ - Init a new decompiler task. - - :param name -- The name of the function or task - :param cfg -- The control flow graph of the function - :param function_return_type -- The type of the return value of the decompiled function - :param function_parameters -- List of function parameters as Variables - """ - self._name = name - self._cfg = cfg - self._ast = ast - self._function_return_type = function_return_type - self._function_parameters = function_parameters if function_parameters else [] - self._options: Options = options if options else Options.load_default_options() - self._failed = False - self._failure_origin = None - self._complex_types = complex_types if complex_types else ComplexTypeMap() - self._code = None - - @property - def name(self) -> str: - """Return the name of the task.""" - return self._name - - @property - def graph(self) -> ControlFlowGraph: - """Return a graph representing the function control flow.""" - return self._cfg - - @property - def syntax_tree(self) -> AbstractSyntaxTree: - """Return a syntax tree representing the function.""" - return self._ast - - @property - def function_return_type(self) -> Type: - """Return the type of the variable returned by the function.""" - return self._function_return_type + name: str + # We allow fronted specific identifiers here. The fronted should check if it can handle a specific type of identifier + function_identifier: object + options: Options = field(default_factory=Options.load_default_options) + cfg: ControlFlowGraph | None = None + ast: AbstractSyntaxTree | None = None + function_return_type: Type = Integer.int32_t() + function_parameters: List[Variable] = field(default_factory=list) + complex_types: ComplexTypeMap = field(default_factory=ComplexTypeMap) - @property - def function_parameters(self) -> List[Variable]: - """Return a list of parameters usually passed to the function.""" - return self._function_parameters + _failure_origin: str | None = field(default=None, init=False) + # Property for backwards compatibility. Previous code used self._cfg, which is now public. @property - def options(self) -> Options: - """Options for various pipeline stages of the task.""" - return self._options - - @options.setter - def options(self, value: Options): - """Setter function for task options.""" - self._options = value + def graph(self): + return self.cfg + # Property for backwards compatibility. Previous code used self._ast, which is now public. @property - def failed(self) -> bool: - """Returns True if an error occurred during a decompilation stage. + def syntax_tree(self): + return self.ast - A failed tasks will not produce valid decompiled code but an error message will be shown.""" - return self._failed + def fail(self, origin: str = ""): + """Sets the task to be failed by setting the failure origin.""" + if self.failure_origin is not None: + raise RuntimeError("Tried failing already failed task") - def fail(self, origin: str = None): - """Sets the task to failed and the origin to the name of the stage where failure occurred.""" - self._failed = True self._failure_origin = origin @property - def failure_message(self) -> str: - """Returns the message to be shown for a failed task.""" - msg = f"Failed to decompile" - if self._failure_origin: - msg += f" due to error during {self._failure_origin}." - return msg - - @property - def complex_types(self) -> ComplexTypeMap: - """Return complex types present in the function (structs, unions, enums, etc.).""" - return self._complex_types + def failed(self) -> bool: + """ + Returns True if an error occurred during decompilation. + A failed task is a task that did not properly finish and is left in an undefined state. + Therefore, no valid decompiled code can be generated from it. + """ + return self._failure_origin is not None @property - def code(self) -> str: - """Return C-Code representation for the Task.""" - return self._code - - @code.setter - def code(self, value): - """Setter function for C-Code representation of the Task""" - self._code = value + def failure_origin(self) -> str | None: + return self._failure_origin diff --git a/decompiler/util/bugfinder/bugfinder.py b/decompiler/util/bugfinder/bugfinder.py index 22b7ec9d6..d015f6840 100644 --- a/decompiler/util/bugfinder/bugfinder.py +++ b/decompiler/util/bugfinder/bugfinder.py @@ -198,9 +198,9 @@ def iter_function_reports(self, sample) -> Iterator[dict]: function_info = DBConnector.get_function_info(function) try: time1 = time.time() - task_result = self.decompile(function, options) + task, code = self.decompile(function, task_options=options) time2 = time.time() - decompilation_info = DBConnector.get_successful_info(task_result.code, int(time2 - time1)) + decompilation_info = DBConnector.get_successful_info(code, int(time2 - time1)) except Exception as e: decompilation_info = DBConnector.get_error_info(e) yield {**dewolf_info, **sample_info, **function_info, **decompilation_info} diff --git a/decompiler/util/commandline.py b/decompiler/util/commandline.py index 56449281d..5fcbb953b 100644 --- a/decompiler/util/commandline.py +++ b/decompiler/util/commandline.py @@ -72,15 +72,15 @@ def main(interface: "Decompiler"): try: if args.all or not args.function: # decompile all functions. - undecorated_code = decompiler.decompile_all(options) + result = decompiler.decompile_all(task_options=options) DecoratedCode.print_code( - undecorated_code, output_stream, color, style=options.getstring("code-generator.style_cmd", fallback="paraiso-dark") + result.code, output_stream, color, style=options.getstring("code-generator.style_cmd", fallback="paraiso-dark") ) else: for function_name in args.function: - task = decompiler.decompile(function_name, options) + task, code = decompiler.decompile(function_name, task_options=options) DecoratedCode.print_code( - task.code, output_stream, color, style=task.options.getstring("code-generator.style_cmd", fallback="paraiso-dark") + code, output_stream, color, style=options.getstring("code-generator.style_cmd", fallback="paraiso-dark") ) finally: if output_stream is not None: diff --git a/decompiler/util/serialization/demo.py b/decompiler/util/serialization/demo.py index 9083ca249..4a2a6fd52 100644 --- a/decompiler/util/serialization/demo.py +++ b/decompiler/util/serialization/demo.py @@ -5,7 +5,7 @@ from decompile import Decompiler decompiler = Decompiler.from_path("tests/samples/bin/systemtests/32/0/test_loop") -task = decompiler.decompile("test7") +task, code = decompiler.decompile("test7") # Serialize an AST from decompiler.util.serialization.ast_serializer import AstSerializer diff --git a/decompiler/util/widget.py b/decompiler/util/widget.py index eb400c5bf..2e0537a4e 100644 --- a/decompiler/util/widget.py +++ b/decompiler/util/widget.py @@ -64,8 +64,8 @@ def decompile_for_widget(binary_view: BinaryView, function: Function): configure_logging() # reload settings decompiler = Decompiler.from_raw(binary_view) options = Options.from_gui() - task = decompiler.decompile(function, options) - return DecoratedCode.formatted_plain(task.code) + task, code = decompiler.decompile(function, task_options=options) + return DecoratedCode.formatted_plain(code) class CodeDisplay(QPlainTextEdit): diff --git a/tests/backend/test_codegenerator.py b/tests/backend/test_codegenerator.py index 1002902d7..d068b2532 100644 --- a/tests/backend/test_codegenerator.py +++ b/tests/backend/test_codegenerator.py @@ -121,7 +121,14 @@ def _task(ast: AbstractSyntaxTree, params: List[DataflowObject] = None, return_t params = [] if not options: options = _generate_options(compounding=False) - return DecompilerTask("test_function", None, ast=ast, options=options, function_parameters=params, function_return_type=return_type) + return DecompilerTask( + name="test_function", + function_identifier="", + ast=ast, + options=options, + function_parameters=params, + function_return_type=return_type, + ) @staticmethod def _regex_matches(regex: str, task: DecompilerTask): @@ -621,7 +628,7 @@ def test_loop_declaration_ListOp(self): class TestExpression: @staticmethod def _visit_code(dfo: DataflowObject, options: Options = _generate_options()) -> str: - return CodeVisitor(DecompilerTask("test", None, options=options)).visit(dfo) + return CodeVisitor(DecompilerTask(name="test", function_identifier="", options=options)).visit(dfo) @pytest.mark.parametrize( "expr, result", @@ -1296,7 +1303,7 @@ def test_variable_declaration(self, vars_per_line: int, variables: List[Variable ), {}, ) - assert LocalDeclarationGenerator.from_task(DecompilerTask("", None, ast, options)) == expected + assert LocalDeclarationGenerator.from_task(DecompilerTask(name="", function_identifier="", ast=ast, options=options)) == expected class TestGlobalVisitor: diff --git a/tests/pipeline/SSA/utils_out_of_ssa_tests.py b/tests/pipeline/SSA/utils_out_of_ssa_tests.py index ed63ccb3c..a7b620af4 100644 --- a/tests/pipeline/SSA/utils_out_of_ssa_tests.py +++ b/tests/pipeline/SSA/utils_out_of_ssa_tests.py @@ -1033,4 +1033,4 @@ def decompiler_task(cfg: ControlFlowGraph, mode: Optional[Union[SSAOptions, str] options = Options() if mode: options.set("out-of-ssa-translation.mode", mode.value if isinstance(mode, SSAOptions) else mode) - return DecompilerTask("out-of-ssa-test", cfg, options=options, function_parameters=args) + return DecompilerTask(name="out-of-ssa-test", function_identifier="", cfg=cfg, options=options, function_parameters=args) diff --git a/tests/pipeline/controlflowanalysis/restructuring_commons/test_condition_aware_refinement.py b/tests/pipeline/controlflowanalysis/restructuring_commons/test_condition_aware_refinement.py index c84d99141..90d99a864 100644 --- a/tests/pipeline/controlflowanalysis/restructuring_commons/test_condition_aware_refinement.py +++ b/tests/pipeline/controlflowanalysis/restructuring_commons/test_condition_aware_refinement.py @@ -7,6 +7,7 @@ from decompiler.pipeline.controlflowanalysis.restructuring import PatternIndependentRestructuring from decompiler.structures.ast.ast_nodes import CaseNode, CodeNode, ConditionNode, SeqNode, SwitchNode, WhileLoopNode from decompiler.structures.graphs.cfg import BasicBlock, ControlFlowGraph, FalseCase, SwitchCase, TrueCase, UnconditionalEdge +from decompiler.structures.pseudo.complextypes import ComplexTypeMap from decompiler.structures.pseudo.expressions import Constant, Expression, FunctionSymbol, GlobalVariable, ImportedFunctionSymbol, Variable from decompiler.structures.pseudo.instructions import Assignment, Branch, Break, Continue, IndirectBranch, Return from decompiler.structures.pseudo.operations import BinaryOperation, Call, Condition, ListOperation, OperationType, UnaryOperation @@ -19,39 +20,23 @@ def imp_function_symbol(name: str, value: int = 0x42, vartype: Type = UnknownTyp return ImportedFunctionSymbol(name, value, vartype) -class MockDecompilerTask(DecompilerTask): - """Mock class for decompilerTasks only containing a cfg.""" - - class MockFunction: - class FunctionType: - def __init__(self): - self.return_value = "void" - self.parameters = [] - - def __init__(self): - self.name = "test" - self.function_type = self.FunctionType() - - def __init__(self, cfg): - super().__init__("test", None) - self._cfg = cfg - self.set_options() - self.function = self.MockFunction() - - def set_options(self): - self.options = Options() - self.options.set("pattern-independent-restructuring.switch_reconstruction", True) - self.options.set("pattern-independent-restructuring.nested_switch_nodes", True) - self.options.set("pattern-independent-restructuring.min_switch_case_number", 2) - - def reset(self): - pass - - @pytest.fixture -def task() -> ControlFlowGraph: - """A mock task with an empty cfg.""" - return MockDecompilerTask(ControlFlowGraph()) +def task() -> DecompilerTask: + """A task with an empty cfg.""" + options = Options() + options.set("pattern-independent-restructuring.switch_reconstruction", True) + options.set("pattern-independent-restructuring.nested_switch_nodes", True) + options.set("pattern-independent-restructuring.min_switch_case_number", 2) + + return DecompilerTask( + name="test", + function_identifier="", + options=options, + cfg=ControlFlowGraph(), + function_return_type=CustomType.void(), + function_parameters=[], + complex_types=ComplexTypeMap(), + ) def print_call(string: str, memory: int) -> Call: @@ -530,7 +515,7 @@ def test_basic_switch(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[-1].instructions @@ -623,7 +608,7 @@ def test_switch_cases_without_break_and_no_instruction(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[-1].instructions @@ -787,7 +772,7 @@ def test_switch_one_large_number(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[5].instructions @@ -970,7 +955,7 @@ def test_switch_two_large_numbers(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[3].instructions @@ -1085,7 +1070,7 @@ def test_switch_cases_without_break_and_instructions(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[3].instructions @@ -1204,7 +1189,7 @@ def test_switch_cases_without_break_and_some_instructions(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[7].instructions @@ -1400,7 +1385,7 @@ def test_switch_condition_node_as_case_node_child(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[9].instructions @@ -1422,18 +1407,18 @@ def test_switch_condition_node_as_case_node_child(task): assert isinstance(cond_node1 := case1.child, ConditionNode) assert isinstance(cond_node1.true_branch.child, CodeNode) and isinstance(cond_node1.false_branch.child, CodeNode) if cond_node1.condition.is_symbol: - assert task._ast.condition_map[cond_node1.condition] == vertices[3].instructions[0].condition + assert task.ast.condition_map[cond_node1.condition] == vertices[3].instructions[0].condition assert cond_node1.true_branch_child.instructions == vertices[10].instructions assert cond_node1.false_branch_child.instructions == vertices[11].instructions else: - assert task._ast.condition_map[~cond_node1.condition] == vertices[3].instructions[0].condition + assert task.ast.condition_map[~cond_node1.condition] == vertices[3].instructions[0].condition assert cond_node1.true_branch_child.instructions == vertices[11].instructions assert cond_node1.false_branch_child.instructions == vertices[10].instructions assert isinstance(cond_node2 := case2.child, ConditionNode) assert isinstance(cond_node2.true_branch.child, CodeNode) and cond_node2.false_branch is None assert cond_node2.condition.is_negation and (~cond_node2.condition).is_symbol - assert task._ast.condition_map[~cond_node2.condition] == vertices[4].instructions[0].condition + assert task.ast.condition_map[~cond_node2.condition] == vertices[4].instructions[0].condition assert cond_node2.true_branch_child.instructions == vertices[12].instructions assert isinstance(case3.child, CodeNode) and case3.child.instructions == vertices[5].instructions @@ -1615,7 +1600,7 @@ def test_switch_in_switch_easy(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[-1].instructions @@ -1796,7 +1781,7 @@ def test_switch_in_switch_long(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[10].instructions @@ -1998,7 +1983,7 @@ def test_switch_only_if_else(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[-1].instructions @@ -2086,7 +2071,7 @@ def test_switch_find_case_in_condition(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch_cond := seq_node.children[1], ConditionNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[4].instructions @@ -2094,7 +2079,7 @@ def test_switch_find_case_in_condition(task): # switch condition: assert switch_cond.false_branch is None and isinstance(switch := switch_cond.true_branch_child, SwitchNode) assert switch_cond.condition.is_literal and not switch_cond.condition.is_symbol - assert task._ast.condition_map[~switch_cond.condition] == vertices[1].instructions[-1].condition + assert task.ast.condition_map[~switch_cond.condition] == vertices[1].instructions[-1].condition # switch node: assert switch.expression == var_0_2 and len(switch.children) == 7 @@ -2229,7 +2214,7 @@ def test_two_entries_to_one_case(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[-1].instructions @@ -2260,8 +2245,8 @@ def test_two_entries_to_one_case(task): assert ( cond.condition.is_conjunction and len(operands := cond.condition.operands) == 2 and all(operands[i].is_negation for i in [0, 1]) ) - term_1 = task._ast.condition_map[~operands[0]] - term_2 = task._ast.condition_map[~operands[1]] + term_1 = task.ast.condition_map[~operands[0]] + term_2 = task.ast.condition_map[~operands[1]] assert {term_1, term_2} == { Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]), Condition(OperationType.equal, [var_0, Constant(2, Integer(32))]), @@ -2400,7 +2385,7 @@ def test_two_exits_to_one_case_depend_on_switch(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[-1].instructions @@ -2429,7 +2414,7 @@ def test_two_exits_to_one_case_depend_on_switch(task): # condition nodes exit one: for cond, child in [(cond_1, 5), (cond_2, 6)]: assert cond.condition.is_negation and ~cond.condition.is_symbol - assert task._ast.condition_map[~cond.condition] == Condition(OperationType.equal, [var_0, Constant(2, Integer(32))]) + assert task.ast.condition_map[~cond.condition] == Condition(OperationType.equal, [var_0, Constant(2, Integer(32))]) assert ( isinstance(cond.true_branch_child, CodeNode) and cond.true_branch_child.instructions == vertices[child].instructions @@ -2443,9 +2428,9 @@ def test_two_exits_to_one_case_depend_on_switch(task): and len(operands := cond.condition.operands) == 3 and all(operands[i].is_negation for i in [0, 1, 2]) ) - term_1 = task._ast.condition_map[~operands[0]] - term_2 = task._ast.condition_map[~operands[1]] - term_3 = task._ast.condition_map[~operands[2]] + term_1 = task.ast.condition_map[~operands[0]] + term_2 = task.ast.condition_map[~operands[1]] + term_3 = task.ast.condition_map[~operands[2]] assert {term_1, term_2, term_3} == { Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]), Condition(OperationType.equal, [var_0, Constant(3, Integer(32))]), @@ -2595,7 +2580,7 @@ def test_two_exits_to_one_case_not_depend_on_switch(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[-1].instructions @@ -2625,7 +2610,7 @@ def test_two_exits_to_one_case_not_depend_on_switch(task): assert cond_1.condition.is_disjunction and len(operands := cond_1.condition.operands) == 2 assert any((cc_1 := operands[i]).is_symbol for i in [0, 1]) and any((cc_2 := operands[i]).is_negation for i in [0, 1]) assert (cc_2 := ~cc_2).is_symbol - assert [task._ast.condition_map[cc_1], task._ast.condition_map[cc_2]] == [ + assert [task.ast.condition_map[cc_1], task.ast.condition_map[cc_2]] == [ Condition(OperationType.equal, [var_0, Constant(3, Integer(32))]), Condition(OperationType.not_equal, [var_1, Constant(1, Integer(32, True))]), ] @@ -2638,9 +2623,9 @@ def test_two_exits_to_one_case_not_depend_on_switch(task): # condition nodes exit one - cond_2: assert cond_2.condition.is_disjunction and len(operands := cond_2.condition.operands) == 3 assert any((cc_not := operands[i]).is_negation for i in [0, 1, 2]) and (cc := ~cc_not).is_symbol - assert task._ast.condition_map[cc] == Condition(OperationType.not_equal, [var_1, Constant(1, Integer(32, True))]) + assert task.ast.condition_map[cc] == Condition(OperationType.not_equal, [var_1, Constant(1, Integer(32, True))]) assert all(cc.is_symbol for cc in operands if str(cc) != str(cc_not)) - assert {task._ast.condition_map[cc] for cc in operands if str(cc) != str(cc_not)} == { + assert {task.ast.condition_map[cc] for cc in operands if str(cc) != str(cc_not)} == { Condition(OperationType.equal, [var_0, Constant(3, Integer(32))]), Condition(OperationType.equal, [var_0, Constant(4, Integer(32))]), } @@ -2656,8 +2641,8 @@ def test_two_exits_to_one_case_not_depend_on_switch(task): or_conditions = [arg for arg in operands if arg.is_disjunction] not_conditions = [arg for arg in operands if arg.is_negation] assert len(not_conditions) == 2 - term_1 = task._ast.condition_map[~not_conditions[0]] - term_2 = task._ast.condition_map[~not_conditions[1]] + term_1 = task.ast.condition_map[~not_conditions[0]] + term_2 = task.ast.condition_map[~not_conditions[1]] assert {term_1, term_2} == { Condition(OperationType.equal, [var_0, Constant(3, Integer(32))]), Condition(OperationType.equal, [var_0, Constant(4, Integer(32))]), @@ -2665,15 +2650,15 @@ def test_two_exits_to_one_case_not_depend_on_switch(task): assert len(or_conditions) == 1 or_cond = or_conditions[0] assert len(operands := or_cond.operands) == or_args and all(arg.is_symbol for arg in operands) - term_1 = task._ast.condition_map[operands[0]] - term_2 = task._ast.condition_map[operands[1]] + term_1 = task.ast.condition_map[operands[0]] + term_2 = task.ast.condition_map[operands[1]] if or_args == 2: assert {term_1, term_2} == { Condition(OperationType.not_equal, [var_1, Constant(1, Integer(32, True))]), Condition(OperationType.equal, [var_0, Constant(5, Integer(32))]), } else: - term_3 = task._ast.condition_map[operands[2]] + term_3 = task.ast.condition_map[operands[2]] assert {term_1, term_2, term_3} == { Condition(OperationType.not_equal, [var_1, Constant(1, Integer(32, True))]), Condition(OperationType.equal, [var_0, Constant(5, Integer(32))]), @@ -2691,7 +2676,7 @@ def test_switch_add_existing_cases(task): """test_switch test7_b or 18 -> later: insert case that is already their (but empty)""" # print(DecoratedCFG.from_cfg(task.graph).export_ascii()) # PatternIndependentRestructuring().run(task) - # DecoratedAST.from_ast(task._ast).export_plot("/home/eva/Projects/decompiler/AST/out.png") + # DecoratedAST.from_ast(task.ast).export_plot("/home/eva/Projects/decompiler/AST/out.png") pass @@ -2747,26 +2732,26 @@ def test_no_switch_ssa_variable_wrong(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 4 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 4 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(friday_case := seq_node.children[1], ConditionNode) and friday_case.condition.is_literal assert isinstance(switch_cond := seq_node.children[2], ConditionNode) assert isinstance(seq_node.children[3], CodeNode) and seq_node.children[3].instructions == vertices[11].instructions # friday case - assert task._ast.condition_map[~friday_case.condition] == vertices[0].instructions[-1].condition + assert task.ast.condition_map[~friday_case.condition] == vertices[0].instructions[-1].condition assert isinstance(branch_seq := friday_case.true_branch_child, SeqNode) and friday_case.false_branch is None assert len(branch_seq.children) == 2 assert isinstance(branch_seq.children[0], CodeNode) and branch_seq.children[0].instructions == vertices[2].instructions[:1] assert isinstance(friday := branch_seq.children[1], ConditionNode) - assert task._ast.condition_map[~friday.condition] == vertices[2].instructions[-1].condition + assert task.ast.condition_map[~friday.condition] == vertices[2].instructions[-1].condition assert isinstance(friday.true_branch_child, CodeNode) and friday.false_branch is None assert friday.true_branch_child.instructions == vertices[4].instructions # switch_condition: assert switch_cond.false_branch is None and isinstance(switch := switch_cond.true_branch_child, SwitchNode) assert switch_cond.condition.is_disjunction and len(switch_cond.condition.operands) == 2 - assert {task._ast.condition_map[op] for op in switch_cond.condition.operands} == { + assert {task.ast.condition_map[op] for op in switch_cond.condition.operands} == { vertices[0].instructions[-1].condition, vertices[2].instructions[-1].condition, } @@ -2903,7 +2888,7 @@ def test_switch_with_loop1(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(return_cond := seq_node.children[2], ConditionNode) @@ -2924,10 +2909,10 @@ def test_switch_with_loop1(task): new_assignment = Assignment(new_variable, Constant(0, Integer.int32_t())) assert isinstance(case1.child, CodeNode) and case1.child.instructions == [new_assignment] assert isinstance(cn2 := case2.child, ConditionNode) and cn2.false_branch is None - assert task._ast.condition_map[~cn2.condition] == Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]) + assert task.ast.condition_map[~cn2.condition] == Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]) assert cn2.true_branch_child.instructions == vertices[4].instructions assert isinstance(cn3 := case3.child, ConditionNode) and cn3.false_branch is None - assert task._ast.condition_map[~cn3.condition] == Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]) + assert task.ast.condition_map[~cn3.condition] == Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]) assert cn3.true_branch_child.instructions == [Assignment(new_variable, Constant(1, Integer.int32_t()))] assert isinstance(loop_seq := case7.child, SeqNode) and len(loop_seq.children) == 2 assert isinstance(case4.child, CodeNode) and case4.child.instructions == vertices[6].instructions @@ -2938,7 +2923,7 @@ def test_switch_with_loop1(task): # loop sequence: assert isinstance(last_entry := loop_seq.children[0], ConditionNode) assert last_entry.condition.is_conjunction and len(operands := last_entry.condition.operands) == 3 - assert {task._ast.condition_map[~cond] for cond in operands} == { + assert {task.ast.condition_map[~cond] for cond in operands} == { Condition(OperationType.equal, [var_0, Constant(const, Integer(32))]) for const in {1, 2, 3} } assert last_entry.false_branch is None and isinstance(last_entry.true_branch_child, CodeNode) @@ -2965,7 +2950,7 @@ def test_switch_with_loop1(task): # return condition assert return_cond.condition.is_disjunction and len(operands := return_cond.condition.operands) == 5 - assert {task._ast.condition_map[cond] for cond in operands} == { + assert {task.ast.condition_map[cond] for cond in operands} == { Condition(OperationType.equal, [var_0, Constant(const, Integer(32))]) for const in {0, 4, 5, 6} } | {Condition(OperationType.greater_us, [var_0, Constant(7, Integer(32, True))])} assert return_cond.false_branch is None and isinstance(return_cond.true_branch_child, CodeNode) @@ -3127,7 +3112,7 @@ def test_switch_with_loop2(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[10].instructions @@ -3148,7 +3133,7 @@ def test_switch_with_loop2(task): new_assignment = Assignment(new_variable, Constant(0, Integer.int32_t())) assert isinstance(case1.child, CodeNode) and case1.child.instructions == vertices[12].instructions + [new_assignment] assert isinstance(cn3 := case3.child, ConditionNode) and cn3.false_branch is None - assert task._ast.condition_map[~cn3.condition] == Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]) + assert task.ast.condition_map[~cn3.condition] == Condition(OperationType.equal, [var_0, Constant(1, Integer(32))]) assert cn3.true_branch_child.instructions == vertices[13].instructions + [Assignment(new_variable, Constant(1, Integer.int32_t()))] assert isinstance(loop_seq := case7.child, SeqNode) and len(loop_seq.children) == 2 assert isinstance(case2.child, CodeNode) and case2.child.instructions == vertices[4].instructions @@ -3160,7 +3145,7 @@ def test_switch_with_loop2(task): # loop sequence: assert isinstance(last_entry := loop_seq.children[0], ConditionNode) assert last_entry.condition.is_conjunction and len(operands := last_entry.condition.operands) == 2 - assert {task._ast.condition_map[~cond] for cond in operands} == { + assert {task.ast.condition_map[~cond] for cond in operands} == { Condition(OperationType.equal, [var_0, Constant(const, Integer(32))]) for const in {1, 3} } assert last_entry.false_branch is None and isinstance(last_entry.true_branch_child, CodeNode) @@ -3193,10 +3178,10 @@ def test_switch_with_loop2(task): assert isinstance(case2_2.child, CodeNode) and case2_2.child.instructions == vertices[5].instructions + [new_assignment] if exit.true_branch_child is None: - assert task._ast.condition_map[~exit.condition] == vertices[9].instructions[-1].condition + assert task.ast.condition_map[~exit.condition] == vertices[9].instructions[-1].condition assert isinstance(exit.false_branch, CodeNode) and exit.false_branch.instructions == [Break()] else: - assert task._ast.condition_map[exit.condition] == vertices[9].instructions[-1].condition + assert task.ast.condition_map[exit.condition] == vertices[9].instructions[-1].condition assert ( isinstance(exit.true_branch_child, CodeNode) and exit.true_branch_child.instructions == [Break()] and exit.false_branch is None ) @@ -3406,7 +3391,7 @@ def test_too_nested(task): PatternIndependentRestructuring().run(task) # initial part - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 5 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 5 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(cond_node := seq_node.children[1], ConditionNode) assert isinstance(switch1 := seq_node.children[2], SwitchNode) @@ -3417,11 +3402,11 @@ def test_too_nested(task): if (cond := cond_node.condition).is_symbol: default_branch = cond_node.true_branch_child switch_branch = cond_node.false_branch_child - assert task._ast.condition_map[cond] == vertices[0].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[0].instructions[-1].condition else: default_branch = cond_node.false_branch_child switch_branch = cond_node.true_branch_child - assert task._ast.condition_map[~cond] == vertices[0].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[0].instructions[-1].condition # default branch assert isinstance(default_branch, CodeNode) and default_branch.instructions == vertices[1].instructions @@ -3560,7 +3545,7 @@ def branch_condition(constant: int) -> Branch: PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 if isinstance(switch := seq_node.children[0], SwitchNode): assert isinstance(cn := seq_node.children[1], ConditionNode) else: @@ -3673,7 +3658,7 @@ def print_call_binary_op(var: Variable, const: int, address: int, memory: int) - PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 5 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 5 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch1 := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[3].instructions[:-1] @@ -3761,7 +3746,7 @@ def test_can_not_combine_not_same_expression(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 4 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 4 assert isinstance(switch1 := seq_node.children[0], SwitchNode) assert isinstance(seq_node.children[1], CodeNode) and seq_node.children[1].instructions == vertices[3].instructions[:-1] assert isinstance(switch2 := seq_node.children[2], SwitchNode) @@ -3795,7 +3780,7 @@ def test_find_default_if_edge_exists(task): var_0 = Variable("var_0", Integer(32, True), None, True, Variable("var_c", Integer(32, True), 0, True, None)) var_1 = Variable("var_1", Pointer(Integer(32, True), 64), None, False, Variable("rsi", Pointer(Integer(32, True), 64), 1, False, None)) var_0_1 = Variable("var_0", Integer(32, True), None, True, Variable("var_c", Integer(32, True), 2, True, None)) - task._cfg.add_nodes_from( + task.cfg.add_nodes_from( vertices := [ BasicBlock( 0, @@ -3852,7 +3837,7 @@ def test_find_default_if_edge_exists(task): ), ] ) - task._cfg.add_edges_from( + task.cfg.add_edges_from( [ TrueCase(vertices[0], vertices[1]), FalseCase(vertices[0], vertices[2]), @@ -3877,7 +3862,7 @@ def test_find_default_if_edge_exists(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 2 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 2 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) @@ -3920,7 +3905,7 @@ def test_fallthrough_reaching_problem(task): var_4 = Variable("var_4", Integer(64, True), None, False, Variable("rcx_1", Integer(64, True), 2, False, None)) var_5 = Variable("var_5", Integer(64, True), None, False, Variable("rdx_1", Integer(64, True), 2, False, None)) var_6 = Variable("var_6", Integer(64, True), None, False, Variable("rax_1", Integer(64, True), 2, False, None)) - task._cfg.add_nodes_from( + task.cfg.add_nodes_from( vertices := [ BasicBlock( 0, @@ -3977,7 +3962,7 @@ def test_fallthrough_reaching_problem(task): BasicBlock(20, [Assignment(var_3, Constant(1, Integer(32, True)))]), ] ) - task._cfg.add_edges_from( + task.cfg.add_edges_from( [ TrueCase(vertices[0], vertices[2]), FalseCase(vertices[0], vertices[1]), @@ -4017,7 +4002,7 @@ def test_fallthrough_reaching_problem(task): PatternIndependentRestructuring().run(task) condition_map = task.syntax_tree.condition_map - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 5 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 5 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(cond := seq_node.children[1], ConditionNode) assert isinstance(switch := seq_node.children[2], SwitchNode) @@ -4166,7 +4151,7 @@ def test_only_one_occurrence_of_each_case(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) and len(switch.cases) == 7 assert isinstance(case1 := switch.cases[0], CaseNode) and case1.constant.value == 1 and isinstance(case1_seq := case1.child, SeqNode) @@ -4523,7 +4508,7 @@ def test_default_disjunction_is_not_true(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 2 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 2 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) @@ -5246,7 +5231,7 @@ def test_insert_before_existing_case(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[4].instructions @@ -5383,7 +5368,7 @@ def test_insert_after_existing_case(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 4 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 4 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(cond := seq_node.children[2], ConditionNode) and cond.false_branch is None @@ -5471,7 +5456,7 @@ def test_nested_cases_unnecessary_condition_all_irrelevant(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(switch := seq_node.children[1], SwitchNode) assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[3].instructions @@ -5593,14 +5578,14 @@ def test_nested_cases_unnecessary_condition_not_all_irrelevant_2(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 4 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 4 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(cond := seq_node.children[1], ConditionNode) assert isinstance(switch := seq_node.children[2], SwitchNode) assert isinstance(seq_node.children[3], CodeNode) and seq_node.children[3].instructions == vertices[20].instructions # condition node: - assert cond.condition.is_conjunction and {task._ast.condition_map[l] for l in cond.condition.operands} == { + assert cond.condition.is_conjunction and {task.ast.condition_map[l] for l in cond.condition.operands} == { vertices[0].instructions[-1].condition, vertices[1].instructions[0].condition, } @@ -5730,8 +5715,8 @@ def test_intersecting_cases(task): PatternIndependentRestructuring().run(task) - assert len(list(task._ast.get_switch_nodes_post_order())) == 2 - assert isinstance(seq_node := task._ast.root, SeqNode) and len(children := seq_node.children) == 6 + assert len(list(task.ast.get_switch_nodes_post_order())) == 2 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(children := seq_node.children) == 6 assert isinstance(children[0], CodeNode) and isinstance(children[5], CodeNode) assert all(isinstance(child, ConditionNode) for child in children[1:4]) assert isinstance(children[4], SwitchNode) and isinstance(children[3].true_branch_child, SwitchNode) @@ -5787,13 +5772,13 @@ def test_missing_cases_switch_in_sequence(task): PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) and len(children := seq_node.children) == 2 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(children := seq_node.children) == 2 assert isinstance(cn := children[0], ConditionNode) and cn.true_branch and cn.false_branch assert isinstance(children[1], CodeNode) and children[1].instructions == vertices[7].instructions if cn.condition.is_negation: cn.switch_branches() - assert cn.condition.is_symbol and task._ast.condition_map[cn.condition] == vertices[0].instructions[0].condition + assert cn.condition.is_symbol and task.ast.condition_map[cn.condition] == vertices[0].instructions[0].condition # True branch assert isinstance(true_seq := cn.true_branch_child, SeqNode) and len(children := true_seq.children) == 2 @@ -5808,7 +5793,7 @@ def test_missing_cases_switch_in_sequence(task): ) assert any((cc_1 := operands[i]).is_symbol for i in [0, 1]) and any((cc_2 := operands[i]).is_negation for i in [0, 1]) assert (cc_2 := ~cc_2).is_symbol - assert [task._ast.condition_map[cc_1], task._ast.condition_map[cc_2]] == [ + assert [task.ast.condition_map[cc_1], task.ast.condition_map[cc_2]] == [ vertices[4].instructions[0].condition, vertices[1].instructions[0].condition, ] @@ -5817,5 +5802,5 @@ def test_missing_cases_switch_in_sequence(task): assert isinstance(false_seq := cn.false_branch_child, SeqNode) and len(children := false_seq.children) == 2 assert isinstance(cn_false := children[0], ConditionNode) and cn_false.false_branch is None and cn_false.condition.is_negation assert isinstance(code_return := cn_false.true_branch_child, CodeNode) and code_return.instructions == vertices[6].instructions - assert task._ast.condition_map[~cn_false.condition] == vertices[2].instructions[0].condition + assert task.ast.condition_map[~cn_false.condition] == vertices[2].instructions[0].condition assert isinstance(code := children[1], CodeNode) and code.instructions == vertices[5].instructions diff --git a/tests/pipeline/controlflowanalysis/test_instruction_length_handler.py b/tests/pipeline/controlflowanalysis/test_instruction_length_handler.py index 5b7db0b7e..81009281e 100644 --- a/tests/pipeline/controlflowanalysis/test_instruction_length_handler.py +++ b/tests/pipeline/controlflowanalysis/test_instruction_length_handler.py @@ -66,7 +66,7 @@ def _generate_options(call: int = 10, assignment: int = 10, ret: int = 10) -> Op def _run_ilh(ast: AbstractSyntaxTree, options: Options = _generate_options()): - InstructionLengthHandler().run(DecompilerTask("test_function", ast=ast, options=options)) + InstructionLengthHandler().run(DecompilerTask(name="test_function", function_identifier="", ast=ast, options=options)) class TestCodeNode: diff --git a/tests/pipeline/controlflowanalysis/test_loop_name_generator.py b/tests/pipeline/controlflowanalysis/test_loop_name_generator.py index 45d13033c..090caba89 100644 --- a/tests/pipeline/controlflowanalysis/test_loop_name_generator.py +++ b/tests/pipeline/controlflowanalysis/test_loop_name_generator.py @@ -16,7 +16,6 @@ Constant, ImportedFunctionSymbol, ListOperation, - OperationType, Variable, ) from decompiler.structures.pseudo.operations import ArrayInfo, OperationType, UnaryOperation @@ -968,7 +967,7 @@ class TestReadabilityBasedRefinementAndLoopNameGenerator: @staticmethod def run_rbr(ast: AbstractSyntaxTree, options: Options = _generate_options()): - task = DecompilerTask("func", cfg=None, ast=ast, options=options) + task = DecompilerTask(name="func", function_identifier="", cfg=None, ast=ast, options=options) ReadabilityBasedRefinement().run(task) LoopNameGenerator().run(task) diff --git a/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring.py b/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring.py index a44ae1cad..47b276b1d 100644 --- a/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring.py +++ b/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring.py @@ -46,7 +46,7 @@ @pytest.fixture def task() -> DecompilerTask: """A mock task with an empty cfg.""" - return DecompilerTask("test", ControlFlowGraph()) + return DecompilerTask(name="test", function_identifier="", cfg=ControlFlowGraph()) def variable(name="a", version=0, ssa_name=None) -> Variable: @@ -67,7 +67,7 @@ def test_empty_graph_one_basic_block(task): task.graph.add_node(BasicBlock(0, instructions=[])) PatternIndependentRestructuring().run(task) - assert isinstance(task._ast.root, CodeNode) and task._ast.root.instructions == [] + assert isinstance(task.ast.root, CodeNode) and task.ast.root.instructions == [] def test_empty_graph_two_basic_blocks(task): @@ -86,7 +86,7 @@ def test_empty_graph_two_basic_blocks(task): task.graph.add_edge(UnconditionalEdge(vertices[0], vertices[1])) PatternIndependentRestructuring().run(task) - assert isinstance(task._ast.root, CodeNode) and task._ast.root.instructions == [] + assert isinstance(task.ast.root, CodeNode) and task.ast.root.instructions == [] def test_empty_graph_with_conditions_1(task): @@ -136,7 +136,7 @@ def test_empty_graph_with_conditions_1(task): ) PatternIndependentRestructuring().run(task) - assert isinstance(task._ast.root, CodeNode) and task._ast.root.instructions == [] + assert isinstance(task.ast.root, CodeNode) and task.ast.root.instructions == [] def test_empty_graph_with_conditions_2(task): @@ -194,7 +194,7 @@ def test_empty_graph_with_conditions_2(task): ) PatternIndependentRestructuring().run(task) - assert isinstance(task._ast.root, CodeNode) and task._ast.root.instructions == [] + assert isinstance(task.ast.root, CodeNode) and task.ast.root.instructions == [] def test_empty_graph_with_switch(task): @@ -246,7 +246,7 @@ def test_empty_graph_with_switch(task): ) PatternIndependentRestructuring().run(task) - assert isinstance(task._ast.root, CodeNode) and task._ast.root.instructions == [] + assert isinstance(task.ast.root, CodeNode) and task.ast.root.instructions == [] def test_graph_with_switch_empty_nodes1(task): @@ -308,7 +308,7 @@ def test_graph_with_switch_empty_nodes1(task): PatternIndependentRestructuring().run(task) assert ( - isinstance(switch_node := task._ast.root, SwitchNode) and len(switch_node.children) == 3 and switch_node.expression == variable("a") + isinstance(switch_node := task.ast.root, SwitchNode) and len(switch_node.children) == 3 and switch_node.expression == variable("a") ) assert ( isinstance(case1 := switch_node.children[0], CaseNode) @@ -393,7 +393,7 @@ def test_graph_with_switch_empty_nodes2(task): ) PatternIndependentRestructuring().run(task) - assert isinstance(switch_node := task._ast.root, SwitchNode) and len(switch_node.children) == 4 + assert isinstance(switch_node := task.ast.root, SwitchNode) and len(switch_node.children) == 4 assert switch_node.expression == variable("a") assert isinstance(case1 := switch_node.children[0], CaseNode) and case1.constant == Constant(1) and case1.break_case is True @@ -465,7 +465,7 @@ def test_empty_basic_block_after_removing(task): resulting_ast._add_edge(resulting_ast.root, condition_node) resulting_ast.flatten_sequence_node(resulting_ast.root) - assert ASTComparator.compare(task._ast, resulting_ast) and task._ast.condition_map == resulting_ast.condition_map + assert ASTComparator.compare(task.ast, resulting_ast) and task.ast.condition_map == resulting_ast.condition_map def test_empty_graph_with_loop(task): @@ -611,7 +611,7 @@ def test_restructure_cfg_sequence(task): PatternIndependentRestructuring().run(task) # make sure that only SeqNodes or CodeNodes have been created during Restructuring - assert isinstance(code_node := task._ast.root, CodeNode) + assert isinstance(code_node := task.ast.root, CodeNode) assert code_node.instructions == [ Assignment(variable(name="i", version=0), Constant(0)), Assignment(variable(name="x", version=0), Constant(42)), @@ -641,7 +641,7 @@ def test_one_node(task): PatternIndependentRestructuring().run(task) - assert isinstance(code_node := task._ast.root, CodeNode) + assert isinstance(code_node := task.ast.root, CodeNode) assert code_node.instructions == [Assignment(ListOperation([]), Call(imp_function_symbol("printf"), [Constant("a")]))] @@ -950,7 +950,7 @@ def test_restructure_cfg_endless(task): assert ASTComparator.compare(task.syntax_tree, resulting_ast) and task.syntax_tree.condition_map == resulting_ast.condition_map - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert all(not isinstance(n, ConditionNode) for n in seq_node.children) assert all(not isinstance(n, SwitchNode) for n in seq_node.children) assert any(isinstance(loop_node := n, WhileLoopNode) for n in seq_node.children) @@ -1513,7 +1513,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_1(task): assert isinstance(loop_node := seq_node.children[1], WhileLoopNode) # make sure that the loop has the correct type and condition - assert isinstance(cond := task._ast.condition_map[loop_node.condition], Condition) and str(cond) == "i#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[loop_node.condition], Condition) and str(cond) == "i#0 != 0x3" assert isinstance(loop_body := loop_node.body, SeqNode) assert len(loop_body.children) == 3 @@ -1526,7 +1526,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_1(task): # make sure condition node is restructured correctly assert condition_node.condition.is_conjunction and len(operands := condition_node.condition.operands) == 2 - assert all(op.is_negation for op in operands) and {str(task._ast.condition_map[~op]) for op in operands} == {"x#0 != 0x3", "j#0 != 0x3"} + assert all(op.is_negation for op in operands) and {str(task.ast.condition_map[~op]) for op in operands} == {"x#0 != 0x3", "j#0 != 0x3"} assert isinstance(continue_node := condition_node.true_branch_child, CodeNode) and condition_node.false_branch is None assert continue_node.instructions == [Continue()] @@ -1799,12 +1799,12 @@ def test_restructure_cfg_loop_two_back_edges_condition_3(task): # if loop_middle.condition.is_symbol: # assert isinstance(loop_middle_seq := loop_middle.true_branch, SeqNode) # assert loop_middle.false_branch is None - # assert isinstance(cond := task._ast.condition_map[loop_middle.condition], Condition) and str(cond) == "i#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[loop_middle.condition], Condition) and str(cond) == "i#0 != 0x3" # else: # assert (loop_middle.condition).is_negation # assert isinstance(loop_middle_seq := loop_middle.false_branch, SeqNode) # assert loop_middle.true_branch is None - # assert isinstance(cond := task._ast.condition_map[loop_middle.condition.operands[0]], Condition) and str(cond) == "i#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[loop_middle.condition.operands[0]], Condition) and str(cond) == "i#0 != 0x3" # # # loop_middle_seq is restructured correctly: # assert len(loop_middle_seq.children) == 4 @@ -1814,12 +1814,12 @@ def test_restructure_cfg_loop_two_back_edges_condition_3(task): # if continue_branch.condition.is_symbol: # assert isinstance(cond_node := continue_branch.false_branch, CodeNode) # assert continue_branch.true_branch is None - # assert isinstance(cond := task._ast.condition_map[continue_branch.condition], Condition) and str(cond) == "x#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[continue_branch.condition], Condition) and str(cond) == "x#0 != 0x3" # else: # assert (continue_branch.condition).is_negation # assert isinstance(cond_node := continue_branch.true_branch, CodeNode) # assert continue_branch.false_branch is None - # assert isinstance(cond := task._ast.condition_map[continue_branch.condition.operands[0]], Condition) and str(cond) == "x#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[continue_branch.condition.operands[0]], Condition) and str(cond) == "x#0 != 0x3" # assert cond_node.stmts == vertices[3].instructions + ["continue"] # # assert isinstance(loop_middle_seq.children[2], CodeNode) and loop_middle_seq.children[2].stmts == vertices[4].instructions[:-1] @@ -1828,14 +1828,14 @@ def test_restructure_cfg_loop_two_back_edges_condition_3(task): # if is_and(break_branch.condition): # assert isinstance(break_branch.true_branch, CodeNode) and break_branch.true_branch.stmts == ["break"] # assert break_branch.false_branch is None - # assert isinstance(cond := task._ast.condition_map[break_branch.condition.operands[0]], Condition) and str(cond) == "x#0 != 0x3" - # assert isinstance(cond := task._ast.condition_map[break_branch.condition.operands[1].operands[0]], Condition) and str(cond) == "j#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[break_branch.condition.operands[0]], Condition) and str(cond) == "x#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[break_branch.condition.operands[1].operands[0]], Condition) and str(cond) == "j#0 != 0x3" # else: # assert is_or(break_branch.condition) # assert isinstance(break_branch.false_branch, CodeNode) and break_branch.false_branch.stmts == ["break"] # assert break_branch.true_branch is None - # assert isinstance(cond := task._ast.condition_map[break_branch.condition.operands[0].operands[0]], Condition) and str(cond) == "x#0 != 0x3" - # assert isinstance(cond := task._ast.condition_map[break_branch.condition.operands[1]], Condition) and str(cond) == "j#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[break_branch.condition.operands[0].operands[0]], Condition) and str(cond) == "x#0 != 0x3" + # assert isinstance(cond := task.ast.condition_map[break_branch.condition.operands[1]], Condition) and str(cond) == "j#0 != 0x3" def test_restructure_cfg_loop_two_back_edges_condition_4(task): @@ -1943,7 +1943,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_4(task): PatternIndependentRestructuring().run(task) # make sure that a LoopNode has been created during Restructuring - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[6].instructions @@ -1962,7 +1962,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_4(task): assert loop_middle.condition.is_symbol assert isinstance(loop_middle_seq := loop_middle.true_branch_child, SeqNode) assert loop_middle.false_branch is None - assert isinstance(cond := task._ast.condition_map[loop_middle.condition], Condition) and str(cond) == "i#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[loop_middle.condition], Condition) and str(cond) == "i#0 != 0x3" # loop_middle_seq is restructured correctly: assert len(loop_middle_seq.children) == 4 @@ -1975,7 +1975,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_4(task): assert continue_branch.condition.is_negation assert isinstance(continue_branch.true_branch_child, CodeNode) and continue_branch.true_branch_child.instructions == [Continue()] assert continue_branch.false_branch is None - assert isinstance(cond := task._ast.condition_map[~continue_branch.condition], Condition) and str(cond) == "x#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[~continue_branch.condition], Condition) and str(cond) == "x#0 != 0x3" assert isinstance(loop_middle_seq.children[2], CodeNode) and loop_middle_seq.children[2].instructions == vertices[4].instructions[:-1] # @@ -1983,7 +1983,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_4(task): assert break_branch.condition.is_negation assert isinstance(break_branch.true_branch_child, CodeNode) and break_branch.true_branch_child.instructions == [Break()] assert break_branch.false_branch is None - assert isinstance(cond := task._ast.condition_map[~break_branch.condition], Condition) and str(cond) == "j#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[~break_branch.condition], Condition) and str(cond) == "j#0 != 0x3" def test_restructure_cfg_loop_two_back_edges_condition_5(task): @@ -2092,7 +2092,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_5(task): PatternIndependentRestructuring().run(task) # make sure that a LoopNode has been created during Restructuring - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions assert isinstance(seq_node.children[2], CodeNode) and seq_node.children[2].instructions == vertices[7].instructions @@ -2113,7 +2113,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_5(task): assert loop_middle.condition.is_symbol assert isinstance(loop_middle_seq := loop_middle.true_branch_child, SeqNode) assert loop_middle.false_branch is None - assert isinstance(cond := task._ast.condition_map[loop_middle.condition], Condition) and str(cond) == "i#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[loop_middle.condition], Condition) and str(cond) == "i#0 != 0x3" # loop_middle_seq is restructured correctly: assert len(loop_middle_seq.children) == 3 @@ -2126,7 +2126,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_5(task): assert continue_branch.condition.is_negation assert isinstance(continue_branch.true_branch_child, CodeNode) and continue_branch.true_branch_child.instructions == [Continue()] assert continue_branch.false_branch is None - assert isinstance(cond := task._ast.condition_map[~continue_branch.condition], Condition) and str(cond) == "x#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[~continue_branch.condition], Condition) and str(cond) == "x#0 != 0x3" assert isinstance(loop_middle_seq.children[2], CodeNode) and loop_middle_seq.children[2].instructions == vertices[4].instructions @@ -2134,7 +2134,7 @@ def test_restructure_cfg_loop_two_back_edges_condition_5(task): assert break_condition.condition.is_negation assert isinstance(break_condition.true_branch_child, CodeNode) and break_condition.true_branch_child.instructions == [Break()] assert break_condition.false_branch is None - assert isinstance(cond := task._ast.condition_map[~break_condition.condition], Condition) and str(cond) == "j#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[~break_condition.condition], Condition) and str(cond) == "j#0 != 0x3" def test_restructure_cfg_nested_loop_not_head(task): @@ -2230,14 +2230,14 @@ def test_restructure_cfg_nested_loop_not_head(task): PatternIndependentRestructuring().run(task) # make sure that a LoopNode has been created during Restructuring - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 3 assert isinstance(seq_node.children[0], CodeNode) assert isinstance(loop_node := seq_node.children[1], WhileLoopNode) assert isinstance(seq_node.children[2], CodeNode) # make sure that the loop has the correct type and condition - assert isinstance(cond := task._ast.condition_map[loop_node.condition], Condition) and str(cond) == "i#0 != 0x3" + assert isinstance(cond := task.ast.condition_map[loop_node.condition], Condition) and str(cond) == "i#0 != 0x3" assert isinstance(loop_body := loop_node.body, SeqNode) assert len(loop_body.children) == 2 @@ -2255,7 +2255,7 @@ def test_restructure_cfg_nested_loop_not_head(task): # Check condition node break assert cond_node.condition.is_negation - assert isinstance(cond := task._ast.condition_map[~cond_node.condition], Condition) + assert isinstance(cond := task.ast.condition_map[~cond_node.condition], Condition) assert isinstance(code_node := cond_node.true_branch_child, CodeNode) assert cond_node.false_branch is None assert str(cond) == "j#0 != 0x3" @@ -2381,7 +2381,7 @@ def test_dream_paper_fig3(task): ) PatternIndependentRestructuring().run(task) - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 2 assert isinstance(seq_node.children[1], CodeNode) assert isinstance(cond_node := seq_node.children[0], ConditionNode) @@ -2583,14 +2583,14 @@ def test_condition_based_corner_case_complementary_condition_yes(task): # PatternIndependentRestructuring().run(task) # make sure that a LoopNode has been created during Restructuring -# assert isinstance(seq_node := task._ast.root, SeqNode) +# assert isinstance(seq_node := task.ast.root, SeqNode) # assert len(seq_node.children) == 2 # assert isinstance(loop_node := seq_node.children[0], LoopNode) # assert isinstance(seq_node.children[1], CodeNode) and seq_node.children[1].stmts == vertices[6].instructions # make sure that the loop has the correct type and condition # assert loop_node.type == "do_while" -# assert isinstance(cond := task._ast.condition_map[loop_node.condition], Condition) and cond == vertices[5].instructions[-1].condition +# assert isinstance(cond := task.ast.condition_map[loop_node.condition], Condition) and cond == vertices[5].instructions[-1].condition # assert isinstance(loop_body := loop_node.body, SeqNode) # assert len(loop_body.children) == 2 # assert isinstance(complementary_cond := loop_body.children[0], ConditionNode) @@ -2602,19 +2602,19 @@ def test_condition_based_corner_case_complementary_condition_yes(task): # assert is_or(complementary_cond.condition) or is_and(complementary_cond.condition) # arg_1, arg_2 = complementary_cond.condition.operands # if is_or(complementary_cond.condition): -# assert isinstance(cond_1 := task._ast.condition_map[arg_1.operands[0]], Condition) -# assert isinstance(cond_2 := task._ast.condition_map[arg_2.operands[0]], Condition) +# assert isinstance(cond_1 := task.ast.condition_map[arg_1.operands[0]], Condition) +# assert isinstance(cond_2 := task.ast.condition_map[arg_2.operands[0]], Condition) # assert complementary_cond.true_branch.stmts == vertices[4].instructions # assert complementary_cond.false_branch.stmts == vertices[3].instructions # else: -# assert isinstance(cond_1 := task._ast.condition_map[arg_1], Condition) -# assert isinstance(cond_2 := task._ast.condition_map[arg_2], Condition) +# assert isinstance(cond_1 := task.ast.condition_map[arg_1], Condition) +# assert isinstance(cond_2 := task.ast.condition_map[arg_2], Condition) # assert complementary_cond.false_branch.stmts == vertices[4].instructions # assert complementary_cond.true_branch.stmts == vertices[3].instructions # assert {cond_1, cond_2} == {vertices[1].instructions[0].condition, vertices[2].instructions[0].condition} # logging.info(f"Abstract syntax tree of this region:") -# for node in task._ast.topological_order(): +# for node in task.ast.topological_order(): # logging.info(f"Node {node}") # if isinstance(node, CodeNode): # logging.info(f"statements: {[str(inst) for inst in node.stmts]}") @@ -2712,7 +2712,7 @@ def test_condition_based_corner_case_complementary_condition_yes(task): # PatternIndependentRestructuring().run(task) # # # logging.info(f"Abstract syntax tree of this region:") -# # for node in task._ast.topological_order(): +# # for node in task.ast.topological_order(): # # logging.info(f"Node {node}") # # if isinstance(node, CodeNode): # # logging.info(f"statements: {[str(inst) for inst in node.stmts]}") @@ -2760,7 +2760,7 @@ def test_condition_based_corner_case_complementary_condition_yes(task): # PatternIndependentRestructuring().run(task) # # # root node -# assert isinstance(seq_node := task._ast.root, SeqNode) +# assert isinstance(seq_node := task.ast.root, SeqNode) # assert len(seq_node.children) == 4 # assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].stmts == [vertices[0].instructions[0]] # assert isinstance(condition_root := seq_node.children[1], ConditionNode) @@ -2769,11 +2769,11 @@ def test_condition_based_corner_case_complementary_condition_yes(task): # # # make sure that the root note condition is restructured correctly # if condition_root.condition.is_negation: -# assert task._ast.condition_map[condition_root.condition.operands[0]] == vertices[0].instructions[-1].condition +# assert task.ast.condition_map[condition_root.condition.operands[0]] == vertices[0].instructions[-1].condition # assert isinstance(condition_root.true_branch, CodeNode) and condition_root.true_branch.stmts == [vertices[2].instructions[0]] # assert isinstance(condition_root.false_branch, CodeNode) and condition_root.false_branch.stmts == vertices[1].instructions # else: -# assert task._ast.condition_map[condition_root.condition] == vertices[0].instructions[-1].condition +# assert task.ast.condition_map[condition_root.condition] == vertices[0].instructions[-1].condition # assert isinstance(condition_root.false_branch, CodeNode) and condition_root.false_branch.stmts == [vertices[2].instructions[0]] # assert isinstance(condition_root.true_branch, CodeNode) and condition_root.true_branch.stmts == vertices[1].instructions # @@ -2781,14 +2781,14 @@ def test_condition_based_corner_case_complementary_condition_yes(task): # cond = complementary_cond.condition # assert len(cond.operands) == 2 and (is_and(cond) or is_or(cond)) # if is_and(cond): -# assert {task._ast.condition_map[cond.arg.operands[0](0)], task._ast.condition_map[cond.arg.operands[0](1)]} == { +# assert {task.ast.condition_map[cond.arg.operands[0](0)], task.ast.condition_map[cond.arg.operands[0](1)]} == { # vertices[0].instructions[-1].condition, # vertices[2].instructions[-1].condition, # } # assert isinstance(complementary_cond.true_branch, CodeNode) and complementary_cond.true_branch.stmts == vertices[7].instructions # assert isinstance(ifelse_node_3 := complementary_cond.false_branch, SeqNode) # else: -# assert {task._ast.condition_map[cond.operands[0]], task._ast.condition_map[cond.operands[1]]} == { +# assert {task.ast.condition_map[cond.operands[0]], task.ast.condition_map[cond.operands[1]]} == { # vertices[0].instructions[-1].condition, # vertices[2].instructions[-1].condition, # } @@ -2802,11 +2802,11 @@ def test_condition_based_corner_case_complementary_condition_yes(task): # assert isinstance(ifelse_node_3.children[2], CodeNode) and ifelse_node_3.children[2].stmts == vertices[6].instructions # # if ifelse_node_3_cond.condition.is_negation: -# assert task._ast.condition_map[ifelse_node_3_cond.condition.operands[0]] == vertices[3].instructions[-1].condition +# assert task.ast.condition_map[ifelse_node_3_cond.condition.operands[0]] == vertices[3].instructions[-1].condition # assert isinstance(ifelse_node_3_cond.true_branch, CodeNode) and ifelse_node_3_cond.true_branch.stmts == vertices[5].instructions # assert isinstance(ifelse_node_3_cond.false_branch, CodeNode) and ifelse_node_3_cond.false_branch.stmts == vertices[4].instructions # else: -# assert task._ast.condition_map[ifelse_node_3_cond.condition] == vertices[3].instructions[-1].condition +# assert task.ast.condition_map[ifelse_node_3_cond.condition] == vertices[3].instructions[-1].condition # assert isinstance(ifelse_node_3_cond.false_branch, CodeNode) and ifelse_node_3_cond.false_branch.stmts == vertices[5].instructions # assert isinstance(ifelse_node_3_cond.true_branch, CodeNode) and ifelse_node_3_cond.true_branch.stmts == vertices[4].instructions @@ -2884,7 +2884,7 @@ def test_easy_multiple_entry_loop(task): PatternIndependentRestructuring().run(task) # make sure that a LoopNode has been created during Restructuring - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 4 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[1].instructions[:-1] assert isinstance(cond_node := seq_node.children[1], ConditionNode) @@ -2896,23 +2896,21 @@ def test_easy_multiple_entry_loop(task): new_variable = cond_node.true_branch_child.instructions[0].definitions[0] if cond_node.condition.is_negation: assert ( - isinstance(cond := task._ast.condition_map[~cond_node.condition], Condition) and cond == vertices[1].instructions[-1].condition + isinstance(cond := task.ast.condition_map[~cond_node.condition], Condition) and cond == vertices[1].instructions[-1].condition ) assert cond_node.true_branch_child.instructions == [Assignment(new_variable, Constant(1, Integer.int32_t()))] assert cond_node.false_branch_child.instructions == [Assignment(new_variable, Constant(0, Integer.int32_t()))] else: - assert ( - isinstance(cond := task._ast.condition_map[cond_node.condition], Condition) and cond == vertices[1].instructions[-1].condition - ) + assert isinstance(cond := task.ast.condition_map[cond_node.condition], Condition) and cond == vertices[1].instructions[-1].condition assert cond_node.true_branch_child.instructions == [Assignment(new_variable, Constant(0, Integer.int32_t()))] assert cond_node.false_branch_child.instructions == [Assignment(new_variable, Constant(1, Integer.int32_t()))] # make sure that the loop is correct assert isinstance(loop_body := loop.body, SeqNode) - assert isinstance(cond := task._ast.condition_map[loop.condition], Condition) and cond == vertices[4].instructions[-1].condition + assert isinstance(cond := task.ast.condition_map[loop.condition], Condition) and cond == vertices[4].instructions[-1].condition assert len(loop_body.children) == 2 assert isinstance(multiple_entry_condition := loop_body.children[0], ConditionNode) - assert isinstance(cond := task._ast.condition_map[multiple_entry_condition.condition], Condition) + assert isinstance(cond := task.ast.condition_map[multiple_entry_condition.condition], Condition) assert cond == Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]) assert isinstance(multiple_entry_condition.true_branch_child, CodeNode) and multiple_entry_condition.false_branch is None assert multiple_entry_condition.true_branch_child.instructions == vertices[2].instructions + vertices[3].instructions @@ -2998,7 +2996,7 @@ def test_easy_multiple_entry_loop(task): # # PatternIndependentRestructuring().run(task) # -# for node in task._ast.topological_order(): +# for node in task.ast.topological_order(): # logging.info(f"Node {node}") # if isinstance(node, CodeNode): # logging.info(f"statements: {[str(inst) for inst in node.stmts]}") @@ -3010,7 +3008,7 @@ def test_easy_multiple_entry_loop(task): # logging.info(f"children {node.children}") # # # Check sequence node children -# assert isinstance(seq_node := task._ast.root, SeqNode) +# assert isinstance(seq_node := task.ast.root, SeqNode) # assert len(seq_node.children) == 6 # assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].stmts == [vertices[0].instructions[0]] # assert isinstance(cond_zero_node := seq_node.children[1], ConditionNode) @@ -3021,11 +3019,11 @@ def test_easy_multiple_entry_loop(task): # # # branches of cond_zero_node # if cond_zero_node.condition.is_negation: -# assert task._ast.condition_map[cond_zero_node.condition.operands[0]] == vertices[0].instructions[-1].condition +# assert task.ast.condition_map[cond_zero_node.condition.operands[0]] == vertices[0].instructions[-1].condition # assert isinstance(cond_zero_node.true_branch, CodeNode) and cond_zero_node.true_branch.stmts == [vertices[4].instructions[0]] # assert isinstance(ifelse_region := cond_zero_node.false_branch, SeqNode) # else: -# assert task._ast.condition_map[cond_zero_node.condition] == vertices[0].instructions[-1].condition +# assert task.ast.condition_map[cond_zero_node.condition] == vertices[0].instructions[-1].condition # assert isinstance(cond_zero_node.false_branch, CodeNode) and cond_zero_node.false_branch.stmts == [vertices[4].instructions[0]] # assert isinstance(ifelse_region := cond_zero_node.true_branch, SeqNode) # assert len(ifelse_region.children) == 2 @@ -3033,11 +3031,11 @@ def test_easy_multiple_entry_loop(task): # assert isinstance(cond_node_1 := ifelse_region.children[1], ConditionNode) # # if cond_node_1.condition.is_negation: -# assert task._ast.condition_map[cond_node_1.condition.operands[0]] == vertices[1].instructions[-1].condition +# assert task.ast.condition_map[cond_node_1.condition.operands[0]] == vertices[1].instructions[-1].condition # assert isinstance(cond_node_1.true_branch, CodeNode) and cond_node_1.true_branch.stmts == [vertices[2].instructions[0]] # assert isinstance(cond_node_1.false_branch, CodeNode) and cond_node_1.false_branch.stmts == [vertices[3].instructions[0]] # else: -# assert task._ast.condition_map[cond_node_1.condition] == vertices[1].instructions[-1].condition +# assert task.ast.condition_map[cond_node_1.condition] == vertices[1].instructions[-1].condition # assert isinstance(cond_node_1.false_branch, CodeNode) and cond_node_1.false_branch.stmts == [vertices[2].instructions[0]] # assert isinstance(cond_node_1.true_branch, CodeNode) and cond_node_1.true_branch.stmts == [vertices[3].instructions[0]] # @@ -3093,7 +3091,7 @@ def test_easy_multiple_entry_loop(task): # PatternIndependentRestructuring().run(task) # # # make sure that a LoopNode has been created during Restructuring -# assert isinstance(seq_node := task._ast.root, SeqNode) +# assert isinstance(seq_node := task.ast.root, SeqNode) # assert len(seq_node.children) == 2 # assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].stmts == vertices[0].instructions # assert isinstance(outer_loop := seq_node.children[1], LoopNode) @@ -3109,12 +3107,12 @@ def test_easy_multiple_entry_loop(task): # assert isinstance(multiple_entry_cond.true_branch, CodeNode) and isinstance(multiple_entry_cond.false_branch, CodeNode) # new_variable = multiple_entry_cond.true_branch.stmts[0].definitions[0] # if multiple_entry_cond.condition.is_negation: -# assert isinstance(cond := task._ast.condition_map[multiple_entry_cond.condition.operands[0]], Condition) +# assert isinstance(cond := task.ast.condition_map[multiple_entry_cond.condition.operands[0]], Condition) # assert cond == vertices[1].instructions[0].condition # assert multiple_entry_cond.true_branch.stmts == [Assignment(new_variable, Constant(1))] # assert multiple_entry_cond.false_branch.stmts == [Assignment(new_variable, Constant(0))] # else: -# assert isinstance(cond := task._ast.condition_map[multiple_entry_cond.condition], Condition) +# assert isinstance(cond := task.ast.condition_map[multiple_entry_cond.condition], Condition) # assert cond == vertices[1].instructions[0].condition # assert multiple_entry_cond.true_branch.stmts == [Assignment(new_variable, Constant(0))] # assert multiple_entry_cond.false_branch.stmts == [Assignment(new_variable, Constant(1))] @@ -3123,7 +3121,7 @@ def test_easy_multiple_entry_loop(task): # assert multiple_entry_loop.type == "endless" and isinstance(multiple_entry_loop_body := multiple_entry_loop.body, SeqNode) # assert len(multiple_entry_loop_body.children) == 3 # assert isinstance(multiple_entry_condition := multiple_entry_loop_body.children[0], ConditionNode) -# # assert isinstance(cond := task._ast.condition_map[multiple_entry_condition.condition], Condition) +# # assert isinstance(cond := task.ast.condition_map[multiple_entry_condition.condition], Condition) # # assert cond == Condition(OperationType.equal, [new_variable, Constant(0)]) # # assert isinstance(multiple_entry_condition.true_branch, CodeNode) and multiple_entry_condition.false_branch is None # # assert multiple_entry_condition.true_branch.stmts == vertices[2].instructions + vertices[3].instructions @@ -3171,7 +3169,7 @@ def test_easy_multiple_entry_loop(task): # PatternIndependentRestructuring().run(task) # # make outer LoopNode created during Restructuring -# assert isinstance(seq_node := task._ast.root, SeqNode) +# assert isinstance(seq_node := task.ast.root, SeqNode) # assert len(seq_node.children) == 2 # assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].stmts == vertices[0].instructions # assert isinstance(outer_loop := seq_node.children[1], LoopNode) @@ -3187,12 +3185,12 @@ def test_easy_multiple_entry_loop(task): # assert isinstance(multiple_entry_cond.true_branch, CodeNode) and isinstance(multiple_entry_cond.false_branch, CodeNode) # new_variable = multiple_entry_cond.true_branch.stmts[0].definitions[0] # if multiple_entry_cond.condition.is_negation: -# assert isinstance(cond := task._ast.condition_map[multiple_entry_cond.condition.operands[0]], Condition) +# assert isinstance(cond := task.ast.condition_map[multiple_entry_cond.condition.operands[0]], Condition) # assert cond == vertices[1].instructions[0].condition # assert multiple_entry_cond.true_branch.stmts == [Assignment(new_variable, Constant(1))] # assert multiple_entry_cond.false_branch.stmts == [Assignment(new_variable, Constant(0))] # else: -# assert isinstance(cond := task._ast.condition_map[multiple_entry_cond.condition], Condition) +# assert isinstance(cond := task.ast.condition_map[multiple_entry_cond.condition], Condition) # assert cond == vertices[1].instructions[0].condition # assert multiple_entry_cond.true_branch.stmts == [Assignment(new_variable, Constant(0))] # assert multiple_entry_cond.false_branch.stmts == [Assignment(new_variable, Constant(1))] @@ -3201,14 +3199,14 @@ def test_easy_multiple_entry_loop(task): # assert multiple_entry_loop.type == "do_while" and isinstance(multiple_entry_loop_body := multiple_entry_loop.body, SeqNode) # assert is_or(cond := z3_to_dnf(multiple_entry_loop.condition)) # assert (arg_1 := cond.operands[0]).is_symbol and is_and(arg_2 := cond.operands[1]) and len(arg_2.operands) == 2 -# assert task._ast.condition_map[arg_1] == vertices[4].instructions[-1].condition -# assert {task._ast.condition_map[arg_2.operands[0]], task._ast.condition_map[arg_2.arg.operands[0](1)]} == { +# assert task.ast.condition_map[arg_1] == vertices[4].instructions[-1].condition +# assert {task.ast.condition_map[arg_2.operands[0]], task.ast.condition_map[arg_2.arg.operands[0](1)]} == { # Condition(OperationType.equal, [new_variable, Constant(0)]), # vertices[2].instructions[-1].condition, # } # assert len(multiple_entry_loop_body.children) == 2 # assert isinstance(multiple_entry_condition := multiple_entry_loop_body.children[0], ConditionNode) -# assert isinstance(cond := task._ast.condition_map[multiple_entry_condition.condition], Condition) +# assert isinstance(cond := task.ast.condition_map[multiple_entry_condition.condition], Condition) # assert cond == Condition(OperationType.equal, [new_variable, Constant(0)]) # assert isinstance(return_cond := multiple_entry_loop_body.children[1], ConditionNode) # assert len(return_cond.condition.operands) == 2 @@ -3224,7 +3222,7 @@ def test_easy_multiple_entry_loop(task): # assert len(multiple_entry_condition.true_branch.children) == 2 # assert multiple_entry_condition.true_branch.children[0].stmts == [vertices[2].instructions[0]] # assert isinstance(multiple_entry_condition.true_branch.children[1], ConditionNode) -# assert task._ast.condition_map[multiple_entry_condition.true_branch.children[-1].condition] == vertices[2].instructions[-1].condition +# assert task.ast.condition_map[multiple_entry_condition.true_branch.children[-1].condition] == vertices[2].instructions[-1].condition # assert multiple_entry_condition.true_branch.children[1].true_branch.stmts == vertices[3].instructions # assert multiple_entry_condition.true_branch.children[1].false_branch is None @@ -3308,7 +3306,7 @@ def test_multiple_entry_with_outgoing_back_edge(task): PatternIndependentRestructuring().run(task) # make outer LoopNode created during Restructuring - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 2 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions assert isinstance(outer_loop := seq_node.children[1], WhileLoopNode) @@ -3325,12 +3323,12 @@ def test_multiple_entry_with_outgoing_back_edge(task): # assert isinstance(multiple_entry_cond.true_branch, CodeNode) and isinstance(multiple_entry_cond.false_branch, CodeNode) # new_variable = multiple_entry_cond.true_branch.stmts[0].definitions[0] # if multiple_entry_cond.condition.is_negation: - # assert isinstance(cond := task._ast.condition_map[multiple_entry_cond.condition.operands[0]], Condition) + # assert isinstance(cond := task.ast.condition_map[multiple_entry_cond.condition.operands[0]], Condition) # assert cond == vertices[1].instructions[0].condition # assert multiple_entry_cond.true_branch.stmts == [Assignment(new_variable, Constant(1))] # assert multiple_entry_cond.false_branch.stmts == [Assignment(new_variable, Constant(0))] # else: - # assert isinstance(cond := task._ast.condition_map[multiple_entry_cond.condition], Condition) + # assert isinstance(cond := task.ast.condition_map[multiple_entry_cond.condition], Condition) # assert cond == vertices[1].instructions[0].condition # assert multiple_entry_cond.true_branch.stmts == [Assignment(new_variable, Constant(0))] # assert multiple_entry_cond.false_branch.stmts == [Assignment(new_variable, Constant(1))] @@ -3340,7 +3338,7 @@ def test_multiple_entry_with_outgoing_back_edge(task): # assert len(multiple_entry_loop_body.children) == 2 # # assert isinstance(multiple_entry_condition := multiple_entry_loop_body.children[0], ConditionNode) - # assert isinstance(cond := task._ast.condition_map[multiple_entry_condition.condition], Condition) + # assert isinstance(cond := task.ast.condition_map[multiple_entry_condition.condition], Condition) # assert cond == Condition(OperationType.equal, [new_variable, Constant(0)]) # assert isinstance(multiple_entry_loop_body.children[1], CodeNode) and multiple_entry_loop_body.children[1].stmts == [ # vertices[4].instructions[0], @@ -3355,11 +3353,11 @@ def test_multiple_entry_with_outgoing_back_edge(task): # # assert isinstance(return_condition := multiple_entry_condition.true_branch.children[1], ConditionNode) # if (cond := return_condition.condition).is_symbol: - # assert task._ast.condition_map[cond] == vertices[2].instructions[-1].condition + # assert task.ast.condition_map[cond] == vertices[2].instructions[-1].condition # assert isinstance(return_condition.false_branch, CodeNode) # assert return_condition.false_branch.stmts == vertices[5].instructions # else: - # assert task._ast.condition_map[cond.operands[0]] == vertices[2].instructions[-1].condition + # assert task.ast.condition_map[cond.operands[0]] == vertices[2].instructions[-1].condition # assert isinstance(return_condition.true_branch, CodeNode) # assert return_condition.true_branch.stmts == vertices[5].instructions # @@ -3368,11 +3366,11 @@ def test_multiple_entry_with_outgoing_back_edge(task): # assert isinstance(break_condition := multiple_entry_condition.true_branch.children[3], ConditionNode) # if is_and(cond := break_condition.condition): # assert ( - # isinstance(cond := task._ast.condition_map[break_condition.condition.operands[0]], Condition) + # isinstance(cond := task.ast.condition_map[break_condition.condition.operands[0]], Condition) # and vertices[2].instructions[-1].condition # ) # assert ( - # isinstance(cond := task._ast.condition_map[break_condition.condition.operands[1].operands[0]], Condition) + # isinstance(cond := task.ast.condition_map[break_condition.condition.operands[1].operands[0]], Condition) # and vertices[3].instructions[-1].condition # ) # assert isinstance(break_condition.true_branch, CodeNode) @@ -3380,11 +3378,11 @@ def test_multiple_entry_with_outgoing_back_edge(task): # else: # is_or(cond := break_condition.condition) # assert ( - # isinstance(cond := task._ast.condition_map[break_condition.condition.operands[0].operands[0]], Condition) + # isinstance(cond := task.ast.condition_map[break_condition.condition.operands[0].operands[0]], Condition) # and vertices[2].instructions[-1].condition # ) # assert ( - # isinstance(cond := task._ast.condition_map[break_condition.condition.operands[1]], Condition) + # isinstance(cond := task.ast.condition_map[break_condition.condition.operands[1]], Condition) # and vertices[3].instructions[-1].condition # ) # assert isinstance(break_condition.false_branch, CodeNode) @@ -3512,7 +3510,7 @@ def test_multiple_exit_1(task): PatternIndependentRestructuring().run(task) # outer branch is restructured correctly: - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 5 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[8].instructions[:-1] assert isinstance(enter_loop := seq_node.children[1], ConditionNode) @@ -3522,7 +3520,7 @@ def test_multiple_exit_1(task): # make sure that loop entered correctly: assert (cond := enter_loop.condition).is_symbol - assert task._ast.condition_map[cond] == vertices[8].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[8].instructions[-1].condition assert isinstance(loop := enter_loop.true_branch_child, WhileLoopNode) and enter_loop.false_branch is None # make sure that loop is correct @@ -3541,20 +3539,20 @@ def test_multiple_exit_1(task): # exit 1 assert (cond := exit_1.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[1].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[1].instructions[-1].condition assert isinstance(branch := exit_1.true_branch_child, CodeNode) and exit_1.false_branch is None new_variable = branch.instructions[-2].definitions[0] assert branch.instructions == [vertices[9].instructions[0], Assignment(new_variable, Constant(0, Integer.int32_t())), Break()] # exit 2 assert (cond := exit_2.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[2].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[2].instructions[-1].condition assert isinstance(branch := exit_2.true_branch_child, CodeNode) and exit_2.false_branch is None assert branch.instructions == [vertices[10].instructions[0], Assignment(new_variable, Constant(1, Integer.int32_t())), Break()] # exit 3 assert (cond := exit_3.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[3].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[3].instructions[-1].condition assert isinstance(branch := exit_3.true_branch_child, CodeNode) and exit_3.false_branch is None assert branch.instructions == [vertices[11].instructions[0], Assignment(new_variable, Constant(2, Integer.int32_t())), Break()] @@ -3562,8 +3560,8 @@ def test_multiple_exit_1(task): assert (cond := succ_1.condition).is_disjunction assert len(arguments := cond.operands) == 2 assert any((arg := argument).is_symbol for argument in arguments) and any((neg_arg := argument).is_negation for argument in arguments) - assert task._ast.condition_map[arg] == Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]) - assert task._ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition + assert task.ast.condition_map[arg] == Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]) + assert task.ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition assert isinstance(branch := succ_1.true_branch_child, CodeNode) and succ_1.false_branch is None assert branch.instructions == vertices[5].instructions @@ -3571,8 +3569,8 @@ def test_multiple_exit_1(task): assert (cond := succ_2.condition).is_disjunction assert len(arguments := cond.operands) == 3 assert any((neg_arg := argument).is_negation for argument in arguments) - assert task._ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition - assert {task._ast.condition_map[arg] for arg in arguments if arg.is_symbol} == { + assert task.ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition + assert {task.ast.condition_map[arg] for arg in arguments if arg.is_symbol} == { Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]), Condition(OperationType.equal, [new_variable, Constant(1, Integer.int32_t())]), } @@ -3684,7 +3682,7 @@ def test_multiple_exit_2(task): PatternIndependentRestructuring().run(task) # outer branch is restructured correctly: - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 5 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[8].instructions[:-1] assert isinstance(enter_loop := seq_node.children[1], ConditionNode) @@ -3694,7 +3692,7 @@ def test_multiple_exit_2(task): # make sure that loop entered correctly: assert (cond := enter_loop.condition).is_symbol - assert task._ast.condition_map[cond] == vertices[8].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[8].instructions[-1].condition assert isinstance(loop := enter_loop.true_branch_child, WhileLoopNode) and enter_loop.false_branch is None # make sure that loop is correct @@ -3713,20 +3711,20 @@ def test_multiple_exit_2(task): # exit 1 assert (cond := exit_1.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[1].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[1].instructions[-1].condition assert isinstance(branch := exit_1.true_branch_child, CodeNode) and exit_1.false_branch is None new_variable = branch.instructions[0].definitions[0] assert branch.instructions == [Assignment(new_variable, Constant(0, Integer.int32_t())), Break()] # exit 2 assert (cond := exit_2.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[2].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[2].instructions[-1].condition assert isinstance(branch := exit_2.true_branch_child, CodeNode) and exit_2.false_branch is None assert branch.instructions == [Assignment(new_variable, Constant(1, Integer.int32_t())), Break()] # exit 3 assert (cond := exit_3.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[3].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[3].instructions[-1].condition assert isinstance(branch := exit_3.true_branch_child, CodeNode) and exit_3.false_branch is None assert branch.instructions == [Assignment(new_variable, Constant(2, Integer.int32_t())), Break()] @@ -3734,8 +3732,8 @@ def test_multiple_exit_2(task): assert (cond := succ_1.condition).is_disjunction assert len(arguments := cond.operands) == 2 assert any((arg := argument).is_symbol for argument in arguments) and any((neg_arg := argument).is_negation for argument in arguments) - assert task._ast.condition_map[arg] == Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]) - assert task._ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition + assert task.ast.condition_map[arg] == Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]) + assert task.ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition assert isinstance(branch := succ_1.true_branch_child, CodeNode) and succ_1.false_branch is None assert branch.instructions == vertices[5].instructions @@ -3743,8 +3741,8 @@ def test_multiple_exit_2(task): assert (cond := succ_2.condition).is_disjunction assert len(arguments := cond.operands) == 3 assert any((neg_arg := argument).is_negation for argument in arguments) - assert task._ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition - assert {task._ast.condition_map[arg] for arg in arguments if arg.is_symbol} == { + assert task.ast.condition_map[~neg_arg] == vertices[8].instructions[-1].condition + assert {task.ast.condition_map[arg] for arg in arguments if arg.is_symbol} == { Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]), Condition(OperationType.equal, [new_variable, Constant(1, Integer.int32_t())]), } @@ -3864,7 +3862,7 @@ def test_multiple_exit_3(task): PatternIndependentRestructuring().run(task) # outer branch is restructured correctly: - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 4 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[8].instructions[:-1] assert isinstance(enter_loop := seq_node.children[1], ConditionNode) @@ -3873,7 +3871,7 @@ def test_multiple_exit_3(task): # make sure that loop entered correctly: assert (cond := enter_loop.condition).is_symbol - assert task._ast.condition_map[cond] == vertices[8].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[8].instructions[-1].condition assert isinstance(loop := enter_loop.true_branch_child, WhileLoopNode) and enter_loop.false_branch is None # make sure that loop is correct @@ -3892,20 +3890,20 @@ def test_multiple_exit_3(task): # exit 1 assert (cond := exit_1.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[1].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[1].instructions[-1].condition assert isinstance(branch := exit_1.true_branch_child, CodeNode) and exit_1.false_branch is None new_variable = branch.instructions[0].definitions[0] assert branch.instructions == [Assignment(new_variable, Constant(0, Integer.int32_t())), Break()] # exit 2 assert (cond := exit_2.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[2].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[2].instructions[-1].condition assert isinstance(branch := exit_2.true_branch_child, CodeNode) and exit_2.false_branch is None assert branch.instructions == [Assignment(new_variable, Constant(1, Integer.int32_t())), Break()] # exit 3 assert (cond := exit_3.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[3].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[3].instructions[-1].condition assert isinstance(branch := exit_3.true_branch_child, CodeNode) and exit_3.false_branch is None assert branch.instructions == [Assignment(new_variable, Constant(2, Integer.int32_t())), Break()] @@ -3921,7 +3919,7 @@ def test_multiple_exit_3(task): and len(arg_1 := arguments[1].operands) == 1 ) assert (cond1 := arg_0[0]).is_symbol and (cond2 := arg_1[0]).is_symbol - assert {task._ast.condition_map[cond1], task._ast.condition_map[cond2]} == { + assert {task.ast.condition_map[cond1], task.ast.condition_map[cond2]} == { Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]), vertices[8].instructions[-1].condition, } @@ -3940,7 +3938,7 @@ def test_multiple_exit_3(task): and len(arg_1 := arguments[1].operands) == 1 ) assert (cond1 := arg_0[0]).is_symbol and (cond2 := arg_1[0]).is_symbol - assert {task._ast.condition_map[cond1], task._ast.condition_map[cond2]} == { + assert {task.ast.condition_map[cond1], task.ast.condition_map[cond2]} == { Condition(OperationType.equal, [new_variable, Constant(1, Integer.int32_t())]), vertices[8].instructions[-1].condition, } @@ -4081,7 +4079,7 @@ def test_multiple_exit_4(task): PatternIndependentRestructuring().run(task) # outer branch is restructured correctly: - assert isinstance(seq_node := task._ast.root, SeqNode) + assert isinstance(seq_node := task.ast.root, SeqNode) assert len(seq_node.children) == 5 assert isinstance(seq_node.children[0], CodeNode) and seq_node.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(enter_loop := seq_node.children[1], ConditionNode) @@ -4091,7 +4089,7 @@ def test_multiple_exit_4(task): # make sure that loop entered correctly: assert (cond := enter_loop.condition).is_symbol - assert task._ast.condition_map[cond] == vertices[0].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[0].instructions[-1].condition assert isinstance(loop := enter_loop.true_branch_child, WhileLoopNode) and enter_loop.false_branch is None # make sure that loop is correct @@ -4115,7 +4113,7 @@ def test_multiple_exit_4(task): if (condition_2.condition).is_negation: condition_2.switch_branches() assert (cond := condition_2.condition).is_symbol - assert task._ast.condition_map[cond] == vertices[2].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[2].instructions[-1].condition assert isinstance(true_branch := condition_2.true_branch_child, SeqNode) assert isinstance(false_branch := condition_2.false_branch_child, SeqNode) @@ -4124,13 +4122,13 @@ def test_multiple_exit_4(task): assert isinstance(true_branch.children[0], CodeNode) and true_branch.children[0].instructions == vertices[3].instructions[:-1] assert isinstance(exit_over_3 := true_branch.children[1], ConditionNode) assert (cond := exit_over_3.condition).is_negation - assert task._ast.condition_map[~cond] == vertices[3].instructions[-1].condition + assert task.ast.condition_map[~cond] == vertices[3].instructions[-1].condition assert isinstance(branch := exit_over_3.true_branch_child, CodeNode) and exit_over_3.false_branch is None assert branch.instructions == [Assignment(new_variable, Constant(0, Integer.int32_t())), Break()] assert isinstance(true_branch.children[2], CodeNode) and true_branch.children[2].instructions == vertices[4].instructions[:-1] assert isinstance(loop_continue := true_branch.children[3], ConditionNode) assert (cond := loop_continue.condition).is_symbol - assert task._ast.condition_map[cond] == vertices[4].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[4].instructions[-1].condition assert isinstance(branch := loop_continue.true_branch_child, CodeNode) and loop_continue.false_branch is None assert branch.instructions == vertices[5].instructions + [Continue()] @@ -4139,7 +4137,7 @@ def test_multiple_exit_4(task): assert isinstance(false_branch.children[0], CodeNode) and false_branch.children[0].instructions == vertices[6].instructions[:-1] assert isinstance(exit_over_6 := false_branch.children[1], ConditionNode) assert (cond := exit_over_6.condition).is_symbol - assert task._ast.condition_map[cond] == vertices[6].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[6].instructions[-1].condition assert isinstance(branch := exit_over_6.true_branch_child, CodeNode) and branch.instructions == [ Assignment(new_variable, Constant(1, Integer.int32_t())), Break(), @@ -4151,7 +4149,7 @@ def test_multiple_exit_4(task): assert succ_node_7.condition.is_disjunction and len(arguments := succ_node_7.condition.operands) == 2 assert any((arg_1 := arg).is_negation for arg in arguments) and any((arg_2 := arg).is_symbol for arg in arguments) # check conditions: - assert {task._ast.condition_map[~arg_1], task._ast.condition_map[arg_2]} == { + assert {task.ast.condition_map[~arg_1], task.ast.condition_map[arg_2]} == { vertices[0].instructions[-1].condition, Condition(OperationType.equal, [new_variable, Constant(1, Integer.int32_t())]), } @@ -4162,7 +4160,7 @@ def test_multiple_exit_4(task): assert succ_node_8.condition.is_disjunction and len(arguments := succ_node_8.condition.operands) == 2 assert all(arg.is_negation for arg in arguments) # check conditions: - assert {task._ast.condition_map[~arg] for arg in arguments} == { + assert {task.ast.condition_map[~arg] for arg in arguments} == { vertices[0].instructions[-1].condition, Condition(OperationType.equal, [new_variable, Constant(0, Integer.int32_t())]), } @@ -4298,7 +4296,7 @@ def test_same_reaching_condition_but_not_groupable(task): PatternIndependentRestructuring().run(task) # first if-else - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 3 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 3 assert isinstance(code_part := seq_node.children[0], ConditionNode) assert isinstance(return_part := seq_node.children[1], ConditionNode) assert isinstance(second_return := seq_node.children[2], CodeNode) and second_return.instructions == vertices[10].instructions @@ -4306,7 +4304,7 @@ def test_same_reaching_condition_but_not_groupable(task): # code_part restructured correctly: assert code_part.condition.is_negation and (cond := ~code_part.condition).is_symbol assert isinstance(code_seq := code_part.true_branch_child, SeqNode) and code_part.false_branch is None - assert task._ast.condition_map[cond] == vertices[0].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[0].instructions[-1].condition assert len(code_seq.children) == 4 assert ( isinstance(code_seq.children[0], CodeNode) @@ -4326,7 +4324,7 @@ def test_same_reaching_condition_but_not_groupable(task): assert isinstance(node_5 := first_if_else.true_branch_child, CodeNode) and isinstance( node_4 := first_if_else.false_branch_child, CodeNode ) - assert task._ast.condition_map[cond] == vertices[3].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[3].instructions[-1].condition assert node_4.instructions == vertices[4].instructions and node_5.instructions == vertices[5].instructions # second if-else correct @@ -4339,7 +4337,7 @@ def test_same_reaching_condition_but_not_groupable(task): assert isinstance(node_8 := second_if_else.true_branch_child, CodeNode) and isinstance( node_7 := second_if_else.false_branch_child, CodeNode ) - assert task._ast.condition_map[cond] == vertices[6].instructions[-1].condition + assert task.ast.condition_map[cond] == vertices[6].instructions[-1].condition assert node_7.instructions == vertices[7].instructions and node_8.instructions == vertices[8].instructions[:-1] # return part @@ -4416,7 +4414,7 @@ def test_head_is_no_loop_predecessor(task): +> | return var_5 | +---------------------------------------+ """ - task._cfg.add_nodes_from( + task.cfg.add_nodes_from( vertices := [ BasicBlock( 1, @@ -4788,7 +4786,7 @@ def test_head_is_no_loop_predecessor(task): ), ] ) - task._cfg.add_edges_from( + task.cfg.add_edges_from( [ FalseCase(vertices[0], vertices[1]), TrueCase(vertices[0], vertices[2]), @@ -4810,12 +4808,12 @@ def test_head_is_no_loop_predecessor(task): PatternIndependentRestructuring().run(task) # outer-loop - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 2 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 2 assert isinstance(do_while := seq_node.children[0], DoWhileLoopNode) assert isinstance(return_part := seq_node.children[1], CodeNode) and return_part.instructions == vertices[4].instructions # do-while loop: - assert str(task._ast.condition_map[do_while.condition]) == "exit_4 == 0x0" + assert str(task.ast.condition_map[do_while.condition]) == "exit_4 == 0x0" assert isinstance(do_while_body := do_while.body, SeqNode) and len(do_while_body.children) == 4 assert isinstance(do_while_body.children[0], CodeNode) and do_while_body.children[0].instructions == vertices[0].instructions[:-1] assert isinstance(block_3_cond := do_while_body.children[1], ConditionNode) @@ -4823,7 +4821,7 @@ def test_head_is_no_loop_predecessor(task): assert isinstance(inner_loop := do_while_body.children[3], WhileLoopNode) and inner_loop.is_endless # block 3 cond: - assert block_3_cond.condition.is_negation and str(task._ast.condition_map[~block_3_cond.condition]) == "var_2 != 0x0" + assert block_3_cond.condition.is_negation and str(task.ast.condition_map[~block_3_cond.condition]) == "var_2 != 0x0" assert isinstance(block_3_cond.true_branch_child, CodeNode) and block_3_cond.false_branch is None assert block_3_cond.true_branch_child.instructions == vertices[1].instructions[:-1] @@ -4834,8 +4832,8 @@ def test_head_is_no_loop_predecessor(task): and any((RC3 := arg).is_negation for arg in arguments) and any((RC1 := arg).is_symbol for arg in arguments) ) - assert str(task._ast.condition_map[~RC3]) == "var_2 != 0x0" - assert str(task._ast.condition_map[RC1]) == "((unsigned int) var_5) == 0x0" + assert str(task.ast.condition_map[~RC3]) == "var_2 != 0x0" + assert str(task.ast.condition_map[RC1]) == "((unsigned int) var_5) == 0x0" assert isinstance(break_cond.true_branch_child, CodeNode) and break_cond.false_branch is None assert break_cond.true_branch_child.instructions == [Break()] @@ -4851,12 +4849,12 @@ def test_head_is_no_loop_predecessor(task): assert isinstance(inner_break_cond := inner_body.children[7], ConditionNode) # block 8 cond: - assert block_8_cond.condition and str(task._ast.condition_map[~block_8_cond.condition]) == "var_2 == 0x0" + assert block_8_cond.condition and str(task.ast.condition_map[~block_8_cond.condition]) == "var_2 == 0x0" assert isinstance(block_8_cond.true_branch_child, CodeNode) and block_8_cond.false_branch is None assert block_8_cond.true_branch_child.instructions == vertices[3].instructions # block 11 cond: - assert block_11_cond.condition.is_symbol and str(task._ast.condition_map[block_11_cond.condition]) == "var_3 != 0x0" + assert block_11_cond.condition.is_symbol and str(task.ast.condition_map[block_11_cond.condition]) == "var_3 != 0x0" assert isinstance(block_11_cond.true_branch_child, CodeNode) and block_11_cond.false_branch is None assert block_11_cond.true_branch_child.instructions == vertices[6].instructions + [ Assignment(Variable("exit_4", Integer.int32_t()), Constant(0, Integer.int32_t())), @@ -4864,12 +4862,12 @@ def test_head_is_no_loop_predecessor(task): ] # continue cond: - assert continue_cond.condition.is_symbol and str(task._ast.condition_map[continue_cond.condition]) == "var_2 != 0x0" + assert continue_cond.condition.is_symbol and str(task.ast.condition_map[continue_cond.condition]) == "var_2 != 0x0" assert isinstance(continue_cond.true_branch_child, CodeNode) and continue_cond.false_branch is None assert continue_cond.true_branch_child.instructions == [Continue()] # inner break cond: - assert inner_break_cond.condition and str(task._ast.condition_map[~inner_break_cond.condition]) == "((unsigned int) var_5) != 0x0" + assert inner_break_cond.condition and str(task.ast.condition_map[~inner_break_cond.condition]) == "((unsigned int) var_5) != 0x0" assert isinstance(inner_break_cond.true_branch_child, CodeNode) and inner_break_cond.false_branch is None assert inner_break_cond.true_branch_child.instructions == [ Assignment(Variable("exit_4", Integer.int32_t()), Constant(1, Integer.int32_t())), @@ -4916,7 +4914,7 @@ def test_extract_return(task): PatternIndependentRestructuring().run(task) # outer-loop - assert isinstance(seq_node := task._ast.root, SeqNode) and len(seq_node.children) == 5 + assert isinstance(seq_node := task.ast.root, SeqNode) and len(seq_node.children) == 5 assert isinstance(node_0 := seq_node.children[0], CodeNode) and node_0.instructions == vertices[0].instructions[:-1] assert isinstance(cond_1 := seq_node.children[1], ConditionNode) and cond_1.false_branch is None assert isinstance(node_1 := seq_node.children[2], CodeNode) and node_1.instructions == vertices[1].instructions[:-1] @@ -4924,12 +4922,12 @@ def test_extract_return(task): assert isinstance(node_4 := seq_node.children[4], CodeNode) and node_4.instructions == vertices[4].instructions # cond 1: - assert (cond := cond_1.condition).is_negation and task._ast.condition_map[~cond] == vertices[0].instructions[-1].condition + assert (cond := cond_1.condition).is_negation and task.ast.condition_map[~cond] == vertices[0].instructions[-1].condition assert isinstance(branch := cond_1.true_branch_child, CodeNode) assert branch.instructions == vertices[2].instructions # cond 2: - assert (cond := cond_2.condition).is_symbol and task._ast.condition_map[cond] == vertices[1].instructions[-1].condition + assert (cond := cond_2.condition).is_symbol and task.ast.condition_map[cond] == vertices[1].instructions[-1].condition assert isinstance(branch := cond_2.true_branch_child, CodeNode) assert branch.instructions == vertices[3].instructions diff --git a/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring_blackbox.py b/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring_blackbox.py index 2677884f2..ef0adbd3d 100644 --- a/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring_blackbox.py +++ b/tests/pipeline/controlflowanalysis/test_pattern_independent_restructuring_blackbox.py @@ -12,15 +12,13 @@ from decompiler.structures.ast.ast_nodes import ConditionNode, SeqNode, SwitchNode from decompiler.structures.ast.condition_symbol import ConditionHandler from decompiler.structures.ast.reachability_graph import SiblingReachabilityGraph -from decompiler.structures.ast.switch_node_handler import ExpressionUsages from decompiler.structures.ast.syntaxforest import AbstractSyntaxForest from decompiler.structures.graphs.cfg import BasicBlock, ControlFlowGraph, FalseCase, TrueCase, UnconditionalEdge -from decompiler.structures.pseudo.expressions import Constant, ImportedFunctionSymbol, Variable +from decompiler.structures.pseudo.expressions import Constant, Variable from decompiler.structures.pseudo.instructions import Assignment, Branch, Return from decompiler.structures.pseudo.operations import BinaryOperation, Condition, OperationType from decompiler.structures.pseudo.typing import CustomType, Integer from decompiler.task import DecompilerTask -from decompiler.util.decoration import DecoratedCFG var_b = Variable("b", Integer.int32_t()) var_c = Variable("c", Integer.int32_t()) @@ -30,7 +28,7 @@ @pytest.fixture def task() -> DecompilerTask: """A mock task with an empty cfg.""" - return DecompilerTask("test", ControlFlowGraph()) + return DecompilerTask(name="test", function_identifier="", cfg=ControlFlowGraph()) def test_no_crash_missing_case_finder(task): @@ -45,7 +43,7 @@ def test_no_crash_missing_case_finder(task): var_4 = Variable("var_4", Integer(32, False), ssa_name=Variable("rbx_2", Integer(32, False), 2)) var_5 = Variable("var_5", Integer(32, False), ssa_name=Variable("rax_1", Integer(32, False), 2)) var_6 = Variable("var_6", Integer(32, False), ssa_name=Variable("rax_2", Integer(32, False), 2)) - task._cfg.add_nodes_from( + task.cfg.add_nodes_from( [ b0 := BasicBlock( 0, @@ -76,7 +74,7 @@ def test_no_crash_missing_case_finder(task): ), ] ) - task._cfg.add_edges_from( + task.cfg.add_edges_from( [ TrueCase(b0, b1), FalseCase(b0, b3), diff --git a/tests/pipeline/controlflowanalysis/test_readability_based_refinement.py b/tests/pipeline/controlflowanalysis/test_readability_based_refinement.py index 1bf2a57ee..b7ddbc8b6 100644 --- a/tests/pipeline/controlflowanalysis/test_readability_based_refinement.py +++ b/tests/pipeline/controlflowanalysis/test_readability_based_refinement.py @@ -21,7 +21,6 @@ Continue, ImportedFunctionSymbol, ListOperation, - OperationType, UnaryOperation, Variable, ) @@ -283,7 +282,7 @@ class TestForLoopRecovery: @staticmethod def run_rbr(ast: AbstractSyntaxTree, options: Options = _generate_options()): - ReadabilityBasedRefinement().run(DecompilerTask("func", cfg=None, ast=ast, options=options)) + ReadabilityBasedRefinement().run(DecompilerTask(name="func", function_identifier="", cfg=None, ast=ast, options=options)) def test_max_condition_complexity(self, ast_innerWhile_simple_condition_complexity): self.run_rbr(ast_innerWhile_simple_condition_complexity, _generate_options(max_condition=2)) @@ -335,7 +334,7 @@ def test_restructure_for_loop_option(self, restructure, ast_while_in_else): class TestGuardedDoWhile: @staticmethod def run_rbr(ast: AbstractSyntaxTree, options: Options = _generate_options()): - ReadabilityBasedRefinement().run(DecompilerTask("func", cfg=None, ast=ast, options=options)) + ReadabilityBasedRefinement().run(DecompilerTask(name="func", function_identifier="", cfg=None, ast=ast, options=options)) def test_guarded_do_while_if(self, ast_guarded_do_while_if): self.run_rbr(ast_guarded_do_while_if, _generate_options()) diff --git a/tests/pipeline/controlflowanalysis/test_variable_name_generation.py b/tests/pipeline/controlflowanalysis/test_variable_name_generation.py index 166a026eb..dc98392b2 100644 --- a/tests/pipeline/controlflowanalysis/test_variable_name_generation.py +++ b/tests/pipeline/controlflowanalysis/test_variable_name_generation.py @@ -87,7 +87,9 @@ def _generate_options(notation: str = "system_hungarian", pointer_base: bool = T def _run_vng(ast: AbstractSyntaxTree, options: Options = _generate_options()): - task = DecompilerTask("variable_name_generation", None, ast, options, VOID) + task = DecompilerTask( + name="variable_name_generation", function_identifier="", cfg=None, ast=ast, options=options, function_return_type=VOID + ) VariableNameGeneration().run(task) DecoratedCode.print_code(CodeGenerator().generate([task])) diff --git a/tests/pipeline/dataflowanalysis/test-delogic_dead_loop_elimination.py b/tests/pipeline/dataflowanalysis/test-delogic_dead_loop_elimination.py index b5d2397cb..9ec9b1eb1 100644 --- a/tests/pipeline/dataflowanalysis/test-delogic_dead_loop_elimination.py +++ b/tests/pipeline/dataflowanalysis/test-delogic_dead_loop_elimination.py @@ -20,7 +20,7 @@ def _run_dead_loop_elimination(cfg: ControlFlowGraph): options = Options() options.set("dead-loop-elimination.timeout_satisfiable", 1000) options.set("logic-engine.engine", "delogic") - DeadLoopElimination().run(DecompilerTask("test", cfg, options=options)) + DeadLoopElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def _run_expression_propagation(cfg: ControlFlowGraph): @@ -29,7 +29,7 @@ def _run_expression_propagation(cfg: ControlFlowGraph): options.set("expression-propagation.maximum_branch_complexity", 10) options.set("expression-propagation.maximum_call_complexity", 10) options.set("expression-propagation.maximum_assignment_complexity", 10) - ExpressionPropagation().run(DecompilerTask("test", cfg, options=options)) + ExpressionPropagation().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def test_no_propagation_no_change(): diff --git a/tests/pipeline/dataflowanalysis/test-delogic_dead_path_elimination.py b/tests/pipeline/dataflowanalysis/test-delogic_dead_path_elimination.py index 51868d35f..42e075d5a 100644 --- a/tests/pipeline/dataflowanalysis/test-delogic_dead_path_elimination.py +++ b/tests/pipeline/dataflowanalysis/test-delogic_dead_path_elimination.py @@ -11,7 +11,7 @@ def run_dead_path_elimination(cfg): options = Options() options.set("dead-path-elimination.timeout_satisfiable", 1000) options.set("logic-engine.engine", "delogic") - DeadPathElimination().run(DecompilerTask("test", cfg, options=options)) + DeadPathElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def test_trivial_no_change(): diff --git a/tests/pipeline/dataflowanalysis/test-z3_dead_loop_elimination.py b/tests/pipeline/dataflowanalysis/test-z3_dead_loop_elimination.py index da60673fb..e1c14edb7 100644 --- a/tests/pipeline/dataflowanalysis/test-z3_dead_loop_elimination.py +++ b/tests/pipeline/dataflowanalysis/test-z3_dead_loop_elimination.py @@ -20,7 +20,7 @@ def _run_dead_loop_elimination(cfg: ControlFlowGraph): options = Options() options.set("dead-loop-elimination.timeout_satisfiable", 1000) options.set("logic-engine.engine", "z3") - DeadLoopElimination().run(DecompilerTask("test", cfg, options=options)) + DeadLoopElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def _run_expression_propagation(cfg: ControlFlowGraph): @@ -29,7 +29,7 @@ def _run_expression_propagation(cfg: ControlFlowGraph): options.set("expression-propagation.maximum_branch_complexity", 10) options.set("expression-propagation.maximum_call_complexity", 10) options.set("expression-propagation.maximum_assignment_complexity", 10) - ExpressionPropagation().run(DecompilerTask("test", cfg, options=options)) + ExpressionPropagation().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def test_no_propagation_no_change(): diff --git a/tests/pipeline/dataflowanalysis/test-z3_dead_path_elimination.py b/tests/pipeline/dataflowanalysis/test-z3_dead_path_elimination.py index 968031c23..eee1dc5b2 100644 --- a/tests/pipeline/dataflowanalysis/test-z3_dead_path_elimination.py +++ b/tests/pipeline/dataflowanalysis/test-z3_dead_path_elimination.py @@ -11,7 +11,7 @@ def run_dead_path_elimination(cfg): options = Options() options.set("dead-path-elimination.timeout_satisfiable", 1000) options.set("logic-engine.engine", "z3") - DeadPathElimination().run(DecompilerTask("test", cfg, options=options)) + DeadPathElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def test_trivial_no_change(): diff --git a/tests/pipeline/dataflowanalysis/test_array_access_detection.py b/tests/pipeline/dataflowanalysis/test_array_access_detection.py index 538f24242..7846013ce 100644 --- a/tests/pipeline/dataflowanalysis/test_array_access_detection.py +++ b/tests/pipeline/dataflowanalysis/test_array_access_detection.py @@ -1,4 +1,3 @@ -import pytest from decompiler.pipeline.dataflowanalysis.array_access_detection import ArrayAccessDetection from decompiler.structures.graphs.cfg import BasicBlock, ControlFlowGraph, FalseCase, TrueCase, UnconditionalEdge from decompiler.structures.pseudo.expressions import Constant, ImportedFunctionSymbol, Variable @@ -31,7 +30,7 @@ def run_array_access_detection(cfg: ControlFlowGraph) -> None: def get_task(cfg: ControlFlowGraph) -> DecompilerTask: - task = DecompilerTask("test", cfg, options=Options.from_dict({"array-access-detection.enabled": True})) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg, options=Options.from_dict({"array-access-detection.enabled": True})) return task diff --git a/tests/pipeline/dataflowanalysis/test_array_access_detection_confidence_false.py b/tests/pipeline/dataflowanalysis/test_array_access_detection_confidence_false.py index 978a9a5dc..895a89649 100644 --- a/tests/pipeline/dataflowanalysis/test_array_access_detection_confidence_false.py +++ b/tests/pipeline/dataflowanalysis/test_array_access_detection_confidence_false.py @@ -32,7 +32,7 @@ def run_array_access_detection(cfg: ControlFlowGraph) -> None: def get_task(cfg: ControlFlowGraph) -> DecompilerTask: - task = DecompilerTask("test", cfg, options=Options.from_dict({"array-access-detection.enabled": True})) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg, options=Options.from_dict({"array-access-detection.enabled": True})) return task diff --git a/tests/pipeline/dataflowanalysis/test_common_subexpression_elimination.py b/tests/pipeline/dataflowanalysis/test_common_subexpression_elimination.py index f5e3bc0bf..46ef6114d 100644 --- a/tests/pipeline/dataflowanalysis/test_common_subexpression_elimination.py +++ b/tests/pipeline/dataflowanalysis/test_common_subexpression_elimination.py @@ -32,7 +32,7 @@ def _generate_options(threshold: int = 4, intra: bool = True, str_threshold: int def _run_cse(cfg: ControlFlowGraph, options: Options = _generate_options()): """Run common subexpression elimination on the given control flow graph.""" - CommonSubexpressionElimination().run(DecompilerTask("test", cfg, options=options)) + CommonSubexpressionElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def test_no_cse_for_calls_1(): diff --git a/tests/pipeline/dataflowanalysis/test_expression_propagation.py b/tests/pipeline/dataflowanalysis/test_expression_propagation.py index c544d606c..a23d62485 100644 --- a/tests/pipeline/dataflowanalysis/test_expression_propagation.py +++ b/tests/pipeline/dataflowanalysis/test_expression_propagation.py @@ -862,7 +862,7 @@ def _generate_options(instr: int = 10, branch: int = 10, call: int = 10, assignm def _run_expression_propagation(cfg: ControlFlowGraph, options: Options = _generate_options()) -> None: - task = DecompilerTask("test", cfg, options=options) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options) ExpressionPropagation().run(task) diff --git a/tests/pipeline/dataflowanalysis/test_expression_propagation_function_call.py b/tests/pipeline/dataflowanalysis/test_expression_propagation_function_call.py index fd19c9752..dadb8e8d2 100644 --- a/tests/pipeline/dataflowanalysis/test_expression_propagation_function_call.py +++ b/tests/pipeline/dataflowanalysis/test_expression_propagation_function_call.py @@ -219,5 +219,5 @@ def _run_expression_propagation(cfg: ControlFlowGraph) -> None: options.set("expression-propagation-function-call.maximum_branch_complexity", 10) options.set("expression-propagation-function-call.maximum_call_complexity", 10) options.set("expression-propagation-function-call.maximum_assignment_complexity", 10) - task = DecompilerTask("test", cfg, options=options) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options) ExpressionPropagationFunctionCall().run(task) diff --git a/tests/pipeline/dataflowanalysis/test_expression_propagation_mem.py b/tests/pipeline/dataflowanalysis/test_expression_propagation_mem.py index f1afc6fe8..1b2558d17 100644 --- a/tests/pipeline/dataflowanalysis/test_expression_propagation_mem.py +++ b/tests/pipeline/dataflowanalysis/test_expression_propagation_mem.py @@ -1654,7 +1654,7 @@ def _generate_options(instr: int = 10, branch: int = 10, call: int = 10, assign: def _run_expression_propagation(cfg: ControlFlowGraph, options=_generate_options()) -> None: - ExpressionPropagationMemory().run(DecompilerTask("test", cfg, None, options)) + ExpressionPropagationMemory().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def _graphs_equal(g1: ControlFlowGraph, g2: ControlFlowGraph) -> bool: diff --git a/tests/pipeline/dataflowanalysis/test_identity_elimination.py b/tests/pipeline/dataflowanalysis/test_identity_elimination.py index ed702b115..04c57c0be 100644 --- a/tests/pipeline/dataflowanalysis/test_identity_elimination.py +++ b/tests/pipeline/dataflowanalysis/test_identity_elimination.py @@ -36,7 +36,9 @@ def test_aliased_problems_1(): ], ) ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[Variable("y", ssa_label=3)])) + IdentityElimination().run( + DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[Variable("y", ssa_label=3)]) + ) assert node.instructions == [ Assignment(Variable("x", ssa_label=0, is_aliased=True), Variable("y", ssa_label=3)), Assignment(ListOperation([]), Call(function_symbol("foo"), [Variable("x", ssa_label=0, is_aliased=True)])), @@ -96,7 +98,7 @@ def test_aliased_problems_2(): ] ) cfg.add_edges_from([UnconditionalEdge(start, loop_body), TrueCase(loop_body, end), FalseCase(loop_body, loop_body)]) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])), Assignment(x0.copy(), y0.copy()), @@ -161,7 +163,7 @@ def test_aliased_problems_3(): ] ) cfg.add_edges_from([UnconditionalEdge(start, loop_body), TrueCase(loop_body, end), FalseCase(loop_body, loop_body)]) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])), Assignment(x0.copy(), y0.copy()), @@ -234,7 +236,7 @@ def test_aliased_problems_4(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])), Assignment(x0.copy(), y0.copy()), @@ -301,7 +303,7 @@ def test_aliased_problems_5(): ] ) cfg.add_edges_from([UnconditionalEdge(start, loop_body), TrueCase(loop_body, end), FalseCase(loop_body, loop_body)]) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])), Assignment(x0.copy(), y0.copy()), @@ -365,7 +367,7 @@ def test_aliased_problems_6(): ] ) cfg.add_edges_from([UnconditionalEdge(start, loop_body), TrueCase(loop_body, end), FalseCase(loop_body, loop_body)]) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])) ] @@ -429,7 +431,7 @@ def test_aliased_problems_7(): ] ) cfg.add_edges_from([UnconditionalEdge(start, loop_body), TrueCase(loop_body, end), FalseCase(loop_body, loop_body)]) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])) ] @@ -497,7 +499,7 @@ def test_aliased_problems_8(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])) ] @@ -565,7 +567,7 @@ def test_aliased_problems_9(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])) ] @@ -633,7 +635,7 @@ def test_aliased_problems_10(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("scanf"), [UnaryOperation(OperationType.address, [y0.copy()])])) ] @@ -701,7 +703,7 @@ def test_aliased_problems_11(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [Assignment(x0.copy(), Constant(10, Integer.int32_t()))] assert loop_body.instructions == [ Phi(x1.copy(), [x0.copy(), x2.copy()]), @@ -775,7 +777,7 @@ def test_paper_example_figure_2a(): UnconditionalEdge(loop_body, loop_condition), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [Assignment(x0.copy(), bar.copy()), Assignment(z0.copy(), Constant(10, Integer.int32_t()))] assert loop_condition.instructions == [ Phi(z1.copy(), [z0.copy(), z2.copy()]), @@ -842,7 +844,7 @@ def test_eva_counterexample(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert loop_body.instructions == [ Phi(x1.copy(), [x0.copy(), z0.copy()]), Phi(y1.copy(), [x0.copy(), z0.copy()]), @@ -907,7 +909,7 @@ def test_counterexample_2(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [Assignment(y0.copy(), Constant(0, Integer.int32_t()))] assert loop_body.instructions == [ Phi(x1.copy(), [y0.copy(), y1.copy()]), @@ -974,7 +976,7 @@ def test_counterexample_3(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [] assert loop_body.instructions == [ Phi(u1.copy(), [Constant(0, Integer.int32_t()), u2.copy()]), @@ -1043,7 +1045,7 @@ def test_counterexample_4(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[z0.copy()])) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[z0.copy()])) assert start.instructions == [] assert loop_body.instructions == [ Phi(x2.copy(), [z0.copy(), y2.copy()]), @@ -1119,7 +1121,7 @@ def test_counterexample_5(): TrueCase(loop_body, end), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[z0.copy()])) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[z0.copy()])) assert head.instructions == [] assert start_1.instructions == [] assert start_2.instructions == [Assignment(y1.copy(), Constant(10, Integer.int32_t()))] @@ -1202,7 +1204,7 @@ def test_counterexample_6(): FalseCase(loop_start, end), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert start.instructions == [ Assignment(y1.copy(), BinaryOperation(OperationType.multiply, [y0.copy(), Constant(4, Integer.int32_t())])), Assignment(u0.copy(), Call(FunctionSymbol("bar", 0x42), [])), @@ -1276,7 +1278,7 @@ def test_counterexample_7(): FalseCase(loop_body2, end), ] ) - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert head.instructions == end.instructions == [] assert loop_body.instructions == loop_body2.instructions == [Branch(Condition(OperationType.greater, [u0.copy(), u0.copy()]))] @@ -1346,7 +1348,7 @@ def test_counterexample_8(): FalseCase(loop_body2, end), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[u0.copy()])) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[u0.copy()])) assert head.instructions == end.instructions == [] assert loop_body.instructions == [ Phi(y1.copy(), [u0.copy(), z1.copy(), y2.copy()]), @@ -1403,7 +1405,9 @@ def test_counterexample_9(): ] ) cfg.add_edges_from([UnconditionalEdge(head, loop_body), FalseCase(loop_body, loop_body), TrueCase(loop_body, end)]) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[Variable("u", Integer.int32_t())])) + IdentityElimination().run( + DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[Variable("u", Integer.int32_t())]) + ) assert head.instructions == end.instructions == [] assert loop_body.instructions == [ Phi(y1.copy(), [u0.copy(), y2.copy()]), @@ -1480,7 +1484,9 @@ def test_counterexample_10(): FalseCase(loop_body2, end), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[Variable("u", Integer.int32_t())])) + IdentityElimination().run( + DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[Variable("u", Integer.int32_t())]) + ) assert head.instructions == end.instructions == [] assert loop_body.instructions == [ Phi(y3.copy(), [z1.copy(), u0.copy(), y4.copy()]), @@ -1568,7 +1574,7 @@ def test_counterexample_11(): FalseCase(loop_body_2, loop_body_2), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[u0.copy()])) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[u0.copy()])) assert start.instructions == [] assert loop_body.instructions == [ Phi(z1.copy(), [u0.copy(), z2.copy()]), @@ -1651,7 +1657,7 @@ def test_counterexample_12(): FalseCase(loop_body_2, loop_body_2), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[u0.copy()])) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[u0.copy()])) assert start.instructions == [Assignment(z0.copy(), BinaryOperation(OperationType.plus, [u0.copy(), Constant(1, Integer.int32_t())]))] assert loop_body.instructions == [ Phi(z1.copy(), [z0.copy(), z2.copy()]), @@ -1719,7 +1725,7 @@ def test_counterexample_13(): FalseCase(loop_body, loop_body), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[u0.copy()])) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[u0.copy()])) assert start.instructions == [Assignment(y0.copy(), BinaryOperation(OperationType.plus, [u0.copy(), Constant(3, Integer.int32_t())]))] assert loop_body.instructions == [ Phi(y1.copy(), [y0.copy(), u0.copy()]), @@ -1753,7 +1759,9 @@ def test_alilased_variables(): ], ) ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[Variable("y", ssa_label=3, is_aliased=True)])) + IdentityElimination().run( + DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[Variable("y", ssa_label=3, is_aliased=True)]) + ) assert node.instructions == [ Assignment(Variable("x", ssa_label=0), Variable("y", ssa_label=3, is_aliased=True)), Assignment(ListOperation([]), Call(function_symbol("foo"), [Variable("x", ssa_label=0)])), @@ -1785,7 +1793,9 @@ def test_replace_in_idential_calls(): ], ) ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[Variable("a", ssa_label=7)])) + IdentityElimination().run( + DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[Variable("a", ssa_label=7)]) + ) assert node.instructions == [ Assignment(ListOperation([]), Call(function_symbol("foo"), [Variable("a", ssa_label=7)])), Assignment(ListOperation([]), Call(function_symbol("foo"), [Variable("a", ssa_label=7)])), @@ -1869,7 +1879,9 @@ def test_replace_in_idential_branches(): UnconditionalEdge(case3, end), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[Variable("a", ssa_label=7)])) + IdentityElimination().run( + DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[Variable("a", ssa_label=7)]) + ) assert head.instructions == [Branch(Condition(OperationType.greater_us, [Variable("a", ssa_label=7), Constant(8)]))] assert case1.instructions == [ Assignment(ListOperation([]), Call(function_symbol("foo"), [Constant(0)])), @@ -2029,7 +2041,11 @@ def test_non_defined_variables_no_sinks(): UnconditionalEdge(vertices[6], vertices[1]), ] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[Variable(f"arg{i}", Integer.int32_t()) for i in [1, 2]])) + IdentityElimination().run( + DecompilerTask( + name="test", function_identifier="", cfg=cfg, function_parameters=[Variable(f"arg{i}", Integer.int32_t()) for i in [1, 2]] + ) + ) assert vertices[0].instructions == [ Assignment(ListOperation([]), Call(imp_function_symbol("__x86.get_pc_thunk.bx"), [], Pointer(CustomType("void", 0), 32), 1)) @@ -2149,7 +2165,7 @@ def test_conflict_in_component(): ] ) instructions = [inst.copy() for inst in cfg.instructions] - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert instructions == list(cfg.instructions) @@ -2365,7 +2381,7 @@ def test_do_not_identify_relations(): ) instructions = [inst.copy() for inst in cfg.instructions] - IdentityElimination().run(DecompilerTask("test", cfg)) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) print([str(i) for i in vertices[2].instructions]) print(instructions[8]) assert vertices[0].instructions == [ @@ -2440,4 +2456,4 @@ def test_do_not_crash_if_no_identity(): cfg.add_edges_from( [TrueCase(head, true), FalseCase(head, false), TrueCase(true, r1), FalseCase(true, r2), TrueCase(false, r2), FalseCase(false, r1)] ) - IdentityElimination().run(DecompilerTask("test", cfg, function_parameters=[a_0, a_1])) + IdentityElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, function_parameters=[a_0, a_1])) diff --git a/tests/pipeline/dataflowanalysis/test_redundant_cast_elimination.py b/tests/pipeline/dataflowanalysis/test_redundant_cast_elimination.py index a7805f741..98fb001c0 100644 --- a/tests/pipeline/dataflowanalysis/test_redundant_cast_elimination.py +++ b/tests/pipeline/dataflowanalysis/test_redundant_cast_elimination.py @@ -77,7 +77,7 @@ def test_when_field_can_be_merged_with_casts(): ), ] cfg.add_node(BasicBlock(0, instructions)) - RedundantCastsElimination().run(DecompilerTask("test", cfg)) + RedundantCastsElimination().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert [i for i in cfg.instructions] == [ Assignment(r64[1], cast(unsigned_int, r64[0])), Branch(Condition(OperationType.less_or_equal, [int_var, Constant(0x4)])), diff --git a/tests/pipeline/preprocessing/test-coherence.py b/tests/pipeline/preprocessing/test-coherence.py index 85f7a3913..a0c2b8935 100644 --- a/tests/pipeline/preprocessing/test-coherence.py +++ b/tests/pipeline/preprocessing/test-coherence.py @@ -82,6 +82,6 @@ def test_acceptance(): ) ] ) - Coherence().run(DecompilerTask("test", cfg)) + Coherence().run(DecompilerTask(name="test", function_identifier="", cfg=cfg)) assert {variable.type for variable in [x01, x02]} == {i32.copy()} assert {variable.is_aliased for variable in [x01, x02, x10, x12]} == {True} diff --git a/tests/pipeline/preprocessing/test_extend_phi_function.py b/tests/pipeline/preprocessing/test_extend_phi_function.py index 267769ca9..d43bb5178 100644 --- a/tests/pipeline/preprocessing/test_extend_phi_function.py +++ b/tests/pipeline/preprocessing/test_extend_phi_function.py @@ -23,7 +23,7 @@ def construct_graph(number: int) -> (List[BasicBlock], ControlFlowGraph): for index, instruction in enumerate(defined_instructions): node.append(BasicBlock(index, instructions=[instruction])) cfg = ControlFlowGraph() - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) cfg.add_edges_from( [ UnconditionalEdge(node[3], node[2]), @@ -197,7 +197,7 @@ def test_phi_function_in_head(): cfg = ControlFlowGraph() cfg.add_node(node) cfg.add_edge(UnconditionalEdge(node, node)) - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) PhiFunctionFixer().run(task) assert node.instructions[0].origin_block == {None: v0, node: u2} diff --git a/tests/pipeline/preprocessing/test_insert_missing_definition.py b/tests/pipeline/preprocessing/test_insert_missing_definition.py index a2f968ea7..b08503652 100644 --- a/tests/pipeline/preprocessing/test_insert_missing_definition.py +++ b/tests/pipeline/preprocessing/test_insert_missing_definition.py @@ -119,7 +119,7 @@ def construct_graph_non_aliased(number: int) -> (List[Instruction], DecompilerTa UnconditionalEdge(nodes[3], nodes[4]), ] ) - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) # First Graph - everything defined if number == 1: @@ -368,7 +368,7 @@ def construct_graph_aliased(number: int) -> (List[Instruction], List[Variable], nodes[3].instructions = [i.copy() for i in list_instructions[26:34]] cfg = ControlFlowGraph() - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) cfg.add_node(nodes[0]) if number == 1: return list_instructions, aliased_variables, task @@ -391,7 +391,7 @@ def construct_graph_aliased(number: int) -> (List[Instruction], List[Variable], if number == 5: cfg = ControlFlowGraph() - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) cfg.add_node(nodes[3]) return list_instructions, aliased_variables + aliased_variables_y, task @@ -945,7 +945,7 @@ def test_memory_version_does_not_exist(): ] cfg = ControlFlowGraph() - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) cfg.add_node(BasicBlock(1, instructions)) with pytest.raises(ValueError): @@ -971,7 +971,7 @@ def test_same_instruction_with_different_memory_version(): cfg = ControlFlowGraph() cfg.add_node(BasicBlock(1, instructions)) - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) InsertMissingDefinitions().run(task) @@ -1053,7 +1053,7 @@ def test_missing_definitions_for_global_variables_are_correct(): cfg.add_node(n1 := BasicBlock(1, instructions_1)) cfg.add_node(n2 := BasicBlock(2, instructions_2)) cfg.add_edges_from([UnconditionalEdge(n0, n1), UnconditionalEdge(n0, n2), UnconditionalEdge(n1, n2)]) - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) InsertMissingDefinitions().run(task) expected_inserted_definition = Relation(globals[1], globals[0]) inserted_definition: Assignment = n0.instructions[1] @@ -1094,7 +1094,7 @@ def test_relation_and_assignment_insertion_after_memory_changing_instructions(): ) cfg = ControlFlowGraph() cfg.add_node(BasicBlock(0, [instruction_0, instruction_1, instruction_2])) - task = DecompilerTask("test", cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=cfg) InsertMissingDefinitions().run(task) assert task.graph.nodes[0].instructions[:-2] == [ diff --git a/tests/pipeline/preprocessing/test_mem_phi_converter.py b/tests/pipeline/preprocessing/test_mem_phi_converter.py index 41c953b6f..b5026d89a 100644 --- a/tests/pipeline/preprocessing/test_mem_phi_converter.py +++ b/tests/pipeline/preprocessing/test_mem_phi_converter.py @@ -1197,7 +1197,7 @@ def cfg_with_single_global_variable(x) -> Tuple[ControlFlowGraph, ControlFlowGra def _test_mem_phi_converter(input_cfg: ControlFlowGraph, expected_output_cfg: ControlFlowGraph): - task = DecompilerTask("test", input_cfg) + task = DecompilerTask(name="test", function_identifier="", cfg=input_cfg) MemPhiConverter().run(task) assert _equal(input_cfg, expected_output_cfg) diff --git a/tests/pipeline/preprocessing/test_remove_stack_canary.py b/tests/pipeline/preprocessing/test_remove_stack_canary.py index 1931c21a8..09a3e51fd 100644 --- a/tests/pipeline/preprocessing/test_remove_stack_canary.py +++ b/tests/pipeline/preprocessing/test_remove_stack_canary.py @@ -10,7 +10,7 @@ def _run_remove_stack_canary(cfg: ControlFlowGraph): options = Options() options.set("remove-stack-canary.remove_canary", True) - RemoveStackCanary().run(DecompilerTask("test", cfg, options=options)) + RemoveStackCanary().run(DecompilerTask(name="test", function_identifier="", cfg=cfg, options=options)) def test_trivial_no_change(): diff --git a/tests/pipeline/test-pipeline.py b/tests/pipeline/test-pipeline.py index cfb6023a8..b72bcb176 100644 --- a/tests/pipeline/test-pipeline.py +++ b/tests/pipeline/test-pipeline.py @@ -16,17 +16,6 @@ class EmptyPipeline(DecompilerPipeline): def __init__(self): super().__init__([]) - class EmptyTask(DecompilerTask): - """An empty task mock object.""" - - def __init__(self): - """Just pass None values.""" - super().__init__(None, None) - - def reset(self): - """Empty reset function so the fields can be set however.""" - pass - class MockStage(PipelineStage): """Ab mock pipeline stage, doing nothing.""" @@ -47,7 +36,7 @@ def run(self, task): def test_empty(self): """An empty pipeline should always work.""" empty_pipeline = self.EmptyPipeline() - empty_pipeline.run(self.EmptyTask()) + empty_pipeline.run(DecompilerTask(name="", function_identifier="")) def test_default_valid(self): """The default pipeline should always be valid."""