Centralize from_ir conversion; switch IR to frozen dataclasses#42
Merged
Conversation
Member
|
Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/pysoot_42 |
0170b0d to
de936b5
Compare
de936b5 to
2c48248
Compare
The sootir/ package was a mix of pure data classes and JPype-dependent
from_ir factory methods. Move all conversion logic into soot_manager.py
so the sootir package becomes a pure-data layer.
Then switch every dataclass from unsafe_hash=True to frozen=True. This
was previously impossible because SootPhiExpr was constructed without
block indices and then mutated post-init:
phi_expr = SootValue.IREXPR_TO_EXPR[ir_expr]
phi_expr.values = values
The new conversion code threads the per-method stmt_to_block_idx context
through _convert_value, so SootPhiExpr is built in a single shot with its
final (value, block_idx) tuples — no mutation required.
Type improvements in soot_manager.py:
- _JavaObj alias (= Any) for JPype-returned objects, used uniformly on
ir_* parameters
- Return type annotations on _convert_class, _convert_method,
_convert_block, _convert_stmt, _convert_value, _convert_expr,
_build_instance_invoke
- _Ctx.stmt_map / stmt_to_block_idx now typed dict[_JavaObj, int]
- _build_instance_invoke cls parameter tightened from Any to a union of
the three concrete InstanceInvokeExpr subclasses
- _BINOP_EXPR_NAMES tightened from dict[str, Any] to
dict[str, type[SootBinopExpr] | type[SootConditionExpr]]
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2c48248 to
982df29
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
from_irfactory logic out of thesootir/package and intosoot_manager.pyas private_convert_*functions. Thesootir/package is now a pure data layer with no Java interop.unsafe_hash=Truetofrozen=True, catching post-init mutation at runtime.soot_manager.py(return type annotations on the conversion helpers, narrower union types for_build_instance_invokeand the binop dispatch table,_JavaObjalias for JPype-returned objects).Stacked on top of #41 — please merge that first.
Why frozen is now possible
SootPhiExprpreviously had to be constructed without block indices and then mutated post-init in a second pass:The new code threads a per-method
_Ctx(containingstmt_to_block_idx) through_convert_value, soSootPhiExpris built in a single shot with its final(value, block_idx)tuples. No mutation, no global side-channel.Notes
_convert_*) since they are only used byrun_soot. No public API change insootir/.frozen=Trueenables value-based__hash__automatically, so the existing pattern of usingSootBlockas a dict key inbasic_cfg/exceptional_predsstill works.Test plan
pytest tests/still passes (needs JPype runtime, can't run in dev sandbox)SootMethod.block_by_labelstill resolves, thatfrozendictlookups forbasic_cfg/exceptional_predsstill work🤖 Generated with Claude Code