private void EmitMessage(InstructionBlock block, InstructionWriter writer, MethodDefDeclaration targetMethod, string messageFormatString)
                {
                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, LogSeverity.Trace);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    int  parameterCount = Context.MethodMapping.MethodSignature.ParameterCount;
                    bool hasThis        = Context.MethodMapping.MethodSignature.CallingConvention == CallingConvention.HasThis;

                    builder.EmitWrite(writer, block, messageFormatString, parameterCount, LogSeverity.Trace, null,
                                      (i, instructionWriter) =>
                    {
                        instructionWriter.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)(hasThis ? i + 1 : i));
                        instructionWriter.EmitConvertToObject(
                            this.Context.MethodMapping.MethodSignature.GetParameterType(i));
                    });

                    writer.DetachInstructionSequence();
                }
                protected override void ImplementOnException(InstructionBlock block, ITypeSignature exceptionType, InstructionWriter writer)
                {
                    MethodDefDeclaration targetMethod = this.transformationInstance.AspectWeaverInstance.TargetElement as MethodDefDeclaration;

                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder  = this.backendInstance.GetCategoryBuilder(category);
                    InstructionSequence     sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    LocalVariableSymbol exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable(
                        exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex"));

                    LogSeverity logSeverity = LogSeverity.Warning;

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logSeverity);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    builder.EmitWrite(writer, block, "An exception occurred:\n{0}", 1, logSeverity,
                                      w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal),
                                      (i, w) => w.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal));

                    writer.EmitInstruction(OpCodeNumber.Rethrow);
                    writer.DetachInstructionSequence();
                }
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            InstructionSequence sequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(sequence, NodePosition.After, null);
            InstructionWriter writer = context.InstructionWriter;
            writer.AttachInstructionSequence(sequence);

            context.InstructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, context.ReturnValueVariable);
            context.InstructionWriter.EmitInstructionType(OpCodeNumber.Box,
                                                          context.ReturnValueVariable.LocalVariable.Type);
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Ldnull);
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Ceq);

            InstructionSequence nextSequence = context.Method.MethodBody.CreateInstructionSequence();

            context.InstructionWriter.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, nextSequence);
            context.InstructionWriter.EmitInstructionString(OpCodeNumber.Ldstr, "return value is null");
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Newobj,
                                                            context.Method.Module.FindMethod(
                                                                typeof (ArgumentNullException).GetConstructor(new[]
                                                                                                                  {
                                                                                                                      typeof
                                                                                                                          (
                                                                                                                          string
                                                                                                                          )
                                                                                                                  }),
                                                                BindingOptions.Default));
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Throw);

            block.AddInstructionSequence(nextSequence, NodePosition.After, sequence);

            writer.DetachInstructionSequence();
        }
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            InstructionSequence nextSequence = null;
            InstructionSequence sequence = null;

            sequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(sequence, NodePosition.Before, null);
            context.InstructionWriter.AttachInstructionSequence(sequence);

            context.InstructionWriter.EmitInstructionParameter(OpCodeNumber.Ldarg, this.paramDef);
            context.InstructionWriter.EmitInstructionType(OpCodeNumber.Box, this.paramDef.ParameterType);
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Ldnull);
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Ceq);

            nextSequence = context.Method.MethodBody.CreateInstructionSequence();

            context.InstructionWriter.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, nextSequence);
            context.InstructionWriter.EmitInstructionString(OpCodeNumber.Ldstr, this.paramDef.Name);
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Newobj,
                                                            context.Method.Module.FindMethod(
                                                                typeof (ArgumentNullException).GetConstructor(
                                                                    new[] {typeof (string)}),
                                                                BindingOptions.Default));
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Throw);

            context.InstructionWriter.DetachInstructionSequence();
            block.AddInstructionSequence(nextSequence, NodePosition.After, sequence);
            sequence = nextSequence;
            context.InstructionWriter.AttachInstructionSequence(sequence);

            context.InstructionWriter.DetachInstructionSequence();
        }
        private MethodDefDeclaration CreateTraceStringFormatWrapper(string name)
        {
            MethodDefDeclaration formatWrapperMethod = new MethodDefDeclaration
            {
                Name       = name,
                Attributes = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
            };

            this.implementationType.Methods.Add(formatWrapperMethod);

            formatWrapperMethod.Parameters.Add(new ParameterDeclaration(0, "format", this.module.Cache.GetIntrinsic(IntrinsicType.String)));
            formatWrapperMethod.Parameters.Add(new ParameterDeclaration(1, "args", this.module.Cache.GetType(typeof(object[]))));

            InstructionBlock block = formatWrapperMethod.MethodBody.CreateInstructionBlock();

            formatWrapperMethod.MethodBody.RootInstructionBlock = block;
            InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(sequence);

            for (int i = 0; i < formatWrapperMethod.Parameters.Count; i++)
            {
                this.writer.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)i);
            }

            this.writer.EmitInstructionMethod(OpCodeNumber.Call, this.stringFormatArrayMethod);

            this.EmitCallHandler(this.traceWriteLineMethod);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            return(formatWrapperMethod);
        }
        /// <summary>
        /// Weaves the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="block">The block.</param>
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            LocalVariableSymbol parameters = block.DefineLocalVariable(context.Method.Module.FindType(typeof(ParameterDictionary), BindingOptions.Default), NameGenerator.Generate("parameters"));

            InstructionSequence entrySequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(entrySequence, NodePosition.Before, null);

            InstructionWriter writer = context.InstructionWriter;
            writer.AttachInstructionSequence(entrySequence);
            writer.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

            writer.EmitInstructionMethod(OpCodeNumber.Call, context.Method.Module.FindMethod(typeof(InternalHelperMethods).GetMethod("CreateParameterCollection"), BindingOptions.Default));

            IMethod add = context.Method.Module.FindMethod(typeof(ParameterDictionary).GetMethod("Add", new[] { typeof(string), typeof(object) }), BindingOptions.Default);

            short parameterIndex = context.Method.IsStatic ? (short)0 : (short)1;
            foreach (var parameter in method.Parameters)
            {
                writer.EmitInstruction(OpCodeNumber.Dup);

                writer.EmitInstructionString(OpCodeNumber.Ldstr, new LiteralString(parameter.Name));
                writer.EmitInstructionInt16(OpCodeNumber.Ldarg, parameterIndex++);

                if (parameter.ParameterType.GetSystemType(null, null).IsValueType)
                {
                    writer.EmitInstructionType(OpCodeNumber.Box, parameter.ParameterType);
                }

                writer.EmitInstructionMethod(OpCodeNumber.Callvirt, add);
            }

            writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, parameters);

            writer.DetachInstructionSequence();
        }
        private static void AddHelloWorldToMethod(MethodDefDeclaration targetMethod, IMethod consoleWriteLine)
        {
            // Removes the original code from the method body. Without this, you would get exceptions:
            InstructionBlock originalCode = targetMethod.MethodBody.RootInstructionBlock;

            originalCode.Detach();

            // Replaces the method body's content:
            InstructionBlock root = targetMethod.MethodBody.CreateInstructionBlock();

            targetMethod.MethodBody.RootInstructionBlock = root;

            InstructionBlock    helloWorldBlock    = root.AddChildBlock();
            InstructionSequence helloWorldSequence = helloWorldBlock.AddInstructionSequence();

            using (var writer = InstructionWriter.GetInstance())
            {
                // Add instructions to the beginning of the method body:
                writer.AttachInstructionSequence(helloWorldSequence);

                // Say that what follows is compiler-generated code:
                writer.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

                // Emit a call to Console.WriteLine("Hello, world!"):
                writer.EmitInstructionString(OpCodeNumber.Ldstr, "Hello, world!");
                writer.EmitInstructionMethod(OpCodeNumber.Call, consoleWriteLine);

                writer.DetachInstructionSequence();
            }

            // Re-adding the original code at the end:
            root.AddChildBlock(originalCode);
        }
