public void Rewriter(ILProcessor processor) { var constraineds = processor.Instructions .OfType <OperandInstruction <Type> >() .Where(i => i.OpCode == OpCodes.Constrained) .ToList(); foreach (var constrained in constraineds) { var constrainedType = constrained.Operand; var methodCall = (OperandInstruction <MethodBase>)constrained.Next; //Remove the Constrained Instruction processor.Remove(constrained); //Check for a quick fix if (constrainedType.IsValueType) { //Check if the value type directly implements the method or not var realMethod = StubGenerator.GetRuntimeMethodForVirtual(constrainedType, (MethodInfo)methodCall.Operand); if (realMethod.DeclaringType == constrainedType) { //the method is directly implemented, just replace the CallVirt with a normal Call processor.Replace(methodCall, OperandInstruction.Create <MethodBase>(OpCodes.Call, realMethod)); //For this case we are done! continue; } } //Find were the this pointer is pushed on the stack var thisInstruction = FindThisInstruction(methodCall); if (constrainedType.IsValueType) //the method is not directly implemented { //ldobj struct //box struct //call virt processor.InsertAfter(thisInstruction, new NoneInstruction(OpCodes.Box)); processor.InsertAfter(thisInstruction, new NoneInstruction(OpCodes.Ldobj)); } else //this is a reference type { //ldind_ref //call virt processor.InsertAfter(thisInstruction, new NoneInstruction(OpCodes.Ldind_Ref)); } } }
public void Rewriter(ILProcessor processor) { var branches = processor.Instructions .OfType <OperandInstruction <ILProcessorInstruction> >() .Where(i => OpCodesMap.ContainsKey(i.OpCode)) .ToList(); if (!branches.Any()) { return; } var offsets = new Dictionary <ILProcessorInstruction, int>(); var curOffset = 0; foreach (var instruction in processor.Instructions) { offsets.Add(instruction, curOffset); curOffset += GetInstructionSize(instruction); } while (branches.Any()) { var branch = branches.FirstOrDefault(i => { var deltaOffset = offsets[i.Operand] - offsets[i.Next]; return(deltaOffset >= sbyte.MinValue && deltaOffset <= sbyte.MaxValue); }); if (branch == null) { break; } var shortFormOpCode = OpCodesMap[branch.OpCode]; var shortBranch = OperandInstruction.Create(shortFormOpCode, branch.Operand); processor.Replace(branch, shortBranch); //Update offsets ILProcessorInstruction loop = shortBranch; curOffset = offsets[branch]; while (loop != null) { offsets[loop] = curOffset; curOffset += GetInstructionSize(loop); loop = loop.Next; } offsets.Remove(branch); branches.Remove(branch); } }
public void Rewriter(ILProcessor processor) { var branches = processor.Instructions .OfType <OperandInstruction <ILProcessorInstruction> >() .Where(i => OpCodesMap.ContainsKey(i.OpCode)) .ToList(); foreach (var instruction in branches) { var longFormOpCode = OpCodesMap[instruction.OpCode]; processor.Replace(instruction, OperandInstruction.Create(longFormOpCode, instruction.Operand)); } }