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;
 }
Ejemplo n.º 2
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
            }
        }
 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));
 }
 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;
 }
Ejemplo n.º 5
0
		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))));
		}
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 7
0
        private Instruction AddConditionGoto(ILProcessor ilp, Instruction last, Instruction stateMachineStarting)
        {
            var shouldRunSynchronouslyMethod = _engine.GetMethod<Func<ActorCore, bool>> (a => a.ShouldRunSynchronously ());

            var loadThis = ilp.Create (OpCodes.Ldarg_0);
            var loadField = ilp.Create (OpCodes.Ldfld, _actorMixin);
            var callMethod = ilp.Create (OpCodes.Call, shouldRunSynchronouslyMethod);
            var gotoNext = ilp.Create (OpCodes.Brtrue_S, stateMachineStarting);

            ilp.InsertAfter (last, loadThis);
            ilp.InsertAfter (loadThis, loadField);
            ilp.InsertAfter (loadField, callMethod);
            ilp.InsertAfter (callMethod, gotoNext);

            return gotoNext;
        }
Ejemplo n.º 8
0
		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))));
		}
        public MethodBodyPatcher(string methodName, MethodDefinition method)
        {
            _methodName = methodName;
            _methodBody = method.Body;
            _processor = _methodBody.GetILProcessor();

            _realBodyStart = _methodBody.Instructions.First();
            _realBodyEnd = _methodBody.Instructions.Last();

            _markStart1BeforeCreateArgumentsArray = _processor.Create(OpCodes.Nop);
            _markStart2BeforeCreateMethodExecutionArgs = _processor.Create(OpCodes.Nop);
            _markStart3BeforeOnEntryCall = _processor.Create(OpCodes.Nop);
            _markStart4BeforeRealBodyStartExceptionHandler = _processor.Create(OpCodes.Nop);
            _markEnd1NewRealBodyEnd = _processor.Create(OpCodes.Nop);
            _markEnd2BeforeOnExitCall = _processor.Create(OpCodes.Nop);
            _markRetNew = EndsWithThrow ? _processor.Create(OpCodes.Throw) : _processor.Create(OpCodes.Ret);
        }
Ejemplo n.º 10
0
            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);
            }
Ejemplo n.º 11
0
        public static Instruction ParseInstruction(ILProcessor processor, TypeDefinition type, XElement instrXML)
        {
            string fieldName = instrXML.Attribute("Field").Value;
            FieldDefinition field = type.Fields.FirstOrDefault(f => f.Name == fieldName);

            if (field == null)
            {
                Console.WriteLine("Couldn't find field named " + fieldName);
                return null;
            }

            return processor.Create(OpCodes.Ldfld, field);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Emits the instructions that call <see cref="IInitialize.Initialize"/> on a given service instance.
        /// </summary>
        /// <param name="il"></param>
        /// <param name="module">The host module.</param>
        /// <param name="serviceInstance">The local variable that points to the current service instance.</param>
        public void Initialize(ILProcessor il, ModuleDefinition module, VariableDefinition serviceInstance)
        {
            var body = il.Body;
            var method = body.Method;
            var declaringType = method.DeclaringType;

            var targetField = GetTargetField(declaringType);
            if (targetField == null)
                return;

            var initializeType = module.ImportType<IInitialize>();

            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);

            var initializeMethod = module.ImportMethod<IInitialize>("Initialize");
            var skipInitializationCall = il.Create(OpCodes.Nop);
            il.Emit(OpCodes.Brfalse, skipInitializationCall);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);

            var containsMethod = module.ImportMethod<Dictionary<int, int>>("ContainsKey");
            il.Emit(OpCodes.Callvirt, containsMethod);
            il.Emit(OpCodes.Brtrue, skipInitializationCall);

            // if (!__initializedServices.ContainsKey(currentService.GetHashCode()) {
            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);
            il.Emit(OpCodes.Ldarg_0);

            il.Emit(OpCodes.Callvirt, initializeMethod);

            // __initializedServices.Add(hashCode, 0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);
            il.Emit(OpCodes.Ldc_I4_1);

            var addMethod = module.ImportMethod<Dictionary<int, int>>("Add");
            il.Emit(OpCodes.Callvirt, addMethod);

            il.Append(skipInitializationCall);
        }