Ejemplo n.º 8
0
        public void Emit(InstructionWriter writer, InstructionBlock block, TypeInitializationClientScopes scope)
        {
            InstructionSequence sequence = block.AddInstructionSequence();

            writer.AttachInstructionSequence(sequence);
            writer.EmitInstructionMethod(OpCodeNumber.Call, attachMethod);
            writer.DetachInstructionSequence();
        }
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            InstructionSequence nextSequence = null;
            InstructionSequence sequence = null;

            sequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(sequence, NodePosition.Before, null);
            context.InstructionWriter.AttachInstructionSequence(sequence);

            IMethod isNullOrEmpty = context.Method.Module.FindMethod(typeof (string).GetMethod("IsNullOrEmpty"),
                                                                     BindingOptions.Default);

            // Checks if not empty

            context.InstructionWriter.EmitInstructionParameter(OpCodeNumber.Ldarg, paramDef);
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, isNullOrEmpty);

            nextSequence = context.Method.MethodBody.CreateInstructionSequence();

            context.InstructionWriter.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, nextSequence);
            context.InstructionWriter.EmitInstructionString(OpCodeNumber.Ldstr, "Parameter is null or empty.");
            context.InstructionWriter.EmitInstructionString(OpCodeNumber.Ldstr, this.paramDef.Name);
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Newobj,
                                                            context.Method.Module.FindMethod(
                                                                typeof (ArgumentException).GetConstructor(new[]
                                                                                                              {
                                                                                                                  typeof
                                                                                                                      (
                                                                                                                      string
                                                                                                                      ),
                                                                                                                  typeof
                                                                                                                      (
                                                                                                                      string
                                                                                                                      )
                                                                                                              }),
                                                                BindingOptions.Default));
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Throw);

            context.InstructionWriter.DetachInstructionSequence();
            block.AddInstructionSequence(nextSequence, NodePosition.After, sequence);
            sequence = nextSequence;
            context.InstructionWriter.AttachInstructionSequence(sequence);

            context.InstructionWriter.DetachInstructionSequence();
        }
Ejemplo n.º 10
0
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            InstructionWriter iw = context.InstructionWriter;

            iw.AttachInstructionSequence(block.AddInstructionSequence());
            iw.EmitInstructionMethod(OpCodeNumber.Call, methodToCall);
            iw.DetachInstructionSequence();
            ReplacedAtLeastOneCall = true;
        }
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            IList<ParameterDeclaration> args = new List<ParameterDeclaration>();
            foreach(ParameterDeclaration p in context.Method.Parameters)
            {
                foreach (CustomAttributeDeclaration c in p.CustomAttributes)
                {
                    object obj = c.ConstructRuntimeObject();
                    if (obj is NonNullAttribute)
                    {
                        args.Add(p);
                    }
                }
            }

            InstructionSequence nextSequence = null;
            InstructionSequence sequence = null;

            sequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(sequence, NodePosition.Before, null);
            context.InstructionWriter.AttachInstructionSequence(sequence);

            foreach (ParameterDeclaration p in args)
            {
                context.InstructionWriter.EmitInstructionParameter(OpCodeNumber.Ldarg, p);
                context.InstructionWriter.EmitInstructionType(OpCodeNumber.Box, p.ParameterType);
                context.InstructionWriter.EmitInstruction(OpCodeNumber.Ldnull);
                context.InstructionWriter.EmitInstruction(OpCodeNumber.Ceq);

                nextSequence = context.Method.MethodBody.CreateInstructionSequence();

                context.InstructionWriter.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, nextSequence);
                context.InstructionWriter.EmitInstructionString(OpCodeNumber.Ldstr, (LiteralString)p.Name);
                context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Newobj, context.Method.Module.FindMethod(typeof(ArgumentNullException).GetConstructor(new Type[] { typeof(string) }), BindingOptions.Default));
                context.InstructionWriter.EmitInstruction(OpCodeNumber.Throw);

                context.InstructionWriter.DetachInstructionSequence();
                block.AddInstructionSequence(nextSequence, NodePosition.After, sequence);
                sequence = nextSequence;
                context.InstructionWriter.AttachInstructionSequence(sequence);
            }

            context.InstructionWriter.DetachInstructionSequence();
        }
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            IMethod             oldOperand = context.InstructionReader.CurrentInstruction.MethodOperand;
            InstructionSequence sequence   = block.MethodBody.CreateInstructionSequence();

            block.AddInstructionSequence(sequence);
            context.InstructionWriter.AttachInstructionSequence(sequence);
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Callvirt, oldOperand);
            context.InstructionWriter.DetachInstructionSequence();
        }
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            InstructionSequence sequence = null;

            sequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(sequence, NodePosition.After, null);
            context.InstructionWriter.AttachInstructionSequence(sequence);

            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, context.Method.Module.FindMethod(m_type.Methods.GetOneByName("get_Instance").GetReflectionWrapper(new Type[]{},new Type[]{}),BindingOptions.Default));
            context.InstructionWriter.DetachInstructionSequence();
        }
        void IAdvice.Weave(WeavingContext context, InstructionBlock block)
        {
            Console.WriteLine("Weave");
            IMethod method = this.methods[context.JoinPoint.Instruction.OpCodeNumber];

            InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

            context.InstructionWriter.AttachInstructionSequence(sequence);
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, method);
            context.InstructionWriter.DetachInstructionSequence();
        }
        public static void AddPropertyGuard(PropertyDeclaration property, MethodBodyTransformationContext context, InstructionBlock block, InstructionWriter writer)
        {
            var propertyType = property.PropertyType;
            var methodBody = block.MethodBody;

            var sequence = block.AddInstructionSequence(null, NodePosition.After, null);
            if (sequence == null) return;

            var oldValueVariable =
                block.DefineLocalVariable(propertyType, string.Format("old{0}Value", property.Name));
            var assets = GetTransformationAssets(property.Module);

            writer.AttachInstructionSequence(sequence);
            var isLocationBinding = CheckIfIsLocationBinding(methodBody,assets);
            if (isLocationBinding) {
                writer.AssignValue_LocalVariable(oldValueVariable
                    , () => writer.Call_MethodOnTarget(property.GetGetter()
                        ,
                        () => {
                            //Load the instance parameter of the SetValue method
                            //and convert it to the type
                            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                            //writer.EmitInstructionLoadIndirect(Assets.ObjectTypeSignature);
                            writer.EmitInstructionType(OpCodeNumber.Ldobj, assets.ObjectTypeSignature);
                            writer.EmitConvertFromObject(property.Parent);
                        }
                    )
                );
                //On the location binding the value parameter is at psotion 3
                writer.EmitInstruction(OpCodeNumber.Ldarg_3);
            } else {
                writer.AssignValue_LocalVariable(oldValueVariable,
                                                    () => writer.Get_PropertyValue(property));
                //For a normal property the value parameter is at position 1
                writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            }
            if (propertyType.IsStruct()) {
                writer.EmitInstructionType(OpCodeNumber.Box, propertyType);
            }
            writer.Box_LocalVariableIfNeeded(oldValueVariable);
            var isPrimitive = propertyType.IsPrimitive();
            if (isPrimitive) {
                writer.Compare_Primitives();
            } else {
                //TODO: Try and use the equality operator when present
                writer.Compare_Objects(assets.ObjectEqualsMethod);
            }
            //writer.Leave_IfTrue(_context.LeaveBranchTarget);
            writer.Leave_IfTrue(context.LeaveBranchTarget);
            writer.DetachInstructionSequence();
        }
