diff options
| author | Ajax <commial@gmail.com> | 2017-03-29 15:09:23 +0200 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2017-03-30 16:04:40 +0200 |
| commit | 056d8496468f36e9388588e3e28bb2379403eb80 (patch) | |
| tree | c601457c227af71a60d61c9576b9220144c5091e /miasm2/expression/expression.py | |
| parent | cedf19e7d73ca8d603f2e1ed7f5306db27678e65 (diff) | |
| download | miasm-056d8496468f36e9388588e3e28bb2379403eb80.tar.gz miasm-056d8496468f36e9388588e3e28bb2379403eb80.zip | |
Let ExprInt always use its Singleton capabilities
Remove the optionnal 'size' argument form, use pointer equality to speed up comparision
Diffstat (limited to 'miasm2/expression/expression.py')
| -rw-r--r-- | miasm2/expression/expression.py | 88 |
1 files changed, 42 insertions, 46 deletions
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index e134e503..94c3825d 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -30,7 +30,7 @@ import itertools from operator import itemgetter -from miasm2.expression.modint import * +from miasm2.expression.modint import mod_size2uint, is_modint, size2mask from miasm2.core.graph import DiGraph import warnings @@ -143,10 +143,6 @@ class Expr(object): Expr.args2expr[(cls, args)] = expr return expr - def __new__(cls, *args, **kwargs): - expr = object.__new__(cls, *args, **kwargs) - return expr - def get_is_canon(self): return self in Expr.canon_exprs @@ -187,23 +183,18 @@ class Expr(object): self.__hash = self._exprhash() return self.__hash - def pre_eq(self, other): - """Return True if ids are equal; - False if instances are obviously not equal - None if we cannot simply decide""" - - if id(self) == id(other): + def __eq__(self, other): + if self is other: return True + elif self.use_singleton: + # In case of Singleton, pointer comparison is sufficient + # Avoid computation of hash and repr + return False + if self.__class__ is not other.__class__: return False if hash(self) != hash(other): return False - return None - - def __eq__(self, other): - res = self.pre_eq(other) - if res is not None: - return res return repr(self) == repr(other) def __ne__(self, a): @@ -246,8 +237,7 @@ class Expr(object): return ExprOp("**",self, a) def __invert__(self): - s = self.size - return ExprOp('^', self, ExprInt(mod_size2uint[s](size2mask(s)))) + return ExprOp('^', self, self.mask) def copy(self): "Deep copy of the expression" @@ -398,25 +388,12 @@ class ExprInt(Expr): __slots__ = Expr.__slots__ + ["__arg"] - def __init__(self, num, size=None): + def __init__(self, arg, size): """Create an ExprInt from a modint or num/size - @arg: modint or num - @size: (optionnal) int size""" - + @arg: 'intable' number + @size: int size""" super(ExprInt, self).__init__() - - if is_modint(num): - self.__arg = num - self.__size = self.arg.size - if size is not None and num.size != size: - raise RuntimeError("size must match modint size") - elif size is not None: - if size not in mod_size2uint: - define_uint(size) - self.__arg = mod_size2uint[size](num) - self.__size = self.arg.size - else: - raise ValueError('arg must by modint or (int,size)! %s' % num) + # Work is done in __new__ size = property(lambda self: self.__size) arg = property(lambda self: self.__arg) @@ -427,10 +404,29 @@ class ExprInt(Expr): def __setstate__(self, state): self.__init__(*state) - def __new__(cls, arg, size=None): - if size is None: - size = arg.size - return Expr.get_object(cls, (arg, size)) + def __new__(cls, arg, size): + """Create an ExprInt from a modint or num/size + @arg: 'intable' number + @size: int size""" + + if is_modint(arg): + assert size == arg.size + # Avoid a common blunder + assert not isinstance(arg, ExprInt) + + # Ensure arg is always a moduint + arg = int(arg) + if size not in mod_size2uint: + define_uint(size) + arg = mod_size2uint[size](arg) + + # Get the Singleton instance + expr = Expr.get_object(cls, (arg, size)) + + # Save parameters (__init__ is called with parameters unchanged) + expr.__arg = arg + expr.__size = expr.__arg.size + return expr def __get_int(self): "Return self integer representation" @@ -1321,28 +1317,28 @@ def canonize_expr_list_compose(l): def ExprInt1(i): - return ExprInt(uint1(i)) + return ExprInt(i, 1) def ExprInt8(i): - return ExprInt(uint8(i)) + return ExprInt(i, 8) def ExprInt16(i): - return ExprInt(uint16(i)) + return ExprInt(i, 16) def ExprInt32(i): - return ExprInt(uint32(i)) + return ExprInt(i, 32) def ExprInt64(i): - return ExprInt(uint64(i)) + return ExprInt(i, 64) def ExprInt_from(e, i): "Generate ExprInt with size equal to expression" - return ExprInt(mod_size2uint[e.size](i)) + return ExprInt(i, e.size) def get_expr_ids_visit(e, ids): |