Ejemplo n.º 13
0
        public static Instruction ParseInstruction(ILProcessor processor, TypeDefinition type, XElement instrXML)
        {
            string assemblyName = instrXML.Attribute("Assembly").Value;
            string typeName = instrXML.Attribute("Type").Value;
            string methodName = instrXML.Attribute("Method").Value;

            // Get Assembly
            AssemblyDefinition assembly = Program.GetAssembly(assemblyName);

            if (assembly == null)
                return null;

            // Get Type
            TypeDefinition typeDefinition = assembly.MainModule.GetType(typeName);

            // Get Method
            MethodDefinition methodDefinition = typeDefinition.Methods.Single(m => m.Name == methodName);
            MethodReference methodReference =
                Program.GetAssembly("Assembly-CSharp").MainModule.Import(methodDefinition);

            // Generic Parameter Check
            if (instrXML.HasElements)
            {
                List<TypeReference> genericParameters = new List<TypeReference>();

                foreach (XElement genericParameter in instrXML.Elements("GenericParameter"))
                {
                    var gPAssemblyName = genericParameter.Attribute("Assembly").Value;
                    var gPType = genericParameter.Attribute("Type").Value;

                    AssemblyDefinition gPAssembly = Program.GetAssembly(gPAssemblyName);
                    TypeDefinition gPTypeDefinition = gPAssembly.MainModule.GetType(gPType);
                    TypeReference gPTypeReference =
                        Program.GetAssembly("Assembly-CSharp").MainModule.Import(gPTypeDefinition);

                    genericParameters.Add(gPTypeReference);
                }

                methodReference = methodReference.MakeGeneric(genericParameters.ToArray());
            }

            // Return Instruction
            return processor.Create(OpCodes.Call, methodReference);
        }
Ejemplo n.º 14
0
            protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action<ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode)
            {
                if (methodInfo.IsAbstract)
                {
                    CecilExtensions.CreateDefaultMethodImplementation(methodInfo, il);
                }
                else
                {
                    var targetNotNull = il.Create(OpCodes.Nop);
                    EmitProxyFromProceed(il);
                    il.Emit(OpCodes.Ldfld, target);              // Load "target" from "this"
                    il.Emit(OpCodes.Brtrue, targetNotNull);      // If target is not null, jump below

                    base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, _ => EmitProxyFromProceed(il), callBaseMethod, OpCodes.Call);

                    il.Append(targetNotNull);                    // Mark where the previous branch instruction should jump to                        
                
                    base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode);
                }
            }
Ejemplo n.º 15
0
        public static int ToNop(ILProcessor ilp, Instruction ins, bool sameSize)
        {
            if (ins == null) return 0;

            int size = ins.GetSize();
            ins.OpCode = OpCodes.Nop;
            ins.Operand = null;
            if (sameSize)
            {
                for (int i = 1; i < size; i++)
                {
                    Instruction newIns = ilp.Create(OpCodes.Nop);
                    ilp.InsertAfter(ins, newIns);
                }
            }
            else
            {
                size = 1;
            }
            return size;
        }
