88from collections import OrderedDict , deque
99from collections .abc import Iterable , Iterator
1010from itertools import chain
11- from typing import TYPE_CHECKING , Generic , NoReturn , TypeVar
11+ from typing import TYPE_CHECKING , NoReturn , TypeVar
1212
1313import claripy .clarirs as clarirs
1414from claripy import operations , simplifications
1515from claripy .backend_manager import backends
16+ from claripy .clarirs import ASTCacheKey
1617from claripy .errors import BackendError , ClaripyOperationError , ClaripyReplacementError
1718
1819if TYPE_CHECKING :
3031T = TypeVar ("T" , bound = "Base" )
3132
3233
33- class ASTCacheKey (Generic [T ]):
34- def __init__ (self , a : T ):
35- self .ast : T = a
36-
37- def __hash__ (self ):
38- return hash (self .ast )
39-
40- def __eq__ (self , other ):
41- return type (self ) is type (other ) and self .ast ._hash == other .ast ._hash
42-
43- def __repr__ (self ):
44- return f"<Key { self .ast ._type_name ()} { self .ast .__repr__ (inner = True )} >"
45-
46-
4734#
4835# AST variable naming
4936#
@@ -251,20 +238,16 @@ def __new__(cls, op, args, add_variables=None, hash=None, **kwargs): # pylint:d
251238 h = Base ._calc_hash (op , a_args , kwargs ) if hash is None else hash
252239 self = cache .get (h & 0x7FFF_FFFF_FFFF_FFFF , None )
253240 if self is None :
241+ # depth = arg_max_depth + 1
254242 self = super ().__new__ (
255243 cls ,
256244 op ,
257245 tuple (args ),
258- kwargs .get ("length" , None ),
259- frozenset (kwargs ["variables" ]),
260- kwargs ["symbolic" ],
261- annotations ,
262- )
263- depth = arg_max_depth + 1
264- self .__a_init__ (
265- op ,
266- a_args ,
267- depth = depth ,
246+ kwargs .pop ("length" , None ),
247+ frozenset (kwargs .pop ("variables" )),
248+ kwargs .pop ("symbolic" ),
249+ # annotations,
250+ depth = arg_max_depth + 1 ,
268251 uneliminatable_annotations = uneliminatable_annotations ,
269252 relocatable_annotations = relocatable_annotations ,
270253 ** kwargs ,
@@ -287,18 +270,15 @@ def __init_with_annotations__(
287270 if self is not None :
288271 return self
289272
273+ print ("aaa" )
290274 self = super ().__new__ (
291275 cls ,
292276 op ,
293277 tuple (a_args ),
294- kwargs .get ("length" , None ),
295- frozenset (kwargs ["variables" ]),
296- kwargs ["symbolic" ],
297- tuple (kwargs .get ("annotations" , ())),
298- )
299- self .__a_init__ (
300- op ,
301- a_args ,
278+ kwargs .pop ("length" , None ),
279+ frozenset (kwargs .pop ("variables" )),
280+ kwargs .pop ("symbolic" ),
281+ tuple (kwargs .pop ("annotations" , ())),
302282 depth = depth ,
303283 uneliminatable_annotations = uneliminatable_annotations ,
304284 relocatable_annotations = relocatable_annotations ,
@@ -322,75 +302,19 @@ def __reduce__(self):
322302 def __init__ (self , * args , ** kwargs ):
323303 pass
324304
325- # pylint:disable=attribute-defined-outside-init
326- def __a_init__ (
327- self ,
328- op ,
329- args ,
330- variables = None ,
331- symbolic = None ,
332- length = None ,
333- simplified = 0 ,
334- errored = None ,
335- eager_backends = None ,
336- uninitialized = None ,
337- uc_alloc_depth = None ,
338- annotations = None ,
339- encoded_name = None ,
340- depth = None ,
341- uneliminatable_annotations = None ,
342- relocatable_annotations = None ,
343- ): # pylint:disable=unused-argument
344- """
345- Initializes an AST. Takes the same arguments as ``Base.__new__()``
346-
347- We use this instead of ``__init__`` due to python's undesirable behavior w.r.t. automatically calling it on
348- return from ``__new__``.
349- """
350-
351- # HASHCONS: these attributes key the cache
352- # BEFORE CHANGING THIS, SEE ALL OTHER INSTANCES OF "HASHCONS" IN THIS FILE
353- # super().__new__(op, args, length, frozenset(variables), symbolic, annotations)
354- # self.op = op
355- # self.args = args if type(args) is tuple else tuple(args)
356- # self.length = length
357- # self.variables = frozenset(variables) if type(variables) is not frozenset else variables
358- # self.symbolic = symbolic
359- # self.annotations: tuple[Annotation] = annotations
360- self ._uneliminatable_annotations = uneliminatable_annotations
361- self ._relocatable_annotations = relocatable_annotations
362-
363- self .depth = depth if depth is not None else 1
364-
365- self ._eager_backends = eager_backends
366- self ._cached_encoded_name = encoded_name
367-
368- self ._errored = errored if errored is not None else set ()
369-
370- self ._simplified = simplified
371- self ._cache_key = ASTCacheKey (self )
372- self ._excavated = None
373- self ._burrowed = None
374-
375- self ._uninitialized = uninitialized
376- self ._uc_alloc_depth = uc_alloc_depth
377-
378- if len (self .args ) == 0 :
379- raise ClaripyOperationError ("AST with no arguments!" )
380-
381- # pylint:enable=attribute-defined-outside-init
382-
383305 def __hash__ (self ):
384306 res = self ._hash
385307 if not isinstance (self ._hash , int ):
386308 res = hash (self ._hash )
387309 return res
388310
389311 @property
390- def cache_key (self : T ) -> ASTCacheKey [ T ] :
312+ def cache_key (self : T ) -> ASTCacheKey :
391313 """
392314 A key that refers to this AST - this value is appropriate for usage as a key in dictionaries.
393315 """
316+ if self ._cache_key is None :
317+ self ._cache_key = ASTCacheKey (self )
394318 return self ._cache_key
395319
396320 @property
@@ -408,6 +332,7 @@ def make_like(self: T, op: str, args: Iterable, **kwargs) -> T:
408332 simplified = simplifications .simpleton .simplify (op , args ) if kwargs .pop ("simplify" , False ) is True else None
409333 if simplified is not None :
410334 op = simplified .op
335+
411336 if (
412337 simplified is None
413338 and len (kwargs ) == 3
0 commit comments