[文档]classEnvironment:""" Represent the environment in which a program runs. It's a mapping of variable names, to `claripy.ast.Base` that should contain possible addresses, or <UNDEFINED>, at which their respective values are stored. **Note**: The <Environment> object does not store the values associated with variables themselves. """__slots__=("_environment",)
[文档]defget(self,names:set[str])->tuple[set[claripy.ast.Base],bool]:""" :param names: Potential values for the name of the environment variable to get the pointers of. :return: The potential addresses of the values the environment variable can take; And a boolean value telling whether all the names were known of the internal representation (i.e. will be False if one of the queried variable was not found). """has_unknown=notall(nameinself._environmentfornameinnames)def_get(name):ifnotisinstance(name,(str,Undefined)):raiseTypeError(f"get(): Expected str, or Undefined, got {type(name).__name__}")returnself._environment.get(name,{UNDEFINED})pointers=set()forvaluesinmap(_get,names):pointers|=valuesreturnpointers,has_unknown
[文档]defset(self,name:str|Undefined,pointers:set[claripy.ast.Base]):""" :param name: Name of the environment variable to which we will associate the pointers. :param pointers: New addresses where the new values of the environment variable are located. """ifnotisinstance(name,(str,Undefined)):raiseTypeError(f"set(): Expected str, or Undefined, got {type(name).__name__}")self._environment[name]=pointers
def__str__(self):returnf"Environment: {self._environment}"def__repr__(self):returnf"Environment: {self._environment}"def__eq__(self,other:object)->bool:assertisinstance(other,Environment),f"Cannot compare Environment with {type(other).__name__}"returnself._environment==other._environment
[文档]defmerge(self,*others:Environment)->tuple[Environment,bool]:new_env=self._environmentforotherinothers:ifnotisinstance(other,Environment):raiseTypeError(f"Cannot merge Environment with {type(other).__name__}")keys=set(new_env.keys())keys|=other._environment.keys()def_dataset_from_key(key,environment1,environment2):v=environment1.get(key,None)w=environment2.get(key,None)# Because the key is coming from one of them, they cannot be both `None`.ifvisNone:returnwifwisNone:returnvreturnv|wnew_env={k:_dataset_from_key(k,new_env,other._environment)forkinkeys}merge_occurred=new_env!=self._environmentreturnEnvironment(environment=new_env),merge_occurred