Ejemplo n.º 16
0
        public static void GetMethod(Instruction i, ILProcessor proc, ModuleDefinition baseModule)
        {
            if (i.Operand is FieldReference
                && ((FieldReference)i.Operand).FullName.Contains("Monocle.Sprite`1<System.Int32> TowerFall.AwardInfo/<>c__DisplayClass")
                && ((FieldReference)i.Operand).FullName.Contains("::sprite"))
            {
                Stored = Instruction.Create(OpCodes.Ldfld, i.Operand as FieldReference);
            }

            if (i.OpCode == OpCodes.Callvirt && i.Next.OpCode != OpCodes.Br_S
                && ((MethodReference)i.Operand).FullName == "System.Void Monocle.Sprite`1<System.Int32>::Add(T,System.Int32)")
            {
                TypeDefinition graphicsComponent = baseModule.GetType("Monocle.GraphicsComponent");
                 var fieldReference = graphicsComponent.Fields.Single(f => f.Name == "Zoom");
                var instr = Instruction.Create(OpCodes.Stfld, fieldReference);
                var ldinstr = Instruction.Create(i.Next.OpCode);
                proc.InsertAfter(i, instr);
                proc.InsertAfter(i, proc.Create(OpCodes.Ldc_R4, (float)0.7));
                proc.InsertAfter(i, Stored);
                proc.InsertAfter(i, ldinstr);
            }
        }
Ejemplo n.º 17
0
        public Instruction ParseInstruction(ILProcessor processor, TypeDefinition type, XmlNode instrXml)
        {
            Instruction instr = null;

            string nameOpCode = instrXml.Attributes["OpCode"].Value;

            if (nameOpCode == "Call")
            {
                string assemblyName = instrXml.Attributes["Assembly"].Value;
                string classToAddName = instrXml.Attributes["Class"].Value;
                string methodToAddName = instrXml.Attributes["Method"].Value;

                ModuleDefinition module = null;

                // We search in which assembly should we pull the method
                if (assemblyName == "CSharp-Assembly")
                {
                    module = this.CSharpAssembly.MainModule;
                }
                else if (assemblyName == "PhiScript")
                {
                    module = this.PhiAssembly.MainModule;
                }
                else
                {
                    // Error handling
                    Console.WriteLine("Couldn't find assembly named " + assemblyName);
                    return null;
                }

                TypeDefinition typeToAdd = module.Types.FirstOrDefault(t => t.Name == classToAddName);

                if (typeToAdd == null)
                {
                    Console.WriteLine("Couldn't find type/class named " + classToAddName);
                    return null;
                }

                MethodDefinition methodToAdd = typeToAdd.Methods.FirstOrDefault(m => m.Name == methodToAddName);

                if (methodToAdd == null)
                {
                    Console.WriteLine("Couldn't find method named " + methodToAddName);
                    return null;
                }

                MethodReference methodToAddImported = this.CSharpAssembly.MainModule.Import(methodToAdd);

                instr = processor.Create(OpCodes.Call, methodToAddImported);
            }
            else if (nameOpCode == "Ldc.I4")
            {
                int value = Int32.Parse(instrXml.Attributes["Value"].Value);
                instr = processor.Create(OpCodes.Ldc_I4, value);
            }
            else if (nameOpCode == "Ldfld")
            {
                string fieldName = instrXml.Attributes["Field"].Value;
                FieldDefinition field = type.Fields.FirstOrDefault(f => f.Name == fieldName);

                if (field == null)
                {
                    Console.WriteLine("Couldn't find field named " + field);
                }

                instr = processor.Create(OpCodes.Ldfld, field);
            }
            else if (nameOpCode == "Ldarg_0")
            {
                instr = processor.Create(OpCodes.Ldarg_0);
            }
            else
            {
                Console.WriteLine("Couldn't find OpCode named " + nameOpCode);
            }

            return instr;
        }
