我正在玩变异测试。我正在研究的一个突变涉及交换参数,我可能需要交换参数,例如Ldarg.0
和Ldarg_S
以及指示索引的操作数。
这是一个内联arg的操作数类型,在Mono.Cecil中我认为需要我创建一个正确实例化的ParameterDefinition
来存储32位int索引。有没有人有足够的经验与Cecil指出我在一个简单方法的正确方向上创建一个Instruction
实例OpCode
Ldarg_S
和Operand
相应的类型?
答案 0 :(得分:8)
这里有两种操作码,ldarg.0
和ldarg
(以及它的_s)变体。
第一个是“宏”操作码,这意味着它用于减少通常使用的值的代码大小。
如果您需要修改方法的参数,我建议您将所有宏操作码转换为完整形式,这是使用帮助库Mono中SimplifyMacros()
上的MethodBody
扩展方法完成的.Cecil.Rocks:
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
// ..
method.Body.SimplifyMacros();
完成此操作后,现有的ldarg.0
指令现在为ldarg
,其中包含正确的操作数,如您所猜测的那样ParameterDefinition
。
有了这些,你可以重新排序参数,并创建新的指令:
var il = method.Body.GetILProcessor();
var instruction = il.Create(OpCodes.Ldarg, aParameterDefinition);
il.InsertBefore(xxx, instruction);
完成后,您可以调用SimplifyMacros()
,OptimizeMacros()
的倒数,如果可能的话,会尝试将操作码优化为宏格式。
你需要注意的一件事是,实例方法的第一个参数,即隐含的“this”,用method.Body.ThisParameter
特殊参数表示,你不会在其中找到。方法的参数集合。