/// <summary>
        /// Aspect method to use for method call substition
        /// </summary>
        /// <param name="typeBuilder"></param>
        /// <param name="il"></param>
        /// <param name="method"></param>
        /// <param name="replaceMethod">Replace Method</param>
        /// <returns></returns>
        internal bool MethodCall(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.MethodDefinition method, Mono.Cecil.MethodDefinition replaceMethod)
        {
            if (!replaceMethod.IsStatic)
            {
                return(false);
            }

            var        attrs = method.GetCustomAttributes <StaticMethodReplacerAttribute>();
            MethodInfo meth  = null;

            foreach (var attr in attrs)
            {
                var staticType = attr.staticMethodType;
                var smeth      = staticType.GetMethod(replaceMethod.Name, BindingFlags.Static | BindingFlags.Public);

                if (smeth != null)
                {
                    meth = smeth;
                }
            }

            if (meth == null)
            {
                return(false);
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Call, meth);

            return(true);
        }
Example #2
0
 public CodegenEmitter(
     Mono.Cecil.Cil.ILProcessor processor,
     RegisterAllocation <CilCodegenRegister> registerAllocation)
 {
     this.Processor           = processor;
     this.RegisterAllocation  = registerAllocation;
     this.branchTargets       = new Dictionary <BasicBlockTag, CilInstruction>();
     this.pendingTargets      = new List <BasicBlockTag>();
     this.patches             = new List <CilOpInstruction>();
     this.registerUseCounters = new Dictionary <Mono.Cecil.Cil.VariableDefinition, int>();
 }
Example #3
0
 public BytecodeTranslator(AnalysisNet.Types.MethodDefinition methodDefinition,
                           IDictionary <AnalysisNetTac.Values.IVariable, Cecil.Cil.VariableDefinition> variableDefinitions,
                           IDictionary <AnalysisNetTac.Values.IVariable, Cecil.ParameterDefinition> parameterDefinitions,
                           ReferenceGenerator referenceGenerator,
                           Cecil.Cil.ILProcessor processor)
 {
     this.methodDefinition     = methodDefinition;
     this.processor            = processor;
     this.variableDefinitions  = variableDefinitions;
     this.parameterDefinitions = parameterDefinitions;
     this.referenceGenerator   = referenceGenerator;
 }
Example #4
0
        /// <summary>
        /// Weave field into current aspect
        /// </summary>
        /// <param name="il">IL Generator</param>
        /// <param name="field">Field</param>
        /// <param name="fieldMethod">Field Method</param>
        private void BlockField(Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.FieldDefinition field, MethodInfo fieldMethod)
        {
            var fieldName = field.Name;

            // Return if it is a backing field
            if (fieldName.IndexOf("k__BackingField") >= 0)
            {
                return;
            }

            var aspect = field.GetCustomAttribute <MemberInterceptionAspect>() ?? field.DeclaringType.GetCustomAttribute <MemberInterceptionAspect>()
                         ?? field.DeclaringType.Module.Assembly.GetCustomAttribute <MemberInterceptionAspect>();

            if (!ILWeaver.IsValidAspectFor(field, aspect))
            {
                return;
            }

            var fieldType   = field.FieldType;
            var isStatic    = field.IsStatic;
            var fieldLocal  = il.DeclareLocal(fieldType);
            var memberLocal = il.DeclareLocal(typeof(MemberContext));
            var aspectField = ILWeaver.TypeFieldAspects[field.DeclaringType.FullName][aspect.GetType().FullName];

            // Store current get field value
            il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, fieldLocal);

            // MemberContext(object instance, string locationName, object value)
            il.Emit(isStatic ? Mono.Cecil.Cil.OpCodes.Ldnull : Mono.Cecil.Cil.OpCodes.Ldarg_0);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldstr, fieldName);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, fieldLocal);

            if (fieldType.IsValueType)
            {
                il.Emit(Mono.Cecil.Cil.OpCodes.Box, fieldType);
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, MemberContextCtor);
            il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, memberLocal);

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldsfld, aspectField);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, memberLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Callvirt, fieldMethod);

            // Load value back to stack and reflect changes if any
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, memberLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Callvirt, MemberContextValueMethod);

            // Convert to expected type
            il.Emit(fieldType.IsValueType ? Mono.Cecil.Cil.OpCodes.Unbox_Any : Mono.Cecil.Cil.OpCodes.Isinst, fieldType);
        }