Ejemplo n.º 18
0
        static int EmitParameters(MethodDefinition method, MethodDefinition native, MethodBody body, ILProcessor il)
        {
            int i;
            for (i = 0; i < method.Parameters.Count; i++)
            {
                var parameter = method.Parameters[i];
                var p = method.Module.Import(method.Parameters[i].ParameterType);
                il.Emit(OpCodes.Ldarg, i);

                if (p.Name.Contains("Int32") && native.Parameters[i].ParameterType.Name.Contains("IntPtr"))
                {
                    // This is a convenience Int32 overload for an IntPtr (size_t) parameter.
                    // We need to convert the loaded argument to IntPtr.
                    il.Emit(OpCodes.Conv_I);
                }
                else if (p.Name == "StringBuilder")
                {
                    EmitStringBuilderParameter(method, parameter, body, il);
                }
                else if (p.Name == "String" && !p.IsArray)
                {
                    EmitStringParameter(method, parameter, body, il);
                }
                else if (p.IsByReference)
                {
                    body.Variables.Add(new VariableDefinition(new PinnedType(p)));
                    var index = body.Variables.Count - 1;
                    il.Emit(OpCodes.Stloc, index);
                    il.Emit(OpCodes.Ldloc, index);
                    il.Emit(OpCodes.Conv_I);
                }
                else if (p.IsArray)
                {
                    if (p.Name != method.Module.Import(typeof(string[])).Name)
                    {
                        // .Net treats 1d arrays differently than higher rank arrays.
                        // 1d arrays are directly supported by instructions such as ldlen and ldelema.
                        // Higher rank arrays must be accessed through System.Array methods such as get_Length.
                        // 1d array:
                        //    check array is not null
                        //    check ldlen array > 0
                        //    ldc.i4.0
                        //    ldelema
                        // 2d array:
                        //    check array is not null
                        //    check array.get_Length() > 0
                        //    ldc.i4.0
                        //    ldc.i4.0
                        //    call instance T& T[0..., 0...]::Address(int32, int32)
                        // Mono treats everything as a 1d array.
                        // Interestingly, the .Net approach works on both Mono and .Net.
                        // The Mono approach fails when using high-rank arrays on .Net.
                        // We should report a bug to http://bugzilla.xamarin.com

                        // Pin the array and pass the address
                        // of its first element.
                        var array = (ArrayType)p;
                        var element_type = p.GetElementType();
                        body.Variables.Add(new VariableDefinition(new PinnedType(new ByReferenceType(element_type))));
                        int pinned_index = body.Variables.Count - 1;

                        var empty = il.Create(OpCodes.Ldc_I4, 0);
                        var pin = il.Create(OpCodes.Ldarg, i);
                        var end = il.Create(OpCodes.Stloc, pinned_index);

                        // if (array == null) goto empty
                        il.Emit(OpCodes.Brfalse, empty);

                        // else if (array.Length != 0) goto pin
                        il.Emit(OpCodes.Ldarg, i);
                        if (array.Rank == 1)
                        {
                            il.Emit(OpCodes.Ldlen);
                            il.Emit(OpCodes.Conv_I4);
                        }
                        else
                        {
                            var get_length = method.Module.Import(
                                mscorlib.MainModule.GetType("System.Array").Methods.First(m => m.Name == "get_Length"));
                            il.Emit(OpCodes.Callvirt, get_length);
                        }
                        il.Emit(OpCodes.Brtrue, pin);

                        // empty: IntPtr ptr = IntPtr.Zero
                        il.Append(empty);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Br, end);

                        // pin: &array[0]
                        il.Append(pin);
                        if (array.Rank == 1)
                        {
                            // 1d array (vector), address is taken by ldelema
                            il.Emit(OpCodes.Ldc_I4, 0);
                            il.Emit(OpCodes.Ldelema, element_type);
                        }
                        else
                        {
                            // 2d-3d array, address must be taken as follows:
                            // call instance T& T[0..., 0..., 0...]::Address(int, int, int)
                            ByReferenceType t_ref = array.ElementType.MakeByReferenceType();
                            MethodReference get_address = new MethodReference("Address", t_ref, array);
                            for (int r = 0; r < array.Rank; r++)
                            {
                                get_address.Parameters.Add(new ParameterDefinition(TypeInt32));
                            }
                            get_address.HasThis = true;

                            // emit the get_address call
                            for (int r = 0; r < array.Rank; r++)
                            {
                                il.Emit(OpCodes.Ldc_I4, 0);
                            }
                            il.Emit(OpCodes.Call, get_address);
                        }

                        // end: fixed (IntPtr ptr = &array[0])
                        il.Append(end);
                        il.Emit(OpCodes.Ldloc, pinned_index);
                        il.Emit(OpCodes.Conv_I);
                    }
                    else
                    {
                        EmitStringArrayParameter(method, parameter, body, il);
                    }
                }
            }
            return i;
        }