Ejemplo n.º 16
0
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            InstructionSequence entrySequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(entrySequence, NodePosition.Before, null);

            InstructionWriter writer = context.InstructionWriter;

            writer.AttachInstructionSequence(entrySequence);
            writer.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

            Weave(context, writer);

            writer.DetachInstructionSequence();
        }
Ejemplo n.º 17
0
        private void ReplaceOperator(TypeDefDeclaration enhancedType, MethodDefDeclaration equalityMethodDef,
                                     bool negate)
        {
            InstructionBlock originalCode = equalityMethodDef.MethodBody.RootInstructionBlock;

            originalCode.Detach();

            InstructionBlock root = equalityMethodDef.MethodBody.CreateInstructionBlock();

            equalityMethodDef.MethodBody.RootInstructionBlock = root;
            var newSequence = root.AddInstructionSequence();

            using (var writer = InstructionWriter.GetInstance())
            {
                writer.AttachInstructionSequence(newSequence);

                if (enhancedType.IsValueType())
                {
                    var canonicalType = enhancedType.GetCanonicalGenericInstance();
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                }
                else
                {
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                }

                writer.EmitInstructionMethod(OpCodeNumber.Call, this.staticEqualsMethod);

                if (negate)
                {
                    writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                    writer.EmitInstruction(OpCodeNumber.Ceq);
                }

                writer.EmitInstruction(OpCodeNumber.Ret);

                writer.DetachInstructionSequence();
            }
        }
        /// <summary>
        /// Creates a new method body and assigns it to <paramref name="hostMethod"/>. The method body looks as described in <see cref="CreatedEmptyMethod"/>.
        /// </summary>
        /// <param name="instructionWriter">A <b>detached</b> instruction writer.</param>
        /// <param name="hostMethod">The method without body. The body will be assigned to this method.</param>
        /// <returns>References to points in the method body.</returns>
        public static CreatedEmptyMethod CreateModifiableMethodBody(InstructionWriter instructionWriter, MethodDefDeclaration hostMethod)
        {
            // Create a new method body to host the pipeline.
            hostMethod.MethodBody = new MethodBodyDeclaration();
            InstructionBlock rootInstructionBlock = hostMethod.MethodBody.RootInstructionBlock = hostMethod.MethodBody.CreateInstructionBlock();

            InstructionBlock    sequencePointBlock    = rootInstructionBlock.AddChildBlock();
            InstructionSequence sequencePointSequence = sequencePointBlock.AddInstructionSequence();

            instructionWriter.AttachInstructionSequence(sequencePointSequence);
            instructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            instructionWriter.EmitInstruction(OpCodeNumber.Nop);
            instructionWriter.DetachInstructionSequence();

            InstructionBlock    implementationBlock = rootInstructionBlock.AddChildBlock();
            InstructionBlock    returnBlock         = rootInstructionBlock.AddChildBlock();
            InstructionSequence returnSequence      = returnBlock.AddInstructionSequence();

            instructionWriter.AttachInstructionSequence(returnSequence);
            instructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            LocalVariableSymbol returnVariable;

            if (!hostMethod.ReturnParameter.ParameterType.IsIntrinsic(IntrinsicType.Void))
            {
                hostMethod.MethodBody.InitLocalVariables = true;
                returnVariable = rootInstructionBlock.DefineLocalVariable(
                    hostMethod.ReturnParameter.ParameterType,
                    DebuggerSpecialNames.GetVariableSpecialName(hostMethod.Domain, "returnValue", DebuggerSpecialVariableKind.ReturnValue)
                    );
                instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, returnVariable);
            }
            else
            {
                returnVariable = null;
            }

            instructionWriter.EmitInstruction(OpCodeNumber.Ret);
            instructionWriter.DetachInstructionSequence();
            return(new CreatedEmptyMethod(hostMethod, implementationBlock, returnVariable, returnSequence));
        }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer,
                                         LogLevel logLevel, string messageFormatString, int[] arguments, ITypeSignature exceptionType = null)
                {
                    MethodDefDeclaration targetMethod = Context.TargetElement as MethodDefDeclaration;

                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    LocalVariableSymbol exceptionLocal = null;

                    if (exceptionType != null)
                    {
                        exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable(
                            exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex"));
                    }

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logLevel);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    bool useWrapper = ShouldUseWrapper(targetMethod);

                    Action <InstructionWriter> getExceptionAction = exceptionLocal != null ? (Action <InstructionWriter>)(w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal)) : null;

                    builder.EmitWrite(writer,
                                      messageFormatString,
                                      exceptionType == null ? arguments.Length : arguments.Length + 1,
                                      logLevel,
                                      getExceptionAction,
                                      (i, instructionWriter) =>
                    {
                        if (i < arguments.Length)
                        {
                            int index = arguments[i];
                            if (index == MessageArgumentsFormatter.ThisArgumentPosition)
                            {
                                this.methodMappingWriter.EmitLoadInstance(false, instructionWriter);
                            }
                            else if (index == MessageArgumentsFormatter.ReturnParameterPosition)
                            {
                                instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, Context.ReturnValueVariable);
                                instructionWriter.EmitConvertToObject(
                                    Context.MethodMapping.MethodSignature.ReturnType);
                            }
                            else
                            {
                                this.methodMappingWriter.EmitLoadArgument(index, instructionWriter);

                                instructionWriter.EmitConvertToObject(this.methodMappingWriter.MethodMapping.MethodSignature.GetParameterType(index).GetNakedType(TypeNakingOptions.IgnoreManagedPointers));
                            }
                        }
                        else
                        {
                            //Emit exception parameter
                            instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal);
                        }
                    },
                                      useWrapper);
                    if (exceptionType == null)
                    {
                        writer.DetachInstructionSequence();
                    }
                }
