feat: HLIL DetailedOperands/Operands/Traverse navigation (#13,#15)#41
Merged
Conversation
Mirror Python HighLevelILInstruction.detailed_operands / operands / traverse
(highlevelil.py:795/786/802). A static descriptor table (operation -> named,
typed operands) drives a kind-dispatched reader; Operands and Traverse derive
from it, exactly as in Python.
- HighLevelILOperand: enum Kind + readonly Operand/Descriptor structs.
- HighLevelILDetailedOperandsTable: 114-op descriptor table generated from the
Python detailed_operands overrides, abstract bases expanded to concrete ops.
- HighLevelILInstruction: GetOperandAsInteger, virtual DetailedOperands,
ReadDetailedOperandByKind (SSA var + constant data occupy two raw slots),
Operands, generic Traverse<T> (DFS, shallow blacklist matches Python).
- HLILVariableDeclare: expose the .Variable accessor (the one missing accessor).
Divergence from Python (intentional, documented in the table header): HLIL_ROR
omits the "carry" operand -- Python's HighLevelILRor inherits CarryBase but the
core (highlevelilinstruction.cpp:189) defines ROR with only {left,right}, so
Python's Ror.carry reads a non-existent slot. C# follows the core (OperationOperands
= 2, matching PR #26's removal of the bogus Carry accessor).
E2E (harness, not in this repo): DetailedOperands parity vs the Python spec for
ADD/STRUCT_FIELD/CONST(+PTR/FLOAT); Operands + Traverse; full cat.bndb sweep
no-throw; static consistency test reflecting over the table + OperationOperands
catches out-of-bounds indices (the ROR bug above was found + fixed by it).
76/76 pass.
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.
Mirrors Python
HighLevelILInstruction.detailed_operands/operands/traverse(highlevelil.py:795/786/802).A static descriptor table (operation → named, typed operands) drives a kind-dispatched reader;
OperandsandTraverse<T>derive from it — the same foundation-first design as Python, whereoperandsandtraverseboth build ondetailed_operands.Changes
HighLevelILOperand.cs:HighLevelILOperandKindenum + readonlyHighLevelILOperand/HighLevelILOperandDescriptorstructs.HighLevelILDetailedOperandsTable.cs: 114-op descriptor table generated from the Pythondetailed_operandsoverrides, abstract bases expanded to every concrete op.BNHighLevelILInstruction.cs:GetOperandAsInteger, virtualDetailedOperands, privateReadDetailedOperandByKind(SSA variable + constant data occupy two raw slots),Operands, genericTraverse<T>(DFS over operand tree; shallow blacklist{true,false,body,cases,default}matches Python).HLILVariableDeclare.cs: expose the.Variableaccessor (the one missing accessor).Intentional divergence from Python —
HLIL_ROR. PythonHighLevelILRorinheritsHighLevelILCarryBase, so itsdetailed_operandslists a thirdcarryoperand — but the core (highlevelilinstruction.cpp:189) definesHLIL_RORwith only{left, right}, so Python'sRor.carryreads a non-existent slot (garbage). This binding follows the core (OperationOperands[HLIL_ROR]=2, consistent with PR #26's removal of the bogusCarryaccessor), so ROR has just{left, right}.RLC/RRC/ADC/SBBgenuinely have a carry slot in the core and keep it.Verification (harness repo, not this one) — 76/76 pass:
DetailedOperandsnames+kinds vs the Python spec forADD,STRUCT_FIELD,CONST/CONST_PTR/FLOAT_CONST.Operandsyields theDetailedOperandsvalues (boxedlongfor integers, sub-expression forsrc).Traversevisits root + descendants, and filters via the callback (constants).cat.bndbsweep: every HLIL instruction'sDetailedOperandsreads without throwing.OperationOperandsand asserts every descriptor stays in-bounds — the persistent drift guard the PR fix: HLIL OperationOperands undercounts + ROR bogus Carry #26/fix: LLIL OperationOperands undercounts (17 ops) #27/fix: MLIL OperationOperands undercounts (27 ops) + bogus VAR_PHI.SourceMemory #28OperationOperandscluster demanded. It found the ROR bug above before merge.Closes parity gaps #13 (Operands) + #15 (Traverse) + the DetailedOperands foundation. #14 (Vars/VarsWritten/VarsRead/VarsAddressTaken) needs a focused follow-up:
HighLevelILSSAVariableandHighLevelILVariableare separate sealed types with no common base, so the collection return type needs design.