Example #5
0
        /// <summary>
        /// Aspect method to use for method call substition
        /// </summary>
        /// <param name="typeBuilder"></param>
        /// <param name="il"></param>
        /// <param name="method"></param>
        /// <param name="replaceMethod">Replace Method</param>
        /// <returns></returns>
        internal bool MethodCall(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.MethodDefinition method, Mono.Cecil.MethodDefinition replaceMethod)
        {
            var methodName    = method.Name.Replace("~", string.Empty);
            var isRecursive   = methodName == replaceMethod.Name;
            var declaringType = replaceMethod.DeclaringType;
            var methodCall    = replaceMethod;

            if (isRecursive)
            {
                methodCall = typeBuilder.GetMethodEx(methodCall.Name, methodCall.ReturnType, methodCall.Parameters.Select(x => x.ParameterType).ToArray());
                il.Emit(Mono.Cecil.Cil.OpCodes.Tail);
            }

            il.Emit(declaringType.IsValueType || replaceMethod.IsStatic || methodCall.ReturnType.IsValueType ? Mono.Cecil.Cil.OpCodes.Call : Mono.Cecil.Cil.OpCodes.Callvirt,
                    methodCall);

            il.Emit(Mono.Cecil.Cil.OpCodes.Ret);

            return(true);
        }
Example #6
0
        public IDictionary <Model.Bytecode.Instruction, IList <Mono.Cecil.Cil.Instruction> > CreateInstructions(Model.Types.MethodDefinition methodDefinition,
                                                                                                                Mono.Cecil.MethodDefinition methodDef,
                                                                                                                IDictionary <AnalysisNet.ThreeAddressCode.Values.IVariable, Cecil.Cil.VariableDefinition> variableDefinitions,
                                                                                                                IDictionary <AnalysisNet.ThreeAddressCode.Values.IVariable, Cecil.ParameterDefinition> parameterDefinitions)
        {
            Cecil.Cil.ILProcessor ilProcessor = methodDef.Body.GetILProcessor();
            BytecodeTranslator    translator  = new BytecodeTranslator(methodDefinition, variableDefinitions, parameterDefinitions, ReferenceGenerator, ilProcessor);

            // analysis net instruction -> [cecil instructions]
            IDictionary <AnalysisNet.Bytecode.Instruction, IList <Cecil.Cil.Instruction> > mappingTranslatedInstructions = translator.Translate();

            IEnumerable <Cecil.Cil.Instruction> instructions = mappingTranslatedInstructions.Values.SelectMany(l => l);

            foreach (Mono.Cecil.Cil.Instruction ins in instructions)
            {
                ilProcessor.Append(ins);
            }

            return(mappingTranslatedInstructions);
        }
 public Mono.Cecil.Cil.Instruction CreateInstruction(Mono.Cecil.Cil.ILProcessor worker, Mono.Cecil.Cil.OpCode opcode)
 {
     throw new NotImplementedException();
 }
Example #8
0
 /// <summary>
 /// Aspect code to inject at the beginning of weaved method
 /// </summary>
 /// <param name="typeBuilder">Type Builder</param>
 /// <param name="method">Method</param>
 /// <param name="parameter">Parameter</param>
 /// <param name="il">ILGenerator</param>
 internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
 {
 }
Example #9
0
 /// <summary>
 /// Aspect code to inject at the end of weaved method
 /// </summary>
 /// <param name="typeBuilder">Type Builder</param>
 /// <param name="method">Method</param>
 /// <param name="parameter">Parameter</param>
 /// <param name="il">ILGenerator</param>
 internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
 {
     il.Emit(Mono.Cecil.Cil.OpCodes.Ldsfld, field);
     il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4_1);
     il.Emit(Mono.Cecil.Cil.OpCodes.Sub);
     il.Emit(Mono.Cecil.Cil.OpCodes.Stsfld, field);
 }