Ejemplo n.º 19
0
        private int TrackMethodExit(MethodDefinition method, MethodReference target, XNodeOut node, ILProcessor processor, int pos)
        {
            // really annoying, we need to box value type that are returned by the target method to pass to xray exit method
            // if the return type is generic msil returns something like !0, but we can't box !0, we have to resolve it from the function declaration
            // hence all the code below

            var resolved = ResolveGenericMethod(target);
            var returnType = resolved.ReturnType;

            if (Build.TrackReturnValue && returnType.FullName != VoidRef.FullName)
            {
                // this is key, duplicate the head of the stack, and we'll pass this to the xray method exit function to be recorded
                AddInstruction(method, ++pos, processor.Create(OpCodes.Dup));

                // if it's a value type or generic param then box because method exit takes an object as a param
                if (returnType.IsValueType || returnType.IsGenericParameter)
                    AddInstruction(method, ++pos, processor.Create(OpCodes.Box, returnType));

                AddInstruction(method, ++pos, processor.Create(OpCodes.Ldc_I4, node.ID)); // push id
                AddInstruction(method, ++pos, processor.Create(OpCodes.Call, MethodExitWithValueRef)); // call exit with object and id
            }
            // else not tracking return value
            else
            {
                AddInstruction(method, ++pos, processor.Create(OpCodes.Ldc_I4, node.ID));
                AddInstruction(method, ++pos, processor.Create(OpCodes.Call, MethodExitRef));
            }

            return pos;
        }
Ejemplo n.º 20
0
        private void TrackMethodEnterParams(MethodDefinition method, int nodeId, ILProcessor processor, bool hasThis)
        {
            // add local variable for parameter array that gets passed to method enter
            method.Body.Variables.Add(new VariableDefinition(ObjectArrayRef));
            int varPos = method.Body.Variables.Count - 1;

            int pos = 0;
            int firstArg = 0;
            int paramCount = method.Parameters.Count;
            int paramPos = 0;

            if (hasThis)
            {
                firstArg = 1;
                paramCount--;
            }

            // create new object array with the same number of elements as there are arguments in function
            AddInstruction(method, pos++, processor.Create(OpCodes.Ldc_I4, paramCount));
            AddInstruction(method, pos++, processor.Create(OpCodes.Newarr, ObjectRef));

            // store array in local variable
            AddInstruction(method, pos++, processor.Create(OpCodes.Stloc, varPos)); // why doesnt cecil optimize this call?

            for (int i = firstArg; i < method.Parameters.Count; i++, paramPos++)
            {
                var paramType = method.Parameters[i].ParameterType;

                var argOffset = method.IsStatic ? 0 : 1;

                // put array, index, and arg on stack and push
                AddInstruction(method, pos++, processor.Create(OpCodes.Ldloc, varPos));
                AddInstruction(method, pos++, processor.Create(OpCodes.Ldc_I4, paramPos));
                AddInstruction(method, pos++, processor.Create(OpCodes.Ldarg, i + argOffset)); // index 0 is this, though for static may not be

                bool box = (paramType.IsValueType || paramType.IsGenericParameter);
                TypeReference boxType = paramType;

                // if reference type
                if (paramType is ByReferenceType)
                {
                    var refType = paramType as ByReferenceType;

                    // load value of what ref address on stack is pointing to
                    AddInstruction(method, pos++, processor.Create(OpCodes.Ldobj, refType.ElementType));

                    // if element type is value type, or generic (possible??? test this case) then box
                    box = (refType.ElementType.IsValueType || refType.ElementType.IsGenericParameter);
                    boxType = refType.ElementType;
                }

                // box value or generic types
                if (box)
                    AddInstruction(method, pos++, processor.Create(OpCodes.Box, boxType));

                // set element
                AddInstruction(method, pos++, processor.Create(OpCodes.Stelem_Ref));
            }

            // put object[], and node id on stack, and call MethodEnterWithParams
            AddInstruction(method, pos++, processor.Create(OpCodes.Ldloc, varPos));
            AddInstruction(method, pos++, processor.Create(OpCodes.Ldc_I4, nodeId));
            AddInstruction(method, pos++, processor.Create(OpCodes.Call, MethodEnterWithParamsRef));
        }
