@@ -58,21 +58,23 @@ public unsafe struct BNInstructionInfo
5858 internal IntPtr branchArch_2 ;
5959 }
6060
61- public sealed class InstructionInfo
62- {
63- public ulong Length { get ; } = 0 ;
64-
65- public ulong BranchCount { get ; } = 0 ;
61+ public sealed class InstructionInfo
62+ {
63+ private const int MaximumBranchCount = 3 ;
6664
67- public bool ArchTransitionByTargetAddr { get ; } = false ;
68-
69- public byte DelaySlots { get ; } = 0 ;
70-
71- public BranchType [ ] BranchType { get ; } = Array . Empty < BranchType > ( ) ;
72-
73- public ulong [ ] BranchTarget { get ; } = Array . Empty < ulong > ( ) ;
74-
75- public Architecture [ ] BranchArch { get ; } = Array . Empty < Architecture > ( ) ;
65+ public ulong Length { get ; set ; } = 0 ;
66+
67+ public ulong BranchCount { get ; private set ; } = 0 ;
68+
69+ public bool ArchTransitionByTargetAddr { get ; set ; } = false ;
70+
71+ public byte DelaySlots { get ; set ; } = 0 ;
72+
73+ public BranchType [ ] BranchType { get ; private set ; } = Array . Empty < BranchType > ( ) ;
74+
75+ public ulong [ ] BranchTarget { get ; private set ; } = Array . Empty < ulong > ( ) ;
76+
77+ public Architecture ? [ ] BranchArch { get ; private set ; } = Array . Empty < Architecture ? > ( ) ;
7678
7779 public InstructionInfo ( )
7880 {
@@ -83,7 +85,7 @@ public InstructionInfo(BNInstructionInfo native)
8385 {
8486 this . Length = native . length ;
8587
86- this . BranchCount = native . branchCount ;
88+ this . BranchCount = Math . Min ( native . branchCount , ( ulong ) MaximumBranchCount ) ;
8789
8890 this . ArchTransitionByTargetAddr = native . archTransitionByTargetAddr ;
8991
@@ -116,38 +118,89 @@ public InstructionInfo(BNInstructionInfo native)
116118 this . BranchTarget = branchTargets . ToArray ( ) ;
117119
118120 // BranchArch
119- List < Architecture > branchArches = new List < Architecture > ( ) ;
121+ List < Architecture ? > branchArches = new List < Architecture ? > ( ) ;
120122
121- if ( this . BranchCount >= 1 )
123+ if ( 1 <= this . BranchCount )
122124 {
123- if ( IntPtr . Zero != native . branchArch_0 )
124- {
125- branchArches . Add ( new Architecture ( native . branchArch_0 ) ) ;
126- }
125+ branchArches . Add ( Architecture . FromHandle ( native . branchArch_0 ) ) ;
127126 }
128127
129- if ( this . BranchCount >= 2 )
128+ if ( 2 <= this . BranchCount )
130129 {
131- if ( IntPtr . Zero != native . branchArch_1 )
132- {
133- branchArches . Add ( new Architecture ( native . branchArch_1 ) ) ;
134- }
130+ branchArches . Add ( Architecture . FromHandle ( native . branchArch_1 ) ) ;
135131 }
136132
137- if ( this . BranchCount >= 3 )
133+ if ( 3 <= this . BranchCount )
138134 {
139- if ( IntPtr . Zero != native . branchArch_2 )
140- {
141- branchArches . Add ( new Architecture ( native . branchArch_2 ) ) ;
142- }
135+ branchArches . Add ( Architecture . FromHandle ( native . branchArch_2 ) ) ;
143136 }
144137
145138 this . BranchArch = branchArches . ToArray ( ) ;
146139 }
147140
141+ public void AddBranch (
142+ BranchType type ,
143+ ulong target = 0 ,
144+ Architecture ? architecture = null ,
145+ byte delaySlots = 0 )
146+ {
147+ if ( MaximumBranchCount <= this . BranchCount )
148+ {
149+ return ;
150+ }
151+
152+ List < BranchType > branchTypes = new List < BranchType > ( this . BranchType ) ;
153+ List < ulong > branchTargets = new List < ulong > ( this . BranchTarget ) ;
154+ List < Architecture ? > branchArchitectures =
155+ new List < Architecture ? > ( this . BranchArch ) ;
156+
157+ branchTypes . Add ( type ) ;
158+ branchTargets . Add ( target ) ;
159+ branchArchitectures . Add ( architecture ) ;
160+
161+ this . BranchType = branchTypes . ToArray ( ) ;
162+ this . BranchTarget = branchTargets . ToArray ( ) ;
163+ this . BranchArch = branchArchitectures . ToArray ( ) ;
164+ this . BranchCount = ( ulong ) this . BranchType . Length ;
165+ this . DelaySlots = delaySlots ;
166+ }
167+
168+ internal unsafe BNInstructionInfo ToNative ( )
169+ {
170+ BNInstructionInfo native = new BNInstructionInfo
171+ {
172+ length = this . Length ,
173+ branchCount = this . BranchCount ,
174+ archTransitionByTargetAddr = this . ArchTransitionByTargetAddr ,
175+ delaySlots = this . DelaySlots
176+ } ;
177+
178+ for ( int index = 0 ; index < this . BranchType . Length ; index ++ )
179+ {
180+ native . branchType [ index ] = ( byte ) this . BranchType [ index ] ;
181+ native . branchTarget [ index ] = this . BranchTarget [ index ] ;
182+ }
183+
184+ native . branchArch_0 = this . GetBranchArchitectureHandle ( 0 ) ;
185+ native . branchArch_1 = this . GetBranchArchitectureHandle ( 1 ) ;
186+ native . branchArch_2 = this . GetBranchArchitectureHandle ( 2 ) ;
187+
188+ return native ;
189+ }
190+
191+ private IntPtr GetBranchArchitectureHandle ( int index )
192+ {
193+ if ( this . BranchArch . Length <= index || null == this . BranchArch [ index ] )
194+ {
195+ return IntPtr . Zero ;
196+ }
197+
198+ return this . BranchArch [ index ] ! . DangerousGetHandle ( ) ;
199+ }
200+
148201 internal static InstructionInfo FromNative ( BNInstructionInfo native )
149202 {
150203 return new InstructionInfo ( native ) ;
151204 }
152205 }
153- }
206+ }
0 commit comments