Example #10
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            field = method.DeclaringType.DefineField("<unsafe>_" + method.Name, typeof(int),
                                                     Mono.Cecil.FieldAttributes.Static | Mono.Cecil.FieldAttributes.Private);

            var notZero = il.DefineLabel();

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldsfld, field);
            il.Emit(Mono.Cecil.Cil.OpCodes.Brfalse, notZero);

            il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, typeof(ConcurrentAccessException).GetConstructor(Type.EmptyTypes));
            il.Emit(Mono.Cecil.Cil.OpCodes.Throw);

            il.MarkLabel(notZero);

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldsfld, field);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4_1);
            il.Emit(Mono.Cecil.Cil.OpCodes.Add);
            il.Emit(Mono.Cecil.Cil.OpCodes.Stsfld, field);
        }
Example #11
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            if (method.IsStatic)
            {
                return;
            }

            if (method.IsConstructor)
            {
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
                il.Emit(Mono.Cecil.Cil.OpCodes.Call, typeof(ThreadAffinityAttribute).GetMethod("SetInstanceThread"));
                return;
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, typeof(ThreadAffinityAttribute).GetMethod("ThrowIfInstanceThreadNotMatch"));
        }
Example #12
0
 /// <summary>
 /// Aspect code to inject at the end of weaved method
 /// </summary>
 /// <param name="typeBuilder">Type Builder</param>
 /// <param name="method">Method</param>
 /// <param name="parameter">Parameter</param>
 /// <param name="il">ILGenerator</param>
 internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
 {
     il.BeginCatchBlock(typeof(System.Exception));
     il.EndExceptionBlock();
 }
Example #13
0
        /// <summary>
        /// Aspect code to inject at the end of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            il.BeginFinallyBlock();

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, @lock);
            il.Emit(Mono.Cecil.Cil.OpCodes.Callvirt, ExitMethod);

            il.EndExceptionBlock();
        }
Example #14
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var aspectType     = this.GetType();
            var hasExLabel     = il.DefineLabel();
            var exceptionLocal = il.DeclareLocal(typeof(Exception));
            var offset         = method.IsStatic ? 0 : 1;

            var paraMethod             = method;
            var parameterType          = parameter.ParameterType;
            var parameterDeclaringType = paraMethod.DeclaringType;
            var aspect = parameter.GetCustomAttribute(aspectType);

            if (aspect == null)
            {
                return;
            }

            var aspectField = ILWeaver.TypeFieldAspects[parameterDeclaringType.FullName][aspectType.FullName];

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldsfld, aspectField);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg, parameter.Index + offset);
            if (parameterType.IsValueType)
            {
                il.Emit(Mono.Cecil.Cil.OpCodes.Box, parameterType);
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldstr, parameter.Name);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4_1);

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldtoken, paraMethod);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, typeof(MethodBase).GetMethod("GetMethodFromHandle", new Type[] { typeof(RuntimeMethodHandle) }));
            il.Emit(Mono.Cecil.Cil.OpCodes.Isinst, typeof(MethodInfo));
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4, parameter.Index);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, GetParameterContractAspectMethod);

            il.Emit(Mono.Cecil.Cil.OpCodes.Callvirt, ValidateContractMethod);
            il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, exceptionLocal);

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, exceptionLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Brfalse, hasExLabel);

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, exceptionLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Throw);

            il.MarkLabel(hasExLabel);
        }
Example #15
0
 /// <summary>
 /// Weave field into current aspect
 /// </summary>
 /// <param name="il">IL Generator</param>
 /// <param name="field">Field</param>
 private void BlockGetField(Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.FieldDefinition field)
 {
     BlockField(il, field, GetValueMethod);
 }