Ejemplo n.º 21
0
        private IEnumerable<Instruction> GetAttributeInstanceInstructions(
            ILProcessor processor,
            ICustomAttribute attribute,
            MethodDefinition method,
            VariableDefinition attributeVariableDefinition,
            VariableDefinition methodVariableDefinition)
        {
            var getMethodFromHandleRef = this._referenceFinder.GetMethodReference(typeof(MethodBase), md => md.Name == "GetMethodFromHandle" &&
                                                                                                            md.Parameters.Count == 2);

            var getTypeof = this._referenceFinder.GetMethodReference(typeof(Type), md => md.Name == "GetTypeFromHandle");
            var ctor = this._referenceFinder.GetMethodReference(typeof(Activator), md => md.Name == "CreateInstance" &&
                                                                                            md.Parameters.Count == 1);

            /*
                    // Code size       23 (0x17)
                      .maxstack  1
                      .locals init ([0] class SimpleTest.IntersectMethodsMarkedByAttribute i)
                      IL_0000:  nop
                      IL_0001:  ldtoken    SimpleTest.IntersectMethodsMarkedByAttribute
                      IL_0006:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
                      IL_000b:  call       object [mscorlib]System.Activator::CreateInstance(class [mscorlib]System.Type)
                      IL_0010:  castclass  SimpleTest.IntersectMethodsMarkedByAttribute
                      IL_0015:  stloc.0
                      IL_0016:  ret
            */

            return new List<Instruction>
                {
                    processor.Create(OpCodes.Nop),

                    processor.Create(OpCodes.Ldtoken, method),
                    processor.Create(OpCodes.Ldtoken, method.DeclaringType),
                    processor.Create(OpCodes.Call, getMethodFromHandleRef),          // Push method onto the stack, GetMethodFromHandle, result on stack
                    processor.Create(OpCodes.Stloc_S, methodVariableDefinition),     // Store method in __fody$method

                    processor.Create(OpCodes.Nop),

                    processor.Create(OpCodes.Ldtoken, attribute.AttributeType),
                    processor.Create(OpCodes.Call,getTypeof),
                    processor.Create(OpCodes.Call,ctor),
                    processor.Create(OpCodes.Castclass, attribute.AttributeType),
                    processor.Create(OpCodes.Stloc_S, attributeVariableDefinition),

                    /*

                     *
                    processor.Create(OpCodes.Ldloc_S, methodVariableDefinition),
                    processor.Create(OpCodes.Ldtoken, attribute.AttributeType),
                    processor.Create(OpCodes.Call, getTypeFromHandleRef),            // Push method + attribute onto the stack, GetTypeFromHandle, result on stack
                    processor.Create(OpCodes.Ldc_I4_0),
                    processor.Create(OpCodes.Callvirt, getCustomAttributesRef),      // Push false onto the stack (result still on stack), GetCustomAttributes
                    processor.Create(OpCodes.Ldc_I4_0),
                    processor.Create(OpCodes.Ldelem_Ref),                            // Get 0th index from result
                    processor.Create(OpCodes.Castclass, attribute.AttributeType),
                    processor.Create(OpCodes.Stloc_S, attributeVariableDefinition)   // Cast to attribute stor in __fody$attribute
                    */
                };
        }
