4

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

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

4

1 回答 1

8

这里有两种操作码ldarg.0,和ldarg(及其 _s)变体。

第一个是“宏”操作码,这意味着它用于减少通常使用的值的代码大小。

如果您需要修改方法的参数,我建议您首先将所有宏操作码转换为完整的形式,这是使用帮助库 Mono.Cecil.Rocks中的SimplifyMacros()扩展方法完成的:MethodBody

using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;

// ..

method.Body.SimplifyMacros();

完成此操作后,现有ldarg.0指令现在将ldarg具有正确的操作数,正如您所猜测的那样, a ParameterDefinition

有了它,您可以重新排序参数,并创建新指令:

var il = method.Body.GetILProcessor();
var instruction = il.Create(OpCodes.Ldarg, aParameterDefinition);
il.InsertBefore(xxx, instruction);

完成后,您可以调用 , 的逆函数,SimplifyMacros()如果OptimizeMacros()可能,它将尝试将操作码优化为宏形式。

您必须注意的一件事是,实例方法的第一个参数,即隐含的“this”,method.Body.ThisParameter由您在方法的 .Parameters 集合中找不到的特殊参数表示。

于 2012-04-19T15:37:44.473 回答