Ejemplo n.º 20
0
        private void WeaveExit(WeavingContext context, InstructionBlock block)
        {
            InstructionSequence exitSequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(exitSequence, NodePosition.Before, null);

            InstructionWriter iw = context.InstructionWriter;

            iw.AttachInstructionSequence(exitSequence);
            iw.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

            MethodDefDeclaration onPropertyChangedMethod = FindOnPropertyChangedMethodFromContext(context);

            iw.EmitInstruction(OpCodeNumber.Ldarg_0);
            iw.EmitInstructionString(OpCodeNumber.Ldstr, _getMethod.Name.Substring(4));

            MethodBase systemMethod = onPropertyChangedMethod.GetSystemMethod(null, null, BindingOptions.Default);
            IMethod boundMethod = this._setMethod.Module.FindMethod(systemMethod, BindingOptions.Default);

            iw.EmitInstructionMethod(OpCodeNumber.Callvirt, boundMethod);

            iw.DetachInstructionSequence();
        }
        private void CallEventInvokerMethod(IMethod method, InstructionBlock block, InstructionWriter writer)
        {
            if (method == null) return;
            if (block.MethodBody.ContainsCallToMethod(method)) return;

            var sequence = block.AddInstructionSequence(null, NodePosition.After, null);
            writer.AttachInstructionSequence(sequence);
            //writer.EmitInstructionString();
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
            writer.EmitInstructionString(OpCodeNumber.Ldstr, _transformationContext.Property.Name);
            //writer.EmitInstructionLocalVariable();
            if (method.IsVirtual) {
                writer.EmitInstructionMethod(OpCodeNumber.Callvirt, method);
            } else {
                writer.EmitInstructionMethod(OpCodeNumber.Call, method);
            }
            writer.DetachInstructionSequence();
        }
            public void Weave(WeavingContext context, InstructionBlock block)
            {
                // Type whose constructor is being woven.
                TypeDefDeclaration wovenType = context.Method.DeclaringType;

                // Logging data for the woven type.
                PerTypeLoggingData perTypeLoggingData = this.parent.perTypeLoggingDatas[wovenType];

                InstructionSequence initializeSequence = context.Method.MethodBody.CreateInstructionSequence();

                block.AddInstructionSequence(initializeSequence, NodePosition.Before, null);

                context.InstructionWriter.AttachInstructionSequence(initializeSequence);
                context.InstructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

                // Get the declaring type of the constructor.
                context.WeavingHelper.GetRuntimeType(GenericHelper.GetTypeCanonicalGenericInstance(wovenType), context.InstructionWriter);
                // Stack: type.
                // Get the logger for the method_declaring_type.
                context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, this.parent.GetLoggerMethod);
                // Stack: logger.
                // Assign logger to the log variable.
                context.InstructionWriter.EmitInstructionField(OpCodeNumber.Stsfld, GenericHelper.GetFieldCanonicalGenericInstance(perTypeLoggingData.Log));
                // Stack: .

                context.InstructionWriter.DetachInstructionSequence();
            }
            public override void Implement(TransformationContext context)
            {
                TypeDefDeclaration typeDef = (TypeDefDeclaration)context.TargetElement;

                ModuleDeclaration module         = this.AspectWeaver.Module;
                ITypeSignature    baseEntityType = module.Cache.GetType(typeof(BaseEntity));

                // Find the base method.
                IMethod         baseCopyToMethod = null;
                IType           baseTypeCursor   = typeDef;
                MethodSignature methodSignature  =
                    new MethodSignature(module, CallingConvention.HasThis, module.Cache.GetIntrinsic(IntrinsicType.Void),
                                        new[] { baseEntityType }, 0);

                while (baseCopyToMethod == null && baseTypeCursor != null)
                {
                    TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition();

                    baseCopyToMethod =
                        baseTypeCursorTypeDef.Methods.GetMethod("CopyTo",
                                                                methodSignature.Translate(baseTypeCursorTypeDef.Module),
                                                                BindingOptions.OnlyExisting |
                                                                BindingOptions.DontThrowException);

                    baseTypeCursor = baseTypeCursorTypeDef.BaseType;
                }

                if (baseCopyToMethod == null)
                {
                    throw new AssertionFailedException("Could not find a method CopyTo.");
                }

                if (baseCopyToMethod.DeclaringType == typeDef)
                {
                    return;
                }


                // Declare the method.
                MethodDefDeclaration methodDef = new MethodDefDeclaration
                {
                    Name       = "CopyTo",
                    Attributes =
                        (MethodAttributes.Family | MethodAttributes.ReuseSlot |
                         MethodAttributes.Virtual),
                    CallingConvention = CallingConvention.HasThis
                };

                typeDef.Methods.Add(methodDef);
                methodDef.CustomAttributes.Add(this.AspectWeaver.AspectInfrastructureTask.WeavingHelper.GetDebuggerNonUserCodeAttribute());

                // Define parameter.
                methodDef.ReturnParameter = new ParameterDeclaration
                {
                    ParameterType = module.Cache.GetIntrinsic(IntrinsicType.Void),
                    Attributes    = ParameterAttributes.Retval
                };

                ParameterDeclaration cloneParameter =
                    new ParameterDeclaration(0, "clone", baseEntityType);

                methodDef.Parameters.Add(cloneParameter);

                // Define the body
                MethodBodyDeclaration methodBody = new MethodBodyDeclaration();

                methodDef.MethodBody = methodBody;
                InstructionBlock instructionBlock = methodBody.CreateInstructionBlock();

                methodBody.RootInstructionBlock = instructionBlock;
                InstructionSequence sequence = methodBody.CreateInstructionSequence();

                instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null);
                using (InstructionWriter writer = new InstructionWriter())
                {
                    writer.AttachInstructionSequence(sequence);

                    // Cast the argument and store it in a local variable.
                    IType typeSpec = GenericHelper.GetTypeCanonicalGenericInstance(typeDef);
                    LocalVariableSymbol castedCloneLocal = instructionBlock.DefineLocalVariable(typeSpec, "typedClone");
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionType(OpCodeNumber.Castclass, typeSpec);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, castedCloneLocal);


                    // TODO: support generic base types.


                    // Call the base method.
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, (IMethod)baseCopyToMethod.Translate(typeDef.Module));

                    // Loop on all fields and clone cloneable ones.
                    TypeRefDeclaration cloneableTypeRef = (TypeRefDeclaration)
                                                          module.Cache.GetType(typeof(ICloneable));
                    MethodRefDeclaration cloneMethodRef = (MethodRefDeclaration)cloneableTypeRef.MethodRefs.GetMethod(
                        "Clone",
                        new MethodSignature(
                            module,
                            CallingConvention.HasThis,
                            module.Cache.GetIntrinsic(
                                IntrinsicType.Object),
                            new ITypeSignature[0], 0),
                        BindingOptions.Default);

                    foreach (FieldDefDeclaration fieldDef in typeDef.Fields)
                    {
                        if ((fieldDef.Attributes & FieldAttributes.Static) != 0)
                        {
                            continue;
                        }

                        if (fieldDef.FieldType == module.Cache.GetIntrinsic(IntrinsicType.String))
                        {
                            continue;
                        }

                        // Does not work?
                        //bool cloneable = fieldDef.FieldType.Inherits(cloneableTypeRef, GenericMap.Empty);
                        bool cloneable = typeof(ICloneable).IsAssignableFrom(fieldDef.FieldType.GetSystemType(null, null));


                        if (cloneable)
                        {
                            IField fieldSpec   = GenericHelper.GetFieldCanonicalGenericInstance(fieldDef);
                            bool   isValueType =
                                fieldSpec.FieldType.BelongsToClassification(TypeClassifications.ValueType).Equals(
                                    NullableBool.True);

                            InstructionSequence nextSequence = null;
                            if (!isValueType)
                            {
                                nextSequence = methodBody.CreateInstructionSequence();
                                writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                                writer.EmitInstructionField(OpCodeNumber.Ldfld, fieldSpec);
                                writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, nextSequence);
                            }
                            writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, castedCloneLocal);
                            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                            writer.EmitInstructionField(OpCodeNumber.Ldfld, fieldSpec);
                            if (isValueType)
                            {
                                writer.EmitInstructionType(OpCodeNumber.Box, fieldSpec.FieldType);
                            }
                            //writer.EmitInstructionType(OpCodeNumber.Castclass, cloneableTypeRef);
                            writer.EmitInstructionMethod(OpCodeNumber.Callvirt, cloneMethodRef);
                            if (isValueType)
                            {
                                writer.EmitInstructionType(OpCodeNumber.Unbox, fieldSpec.FieldType);
                                writer.EmitInstructionType(OpCodeNumber.Ldobj, fieldSpec.FieldType);
                            }
                            else
                            {
                                writer.EmitInstructionType(OpCodeNumber.Castclass, fieldSpec.FieldType);
                            }
                            writer.EmitInstructionField(OpCodeNumber.Stfld, fieldSpec);


                            if (!isValueType)
                            {
                                writer.DetachInstructionSequence();
                                instructionBlock.AddInstructionSequence(nextSequence, NodePosition.After, sequence);
                                sequence = nextSequence;
                                writer.AttachInstructionSequence(sequence);
                            }
                        }
                    }

                    writer.EmitInstruction(OpCodeNumber.Ret);
                    writer.DetachInstructionSequence();
                }
            }
 public void Weave( WeavingContext context, InstructionBlock block )
 {
     InstructionSequence sequence = context.Method.MethodBody.CreateInstructionSequence();
     block.AddInstructionSequence( sequence, NodePosition.After, null );
     EmitCallInitialize( initializeMethodDef, sequence, context.InstructionWriter );
 }
        /// <summary>
        /// Emits the MSIL which checks if the logging is enabled and logs the message.
        /// </summary>
        /// <param name="context">Weaving context.</param>
        /// <param name="block">Block where the code has to be injected.</param>
        /// <param name="level">Level for the message.</param>
        /// <param name="template">Template that will be tokenized in order to get message text.</param>
        /// <exception cref="ArgumentNullException"><paramref name="context"/>, <paramref name="block"/> or <paramref name="template"/> is <see langword="null"/>.</exception>
        /// <exception cref="FormatException">Template is not valid.</exception>
        /// <remarks>
        /// <para>If the <paramref name="level"/> is set to <see cref="LogLevel.None"/>, the method emits no code.</para>
        /// </remarks>
        private void EmitCheckingAndTemplateLogging(WeavingContext context, InstructionBlock block, LogLevel level, string template)
        {
            if (context == null)
              {
            throw new ArgumentNullException("context");
              }
              if (block == null)
              {
            throw new ArgumentNullException("block");
              }
              if (template == null)
              {
            throw new ArgumentNullException("template");
              }

              if (level != LogLevel.None)
              {
            // Method being woven and the type the method is declared in.
            MethodDefDeclaration wovenMethod = context.Method;
            TypeDefDeclaration wovenType = wovenMethod.DeclaringType;

            // Objects that contain required methods, fields, etc.
            LogLevelSupportItem supportItem = this.parent.GetSupportItem(level);
            PerTypeLoggingData perTypeLoggingData = this.parent.GetPerTypeLoggingData(wovenType);

            // Get the tokens for the message template.
            StringBuilder messageFormatString = new StringBuilder();
            List<IMessageToken> nonStaticTokens = new List<IMessageToken>();
            List<IMessageToken> messageParts = TemplateParser.Tokenize(template, wovenMethod, attribute.IncludeParamName);
            MakeFormatString(messageParts, messageFormatString, nonStaticTokens);

            // Sequence that contains the logging check and the logging itself.
            InstructionSequence logEntrySequence = wovenMethod.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(logEntrySequence, NodePosition.Before, null);

            // Sequence that follows the logging code.
            InstructionSequence afterLoggingSequence = wovenMethod.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(afterLoggingSequence, NodePosition.After, logEntrySequence);

            // Check if logging is enabled and log the message.
            context.InstructionWriter.AttachInstructionSequence(logEntrySequence);
            context.InstructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            EmitLoggingEnabledCheck(context.InstructionWriter, supportItem, perTypeLoggingData, afterLoggingSequence);
            if (nonStaticTokens.Count == 0)
            {
              // There are no dynamic tokens, use the faster logging method.
              EmitLogString(context.InstructionWriter, perTypeLoggingData.Log, supportItem.LogStringMethod, messageFormatString.ToString());
            }
            else
            {
              // There are dynamic tokens, prepare log message at run-time.
              LocalVariableSymbol args = this.EmitCreateFormatArgumentArray(context, block, nonStaticTokens);
              EmitLogProviderStringArgs(context.InstructionWriter, perTypeLoggingData.Log, supportItem.LogCultureStringArgsMethod, this.parent.InvariantCultureGetter, messageFormatString.ToString(), args);
            }
            context.InstructionWriter.DetachInstructionSequence();

            // Logging is finished (or skipped), do nothing.
            context.InstructionWriter.AttachInstructionSequence(afterLoggingSequence);
            context.InstructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Nop);
            context.InstructionWriter.DetachInstructionSequence();
              }
        }
                public override void Implement(MethodBodyTransformationContext context)
                {
                    /* We want to generate the following
                     *  if ( !this.<>4__this.Dispatcher.CheckAccess() )
                     *   {
                     *      SynchronizationContext oldContext = SynchronizationContext.Current;
                     *      SynchronizationContext.SetSynchronizationContext( this.<>4__this.Dispatcher.SynchronizationContext );
                     *      this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter();
                     *      this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref  this.<>t__dispatchAwaiter, ref this);
                     *      SynchronizationContext.SetSynchronizationContext( oldContext );
                     *      return;
                     *   }
                     *
                     */



                    MethodDefDeclaration targetMethod = (MethodDefDeclaration)context.TargetElement;
                    TypeDefDeclaration   targetType   = targetMethod.DeclaringType;

                    targetMethod.MethodBody.MaxStack = -1;

                    // Add the field where we will store the awaiter.
                    FieldDefDeclaration awaiterFieldDef = new FieldDefDeclaration
                    {
                        Name       = "<>t__dispatchAwaiter",
                        FieldType  = this.parent.yieldAwaiter_Type,
                        Attributes = FieldAttributes.Private
                    };

                    targetType.Fields.Add(awaiterFieldDef);
                    IField awaiterField = awaiterFieldDef.GetCanonicalGenericInstance();

                    // Find other fields.
                    IField thisField    = targetType.Fields.Single <FieldDefDeclaration>(f => f.Name.EndsWith("__this")).GetCanonicalGenericInstance();
                    IField builderField = targetType.Fields.GetByName("<>t__builder").GetCanonicalGenericInstance();

                    // Emit instructions.
                    InstructionBlock myBlock    = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null);
                    InstructionBlock theirBlock = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null);

                    LocalVariableSymbol awaitableLocal = myBlock.DefineLocalVariable(this.parent.task_Yield_Method.ReturnType, "awaitable");
                    LocalVariableSymbol synchronizationContextLocal = myBlock.DefineLocalVariable(this.parent.synchronizationContext_Type, "oldContext");

                    InstructionSequence entrySequence = myBlock.AddInstructionSequence(null, NodePosition.After, null);
                    InstructionSequence exitSequence  = myBlock.AddInstructionSequence(null, NodePosition.After, null);
                    InstructionWriter   writer        = new InstructionWriter();

                    writer.AttachInstructionSequence(entrySequence);

                    // Emit: if ( this.<>4__this.Dispatcher.CheckAccess() ) goto exitSequence;
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_CheckAccess_Method);
                    writer.EmitBranchingInstruction(OpCodeNumber.Brtrue, exitSequence);

                    // Emit: this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter()
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.task_Yield_Method);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, awaitableLocal);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloca, awaitableLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.yieldAwaitable_GetAwaiter_Method);
                    writer.EmitInstructionField(OpCodeNumber.Stfld, awaiterField);

                    // Emit: oldContext = SynchronizationContext.Current
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_getCurrent_Method);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, synchronizationContextLocal);

                    // Emit: SynchronizationContext.SetSynchronizationContext(this.<>4__this.Dispatcher.SynchronizationContext)
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_getSynchronizationContext_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method);

                    // Choose which AwaitUnsafeOnCompleted method to call.
                    IGenericMethodDefinition awaitUnsafeOnCompletedMethod;

                    ITypeSignature[] awaitUnsafeOnCompletedGenericTypeParameters;
                    if (builderField.FieldType == this.parent.asyncVoidMethodBuilder_Type)
                    {
                        awaitUnsafeOnCompletedMethod = this.parent.asyncVoidMethodBuilder_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters = null;
                    }
                    else if (builderField.FieldType == this.parent.asyncTaskMethodBuilder_Type)
                    {
                        awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilder_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters = null;
                    }
                    else
                    {
                        // This is a generic task.
                        awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilderGeneric_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters =
                            builderField.FieldType.GetGenericContext(GenericContextOptions.None).GetGenericTypeParameters();
                    }

                    IMethod awaitUnsafeOnCompletedGenericMethod =
                        awaitUnsafeOnCompletedMethod.GetGenericInstance(new GenericMap(awaitUnsafeOnCompletedGenericTypeParameters,
                                                                                       new ITypeSignature[]
                    {
                        this.parent.yieldAwaiter_Type,
                        targetType.GetCanonicalGenericInstance()
                    }));

                    // Emit: this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref  this.<>t__dispatchAwaiter, ref this);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldflda, builderField);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldflda, awaiterField);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, awaitUnsafeOnCompletedGenericMethod);

                    // Emit: SynchronizationContext.SetSynchronizationContext( oldContext );
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, synchronizationContextLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method);


                    writer.EmitBranchingInstruction(OpCodeNumber.Leave, context.LeaveBranchTarget);

                    writer.DetachInstructionSequence();

                    // We are done. Give the pipeline to the next node.
                    context.AddRedirection(theirBlock, context.LeaveBranchTarget);
                }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer,
                    LogLevel logLevel, string messageFormatString, int[] arguments, ITypeSignature exceptionType = null)
                {
                    MethodDefDeclaration targetMethod = Context.TargetElement as MethodDefDeclaration;
                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);
                    writer.AttachInstructionSequence(sequence);

                    LocalVariableSymbol exceptionLocal = null;
                    if (exceptionType != null)
                    {
                        exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable(
                        exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex"));
                    }

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logLevel);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    bool useWrapper = ShouldUseWrapper(targetMethod);

                    Action<InstructionWriter> getExceptionAction = exceptionLocal != null ? (Action<InstructionWriter>)(w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal)) : null;

                    builder.EmitWrite(writer,
                        messageFormatString,
                        exceptionType == null ? arguments.Length : arguments.Length + 1,
                        logLevel,
                        getExceptionAction,
                        (i, instructionWriter) =>
                        {
                            if (i < arguments.Length)
                            {
                                int index = arguments[i];
                                if (index == MessageArgumentsFormatter.ThisArgumentPosition)
                                {
                                    this.methodMappingWriter.EmitLoadInstance(false, instructionWriter);
                                }
                                else if (index == MessageArgumentsFormatter.ReturnParameterPosition)
                                {
                                    instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, Context.ReturnValueVariable);
                                    instructionWriter.EmitConvertToObject(
                                        Context.MethodMapping.MethodSignature.ReturnType);
                                }
                                else
                                {
                                    this.methodMappingWriter.EmitLoadArgument(index, instructionWriter);

                                    instructionWriter.EmitConvertToObject(this.methodMappingWriter.MethodMapping.MethodSignature.GetParameterType(index).GetNakedType(TypeNakingOptions.IgnoreManagedPointers));
                                }
                            }
                            else
                            {
                                //Emit exception parameter
                                instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal);
                            }
                        },
                        useWrapper);
                    if (exceptionType == null)
                    {
                        writer.DetachInstructionSequence();
                    }
                }
        private void EmitWrapperCallBody(MethodDefDeclaration wrapperMethod, IMethod loggerMethod)
        {
            InstructionBlock rootBlock = wrapperMethod.MethodBody.CreateInstructionBlock();

            wrapperMethod.MethodBody.RootInstructionBlock = rootBlock;

            InstructionBlock parentBlock   = rootBlock.AddChildBlock(null, NodePosition.After, null);
            InstructionBlock tryBlock      = rootBlock.AddChildBlock(null, NodePosition.After, null);
            InstructionBlock leaveTryBlock = rootBlock.AddChildBlock(null, NodePosition.After, null);

            InstructionSequence sequence = parentBlock.AddInstructionSequence(null, NodePosition.After, null);

            // set isLogging to true
            this.writer.AttachInstructionSequence(sequence);
            this.writer.EmitInstruction(OpCodeNumber.Ldc_I4_1);
            this.writer.EmitInstructionField(OpCodeNumber.Stsfld, this.isLoggingField);
            this.writer.DetachInstructionSequence();

            // if isLogging is true, return
            InstructionSequence branchSequence = parentBlock.AddInstructionSequence(null, NodePosition.Before, null);

            this.writer.AttachInstructionSequence(branchSequence);
            this.writer.EmitInstructionField(OpCodeNumber.Ldsfld, this.isLoggingField);
            this.writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, sequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            // return instruction at the end of the method
            InstructionSequence retSequence = leaveTryBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(retSequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            InstructionSequence trySequence = tryBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(trySequence);

            for (int i = 0; i < wrapperMethod.Parameters.Count; i++)
            {
                writer.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)i);
            }

            this.EmitCallHandler(loggerMethod);

            this.writer.DetachInstructionSequence();

            InstructionSequence leaveSequence = tryBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(leaveSequence);
            this.writer.EmitBranchingInstruction(OpCodeNumber.Leave, retSequence);
            this.writer.DetachInstructionSequence();

            InstructionBlock protectedBlock;

            InstructionBlock[] catchBlocks;
            InstructionBlock   finallyBlock;

            this.weavingHelper.AddExceptionHandlers(this.writer, tryBlock, leaveSequence, null, true, out protectedBlock, out catchBlocks, out finallyBlock);

            InstructionSequence finallySequence = finallyBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(finallySequence);
            this.writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
            this.writer.EmitInstructionField(OpCodeNumber.Stsfld, this.isLoggingField);
            //this.writer.EmitInstruction(OpCodeNumber.Endfinally);
            this.writer.DetachInstructionSequence();
        }
