internal static Instruction FixReturns(this ILProcessor ilProcessor) { var methodDefinition = ilProcessor.Body.Method; if (methodDefinition.ReturnType == methodDefinition.Module.TypeSystem.Void) { var instructions = ilProcessor.Body.Instructions.ToArray(); var newReturnInstruction = ilProcessor.Create(OpCodes.Ret); ilProcessor.Append(newReturnInstruction); foreach (var instruction in instructions) { if (instruction.OpCode == OpCodes.Ret) { var leaveInstruction = ilProcessor.Create(OpCodes.Leave, newReturnInstruction); ilProcessor.Replace(instruction, leaveInstruction); ilProcessor.ReplaceInstructionReferences(instruction, leaveInstruction); } } return(newReturnInstruction); } else { var instructions = ilProcessor.Body.Instructions.ToArray(); var returnVariable = new VariableDefinition(methodDefinition.ReturnType); ilProcessor.Body.Variables.Add(returnVariable); var loadResultInstruction = ilProcessor.Create(OpCodes.Ldloc, returnVariable); ilProcessor.Append(loadResultInstruction); var newReturnInstruction = ilProcessor.Create(OpCodes.Ret); ilProcessor.Append(newReturnInstruction); foreach (var instruction in instructions) { if (instruction.OpCode == OpCodes.Ret) { var saveResultInstruction = ilProcessor.Create(OpCodes.Stloc, returnVariable); ilProcessor.Replace(instruction, saveResultInstruction); var leaveInstruction = ilProcessor.Create(OpCodes.Leave, loadResultInstruction); ilProcessor.InsertAfter(saveResultInstruction, leaveInstruction); ilProcessor.ReplaceInstructionReferences(instruction, leaveInstruction); } } return(loadResultInstruction); } }
internal static void RemoveTailInstructions(this ILProcessor ilProcessor) { foreach (var instruction in ilProcessor.Body.Instructions.ToArray()) { if (instruction.OpCode == OpCodes.Tail) { var noOpInstruction = ilProcessor.Create(OpCodes.Nop); ilProcessor.Replace(instruction, noOpInstruction); ReplaceInstructionReferences(ilProcessor, instruction, noOpInstruction); } } }
private void ProcessCachedStaticFieldPattern(ILProcessor il, Instruction queryInvocation) { MethodReference predicateMethod = GetMethodReferenceFromStaticFieldPattern(queryInvocation); il.InsertBefore(queryInvocation, il.Create(OpCodes.Ldtoken, predicateMethod)); // At this point the stack is like this: // runtime method handle, delegate reference, ObjectContainer il.Replace(queryInvocation, il.Create(OpCodes.Call, InstantiateGenericMethod( _NativeQueryHandler_ExecuteInstrumentedStaticDelegateQuery, GetQueryCallExtent(queryInvocation)))); }
private void ProcessPredicateCreationPattern(ILProcessor il, Instruction queryInvocation) { MethodReference predicateMethod = GetMethodReferenceFromInlinePredicatePattern(queryInvocation); Instruction ldftn = GetNthPrevious(queryInvocation, 2); il.InsertBefore(ldftn, il.Create(OpCodes.Dup)); il.InsertBefore(queryInvocation, il.Create(OpCodes.Ldtoken, predicateMethod)); // At this point the stack is like this: // runtime method handle, delegate reference, target object, ObjectContainer il.Replace(queryInvocation, il.Create(OpCodes.Call, InstantiateGenericMethod( _NativeQueryHandler_ExecuteInstrumentedDelegateQuery, GetQueryCallExtent(queryInvocation)))); }
private void ReplaceFixedArrayStatement(MethodDefinition method, ILProcessor ilProcessor, Instruction fixedtoPatch) { var paramT = ((GenericInstanceMethod)fixedtoPatch.Operand).GenericArguments[0]; // Preparing locals // local(0) T* method.Body.Variables.Add(new VariableDefinition("pin", new PinnedType(new ByReferenceType(paramT)))); int index = method.Body.Variables.Count - 1; Instruction ldlocFixed; Instruction stlocFixed; switch (index) { case 0: stlocFixed = ilProcessor.Create(OpCodes.Stloc_0); ldlocFixed = ilProcessor.Create(OpCodes.Ldloc_0); break; case 1: stlocFixed = ilProcessor.Create(OpCodes.Stloc_1); ldlocFixed = ilProcessor.Create(OpCodes.Ldloc_1); break; case 2: stlocFixed = ilProcessor.Create(OpCodes.Stloc_2); ldlocFixed = ilProcessor.Create(OpCodes.Ldloc_2); break; case 3: stlocFixed = ilProcessor.Create(OpCodes.Stloc_3); ldlocFixed = ilProcessor.Create(OpCodes.Ldloc_3); break; default: stlocFixed = ilProcessor.Create(OpCodes.Stloc, index); ldlocFixed = ilProcessor.Create(OpCodes.Ldloc, index); break; } var instructionLdci40 = ilProcessor.Create(OpCodes.Ldc_I4_0); ilProcessor.InsertBefore(fixedtoPatch, instructionLdci40); var instructionLdElema = ilProcessor.Create(OpCodes.Ldelema, paramT); ilProcessor.InsertBefore(fixedtoPatch, instructionLdElema); ilProcessor.InsertBefore(fixedtoPatch, stlocFixed); ilProcessor.Replace(fixedtoPatch, ldlocFixed); }
private void ReplaceSizeOfStructGeneric(MethodDefinition method, ILProcessor ilProcessor, Instruction fixedtoPatch) { var paramT = ((GenericInstanceMethod)fixedtoPatch.Operand).GenericArguments[0]; var copyInstruction = ilProcessor.Create(OpCodes.Sizeof, paramT); ilProcessor.Replace(fixedtoPatch, copyInstruction); }
private void ReplaceIncrementPinnedStructGeneric(MethodDefinition method, ILProcessor ilProcessor, Instruction incrementPinnedToPatch) { var paramT = ((GenericInstanceMethod)incrementPinnedToPatch.Operand).GenericArguments[0]; var sizeOfInst = ilProcessor.Create(OpCodes.Sizeof, paramT); ilProcessor.Replace(incrementPinnedToPatch, sizeOfInst); ilProcessor.InsertAfter(sizeOfInst, ilProcessor.Create(OpCodes.Add)); }
private static void ReplaceWriteInline(MethodReference methodDescr, ILProcessor ilGen, Instruction instructionToPatch) { TypeReference paramT = ((GenericInstanceMethod) instructionToPatch.Operand).GenericArguments[0]; Instruction newInstruction = ilGen.Create(OpCodes.Cpobj, paramT); ilGen.Replace(instructionToPatch, newInstruction); }
private void ReplaceBranchesWithLeaves(ILProcessor il, ExceptionHandler handler) { var current = handler.TryStart; while (current != handler.TryEnd) { var next = current.Next; if (current.OpCode == OpCodes.Br && ((Instruction)current.Operand).Offset > handler.TryEnd.Offset) il.Replace(current, il.Create(OpCodes.Leave, (Instruction)current.Operand)); current = next; } }