diff --git a/ailment/converter_vex.py b/ailment/converter_vex.py index 2bcbc26..6c87ddf 100644 --- a/ailment/converter_vex.py +++ b/ailment/converter_vex.py @@ -350,7 +350,9 @@ def Triop(expr, manager): bits=bits, ) - raise TypeError("Please figure out what kind of operation this is (smart money says fused multiply) and convert it into multiple binops") + raise TypeError( + "Please figure out what kind of operation this is (smart money says fused multiply) and convert it into multiple binops" + ) @staticmethod def Const(expr, manager): diff --git a/ailment/expression.py b/ailment/expression.py index 9a75326..238d07e 100644 --- a/ailment/expression.py +++ b/ailment/expression.py @@ -1,6 +1,7 @@ # pylint:disable=arguments-renamed,isinstance-second-argument-not-valid-type,missing-class-docstring from __future__ import annotations -from typing import TYPE_CHECKING, Sequence, cast +from typing import TYPE_CHECKING, cast +from collections.abc import Sequence from typing_extensions import Self from enum import Enum, IntEnum from abc import abstractmethod @@ -460,7 +461,9 @@ class UnaryOp(Op): "variable_offset", ) - def __init__(self, idx: int | None, op: str, operand: Expression, variable=None, variable_offset: int | None=None, **kwargs): + def __init__( + self, idx: int | None, op: str, operand: Expression, variable=None, variable_offset: int | None = None, **kwargs + ): super().__init__(idx, (operand.depth if isinstance(operand, Expression) else 0) + 1, op, **kwargs) self.operand = operand @@ -476,12 +479,18 @@ def __repr__(self): def likes(self, other): return ( - type(other) is UnaryOp and self.op == other.op and self.bits == other.bits and self.operand.likes(other.operand) + type(other) is UnaryOp + and self.op == other.op + and self.bits == other.bits + and self.operand.likes(other.operand) ) def matches(self, other): return ( - type(other) is UnaryOp and self.op == other.op and self.bits == other.bits and self.operand.matches(other.operand) + type(other) is UnaryOp + and self.op == other.op + and self.bits == other.bits + and self.operand.matches(other.operand) ) __hash__ = TaggedObject.__hash__ @@ -519,10 +528,12 @@ def has_atom(self, atom, identity=True): return True return self.operand.has_atom(atom, identity=identity) + class ConvertType(Enum): TYPE_INT = 0 TYPE_FP = 1 + class Convert(UnaryOp): TYPE_INT = ConvertType.TYPE_INT TYPE_FP = ConvertType.TYPE_FP @@ -991,7 +1002,18 @@ class Load(Expression): "bits", ) - def __init__(self, idx: int | None, addr: Expression, size: int, endness: str, variable=None, variable_offset=None, guard=None, alt=None, **kwargs): + def __init__( + self, + idx: int | None, + addr: Expression, + size: int, + endness: str, + variable=None, + variable_offset=None, + guard=None, + alt=None, + **kwargs, + ): depth = max(addr.depth, size.depth if isinstance(size, Expression) else 0) + 1 super().__init__(idx, depth, **kwargs) @@ -1090,7 +1112,16 @@ class ITE(Expression): "variable_offset", ) - def __init__(self, idx: int | None, cond: Expression, iffalse: Expression, iftrue: Expression, variable=None, variable_offset=None, **kwargs): + def __init__( + self, + idx: int | None, + cond: Expression, + iffalse: Expression, + iftrue: Expression, + variable=None, + variable_offset=None, + **kwargs, + ): depth = ( max( cond.depth if isinstance(cond, Expression) else 0, @@ -1486,7 +1517,16 @@ class BasePointerOffset(Expression): "variable_offset", ) - def __init__(self, idx: int | None, bits: int, base: Expression | str, offset: int, variable=None, variable_offset=None, **kwargs): + def __init__( + self, + idx: int | None, + bits: int, + base: Expression | str, + offset: int, + variable=None, + variable_offset=None, + **kwargs, + ): super().__init__(idx, (offset.depth if isinstance(offset, Expression) else 0) + 1, **kwargs) self.bits = bits self.base = base diff --git a/ailment/statement.py b/ailment/statement.py index 2bb8c77..0af5951 100644 --- a/ailment/statement.py +++ b/ailment/statement.py @@ -1,6 +1,7 @@ # pylint:disable=isinstance-second-argument-not-valid-type,no-self-use,arguments-renamed from __future__ import annotations -from typing import TYPE_CHECKING, Sequence +from typing import TYPE_CHECKING +from collections.abc import Sequence from abc import ABC, abstractmethod from typing_extensions import Self @@ -105,7 +106,7 @@ def replace(self, old_expr: Expression, new_expr: Expression): else: return False, self - def copy(self) -> "Assignment": + def copy(self) -> Assignment: return Assignment(self.idx, self.dst, self.src, **self.tags) @@ -124,7 +125,18 @@ class Store(Statement): "guard", ) - def __init__(self, idx: int | None, addr: Expression, data: Expression, size: int, endness: str, guard: Expression | None = None, variable=None, offset=None, **kwargs): + def __init__( + self, + idx: int | None, + addr: Expression, + data: Expression, + size: int, + endness: str, + guard: Expression | None = None, + variable=None, + offset=None, + **kwargs, + ): super().__init__(idx, **kwargs) self.addr = addr @@ -228,7 +240,7 @@ def replace(self, old_expr, new_expr): else: return False, self - def copy(self) -> "Store": + def copy(self) -> Store: return Store( self.idx, self.addr, @@ -433,7 +445,7 @@ def replace(self, old_expr, new_expr): else: return False, self - def copy(self) -> "ConditionalJump": + def copy(self) -> ConditionalJump: return ConditionalJump( self.idx, self.condition, @@ -470,7 +482,7 @@ def __init__( target, calling_convention: SimCC | None = None, prototype=None, - args: Sequence[Expression] | None=None, + args: Sequence[Expression] | None = None, ret_expr: Expression | None = None, fp_ret_expr: Expression | None = None, bits: int | None = None, @@ -491,7 +503,7 @@ def __init__( elif fp_ret_expr is not None: self.bits = fp_ret_expr.bits else: - self.bits = 0 # uhhhhhhhhhhhhhhhhhhh + self.bits = 0 # uhhhhhhhhhhhhhhhhhhh def likes(self, other): return ( @@ -730,7 +742,7 @@ def replace(self, old_expr, new_expr): return True, DirtyStatement(self.idx, new_dirty, **self.tags) return False, self - def copy(self) -> "DirtyStatement": + def copy(self) -> DirtyStatement: return DirtyStatement(self.idx, self.dirty, **self.tags) def likes(self, other): @@ -757,7 +769,7 @@ def __init__(self, idx, name: str, ins_addr: int, block_idx: int | None = None, self.ins_addr = ins_addr self.block_idx = block_idx - def likes(self, other: "Label"): + def likes(self, other: Label): return isinstance(other, Label) def replace(self, old_expr, new_expr): @@ -781,5 +793,5 @@ def __repr__(self): def __str__(self): return f"{self.name}:" - def copy(self) -> "Label": + def copy(self) -> Label: return Label(self.idx, self.name, self.ins_addr, self.block_idx, **self.tags) diff --git a/ailment/utils.py b/ailment/utils.py index 933d8c0..51bf290 100644 --- a/ailment/utils.py +++ b/ailment/utils.py @@ -1,5 +1,5 @@ from __future__ import annotations -from typing import TYPE_CHECKING, TypeAlias +from typing import TypeAlias import struct try: @@ -119,4 +119,5 @@ def is_none_or_matchable(arg1, arg2, is_list=False): return arg1.matches(arg2) return arg1 == arg2 + from .expression import Expression