Ejemplo n.º 22
0
 private static IList<Instruction> GetTryCatchLeaveInstructions(ILProcessor processor, Instruction methodBodyReturnInstruction)
 {
     return new[] { processor.Create(OpCodes.Leave_S, methodBodyReturnInstruction) };
 }
Ejemplo n.º 23
0
        private static IEnumerable<Instruction> GetTaskContinuationInstructions(ILProcessor processor, VariableDefinition retvalVariableDefinition, VariableDefinition attributeVariableDefinition, MethodReference taskContinuationMethodReference)
        {
            if (retvalVariableDefinition != null) {
                var tr = retvalVariableDefinition.VariableType;

                if (tr.FullName.Contains("System.Threading.Tasks.Task"))
                    return new[]
                    {
                    processor.Create(OpCodes.Ldloc_S, attributeVariableDefinition),
                    processor.Create(OpCodes.Ldloc_S, retvalVariableDefinition),
                    processor.Create(OpCodes.Callvirt, taskContinuationMethodReference),
                };
            }
            return new Instruction[0];
        }
Ejemplo n.º 24
0
 private static IList<Instruction> GetSaveRetvalInstructions(ILProcessor processor, VariableDefinition retvalVariableDefinition)
 {
     return retvalVariableDefinition == null || processor.Body.Instructions.All(i => i.OpCode != OpCodes.Ret) ?
         new Instruction[0] : new[] { processor.Create(OpCodes.Stloc_S, retvalVariableDefinition) };
 }
Ejemplo n.º 25
0
 private static IList<Instruction> GetMethodBodyReturnInstructions(ILProcessor processor, VariableDefinition retvalVariableDefinition)
 {
     var instructions = new List<Instruction>();
     if (retvalVariableDefinition != null)
         instructions.Add(processor.Create(OpCodes.Ldloc_S, retvalVariableDefinition));
     instructions.Add(processor.Create(OpCodes.Ret));
     return instructions;
 }
Ejemplo n.º 26
0
 private static List<Instruction> GetCatchHandlerInstructions(ILProcessor processor, VariableDefinition attributeVariableDefinition, VariableDefinition exceptionVariableDefinition, MethodReference onExceptionMethodRef)
 {
     // Store the exception in __fody$exception
     // Call __fody$attribute.OnExcetion("{methodName}", __fody$exception)
     // rethrow
     return new List<Instruction>
            {
                processor.Create(OpCodes.Stloc_S, exceptionVariableDefinition),
                processor.Create(OpCodes.Ldloc_S, attributeVariableDefinition),
                processor.Create(OpCodes.Ldloc_S, exceptionVariableDefinition),
                processor.Create(OpCodes.Callvirt, onExceptionMethodRef),
                processor.Create(OpCodes.Rethrow)
            };
 }
