使用Mono.Cecil创建带有内联参数的IL指令

时间:2012-04-19 15:24:05

标签: .net mono.cecil mutation-testing

我正在玩变异测试。我正在研究的一个突变涉及交换参数,我可能需要交换参数,例如Ldarg.0Ldarg_S以及指示索引的操作数。

这是一个内联arg的操作数类型,在Mono.Cecil中我认为需要我创建一个正确实例化的ParameterDefinition来存储32位int索引。有没有人有足够的经验与Cecil指出我在一个简单方法的正确方向上创建一个Instruction实例OpCode Ldarg_SOperand相应的类型?

1 个答案:

答案 0 :(得分:8)

这里有两种操作码,ldarg.0ldarg(以及它的_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特殊参数表示,你不会在其中找到。方法的参数集合。