Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pybind/AE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,10 @@ void bind_abstract_state(py::module& m) {
.def("__getitem__", [](AbstractStateManager& self, const ICFGNode* node) -> AbstractState& {
return self[node];
}, py::arg("node"), py::return_value_policy::reference)
.def("__setitem__", [](AbstractStateManager& self, const ICFGNode* node, const AbstractState& state) {
self.updateAbstractState(node, state);
}, py::arg("node"), py::arg("state"))
.def("__contains__", &AbstractStateManager::hasAbstractState, py::arg("node"))

// Def/Use site queries
.def("getUseSitesOfObjVar", &AbstractStateManager::getUseSitesOfObjVar,
Expand Down
62 changes: 54 additions & 8 deletions pysvf/pysvf.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,9 @@ class GepStmt(AssignStmt):
def getSrcPointeeType(self) -> "SVFType": ...
"""Get the source pointee type"""

def getStructFieldOffset(self, idx_var: "ValVar", struct_type: "SVFStructType") -> int: ...
"""Compute the byte offset for a struct field index"""

class MultiOpndStmt(SVFStmt):
def getOpVar(self, ID: int) -> "SVFVar": ...
"""Get the operand variable"""
Expand Down Expand Up @@ -1964,16 +1967,10 @@ class AbstractState:
def bottom(self) -> None: ...
def getIDFromAddr(self, addr: int) -> int: ...
def top(self) -> None: ...
def getElementIndex(self, gep: 'GepStmt') -> IntervalValue: ...
def getByteOffset(self, gep: 'GepStmt') -> IntervalValue: ...
def getPointeeElement(self, var_id: int) -> SVFType: ...
def isVirtualMemAddress(self, val: int) -> bool: ...
def getVirtualMemAddress(self, idx: int) -> int: ...
def isCmpBranchFeasible(self, cmp: 'CmpStmt', succ: int, abstract_state: AbstractState) -> bool: ...
def isSwitchBranchFeasible(self, switch_var: SVFVar, succ: int, abstract_state: AbstractState) -> bool: ...
def storeValue(self, varId: int, val: AbstractValue) -> None: ...
def loadValue(self, varId: int) -> AbstractValue: ...
def getAllocaInstByteSize(self, addr: AddrStmt) -> int: ...
def inVarToValTable(self, var_id: int) -> bool: ...
def inVarToAddrsTable(self, var_id: int) -> bool: ...
def inAddrToAddrsTable(self, id: int) -> bool: ...
Expand All @@ -1986,7 +1983,6 @@ class AbstractState:
"""Check if an address is freed memory"""
def hash(self) -> int: ...
"""Get the hash of this abstract state"""
def getGepObjAddrs(self, var_id: int, offset: IntervalValue) -> AddressValue: ...

def clear(self) -> None: ...
def clone(self) -> 'AbstractState': ...
Expand All @@ -2001,7 +1997,57 @@ class AbstractState:
def isBlackHoleObjAddr(self, addr: int) -> bool: ...


class PointsTo(Set[int]):
class AbstractStateManager:
"""Manages abstract states across ICFG nodes and provides the
sparsity-aware GEP / load / store / size helpers that used to live on
AbstractState (moved upstream by the Semi-Sparse refactor)."""

def __init__(self, svfir: 'SVFIR', pta: 'AndersenWaveDiff') -> None: ...

def getAbstractValue(self, var: 'SVFVar', node: 'ICFGNode') -> AbstractValue: ...
def hasAbstractValue(self, var: 'SVFVar', node: 'ICFGNode') -> bool: ...
def updateAbstractValue(self, var: 'SVFVar', val: AbstractValue, node: 'ICFGNode') -> None: ...

def getAbstractState(self, node: 'ICFGNode') -> AbstractState: ...
def hasAbstractState(self, node: 'ICFGNode') -> bool: ...
def updateAbstractState(self, node: 'ICFGNode', state: AbstractState) -> None: ...

def getGepElementIndex(self, gep: 'GepStmt') -> IntervalValue: ...
def getGepByteOffset(self, gep: 'GepStmt') -> IntervalValue: ...
def getGepObjAddrs(self, pointer: 'ValVar', offset: IntervalValue) -> AddressValue: ...

def loadValue(self, pointer: 'ValVar', node: 'ICFGNode') -> AbstractValue: ...
def storeValue(self, pointer: 'ValVar', val: AbstractValue, node: 'ICFGNode') -> None: ...

def getPointeeElement(self, var: 'ObjVar', node: 'ICFGNode') -> 'SVFType': ...
def getAllocaInstByteSize(self, addr: 'AddrStmt') -> int: ...

def getTrace(self) -> dict: ...
def __getitem__(self, node: 'ICFGNode') -> AbstractState: ...
def __setitem__(self, node: 'ICFGNode', state: AbstractState) -> None: ...
def __contains__(self, node: 'ICFGNode') -> bool: ...

def getUseSitesOfObjVar(self, obj: 'ObjVar', node: 'ICFGNode') -> set: ...
def getUseSitesOfValVar(self, var: 'ValVar') -> set: ...
def getDefSiteOfValVar(self, var: 'ValVar') -> 'ICFGNode': ...
def getDefSiteOfObjVar(self, obj: 'ObjVar', node: 'ICFGNode') -> 'ICFGNode': ...


class AbstractInterpretation:
"""Minimal binding -- exposes getStateMgr() so Python can grab the
AbstractStateManager from a running analysis."""

def getStateMgr(self) -> AbstractStateManager: ...


class Options:
"""A small subset of SVF Options exposed for downstream Python code."""

@staticmethod
def max_field_limit() -> int: ...


class PointsTo(Set[int]):
def set(self, value: int) -> None: ...


Expand Down
5 changes: 5 additions & 0 deletions stubtest_allowlist.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
pysvf.AbstractState
pysvf.AbstractStateManager
pysvf.AbstractInterpretation
pysvf.AbstractInterpretation.__init__
pysvf.AbstractValue
pysvf.Options
pysvf.Options.__init__
pysvf.ActualINSVFGNode
pysvf.ActualINSVFGNode.__init__
pysvf.ActualOUTSVFGNode
Expand Down
Loading