void HandleOfParameter(Instruction instruction, ILProcessor ilProcessor) { //Info.OfMethod("AssemblyToProcess","MethodClass","InstanceMethod"); var methodNameInstruction = instruction.Previous; var methodName = GetLdString(methodNameInstruction); var typeNameInstruction = methodNameInstruction.Previous; var typeName = GetLdString(typeNameInstruction); var assemblyNameInstruction = typeNameInstruction.Previous; var assemblyName = GetLdString(assemblyNameInstruction); var typeDefinition = GetTypeDefinition(assemblyName, typeName); var methodDefinition = typeDefinition.Methods.FirstOrDefault(x => x.Name == methodName); if (methodDefinition == null) { throw new WeavingException($"Could not find method named '{methodName}'."); } var methodReference = ModuleDefinition.ImportReference(methodDefinition); ilProcessor.Remove(typeNameInstruction); assemblyNameInstruction.OpCode = OpCodes.Ldtoken; assemblyNameInstruction.Operand = methodReference; instruction.Operand = getMethodFromHandle; ilProcessor.InsertAfter(instruction,Instruction.Create(OpCodes.Castclass,methodInfoType)); }
public void ModifyCallScope(MethodDefinition renamedMethod, MethodDefinition interceptorMethod, ILProcessor il, MethodInterceptionScopeType interceptionScope) { if (interceptionScope == MethodInterceptionScopeType.Deep) { foreach (var module in Type.Assembly.Definition.Modules) { foreach (var type in module.Types.ToList()) { if (type.Methods == null || type.Methods.Count == 0) continue; foreach (var method in type.Methods.ToList()) { if (Context.Marker.HasMarker(method, Method.MethodMarker)) continue; if (method == null || method.Body == null || method.Body.Instructions == null || method.Body.Instructions.Count() == 0) continue; foreach (var instruction in method.Body.Instructions.ToList()) { if (instruction.OpCode == OpCodes.Call && instruction.Operand == renamedMethod) { var processor = method.Body.GetILProcessor(); processor.InsertAfter(instruction, il.Create(OpCodes.Call, interceptorMethod)); processor.Remove(instruction); } } } } } } }
public override void StoreStart(ILProcessor ilProcessor) { if (Previous.Type.Resolve().IsValueType) Previous.EmitAddress(ilProcessor); else Previous.Emit(ilProcessor); }
public override void Generate(ILProcessor processor) { // Load the arguments. foreach (VariableDefinition v in m_Parameters) { processor.Append(Instruction.Create(OpCodes.Ldloc, v)); } // Call the delegate. processor.Append(Instruction.Create(OpCodes.Call, this.m_Target)); // Handle the return type. if (this.m_ReturnType.FullName == this.m_Target.Module.Import(typeof(void)).FullName) { // Return value is void. Discard any result and return. processor.Append(Instruction.Create(OpCodes.Pop)); } else if (this.m_ReturnType.IsValueType || this.m_ReturnType.IsGenericParameter) { // Return value is value type (not reference). Unbox and return it. processor.Append(Instruction.Create(OpCodes.Unbox_Any, this.m_ReturnType)); processor.Append(Instruction.Create(OpCodes.Stloc, this.Result)); } else { // Return value is reference type. Cast it and return it. processor.Append(Instruction.Create(OpCodes.Isinst, this.m_ReturnType)); processor.Append(Instruction.Create(OpCodes.Stloc, this.Result)); } }
/// <summary> /// Need to do this so we retain pointer from original first instruction to new first instruction (nop) /// for dbg file to point to it so VS debugger will step into weaved methods /// </summary> /// <param name="ilProcessor"></param> /// <param name="firstInstruction"></param> /// <returns></returns> private static Instruction RejigFirstInstruction(ILProcessor ilProcessor, Instruction firstInstruction) { /* From: opcode operand <-- pdb first line pointer To: nop <-- pdb first line pointer opcode operand <-- cloned second acting as first */ // clone first instruction which will be used as actual var clonedSecond = CloneInstruction(firstInstruction); clonedSecond.Offset++; var sampleNop = ilProcessor.Create(OpCodes.Nop); // change actual first instruction to NOP firstInstruction.OpCode = sampleNop.OpCode; firstInstruction.Operand = sampleNop.Operand; // append second instruction which now is same as first one used to be at the start of this method // and actual first one is nop firstInstruction.Append(clonedSecond, ilProcessor); // return cloned second as new first instruction return clonedSecond; }
private Instruction EmitCodeInit(TypeReference role, Instruction instructionBeforeInit, ILProcessor il) { var current = instructionBeforeInit; current = InsertAfter(il, current, il.Create(OpCodes.Ldarg_0)); current = InsertAfter(il, current, il.Create(OpCodes.Call, ResolveInitReference(role))); return current; }
public void ModifyAssembly(string fileName) { MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); // ReaderParameters { ReadWrite = true } is necessary to later write the file using (ModuleDefinition module = ModuleDefinition.ReadModule(fileName, new ReaderParameters { ReadWrite = true })) { // Modify the assembly TypeDefinition[] types = module.Types.ToArray(); MethodReference methodReference = module.ImportReference(writeLineMethod); foreach (var type in types) { foreach (MethodDefinition methodToChange in type.Methods) { string sentence = String.Concat("Code added in ", methodToChange.Name); Mono.Cecil.Cil.ILProcessor ilProcessor = methodToChange.Body.GetILProcessor(); Mono.Cecil.Cil.Instruction loadStringInstruction = ilProcessor.Create(OpCodes.Ldstr, sentence); Mono.Cecil.Cil.Instruction callInstruction = ilProcessor.Create(OpCodes.Call, methodReference); Mono.Cecil.Cil.Instruction methodFirstInstruction = methodToChange.Body.Instructions[0]; ilProcessor.InsertBefore(methodFirstInstruction, loadStringInstruction); ilProcessor.InsertAfter(loadStringInstruction, callInstruction); } } module.Write(); // Write to the same file that was used to open the file } }
/// <summary> /// Inserts a group of instructions after the target instruction /// </summary> public static void InsertAfter(this Mono.Cecil.Cil.ILProcessor processor, Instruction target, IEnumerable <Instruction> instructions) { foreach (var instruction in instructions.Reverse()) { processor.InsertAfter(target, instruction); } }
/// <summary> /// Emits a call that obtains the hash code for the current service instance. /// </summary> /// <param name="il">The <see cref="ILProcessor"/> that points to the method body.</param> /// <param name="module">The target module.</param> /// <param name="serviceInstance">The local variable that contains the service instance.</param> private void GetServiceHash(ILProcessor il, ModuleDefinition module, VariableDefinition serviceInstance) { il.Emit(OpCodes.Ldloc, serviceInstance); var getHashCodeMethod = module.ImportMethod<object>("GetHashCode"); il.Emit(OpCodes.Callvirt, getHashCodeMethod); }
public Instruction InsertAfter(Instruction instruction, ILProcessor processor) { var currentInstruction = instruction; foreach (var newInstructionBlock in InstructionBlocks) currentInstruction = newInstructionBlock.InsertAfter(currentInstruction, processor); return currentInstruction; }
public AssemblyResolveUpdater(ModuleDefinition module) { _module = module; var type = _module.GetType("TheIndex", "Resolver"); _initMethod = type.Methods.Single(m => m.Name == "DictionaryInitialization"); _addResolveMethod = type.Methods.Single(m => m.Name == "Add"); _proc = _initMethod.Body.GetILProcessor(); }
public override void EmitAddress(ILProcessor ilProcessor) { if (Previous.Type.Resolve().IsValueType) Previous.EmitAddress(ilProcessor); else Previous.Emit(ilProcessor); ilProcessor.Emit(OpCodes.Ldflda, Field); }
static void InjectWriteIl(List<Instruction> writeTimeIl, ILProcessor ilProcessor, Instruction beforeThis) { foreach (var instruction in writeTimeIl) { ilProcessor.InsertBefore(beforeThis, instruction); } ilProcessor.InsertBefore(beforeThis, Instruction.Create(OpCodes.Endfinally)); }
private void CompileCil(ILProcessor body, IAstElement element, CilCompilationContext context) { var compiler = this.cilCompilers.SingleOrDefault(c => c.CanCompile(body, element)); if (compiler == null) throw new NotImplementedException("LightCompiler: No CilCompiler for " + element); compiler.Compile(body, element, context); }
public Boolean IsPredicated(Instruction instruction, ILProcessor ilProcessor) { try { return predicate(instruction, ilProcessor); } catch (Exception) { return false; } }
public MethodPatcher(PatcherObject prnt, MethodDefinition metDef) : base(prnt) { methodDefinition = metDef; IlProc = metDef.Body.GetILProcessor(); rootAssemblyPatcher = prnt.rootAssemblyPatcher; if (MainClass.gendiffs && MainClass.newAssCS) original = metDef.Print(); }
private void InterceptMethod(ILProcessor processor, TypeReference typeReference, Instruction instruction, string name) { var typeDefinition = typeReference.Resolve(); var attributeConstructor = typeDefinition.Methods.First(x => x.Name == ".ctor"); var attributeMethod = typeDefinition.Methods.First(x => x.Name == name); processor.InsertBefore(instruction, processor.Create(OpCodes.Newobj, attributeConstructor)); processor.InsertBefore(instruction, processor.Create(OpCodes.Call, _getCurrentMethod)); processor.InsertBefore(instruction, processor.Create(OpCodes.Call, attributeMethod)); }
/// <summary> /// Emits the instructions that will obtain the <see cref="IMicroContainer"/> instance. /// </summary> /// <param name="module">The target module.</param> /// <param name="microContainerType">The type reference that points to the <see cref="IMicroContainer"/> type.</param> /// <param name="worker">The <see cref="CilWorker"/> that points to the <see cref="IMicroContainer.GetInstance"/> method body.</param> /// <param name="skipCreate">The skip label that will be used if the service cannot be instantiated.</param> protected override void EmitGetContainerInstance(ModuleDefinition module, TypeReference microContainerType, ILProcessor il, Instruction skipCreate) { var getNextContainer = module.ImportMethod<IMicroContainer>("get_NextContainer"); EmitGetNextContainerCall(il, microContainerType, getNextContainer); il.Emit(OpCodes.Brfalse, skipCreate); // var result = NextContainer.GeService(serviceType, serviceName); EmitGetNextContainerCall(il, microContainerType, getNextContainer); }
private static void TestSequence1(ILProcessor il) { TypeReference type = new TypeReference("", "Test", null, null); FieldDefinition blank = new FieldDefinition("Test", FieldAttributes.Public, type); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldsfld, blank); il.Emit(OpCodes.Stsfld, blank); il.Emit(OpCodes.Ret); }
public static void EmitCreateDelegateToLocalMethod(ModuleDefinition module, ILProcessor worker, TypeDefinition declaringType, MethodDefinition source, out VariableDefinition dlg, out MethodDefinition ctor, out MethodDefinition invok) { // Define some variables var body = worker.Body; var method = body.Method; var newdlg = new VariableDefinition(module.Import(typeof(Delegate))); body.Variables.Add(newdlg); var multiDelegateType = module.Import(typeof(MulticastDelegate)); var voidType = module.Import(typeof(void)); var objectType = module.Import(typeof(object)); var nativeIntType = module.Import(typeof(IntPtr)); var asyncCallbackType = module.Import(typeof(AsyncCallback)); var asyncResultType = module.Import(typeof(IAsyncResult)); // Create new delegate type var dlgtype = new TypeDefinition(declaringType.Namespace, method.Name + "_Delegate" + declaringType.NestedTypes.Count, TypeAttributes.Sealed | TypeAttributes.NestedAssembly | TypeAttributes.RTSpecialName, multiDelegateType); declaringType.NestedTypes.Add(dlgtype); dlgtype.IsRuntimeSpecialName = true; var constructor = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.CompilerControlled | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig, voidType); dlgtype.Methods.Add(constructor); constructor.Parameters.Add(new ParameterDefinition("object", ParameterAttributes.None, objectType)); constructor.Parameters.Add(new ParameterDefinition("method", ParameterAttributes.None, nativeIntType)); constructor.IsRuntime = true; var begininvoke = new MethodDefinition("BeginInvoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, asyncResultType); dlgtype.Methods.Add(begininvoke); foreach (var para in source.Parameters) { begininvoke.Parameters.Add(new ParameterDefinition(para.Name, para.Attributes, para.ParameterType)); } begininvoke.Parameters.Add(new ParameterDefinition("callback", ParameterAttributes.None, asyncCallbackType)); begininvoke.Parameters.Add(new ParameterDefinition("object", ParameterAttributes.None, objectType)); begininvoke.IsRuntime = true; var endinvoke = new MethodDefinition("EndInvoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, voidType); dlgtype.Methods.Add(endinvoke); endinvoke.Parameters.Add(new ParameterDefinition("result", ParameterAttributes.None, asyncResultType)); endinvoke.IsRuntime = true; endinvoke.ReturnType = source.ReturnType; var invoke = new MethodDefinition("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, voidType); dlgtype.Methods.Add(invoke); foreach (var para in source.Parameters) { invoke.Parameters.Add(new ParameterDefinition(para.Name, para.Attributes, para.ParameterType)); } invoke.IsRuntime = true; invoke.ReturnType = source.ReturnType; ctor = constructor; dlg = newdlg; invok = invoke; }
public RewriteContext(Configuration configuration, ILProcessor processor, Instruction originalInstruction, List<IRewriteTarget> targets, MethodReference method) { Variables = new List<VariableDefinition>(); Configuration = configuration; Processor = processor; OriginalInstruction = originalInstruction; Targets = targets; Method = method; }
public CecilILEmitter( AssemblyDefinition assemblyDefinition, ILProcessor ilProcessor, Action<Instruction> continuation ) { _assemblyDefinitionField = assemblyDefinition; _ilProcessorField = ilProcessor; _continuationField = continuation; }
public override void Generate(ILProcessor processor) { // Now add the IL that creates the delegate. processor.Append(Instruction.Create(OpCodes.Nop)); processor.Append(Instruction.Create(OpCodes.Ldarg_0)); processor.Append(Instruction.Create(OpCodes.Ldftn, this.m_Target)); //processor.Append(Instruction.Create(OpCodes.Ldnull)); processor.Append(Instruction.Create(OpCodes.Newobj, this.m_Constructor)); processor.Append(Instruction.Create(OpCodes.Stloc, this.m_Storage)); }
protected InstructionBuilderBase(ILProcessor processor) { if (processor == null) { Globals.Loggers.File.Error("[InstructionBuilders].[InstructionBuilderBase] is throwing exception ([processor] == [null])."); throw new ArgumentNullException("processor"); } Processor = processor; }
protected MethodDefinition CreateAPIDummy(out ILProcessor ilProc, string apitoken, string[] man) { CustomAttribute defRemoveWatchdog = new CustomAttribute(TypesystemSprakApiArgument) { ConstructorArguments = { GetSprakDocs(man) }//new CustomAttributeArgument[] { new CustomAttributeArgument(_target.Module.TypeSystem.String,"well") }) }; MethodDefinition methodDef = new MethodDefinition("API_" + apitoken, MethodAttributes.Public, TypesystemVoid); methodDef.CustomAttributes.Add(defRemoveWatchdog); ilProc = methodDef.Body.GetILProcessor(); return methodDef; }
public Instruction InsertAfter(Instruction instruction, ILProcessor processor) { var currentInstruction = instruction; foreach (var newInstruction in Instructions) { processor.InsertAfter(currentInstruction, newInstruction); currentInstruction = newInstruction; } return currentInstruction; }
public MethodAttributeBase(ILProcessor processor, CustomAttribute attribute) : base(processor, attribute) { var baseTypeDef = TypeDefinition.Module.Types.FirstOrDefault(t => t.FullName == Globals.TypeReferences.MethodAttributeBase.FullName); if (baseTypeDef == null || !TypeDefinition.IsInheritorOf(baseTypeDef)) { Globals.Loggers.File.Error("[InstructionBuilders].[MethodAttributeBase] is throwing exception (![TypeDefinition].[IsInheritorOf(baseTypeDefinition)])."); throw new ArgumentException("[attribute] is not inheritor of [MethodAttributeBase]."); } }
/// <summary> /// Emit a reference to an arbitrary object. Note that the references "leak." /// </summary> public static int EmitGetReference <T>(this CIL.ILProcessor il, int id) { Type t = typeof(T); il.Emit(CIL.OpCodes.Ldc_I4, id); il.Emit(CIL.OpCodes.Call, _GetReference); if (t.GetTypeInfo().IsValueType) { il.Emit(CIL.OpCodes.Unbox_Any, t); } return(id); }
void InjectNewWriter(MethodDefinition sendData, ILProcessor processor, out VariableDefinition mswriter, out OpCode binaryWriter) { var buffer = sendData.Body.Instructions.First( x => x.OpCode == OpCodes.Ldsfld && (x.Operand as FieldReference).Name == "buffer" ); while (!(buffer.Next.OpCode == OpCodes.Callvirt && (buffer.Next.Operand as MethodReference).Name == "set_Position")) { processor.Remove(buffer.Next); } processor.Remove(buffer.Next); //processor.Remove(buffer); //VariableDefinition mswriter; sendData.Body.Variables.Add(mswriter = new VariableDefinition("mswriter", this.SourceDefinition.MainModule.Import(typeof(MemoryStream)) )); var res = processor.InsertBefore(buffer.Previous.Previous, new { OpCodes.Newobj, Operand = this.SourceDefinition.MainModule.Import(typeof(MemoryStream) .GetConstructors() .Single(x => x.GetParameters().Count() == 0) ) }, new { OpCodes.Stloc, Operand = mswriter }, new { OpCodes.Ldloc, Operand = mswriter } ); buffer.Previous.Previous.ReplaceTransfer(res[0], sendData); processor.Remove(buffer.Previous); processor.Remove(buffer.Previous); buffer.OpCode = OpCodes.Newobj; buffer.Operand = this.SourceDefinition.MainModule.Import(typeof(BinaryWriter) .GetConstructors() .Single(x => x.GetParameters().Count() == 1) ); if (buffer.Next.OpCode != OpCodes.Ldloc_1) { throw new NotSupportedException("Expected Ldloc_1"); } /*var*/ binaryWriter = buffer.Next.OpCode; processor.InsertAfter(buffer, new { OpCodes.Stloc_1 } ); }
protected Type(ILProcessor processor, TypeDefinition definition) : base(processor) { if (definition == null) { Globals.Loggers.File.Error("[InstructionBuilders].[Type] is throwing exception ([definition] == [null])."); throw new ArgumentNullException("definition"); } TypeDefinition = definition; SystemType = definition.GetSystemType(); }
/// <summary> /// Emit a reference to an arbitrary object. Note that the references "leak." /// </summary> public static int EmitGetReference <T>(this CIL.ILProcessor il, int id) { ModuleDefinition ilModule = il.Body.Method.Module; Type t = typeof(T); il.Emit(CIL.OpCodes.Ldc_I4, id); il.Emit(CIL.OpCodes.Call, ilModule.ImportReference(_GetReference)); if (t.IsValueType) { il.Emit(CIL.OpCodes.Unbox_Any, ilModule.ImportReference(t)); } return(id); }
private Instruction EmitStateClassCreation(TypeReference role, Instruction instructionBeforeCreation, ILProcessor il) { var current = instructionBeforeCreation; var stateClassFieldReference = ResolveStateClassField(role); // don't emit this code if the state field and property was not implemented // TODO: this needs to be checked before, possibly at the conflict resolution stage if (stateClassFieldReference != null) { current = InsertAfter(il, current, il.Create(OpCodes.Ldarg_0)); current = InsertAfter(il, current, il.Create(OpCodes.Newobj, role.ResolveStateClassCtor())); current = InsertAfter(il, current, il.Create(OpCodes.Stfld, stateClassFieldReference)); } return current; }
protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action<ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode) { // If T is an interface, then we want to check if target is null; if so, we want to just return the default value var targetNotNull = il.Create(OpCodes.Nop); EmitProxyFromProceed(il); il.Emit(OpCodes.Ldfld, ClassWeaver.Target); // Load "target" from "this" il.Emit(OpCodes.Brtrue, targetNotNull); // If target is not null, jump below CecilExtensions.CreateDefaultMethodImplementation(methodBody.Method, il); il.Append(targetNotNull); // Mark where the previous branch instruction should jump to base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode); }
public static void RemoveInstructions(ILProcessor p, Instruction first, int count) { var cur = first; for (int i = 0; i < count; i++) { if (cur == null) break; var n = cur.Next; p.Remove(cur); cur = n; } }
/// <summary> /// Inserts a list of anonymous instructions after the target instruction /// </summary> public static List <Instruction> InsertAfter(this Mono.Cecil.Cil.ILProcessor processor, Instruction target, params object[] instructions) { var created = new List <Instruction>(); foreach (var anon in instructions.Reverse()) { var ins = AnonymousToInstruction(anon); processor.InsertAfter(target, ins); created.Add(ins); } return(created); }
/// <summary> /// Inserts a list of anonymous instructions before the target instruction /// </summary> public static List <Instruction> InsertBefore(this Mono.Cecil.Cil.ILProcessor processor, Instruction target, params object[] instructions) { var created = new List <Instruction>(); foreach (var anon in instructions) { foreach (var ins in ParseAnonymousInstruction(anon)) { processor.InsertBefore(target, ins); created.Add(ins); } } return(created); }
/// <summary> /// Fill the DynamicMethod with a stub. /// </summary> public static DynamicMethodDefinition Stub(this DynamicMethodDefinition dmd) { CIL.ILProcessor il = dmd.GetILProcessor(); for (int i = 0; i < 32; i++) { // Prevent mono from inlining the DynamicMethod. il.Emit(CIL.OpCodes.Nop); } if (dmd.Definition.ReturnType != dmd.Definition.Module.TypeSystem.Void) { il.Body.Variables.Add(new CIL.VariableDefinition(dmd.Definition.ReturnType)); il.Emit(CIL.OpCodes.Ldloca_S, (sbyte)0); il.Emit(CIL.OpCodes.Initobj, dmd.Definition.ReturnType); il.Emit(CIL.OpCodes.Ldloc_0); } il.Emit(CIL.OpCodes.Ret); return(dmd); }
internal static void EncapsulateMethodBodyWithTryFinallyBlock(this ILProcessor ilProcessor, Instruction firstInstruction, Action <ILProcessor, Instruction> insertBeforReturn) { var body = ilProcessor.Body; if (body.Method.IsConstructor && !body.Method.IsStatic) { var ctor = GetFirstConstructorInstruction(body); if (ctor != null) { if (body.Instructions.IndexOf(ctor) > 2) { var lastInstruction = body.Instructions.Last(); var firtLDarg0BeforeCtor = ctor.GetFirstPreviousLdarg_0(); if (firstInstruction != firtLDarg0BeforeCtor) { EncapsulateWithTryCatch(ilProcessor, firstInstruction, firtLDarg0BeforeCtor); } if (ctor.GetFirstNotNopInstruction().Equals(lastInstruction)) { insertBeforReturn(ilProcessor, lastInstruction); return; } } if (firstInstruction.Next.OpCode != OpCodes.Nop) { firstInstruction = Instruction.Create(OpCodes.Nop); ilProcessor.InsertAfter(ctor, firstInstruction); } } } var returnStart = ilProcessor.FixReturns(); var beforeReturn = Instruction.Create(OpCodes.Endfinally); ilProcessor.InsertBefore(returnStart, beforeReturn); if (body.Instructions.First().Equals(firstInstruction)) { Instruction tryStart = Instruction.Create(OpCodes.Nop); ilProcessor.InsertBefore(firstInstruction, tryStart); } Instruction finallyStart = Instruction.Create(OpCodes.Nop); ilProcessor.InsertBefore(beforeReturn, finallyStart); insertBeforReturn(ilProcessor, beforeReturn); var handler = new ExceptionHandler(ExceptionHandlerType.Finally) { TryStart = firstInstruction, TryEnd = finallyStart, HandlerStart = finallyStart, HandlerEnd = returnStart, }; body.ExceptionHandlers.Add(handler); }
protected abstract Instruction Visit(Mono.Cecil.Cil.ILProcessor ilProcessor, Mono.Cecil.Cil.Instruction instruction);