@@ -55,6 +55,8 @@ public enum ExprNodeKind : byte
5555[ StructLayout ( LayoutKind . Explicit , Size = 24 ) ]
5656public struct ExprNode
5757{
58+ // Packed layout of `_data` (MSB -> LSB):
59+ // [ 8 bits NodeType ][ 8 bits Tag(flags+kind) ][ 16 bits NextIdx ][ 16 bits ChildCount ][ 16 bits ChildIdx ]
5860 private const int NodeTypeShift = 56 ;
5961 private const int TagShift = 48 ;
6062 private const int NextShift = 32 ;
@@ -82,11 +84,14 @@ public struct ExprNode
8284 private ulong _data ;
8385
8486 /// <summary>Gets the expression kind encoded for this node.</summary>
87+ // Extracts bits [63..56].
8588 public ExpressionType NodeType => ( ExpressionType ) ( ( _data >> NodeTypeShift ) & 0xFF ) ;
8689
8790 /// <summary>Gets the payload classification for this node.</summary>
91+ // Extracts low 4 bits from Tag [51..48].
8892 public ExprNodeKind Kind => ( ExprNodeKind ) ( ( _data >> TagShift ) & KindMask ) ;
8993
94+ // Extracts high 4 bits from Tag [55..52].
9095 internal byte Flags => ( byte ) ( ( ( byte ) ( _data >> TagShift ) ) >> FlagsShift ) ;
9196
9297 /// <summary>Gets the next sibling node index in the intrusive child chain.</summary>
@@ -117,19 +122,22 @@ internal ExprNode(Type type, object obj, ExpressionType nodeType, ExprNodeKind k
117122 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
118123 internal void SetNextSiblingIdx ( int nextIdx )
119124 {
125+ // Replace NextIdx [47..32] and clear link-state flags to "regular sibling link".
120126 _data = ( _data & KeepWithoutNextMask ) | ( ( ulong ) ( ushort ) nextIdx << NextShift ) ;
121127 SetFlags ( ( byte ) ( Flags & ~ ( NextPointsParentFlag | NextReservedFlag ) ) ) ;
122128 }
123129
124130 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
125131 internal void SetParentIdx ( int parentIdx )
126132 {
133+ // Replace NextIdx [47..32] and mark it as "points to parent" (not sibling).
127134 _data = ( _data & KeepWithoutNextMask ) | ( ( ulong ) ( ushort ) parentIdx << NextShift ) ;
128135 SetFlags ( ( byte ) ( ( Flags | NextPointsParentFlag ) & ~ NextReservedFlag ) ) ;
129136 }
130137
131138 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
132139 internal void SetChildInfo ( int childIdx , int childCount ) =>
140+ // Replace ChildCount [31..16] and ChildIdx [15..0] together as one logical payload.
133141 _data = ( _data & KeepWithoutChildInfoMask )
134142 | ( ( ulong ) ( ushort ) childCount << CountShift )
135143 | ( ushort ) childIdx ;
@@ -152,6 +160,7 @@ internal bool IsExpression() =>
152160 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
153161 private void SetFlags ( byte flags )
154162 {
163+ // Rebuild Tag [55..48] as [flags(4 bits) | kind(4 bits)] and replace in place.
155164 var tag = ( byte ) ( ( flags << FlagsShift ) | ( byte ) Kind ) ;
156165 _data = ( _data & ~ TagMask ) | ( ( ulong ) tag << TagShift ) ;
157166 }
0 commit comments