Example #16
0
        /// <summary>
        /// Aspect code to inject at the end of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var meth       = method;
            var module     = typeBuilder.Module;
            var returnType = meth.ReturnType.ReflectionType();

            if (returnType == typeof(void) || !(meth.Name.StartsWith("get_") || meth.Parameters.Count == 0))
            {
                return;
            }

            var isPrimitive = returnType.IsPrimitive();
            var isStatic    = method.IsStatic;

            if (autoField != null)
            {
                //var local = il.DeclareLocal(returnType);

                //il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, 0);
                //il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, local);

                if (!isStatic)
                {
                    il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
                }
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, 0);

                if (isPrimitive)
                {
                    il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, typeof(Nullable <>).MakeGenericType(returnType)
                            .GetConstructor(new Type[] { returnType }));
                }

                il.Emit(isStatic ? Mono.Cecil.Cil.OpCodes.Stsfld : Mono.Cecil.Cil.OpCodes.Stfld, autoField);
            }

            il.MarkLabel(autoLabel);

            if (autoField != null)
            {
                if (!isStatic)
                {
                    il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
                }
                il.Emit(isStatic ? Mono.Cecil.Cil.OpCodes.Ldsflda : Mono.Cecil.Cil.OpCodes.Ldflda, autoField);
                if (isPrimitive)
                {
                    returnType = typeof(Nullable <>).MakeGenericType(returnType);
                    il.Emit(Mono.Cecil.Cil.OpCodes.Call, module.Import(returnType.GetMethod("get_Value")));
                }
                il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, 0);
            }
        }
Example #17
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var meth       = method;
            var module     = typeBuilder.Module;
            var returnType = meth.ReturnType.ReflectionType();

            if (returnType == typeof(void) || !(meth.Name.StartsWith("get_") || meth.Parameters.Count == 0))
            {
                return;
            }

            var isStatic    = meth.IsStatic;
            var isPrimitive = returnType.IsPrimitive();

            if (isPrimitive)
            {
                returnType = typeof(Nullable <>).MakeGenericType(returnType);
            }

            autoField = method.DeclaringType.DefineField("<auto_lazy>_" + meth.Name, returnType,
                                                         isStatic ? Mono.Cecil.FieldAttributes.Static | Mono.Cecil.FieldAttributes.Private : Mono.Cecil.FieldAttributes.Private);

            autoLabel = il.DefineLabel();

            if (!isStatic)
            {
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
            }
            il.Emit(isStatic ? Mono.Cecil.Cil.OpCodes.Ldsflda : Mono.Cecil.Cil.OpCodes.Ldflda, autoField);
            if (isPrimitive)
            {
                il.Emit(Mono.Cecil.Cil.OpCodes.Call, module.Import(returnType.GetMethod("get_HasValue")));
            }

            il.Emit(isPrimitive ? Mono.Cecil.Cil.OpCodes.Brtrue : Mono.Cecil.Cil.OpCodes.Brfalse, autoLabel);
        }