Ejemplo n.º 29
0
            public override void Implement(TransformationContext context)
            {
                ModuleDeclaration module = this.AspectWeaver.Module;

                TypeDefDeclaration typeDef = (TypeDefDeclaration)context.TargetElement;

                // Declare the method.
                MethodDefDeclaration methodDef = new MethodDefDeclaration
                {
                    Name              = "AutoGeneratedValidate",
                    Attributes        = (MethodAttributes.Family | MethodAttributes.ReuseSlot | MethodAttributes.Virtual),
                    CallingConvention = CallingConvention.HasThis
                };

                typeDef.Methods.Add(methodDef);
                methodDef.CustomAttributes.Add(this.AspectWeaver.AspectInfrastructureTask.WeavingHelper.GetDebuggerNonUserCodeAttribute());

                // Define parameter.
                methodDef.ReturnParameter = new ParameterDeclaration
                {
                    ParameterType = module.Cache.GetIntrinsic(IntrinsicType.Void),
                    Attributes    = ParameterAttributes.Retval
                };

                // Define the body
                MethodBodyDeclaration methodBody = new MethodBodyDeclaration();

                methodDef.MethodBody = methodBody;
                InstructionBlock instructionBlock = methodBody.CreateInstructionBlock();

                methodBody.RootInstructionBlock = instructionBlock;
                InstructionSequence sequence = methodBody.CreateInstructionSequence();

                instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null);

                using (InstructionWriter writer = new InstructionWriter())
                {
                    writer.AttachInstructionSequence(sequence);

                    // Find the base method.
                    IMethod         baseValidateMethod = null;
                    IType           baseTypeCursor     = typeDef.BaseType;
                    MethodSignature methodSignature    =
                        new MethodSignature(module, CallingConvention.HasThis, module.Cache.GetIntrinsic(IntrinsicType.Void),
                                            new ITypeSignature[0], 0);

                    while (baseValidateMethod == null)
                    {
                        TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition();

                        baseValidateMethod =
                            baseTypeCursorTypeDef.Methods.GetMethod("AutoGeneratedValidate",
                                                                    methodSignature.Translate(baseTypeCursorTypeDef.Module),
                                                                    BindingOptions.OnlyExisting |
                                                                    BindingOptions.DontThrowException);

                        baseTypeCursor = baseTypeCursorTypeDef.BaseType;
                    }

                    // TODO: support generic base types.

                    // Call the base method.
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, (IMethod)baseValidateMethod.Translate(typeDef.Module));

                    // Make an array with the boxed field values.
                    TypeValidationAspect aspect = (TypeValidationAspect)this.AspectWeaverInstance.Aspect;
                    LocalVariableSymbol  fieldValuesArrayLocal = instructionBlock.DefineLocalVariable(
                        module.Cache.GetType(typeof(object[])), "fieldValues");
                    writer.EmitInstructionInt32(OpCodeNumber.Ldc_I4, aspect.Validators.Count);
                    writer.EmitInstructionType(OpCodeNumber.Newarr, module.Cache.GetIntrinsic(IntrinsicType.Object));
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, fieldValuesArrayLocal);

                    int i = 0;
                    foreach (FieldValidationAttribute validator in aspect.Validators)
                    {
                        FieldDefDeclaration fieldDef = typeDef.Fields.GetByName(validator.TargetLocation.Name);
                        IField fieldSpec             = GenericHelper.GetFieldCanonicalGenericInstance(fieldDef);

                        writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, fieldValuesArrayLocal);
                        writer.EmitInstructionInt32(OpCodeNumber.Ldc_I4, i);
                        writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                        writer.EmitInstructionField(OpCodeNumber.Ldfld, fieldSpec);
                        writer.EmitConvertToObject(fieldSpec.FieldType);
                        writer.EmitInstruction(OpCodeNumber.Stelem_Ref);

                        i++;
                    }

                    // Get the validator method.
                    IMethod validateMethod = module.Cache.GetItem(
                        () => module.FindMethod(
                            typeof(TypeValidationAspect).GetMethod("Validate"),
                            BindingOptions.Default));

                    // Call the validator.
                    this.AspectWeaverInstance.AspectRuntimeInstanceField.EmitLoadField(writer, null);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, fieldValuesArrayLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, validateMethod);

                    writer.EmitInstruction(OpCodeNumber.Ret);
                    writer.DetachInstructionSequence();
                }
            }
        public void Weave(WeavingContext context, InstructionBlock block)
        {
            TypeDefDeclaration typeDef = m_type;
            // Declare the static field
            FieldDefDeclaration fieldDef = new FieldDefDeclaration();
            fieldDef.Attributes = FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.NotSerialized |
                                  FieldAttributes.InitOnly;
            fieldDef.Name = "s_instance";
            fieldDef.FieldType = typeDef;

            typeDef.Fields.Add(fieldDef);

            // Declare the static accessor.
            PropertyDeclaration propDef = new PropertyDeclaration();
            propDef.Name = "Instance";

            typeDef.Properties.Add(propDef);

            MethodSemanticDeclaration sematic = new MethodSemanticDeclaration();
            sematic.Semantic = MethodSemantics.Getter;

            MethodDefDeclaration methodDef = new MethodDefDeclaration();
            methodDef.Name = "get_Instance";
            methodDef.Attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static |
                                   MethodAttributes.SpecialName;
            methodDef.CallingConvention = CallingConvention.Default;

            typeDef.Methods.Add(methodDef);

            ParameterDeclaration retVal = new ParameterDeclaration();
            retVal.ParameterType = typeDef;
            retVal.Attributes = ParameterAttributes.Retval;
            methodDef.ReturnParameter = retVal;

            sematic.Method = methodDef;

            propDef.Members.Add(sematic);
            propDef.PropertyType = typeDef;

            methodDef.MethodBody = new MethodBodyDeclaration();
            methodDef.MethodBody.MaxStack = 1;
            methodDef.MethodBody.RootInstructionBlock = methodDef.MethodBody.CreateInstructionBlock();

            //throw new NotFiniteNumberException();
            InstructionSequence sequence = methodDef.MethodBody.CreateInstructionSequence();
            methodDef.MethodBody.RootInstructionBlock.AddInstructionSequence(sequence, NodePosition.After, null);
            context.InstructionWriter.AttachInstructionSequence(sequence);

            context.InstructionWriter.EmitInstructionField(OpCodeNumber.Ldsfld, typeDef.Fields.GetByName("s_instance"));
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Ret);

            context.InstructionWriter.DetachInstructionSequence();

            // code for the static constructor
            sequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(sequence, NodePosition.Before, null);
            context.InstructionWriter.AttachInstructionSequence(sequence);
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Newobj, typeDef.Methods.GetOneByName(".ctor"));
            context.InstructionWriter.EmitInstructionField(OpCodeNumber.Stsfld, typeDef.Fields.GetByName("s_instance"));
            context.InstructionWriter.DetachInstructionSequence();

            // Change visibility to the constructor
            typeDef.Methods.GetOneByName(".ctor").Attributes = MethodAttributes.Private | MethodAttributes.HideBySig |
                                                               MethodAttributes.SpecialName |
                                                               MethodAttributes.RTSpecialName;
        }
