Skip to content

Commit 2c2f0d7

Browse files
committed
Fix comparison operators for Variable objects, make setting of name & type synchoronous, and provide asynchronous setters for name and type
1 parent 11a011a commit 2c2f0d7

1 file changed

Lines changed: 42 additions & 14 deletions

File tree

python/variable.py

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ def from_core_variable(cls, var, name, type):
629629

630630
class Variable(CoreVariable):
631631
def __init__(self, func:FunctionOrILFunction, source_type:VariableSourceType, index:int, storage:int):
632-
super(Variable, self).__init__(source_type, index, storage)
632+
super(Variable, self).__init__(int(source_type), index, storage)
633633
if isinstance(func, binaryninja.function.Function):
634634
self._function = func
635635
self._il_function = None
@@ -658,15 +658,15 @@ def __repr__(self):
658658
if self.type is not None:
659659
return f"<var {self.type.get_string_before_name()} {self.name}{self.type.get_string_after_name()}>"
660660
else:
661-
return repr(super(Variable, self))
661+
return repr(super())
662662

663663
def __str__(self):
664664
return self.name
665665

666666
def __eq__(self, other):
667667
if not isinstance(other, self.__class__):
668668
return NotImplemented
669-
return (self.identifier, self._function) == (other.identifier, other._function)
669+
return super().__eq__(other) and (self._function == other._function)
670670

671671
def __ne__(self, other):
672672
if not isinstance(other, self.__class__):
@@ -676,40 +676,43 @@ def __ne__(self, other):
676676
def __lt__(self, other):
677677
if not isinstance(other, self.__class__):
678678
return NotImplemented
679-
return (self.identifier, self._function) < (other.identifier, other._function)
679+
return super().__lt__(other) and self._function < other._function
680680

681681
def __gt__(self, other):
682682
if not isinstance(other, self.__class__):
683683
return NotImplemented
684-
return (self.identifier, self._function) > (other.identifier, other._function)
684+
return super().__gt__(other) and self._function > other._function
685685

686686
def __le__(self, other):
687687
if not isinstance(other, self.__class__):
688688
return NotImplemented
689-
return (self.identifier, self._function) <= (other.identifier, other._function)
689+
return super().__le__(other) and self._function <= other._function
690690

691691
def __ge__(self, other):
692692
if not isinstance(other, self.__class__):
693693
return NotImplemented
694-
return (self.identifier, self._function) >= (other.identifier, other._function)
694+
return super().__ge__(other) and self._function >= other._function
695695

696696
def __hash__(self):
697-
return hash((self._function, self.identifier))
697+
return hash((self._function, super()))
698+
699+
@property
700+
def core_variable(self) -> CoreVariable:
701+
return CoreVariable(self._source_type, self.index, self.storage)
698702

699703
@property
700704
def var_name_and_type(self) -> VariableNameAndType:
701705
return VariableNameAndType.from_core_variable(self, self.name, self.type)
702706

703707
@property
704-
def name(self):
705-
"""Name of the variable"""
708+
def name(self) -> str:
709+
"""Name of the variable, Settings thisslow because it ensures that analysis has been updated. """
706710
return core.BNGetRealVariableName(self._function.handle, self._function.arch.handle, self.to_BNVariable())
707711

708712
@name.setter
709713
def name(self, name:Optional[str]) -> None:
710-
if name is None:
711-
name = ""
712-
self._function.create_user_var(self, self.type, name)
714+
self.set_name_async(name)
715+
self._function.view.update_analysis_and_wait()
713716

714717
@property
715718
def type(self) -> Optional['binaryninja.types.Type']:
@@ -722,7 +725,8 @@ def type(self) -> Optional['binaryninja.types.Type']:
722725

723726
@type.setter
724727
def type(self, new_type:'binaryninja.types.Type') -> None:
725-
self._function.create_user_var(self, new_type, self.name)
728+
self.set_type_async(new_type)
729+
self._function.view.update_analysis_and_wait()
726730

727731
@property
728732
def ssa_versions(self) -> Generator[int, None, None]:
@@ -760,6 +764,30 @@ def function(self) -> 'binaryninja.function.Function':
760764
"""returns the source Function object which this variable belongs to"""
761765
return self._function
762766

767+
def set_name_async(self, name:Optional[str]) -> None:
768+
"""
769+
``set_name_async`` provides a way to asynchronously set the name of a variable. This method should be used
770+
when speed is of concern.
771+
"""
772+
if name is None:
773+
name = ""
774+
self._function.create_user_var(self, self.type, name)
775+
776+
def set_type_async(self, new_type:'binaryninja.types.Type') -> None:
777+
"""
778+
``set_type_async`` provides a way to asynchronously set the type of a variable. This method should be used
779+
when speed is of concern.
780+
"""
781+
self._function.create_user_var(self, new_type, self.name)
782+
783+
def set_name_and_type_async(self, name:Optional[str], new_type:'binaryninja.types.Type') -> None:
784+
"""
785+
``set_name_and_type_async`` provides a way to asynchronously set both the name and type of a variable. This method should be used
786+
when speed is of concern.
787+
"""
788+
self._function.create_user_var(self, new_type, name)
789+
790+
763791
@dataclass(frozen=True)
764792
class ConstantReference:
765793
value:int

0 commit comments

Comments
 (0)