Example #18
0
        public static void Inject(string input_assembly_path, string output_assembly_path, string logger_assembly_path, string logger_type_name, string before_call_log_method_name, string log_attribute_name)
        {
            System.Diagnostics.Debug.Assert(System.IO.File.Exists(input_assembly_path));

            if (input_assembly_path != output_assembly_path)
            {
                if (System.IO.File.Exists(output_assembly_path))
                {
                    System.IO.File.Delete(output_assembly_path);
                }
                System.IO.File.Copy(input_assembly_path, output_assembly_path);
                System.Diagnostics.Debug.Assert(System.IO.File.Exists(output_assembly_path));
            }

            var    assembly_resolver        = new Mono.Cecil.DefaultAssemblyResolver();
            string input_assembly_directory = System.IO.Path.GetDirectoryName(input_assembly_path);

            assembly_resolver.AddSearchDirectory(input_assembly_directory);
            #if SILVERLIGHT
            Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath path_task = new Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath();
            path_task.RegistryBase = "Software\\Microsoft\\Microsoft SDKs\\Silverlight";
            path_task.Execute();
            assembly_resolver.AddSearchDirectory(path_task.SilverlightPath);
            foreach (string path in path_task.SilverlightSDKPaths)
            {
                assembly_resolver.AddSearchDirectory(path);
            }
            #endif
            Mono.Cecil.AssemblyDefinition injectible_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(output_assembly_path, new Mono.Cecil.ReaderParameters {
                AssemblyResolver = assembly_resolver
            });

            System.Diagnostics.Debug.Assert(System.IO.File.Exists(logger_assembly_path));
            Mono.Cecil.AssemblyDefinition logger_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(logger_assembly_path);
            Mono.Cecil.TypeDefinition     logger_type     = logger_assembly.MainModule.GetType(logger_type_name);
            System.Diagnostics.Debug.Assert(logger_type != null);
            Mono.Cecil.MethodDefinition before_callback_method_info = logger_type.Methods.First(m => m.Name == before_call_log_method_name);
            Mono.Cecil.MethodReference  before_callback_reference   = injectible_assembly.MainModule.Import(before_callback_method_info);

            //make sure to get System.Object.ToString method from assembly compatible with the injected assembly
            #if SILVERLIGHT
            string core_assembly_path = path_task.SilverlightPath + "mscorlib.dll";
            Mono.Cecil.AssemblyDefinition core_assembly         = Mono.Cecil.AssemblyDefinition.ReadAssembly(core_assembly_path);
            Mono.Cecil.TypeDefinition     object_type           = core_assembly.MainModule.GetType("System.Object");
            Mono.Cecil.MethodDefinition   to_string_method_info = object_type.Methods.First(m => m.Name == "ToString");
            #else
            System.Reflection.MethodInfo to_string_method_info = typeof(System.Object).GetMethod("ToString");
            #endif
            Mono.Cecil.MethodReference to_string_reference = injectible_assembly.MainModule.Import(to_string_method_info);

            foreach (Mono.Cecil.TypeDefinition type_definition in injectible_assembly.MainModule.Types)
            {
                bool is_type_logable = type_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name);
                foreach (Mono.Cecil.MethodDefinition method_definition in type_definition.Methods)
                {
                    bool is_method_logable = is_type_logable || method_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name);

                    if (is_method_logable)
                    {
                        Mono.Cecil.Cil.ILProcessor processor = method_definition.Body.GetILProcessor();

                        System.Collections.Generic.List <Mono.Cecil.Cil.Instruction> original_instructions = new System.Collections.Generic.List <Mono.Cecil.Cil.Instruction>();
                        original_instructions.AddRange(method_definition.Body.Instructions);
                        method_definition.Body.Instructions.Clear();

                        #region parameters

                        int method_parameters_count = method_definition.Parameters.Count;
                        int local_variables_count   = method_definition.Body.Variables.Count;
                        int arguments_array_index   = local_variables_count;

                        // Create an array of type System.String with the same number of elements as count of method parameters
                        // Add metadata for a new variable of type System.String[] to method body
                        // .locals init (System.String[] V_0)
                        Mono.Cecil.ArrayType arguments = new Mono.Cecil.ArrayType(injectible_assembly.MainModule.TypeSystem.String);
                        method_definition.Body.Variables.Add(new Mono.Cecil.Cil.VariableDefinition((Mono.Cecil.TypeReference)arguments));
                        method_definition.Body.InitLocals = true;
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, method_parameters_count));
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Newarr, injectible_assembly.MainModule.TypeSystem.String));
                        // This instruction will store the address of the newly created array in the newly added local variable, which is at index = local_variables_count
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stloc, arguments_array_index));

                        #region parameters_to_string

                        // Instance methods have an an implicit argument called "this"
                        // so in that case we need to refer to actual arguments with +1 position
                        int parameter_offset = method_definition.IsStatic ? 0 : 1;
                        for (int i = 0; i < method_parameters_count; ++i)
                        {
                            // load argument array and current index
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index));
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, i));

                            // load argument
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldarga, i + parameter_offset));

                            // convert argument to string
                            Mono.Cecil.TypeReference argument_type = method_definition.Parameters[i].ParameterType;

                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Constrained, argument_type));
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Callvirt, to_string_reference));

                            // store string in array
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stelem_Ref));
                        }

                        #endregion parameters_to_string

                        string method_signature = method_definition.ToString();
                        // load method signature
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldstr, method_signature));

                        // load parameters array
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index));

                        #endregion parameters

                        // load before call instruction
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Call, before_callback_reference));

                        foreach (var IL in original_instructions)
                        {
                            method_definition.Body.Instructions.Add(IL);
                        }
                    }
                }
            }

            injectible_assembly.Write(output_assembly_path);
        }
Example #19
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var meth = method;

            lockWasTokenLocal = il.DeclareLocal(typeof(bool));
            tempLocal         = il.DeclareLocal(typeof(object));

            il.Emit(method.IsStatic ? Mono.Cecil.Cil.OpCodes.Ldnull : Mono.Cecil.Cil.OpCodes.Ldarg_0);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, GetLockObjectMethod);
            il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, tempLocal);

            il.BeginExceptionBlock();
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, tempLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloca, lockWasTokenLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, EnterMethod);
        }