Ejemplo n.º 27
0
        private static void Emit(ILProcessor ip, ModuleDefinition mod, VariableDefinition arrayVar, VariableDefinition indexVar, Dictionary<int, Instruction> braces, OpValue[] ops, int i)
        {
            OpValue op = ops[i];
            switch (op.OpCode)
            {
                case BFOpCode.Increment:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Add);
                    ip.Emit(OpCodes.Stelem_I4);
                    break;

                case BFOpCode.Decrement:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Sub);
                    ip.Emit(OpCodes.Stelem_I4);
                    break;

                case BFOpCode.ShiftRight:
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Add);
                    ip.Emit(OpCodes.Stloc, indexVar);
                    break;

                case BFOpCode.ShiftLeft:
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Sub);
                    ip.Emit(OpCodes.Stloc, indexVar);
                    break;

                case BFOpCode.Output:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Conv_I1);
                    ip.Emit(OpCodes.Call, mod.Import(typeof(Console).GetMethod("Write", new[] { typeof(char) })));
                    break;

                case BFOpCode.Input:
                    ip.Emit(OpCodes.Call, mod.Import(typeof(Console).GetMethod("Read", new Type[0])));
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Conv_I1);
                    break;

                case BFOpCode.CondLeft:
                    var leftB = ip.Create(OpCodes.Ldloc, arrayVar);
                    var rightB = ip.Create(OpCodes.Nop);
                    ip.Append(leftB);
                    braces[i] = leftB;
                    braces[op.Data] = rightB;
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldelem_I4);
                    ip.Emit(OpCodes.Brfalse, rightB);
                    ip.Emit(OpCodes.Nop);
                    break;

                case BFOpCode.CondRight:
                    ip.Emit(OpCodes.Br, braces[op.Data]);
                    ip.Append(braces[i]);
                    break;

                case BFOpCode.Assign:
                    ip.Emit(OpCodes.Ldloc, arrayVar);
                    ip.Emit(OpCodes.Ldloc, indexVar);
                    ip.Emit(OpCodes.Ldc_I4, op.Data);
                    ip.Emit(OpCodes.Stelem_I4);
                    break;
            }
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Emits the instructions that will instantiate each property value and assign it to the target property.
        /// </summary>
        /// <param name="serviceMap">The service map that contains the application dependencies.</param>
        /// <param name="targetMethod">The target method.</param>
        /// <param name="module">The module that hosts the container type.</param>
        /// <param name="il">The <see cref="ILProcessor"/> that points to the target method body.</param>
        /// <param name="property">The target property.</param>
        /// <param name="curentDependency">The <see cref="IDependency"/> that describes the service instance that will be assigned to the target property.</param>
        private static void EmitPropertySetter(IDictionary<IDependency, IImplementation> serviceMap, MethodDefinition targetMethod, ModuleDefinition module, ILProcessor il, PropertyInfo property, IDependency curentDependency)
        {
            // Push the target onto the stack
            il.Emit(OpCodes.Dup);

            // Get the code that will instantiate the property value
            var propertyValueImplementation = serviceMap[curentDependency];
            propertyValueImplementation.Emit(curentDependency, serviceMap, targetMethod);

            // Call the setter
            var setterMethod = property.GetSetMethod();
            var setter = module.Import(setterMethod);

            var callInstruction = setterMethod.IsVirtual ? il.Create(OpCodes.Callvirt, setter) : il.Create(OpCodes.Call, setter);
            il.Append(callInstruction);
        }
Ejemplo n.º 29
0
 private static IEnumerable<Instruction> GetCallOnEntryInstructions(
     ILProcessor processor,
     VariableDefinition attributeVariableDefinition,
     MethodReference onEntryMethodRef)
 {
     // Call __fody$attribute.OnEntry()
     return new List<Instruction>
            {
                processor.Create(OpCodes.Ldloc, attributeVariableDefinition),
                processor.Create(OpCodes.Callvirt, onEntryMethodRef),
            };
 }
Ejemplo n.º 30
0
 public static Instruction ParseInstruction(ILProcessor processor, TypeDefinition type, XElement instrXML)
 {
     int value = int.Parse(instrXML.Attribute("Value").Value);
     return processor.Create(OpCodes.Ldloc_S, processor.Body.Variables[value]);
 }
Ejemplo n.º 31
0
 private static IList<Instruction> GetCallOnExitInstructions(ILProcessor processor, VariableDefinition attributeVariableDefinition, MethodReference onExitMethodRef)
 {
     // Call __fody$attribute.OnExit()
     return new List<Instruction>
            {
                processor.Create(OpCodes.Ldloc_S, attributeVariableDefinition),
                //processor.Create(OpCodes.Ldarg_0),
                processor.Create(OpCodes.Callvirt, onExitMethodRef)
            };
 }