Beispiel #1
0
    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);
 }
Beispiel #4
0
        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));
            }
        }
Beispiel #5
0
        /// <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;
 }
Beispiel #7
0
        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
            }
        }
Beispiel #8
0
 /// <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));
 }
Beispiel #14
0
        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);
        }
Beispiel #15
0
 public Boolean IsPredicated(Instruction instruction, ILProcessor ilProcessor) {
     try {
         return predicate(instruction, ilProcessor);
     }
     catch (Exception) {
         return false;
     }
 }
Beispiel #16
0
        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));
 }
Beispiel #18
0
        /// <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);
        }
Beispiel #19
0
		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);
		}
Beispiel #20
0
        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;
        }
Beispiel #21
0
 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;
 }
Beispiel #22
0
 public CecilILEmitter(
     AssemblyDefinition assemblyDefinition,
     ILProcessor ilProcessor,
     Action<Instruction> continuation
     )
 {
     _assemblyDefinitionField = assemblyDefinition;
     _ilProcessorField = ilProcessor;
     _continuationField = continuation;
 }
Beispiel #23
0
 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;
        }
Beispiel #25
0
 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].");
            }
        }
Beispiel #28
0
        /// <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 }
			);
		}
Beispiel #30
0
        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);
            }
Beispiel #34
0
        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;
            }
        }
Beispiel #35
0
        /// <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);
        }
Beispiel #36
0
        /// <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);
 }
Beispiel #38
0
        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);
        }
Beispiel #39
0
 protected abstract Instruction Visit(Mono.Cecil.Cil.ILProcessor ilProcessor, Mono.Cecil.Cil.Instruction instruction);