Example #20
0
        /// <summary>
        /// Aspect code to inject at the end of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            il.BeginFinallyBlock();

            var takenLabel = il.DefineLabel();

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, lockWasTokenLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Brfalse, takenLabel);

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, tempLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, ExitMethod);

            il.MarkLabel(takenLabel);

            il.EndExceptionBlock();
        }
Example #21
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var isSetProperty = method.Name.StartsWith("set_") && !method.IsStatic;

            if (!isSetProperty)
            {
                return;
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, ThrowIfFrozenMethod);
        }
Example #22
0
        /// <summary>
        /// Weave event invoke
        /// </summary>
        /// <param name="il">IL Generator</param>
        /// <param name="method">Method</param>
        /// <param name="field">Field</param>
        private void BlockInvokeEvent(Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.MethodDefinition method, Mono.Cecil.FieldDefinition field)
        {
            var isStatic        = method.IsStatic;
            var eventContext    = il.DeclareLocal(typeof(EventContext));
            var locals          = new List <Mono.Cecil.Cil.VariableDefinition>();
            var objLocal        = il.DeclareLocal(typeof(object[]));
            var parameters      = method.Parameters;
            var parameterLength = parameters.Count;

            var fieldDeclaringType = field.DeclaringType;
            var aspect             = field.GetCustomAttribute <EventInterceptionAspect>() ?? fieldDeclaringType.GetCustomAttribute <EventInterceptionAspect>()
                                     ?? fieldDeclaringType.Module.Assembly.GetCustomAttribute <EventInterceptionAspect>();

            if (!ILWeaver.IsValidAspectFor(field, aspect, allowEvents: true))
            {
                return;
            }

            var aspectField = ILWeaver.TypeFieldAspects[fieldDeclaringType.FullName][aspect.GetType().FullName];

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4, parameterLength);
            il.Emit(Mono.Cecil.Cil.OpCodes.Newarr, typeof(object));
            il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, objLocal);

            for (var i = 0; i < parameterLength; i++)
            {
                var parameter     = parameters[i];
                var parameterType = parameter.ParameterType;
                var local         = il.DeclareLocal(parameterType);

                il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, local);
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, objLocal);
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4, parameterLength - i - 1);
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, local);
                if (parameterType.IsValueType)
                {
                    il.Emit(Mono.Cecil.Cil.OpCodes.Box, parameterType);
                }
                il.Emit(Mono.Cecil.Cil.OpCodes.Stelem_Ref);

                locals.Add(local);
            }

            if (!isStatic)
            {
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
            }
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldnull);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4, 1);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, objLocal);
            il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, EventContextCtor);
            il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, eventContext);

            //InvokeEventMethod
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldsfld, aspectField);
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, eventContext);
            il.Emit(Mono.Cecil.Cil.OpCodes.Callvirt, InvokeEventMethod);

            //Restore original invoke event parameters
            //locals.Reverse();
            foreach (var local in locals)
            {
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, local);
            }
        }
Example #23
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var methodName    = method.Name;
            var isSetProperty = methodName.StartsWith("set_") && !method.IsStatic;

            if (!isSetProperty)
            {
                return;
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldstr, methodName.Substring(4));
            il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, typeof(ObjectReadOnlyException).GetConstructor(new[] { typeof(string) }));
            il.Emit(Mono.Cecil.Cil.OpCodes.Throw);
        }
Example #24
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var meth       = method;
            var returnType = meth.ReturnType.ReflectionType();

            @lock = il.DeclareLocal(typeof(Thread.ReaderWriterLockSlim));

            il.Emit(method.IsStatic ? Mono.Cecil.Cil.OpCodes.Ldnull : Mono.Cecil.Cil.OpCodes.Ldarg_0);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, GetLockMethod);
            il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, @lock);

            il.BeginExceptionBlock();
            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, @lock);
            il.Emit(Mono.Cecil.Cil.OpCodes.Callvirt, EnterMethod);
        }