Skip to content

Expose AbstractInterpretation.getAEInstance() to Python - #57

Merged
bjjwwang merged 1 commit into
SVF-tools:mainfrom
bjjwwang:sync/AE-getAEInstance-binding
May 11, 2026
Merged

bjjwwang merged 1 commit into
SVF-tools:mainfrom
bjjwwang:sync/AE-getAEInstance-binding

Conversation

@bjjwwang

Copy link
Copy Markdown
Collaborator

The course-side Assignment-3 Python helper calls
pysvf.AbstractInterpretation.getAEInstance() to obtain the SVF abstract interpreter singleton. Previously pysvf intentionally did NOT bind getAEInstance because a straightforward .def_static hit a static_assert deep inside <bits/stl_uninitialized.h>: pybind11 instantiates make_(copy|move)_constructor whenever a binding returns the type, and AbstractInterpretation owns a vector<unique_ptr> that makes the implicit copy/move ctors ill-formed, but the standard traits don't catch this until the body is generated.

Two-part workaround:

  1. pybind/AE.cpp:

    • Specialise pybind11::detail::is_copy_constructible and is_move_constructible for AbstractInterpretation, so pybind11 skips both factory paths when binding methods on the class.
    • Add the py::nodelete holder so pybind never tries to delete the SVF-owned singleton.
    • Bind a module-level shim _AbstractInterpretation_getAEInstance (the .def_static path turned out to take a different SFINAE route that the trait specialisations don't cover).
  2. pysvf/init.py: import the shim and attach it as AbstractInterpretation.getAEInstance = staticmethod(...), so Python callers use the natural class-method form.

  3. pysvf/pysvf.pyi: add the @staticmethod stub entry.

Verified end-to-end in Docker against svftools/software-security-analysis image (after applying the SVF leak-singleton fix to libSvfCore.so): SSA Python Assignment-3 tests now reach the analysis logic instead of crashing at import; ctest pass rate 28/64 -> 62/64.

The course-side Assignment-3 Python helper calls
pysvf.AbstractInterpretation.getAEInstance() to obtain the SVF abstract
interpreter singleton.  Previously pysvf intentionally did NOT bind
getAEInstance because a straightforward .def_static hit a static_assert
deep inside <bits/stl_uninitialized.h>: pybind11 instantiates
make_(copy|move)_constructor<AbstractInterpretation> whenever a binding
returns the type, and AbstractInterpretation owns a
vector<unique_ptr<AEDetector>> that makes the implicit copy/move ctors
ill-formed, but the standard traits don't catch this until the body is
generated.

Two-part workaround:

1. pybind/AE.cpp:
   - Specialise pybind11::detail::is_copy_constructible<T> and
     is_move_constructible<T> for AbstractInterpretation, so pybind11
     skips both factory paths when binding methods on the class.
   - Add the py::nodelete holder so pybind never tries to delete the
     SVF-owned singleton.
   - Bind a module-level shim _AbstractInterpretation_getAEInstance
     (the .def_static path turned out to take a different SFINAE route
     that the trait specialisations don't cover).

2. pysvf/__init__.py: import the shim and attach it as
   AbstractInterpretation.getAEInstance = staticmethod(...), so Python
   callers use the natural class-method form.

3. pysvf/pysvf.pyi: add the @staticmethod stub entry.

Verified end-to-end in Docker against svftools/software-security-analysis
image (after applying the SVF leak-singleton fix to libSvfCore.so):
SSA Python Assignment-3 tests now reach the analysis logic instead of
crashing at import; ctest pass rate 28/64 -> 62/64.
@bjjwwang
bjjwwang merged commit 740ff1b into SVF-tools:main May 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant