@@ -11,7 +11,7 @@ public static partial class MonoModCommon
1111 public static class IL
1212 {
1313 /// <summary>
14- /// The name of the "this" parameter is an empty string rather than "this".
14+ /// The name of the "this" TrackingParameter is an empty string rather than "this".
1515 /// </summary>
1616 public const string ThisParameterName = "" ;
1717 public static Instruction BuildParameterLoad ( MethodDefinition method , MethodBody body , ParameterDefinition parameter ) {
@@ -32,7 +32,7 @@ public static Instruction BuildParameterLoad(MethodDefinition method, MethodBody
3232 }
3333 public static Instruction BuildParameterSet ( MethodDefinition method , MethodBody body , ParameterDefinition parameter ) {
3434 if ( method . HasThis && ( ( body is not null && body . ThisParameter == parameter ) || parameter . Name == "" ) ) {
35- throw new ArgumentException ( "Cannot set \" this\" parameter " , nameof ( parameter ) ) ;
35+ throw new ArgumentException ( "Cannot set \" this\" TrackingParameter " , nameof ( parameter ) ) ;
3636 }
3737 else {
3838 var index = method . Parameters . IndexOf ( parameter ) + ( method . HasThis ? 1 : 0 ) ;
@@ -107,7 +107,7 @@ Code.Starg_S or
107107 }
108108 var param = method . Parameters [ paramIndex ] ;
109109 if ( tmpCheck is not null && tmpCheck . Name != param . Name ) {
110- throw new InvalidOperationException ( "Operand parameter is invalid" ) ;
110+ throw new InvalidOperationException ( "Operand TrackingParameter is invalid" ) ;
111111 }
112112 return param ;
113113 }
@@ -143,7 +143,7 @@ Code.Starg_S or
143143 var paramIndex = paramInnerIndex - ( method . HasThis ? 1 : 0 ) ;
144144 parameter = method . Parameters [ paramIndex ] ;
145145 if ( tmpCheck is not null && tmpCheck . Name != parameter . Name ) {
146- throw new InvalidOperationException ( "Operand parameter is invalid" ) ;
146+ throw new InvalidOperationException ( "Operand TrackingParameter is invalid" ) ;
147147 }
148148 }
149149 return true ;
@@ -182,11 +182,37 @@ public static bool TryGetReferencedVariable(MethodDefinition method, Instruction
182182 Code . Ldloc_1 or Code . Stloc_1 => 1 ,
183183 Code . Ldloc_2 or Code . Stloc_2 => 2 ,
184184 Code . Ldloc_3 or Code . Stloc_3 => 3 ,
185+
185186 Code . Ldloc_S or
186187 Code . Ldloc or
187- Code . Ldloca or
188188 Code . Ldloca_S or
189- Code . Stloc or
189+ Code . Ldloca or
190+ Code . Stloc_S or
191+ Code . Stloc => ( tmpCheck = ( VariableDefinition ) instruction . Operand ) . Index ,
192+ _ => - 1
193+ } ;
194+
195+ if ( tmpCheck is not null && tmpCheck != method . Body . Variables [ localIndex ] ) {
196+ throw new ArgumentException ( "Operand variable is invalid" , nameof ( instruction ) ) ;
197+ }
198+
199+ if ( localIndex == - 1 ) {
200+ variable = null ;
201+ return false ;
202+ }
203+
204+ variable = method . Body . Variables [ localIndex ] ;
205+ return true ;
206+ }
207+ public static bool MatchSetVariable ( MethodDefinition method , Instruction instruction , [ NotNullWhen ( true ) ] out VariableDefinition ? variable ) {
208+ VariableDefinition ? tmpCheck = null ;
209+
210+ var localIndex = instruction . OpCode . Code switch {
211+ Code . Stloc_0 => 0 ,
212+ Code . Stloc_1 => 1 ,
213+ Code . Stloc_2 => 2 ,
214+ Code . Stloc_3 => 3 ,
215+
190216 Code . Stloc_S or
191217 Code . Stloc => ( tmpCheck = ( VariableDefinition ) instruction . Operand ) . Index ,
192218 _ => - 1
@@ -204,6 +230,53 @@ Code.Stloc_S or
204230 variable = method . Body . Variables [ localIndex ] ;
205231 return true ;
206232 }
233+ public static bool MatchLoadVariableAddress ( MethodDefinition method , Instruction instruction , [ NotNullWhen ( true ) ] out VariableDefinition ? variable ) {
234+ VariableDefinition ? tmpCheck = null ;
235+
236+ var localIndex = instruction . OpCode . Code switch {
237+ Code . Ldloca_S or
238+ Code . Ldloca => ( tmpCheck = ( VariableDefinition ) instruction . Operand ) . Index ,
239+ _ => - 1
240+ } ;
241+
242+ if ( tmpCheck is not null && tmpCheck != method . Body . Variables [ localIndex ] ) {
243+ throw new ArgumentException ( "Operand variable is invalid" , nameof ( instruction ) ) ;
244+ }
245+
246+ if ( localIndex == - 1 ) {
247+ variable = null ;
248+ return false ;
249+ }
250+
251+ variable = method . Body . Variables [ localIndex ] ;
252+ return true ;
253+ }
254+ public static bool MatchLoadVariable ( MethodDefinition method , Instruction instruction , [ NotNullWhen ( true ) ] out VariableDefinition ? variable ) {
255+ VariableDefinition ? tmpCheck = null ;
256+
257+ var localIndex = instruction . OpCode . Code switch {
258+ Code . Ldloc_0 => 0 ,
259+ Code . Ldloc_1 => 1 ,
260+ Code . Ldloc_2 => 2 ,
261+ Code . Ldloc_3 => 3 ,
262+
263+ Code . Ldloc_S or
264+ Code . Ldloc => ( tmpCheck = ( VariableDefinition ) instruction . Operand ) . Index ,
265+ _ => - 1
266+ } ;
267+
268+ if ( tmpCheck is not null && tmpCheck != method . Body . Variables [ localIndex ] ) {
269+ throw new ArgumentException ( "Operand variable is invalid" , nameof ( instruction ) ) ;
270+ }
271+
272+ if ( localIndex == - 1 ) {
273+ variable = null ;
274+ return false ;
275+ }
276+
277+ variable = method . Body . Variables [ localIndex ] ;
278+ return true ;
279+ }
207280 public static TypeReference GetMethodReturnType ( MethodReference target , MethodDefinition callerContext ) {
208281 if ( target is GenericInstanceMethod genericMethod ) {
209282 return ResolveGenericReturnType ( genericMethod , genericMethod . ReturnType ) ;
0 commit comments