Ejemplo n.º 31
0
        private void WeaveEntry(WeavingContext context, InstructionBlock block)
        {
            InstructionSequence entrySequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(entrySequence, NodePosition.Before, null);

            InstructionWriter iw = context.InstructionWriter;

            iw.AttachInstructionSequence(entrySequence);
            iw.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

            iw.EmitInstruction(OpCodeNumber.Ldarg_1);
            iw.EmitInstruction(OpCodeNumber.Ldarg_0);
            iw.EmitInstructionMethod(OpCodeNumber.Call, this._getMethod);

            InstructionSequence valuesAreEqualSequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(valuesAreEqualSequence, NodePosition.After, iw.CurrentInstructionSequence);

            ITypeSignature getMethodReturnTypeSignature = _getMethod.ReturnParameter.ParameterType;

            if (getMethodReturnTypeSignature is GenericParameterTypeSignature)
            {
                throw new Exception("PropFu does not support properties returning generic types");
            }

            Type getMethodSystemType = getMethodReturnTypeSignature.GetSystemType(null, null);

            MethodInfo equalityOperator = getMethodSystemType.GetMethod("op_Equality");

            if (equalityOperator == null)
            {
                iw.EmitInstruction(OpCodeNumber.Ceq);
            }
            else
            {
                IMethod methodEquality = this._setMethod.Module.FindMethod(equalityOperator, BindingOptions.Default);
                iw.EmitInstructionMethod(OpCodeNumber.Call, methodEquality);
            }

            iw.EmitBranchingInstruction(OpCodeNumber.Brfalse, valuesAreEqualSequence);
            iw.EmitInstruction(OpCodeNumber.Ret);

            iw.DetachInstructionSequence();

            iw.AttachInstructionSequence(valuesAreEqualSequence);
            iw.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

            iw.EmitInstruction(OpCodeNumber.Nop);

            iw.DetachInstructionSequence();
        }
                protected override void ImplementOnException(InstructionBlock block, ITypeSignature exceptionType, InstructionWriter writer)
                {
                    MethodDefDeclaration targetMethod = this.transformationInstance.AspectWeaverInstance.TargetElement as MethodDefDeclaration;
                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);
                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);
                    writer.AttachInstructionSequence(sequence);

                    LocalVariableSymbol exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable(
                        exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex"));

                    LogSeverity logSeverity = LogSeverity.Warning;
                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logSeverity);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    builder.EmitWrite(writer, block, "An exception occurred:\n{0}", 1, logSeverity,
                                      w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal),
                                      (i, w) => w.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal));

                    writer.EmitInstruction(OpCodeNumber.Rethrow);
                    writer.DetachInstructionSequence();
                }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer, MethodDefDeclaration targetMethod, string messageFormatString)
                {
                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);
                    writer.AttachInstructionSequence(sequence);

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, LogSeverity.Trace);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    int parameterCount = Context.MethodMapping.MethodSignature.ParameterCount;
                    bool hasThis = Context.MethodMapping.MethodSignature.CallingConvention == CallingConvention.HasThis;

                    builder.EmitWrite(writer, block, messageFormatString, parameterCount, LogSeverity.Trace, null,
                                      (i, instructionWriter) =>
                                      {
                                          instructionWriter.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)(hasThis ? i + 1 : i));
                                          instructionWriter.EmitConvertToObject(
                                              this.Context.MethodMapping.MethodSignature.GetParameterType(i));
                                      });

                    writer.DetachInstructionSequence();
                }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer, LogLevel logLevel, string messageFormatString, int[] arguments)
                {
                    MethodDefDeclaration targetMethod = Context.TargetElement as MethodDefDeclaration;
                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);
                    writer.AttachInstructionSequence(sequence);

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logLevel);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    bool useWrapper = ShouldUseWrapper(targetMethod);

                    builder.EmitWrite(writer, messageFormatString, arguments.Length, logLevel, null, (i, instructionWriter) =>
                    {
                        int index = arguments[i];
                        if (index == MessageArgumentsFormatter.ThisArgumentPosition)
                        {
                            this.methodMappingWriter.EmitLoadInstance(false, instructionWriter);
                        }
                        else if (index == MessageArgumentsFormatter.ReturnParameterPosition)
                        {
                            instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, Context.ReturnValueVariable);
                            instructionWriter.EmitConvertToObject(Context.MethodMapping.MethodSignature.ReturnType);
                        }
                        else
                        {
                            this.methodMappingWriter.EmitLoadArgument(index, instructionWriter);

                            instructionWriter.EmitConvertToObject(this.methodMappingWriter.MethodMapping.MethodSignature.GetParameterType(index));
                        }
                    }, useWrapper);

                    writer.DetachInstructionSequence();
                }
        private void WeaveException(WeavingContext context, InstructionBlock block)
        {
            LogLevel level = this.attribute.ExceptionLevel;
              string text = this.attribute.ExceptionText;

              // Inject the logging code only if the logging is turned on.
              if (this.attribute.ExceptionLevel != LogLevel.None)
              {
            // Method being woven and the type the method is declared in.
            MethodDefDeclaration wovenMethod = context.Method;
            TypeDefDeclaration wovenType = wovenMethod.DeclaringType;

            // Objects that contain required methods, fields, etc.
            LogLevelSupportItem supportItem = this.parent.GetSupportItem(level);
            PerTypeLoggingData perTypeLoggingData = this.parent.GetPerTypeLoggingData(wovenType);

            // Get the tokens for the message template.
            StringBuilder messageFormatString = new StringBuilder();
            List<IMessageToken> nonStaticTokens = new List<IMessageToken>();
            List<IMessageToken> messageParts = TemplateParser.Tokenize(text, wovenMethod, attribute.IncludeParamName);
            MakeFormatString(messageParts, messageFormatString, nonStaticTokens);

            // As log4net does not provide an overload for the LogXXX() methods which would accept
            // both exception and array of arguments for a format string, disallow usage of dynamic
            // tokens in the template.
            if (nonStaticTokens.Count > 0)
            {
              throw new FormatException("Message for logging exception can contain only placeholders whose value can be expanded at weaving time.");
            }

            // Variable that stores the reference to the thrown exception.
            LocalVariableSymbol exception = block.DefineLocalVariable(context.Method.Module.FindType(typeof(Exception), BindingOptions.Default), "~ex~{0}");

            // Sequence that contains code that checks if the logging is enabled and logs the message.
            InstructionSequence logExceptionSequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(logExceptionSequence, NodePosition.Before, null);
            // Sequence that contains code that is executed after logging.
            InstructionSequence afterLoggingSequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(afterLoggingSequence, NodePosition.After, logExceptionSequence);

            // Emit code that checks if the logging is enabled and logs the message.
            context.InstructionWriter.AttachInstructionSequence(logExceptionSequence);
            context.InstructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            context.InstructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Stloc_S, exception);
            EmitLoggingEnabledCheck(context.InstructionWriter, supportItem, perTypeLoggingData, afterLoggingSequence);
            EmitLogStringException(context.InstructionWriter, perTypeLoggingData.Log, supportItem.LogStringExceptionMethod, messageFormatString.ToString(), exception);
            context.InstructionWriter.DetachInstructionSequence();

            // After logging is finished (or skipped), rethrow the exception.
            context.InstructionWriter.AttachInstructionSequence(afterLoggingSequence);
            context.InstructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Rethrow);
            context.InstructionWriter.DetachInstructionSequence();
              }
              else
              {
            // Logging is turned off, just rethrow the exception.
            InstructionSequence rethrowSequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(rethrowSequence, NodePosition.Before, null);
            context.InstructionWriter.AttachInstructionSequence(rethrowSequence);
            context.InstructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Rethrow);
            context.InstructionWriter.DetachInstructionSequence();
              }
        }
            public void Weave(WeavingContext context, InstructionBlock block)
            {
                // Type whose constructor is being woven.
                TypeDefDeclaration wovenType = context.Method.DeclaringType;

                // Logging data for the woven type.
                PerTypeLoggingData perTypeLoggingData = this.parent.perTypeLoggingDatas[wovenType];

                InstructionSequence initializeSequence = context.Method.MethodBody.CreateInstructionSequence();

                block.AddInstructionSequence(initializeSequence, NodePosition.Before, null);

                context.InstructionWriter.AttachInstructionSequence(initializeSequence);
                context.InstructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);

                IAnnotationValue loggerPolicyAtt;
                sm_loggerPolicies.TryGetValue(wovenType.Name, out loggerPolicyAtt);

                //Use the helper to get the Logger's name.
                context.WeavingHelper.GetRuntimeType(GenericHelper.GetCanonicalGenericInstance(wovenType), context.InstructionWriter);
                // Stack: type.

                if (loggerPolicyAtt != null)
                {

                  //Two additional params are needed for this method.
                  LoggerPolicyAttribute att = (LoggerPolicyAttribute)(new CustomAttributeDeclaration(loggerPolicyAtt)).ConstructRuntimeObject();
                  context.InstructionWriter.EmitInstructionInt32(OpCodeNumber.Ldc_I4, (int)att.LoggerNamePolicy);
                  context.InstructionWriter.EmitInstructionInt32(OpCodeNumber.Ldc_I4, (int)att.GenericArgsLoggerNamePolicy);
                  context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, this.parent.registerLoggerWithPolicyMethod);
                  // Stack: string  (logger name)
                }
                else
                {
                  context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, this.parent.RegisterLoggerMethod);
                  // Stack: string  (logger name)
                }

                context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Call, this.parent.GetLoggerByStringMethod);
                // Stack: logger.

                // Assign logger to the log variable.
                context.InstructionWriter.EmitInstructionField(OpCodeNumber.Stsfld, GenericHelper.GetCanonicalGenericInstance(perTypeLoggingData.Log));
                // Stack: .

                context.InstructionWriter.DetachInstructionSequence();
            }