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
232 changes: 116 additions & 116 deletions HighLevelIL/HighLevelILDetailedOperandsTable.cs

Large diffs are not rendered by default.

110 changes: 0 additions & 110 deletions HighLevelIL/HighLevelILOperand.cs

This file was deleted.

35 changes: 35 additions & 0 deletions IL/ILOperand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace BinaryNinja
{
/// <summary>
/// A named, typed operand of an IL instruction: the value plus its name, kind, and the Python
/// type string. Shared by every IL. This is the C# equivalent of one
/// <c>(name, value, type_str)</c> tuple from the official Python binding's
/// <c>*ILInstruction.detailed_operands</c> property.
/// </summary>
public readonly struct ILOperand
{
/// <summary>The operand's name, e.g. "left", "src", "condition" (matches Python).</summary>
public string Name { get; }

/// <summary>
/// The operand value. The runtime type follows <see cref="Kind"/>: an IL instruction,
/// <c>long</c>, a Variable/SSAVariable, <c>float</c>, or an array of those. May be null
/// when the underlying native operand is absent.
/// </summary>
public object? Value { get; }

/// <summary>How the value was read; drives traversal and variable collection.</summary>
public ILOperandKind Kind { get; }

/// <summary>The Python type string, e.g. "*ILInstruction", "int", "Variable".</summary>
public string TypeName { get; }

internal ILOperand(string name, object? value, ILOperandKind kind, string typeName)
{
this.Name = name;
this.Value = value;
this.Kind = kind;
this.TypeName = typeName;
}
}
}
52 changes: 52 additions & 0 deletions IL/ILOperandDescriptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace BinaryNinja
{
/// <summary>
/// One row of the static detailed-operands table shared by every IL: an operand's name, the
/// reader kind, the raw operand index it occupies, and the Python type string. Used to build
/// <see cref="ILOperand"/> values at query time.
/// </summary>
internal readonly struct ILOperandDescriptor
{
internal string Name { get; }

internal ILOperandKind Kind { get; }

/// <summary>
/// The raw operand slot the value starts at. For <see cref="ILOperandKind.SSAVariable"/>
/// the variable identifier occupies this slot; for <see cref="ILOperandKind.ConstantData"/>
/// the register-value state occupies this slot.
/// </summary>
internal int RawIndex { get; }

/// <summary>
/// The second raw slot a two-slot operand uses, or -1 to mean "the slot right after
/// <see cref="RawIndex"/>". For <see cref="ILOperandKind.SSAVariable"/> this is the version
/// slot; for <see cref="ILOperandKind.ConstantData"/> it is the value slot. The explicit
/// form is needed for the MediumLevelIL "aliased" dest/prev operands, where <c>prev</c>
/// shares the variable slot with <c>dest</c> but reads a different version slot (e.g. the
/// core lays out <c>SET_VAR_ALIASED</c> as var@0, dest-version@1, prev-version@2).
/// </summary>
internal int SecondaryRawIndex { get; }

internal string TypeName { get; }

internal ILOperandDescriptor(string name, ILOperandKind kind, int rawIndex, string typeName)
{
this.Name = name;
this.Kind = kind;
this.RawIndex = rawIndex;
this.SecondaryRawIndex = -1;
this.TypeName = typeName;
}

internal ILOperandDescriptor(
string name, ILOperandKind kind, int rawIndex, int secondaryRawIndex, string typeName)
{
this.Name = name;
this.Kind = kind;
this.RawIndex = rawIndex;
this.SecondaryRawIndex = secondaryRawIndex;
this.TypeName = typeName;
}
}
}
51 changes: 51 additions & 0 deletions IL/ILOperandKind.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
namespace BinaryNinja
{
/// <summary>
/// Categorizes one detailed operand of an IL instruction by how it is read from the native
/// instruction's raw operand slots. Shared by every IL (HighLevelIL, MediumLevelIL, ...) so the
/// descriptor tables, traversal, and operand collection can be written once.
/// </summary>
/// <remarks>
/// Each value mirrors a type string returned by the official Python binding's
/// <c>*ILInstruction.detailed_operands</c> property, collapsed to the reader dispatched in the
/// matching <c>DetailedOperands</c> implementation.
/// </remarks>
public enum ILOperandKind
{
/// <summary>A single sub-expression (Python type "*ILInstruction").</summary>
Expression,

/// <summary>A list of sub-expressions (Python type "List[*ILInstruction]").</summary>
ExpressionList,

/// <summary>A single integer slot (Python type "int" or "Optional[int]").</summary>
Integer,

/// <summary>A list of integer slots (Python type "List[int]" or "Dict[int, int]").</summary>
IntegerList,

/// <summary>A single variable (Python type "Variable").</summary>
Variable,

/// <summary>A list of variables (Python type "List[Variable]").</summary>
VariableList,

/// <summary>A single SSA variable occupying two raw slots (Python type "SSAVariable").</summary>
SSAVariable,

/// <summary>A list of SSA variables (Python type "List[SSAVariable]").</summary>
SSAVariableList,

/// <summary>A floating-point constant (Python type "float").</summary>
Float,

/// <summary>A goto label reference (Python type "GotoLabel"). HighLevelIL only.</summary>
GotoLabel,

/// <summary>Constant data (Python type "ConstantData").</summary>
ConstantData,

/// <summary>An intrinsic reference (Python type "ILIntrinsic").</summary>
Intrinsic
}
}
Loading
Loading