private VBStyleCollection <BasicBlock, int> CreateBasicBlocks(short[] startblock,
                                                                      InstructionSequence instrseq, Dictionary <int, BasicBlock> mapInstrBlocks)
        {
            VBStyleCollection <BasicBlock, int> col = new VBStyleCollection <BasicBlock, int>();
            InstructionSequence currseq             = null;
            List <int>          lstOffs             = null;
            int        len          = startblock.Length;
            short      counter      = 0;
            int        blockoffset  = 0;
            BasicBlock currentBlock = null;

            for (int i = 0; i < len; i++)
            {
                if (startblock[i] == 1)
                {
                    currentBlock = new BasicBlock(++counter);
                    currseq      = currentBlock.GetSeq();
                    lstOffs      = currentBlock.GetInstrOldOffsets();
                    col.AddWithKey(currentBlock, currentBlock.id);
                    blockoffset = instrseq.GetOffset(i);
                }
                startblock[i] = counter;
                Sharpen.Collections.Put(mapInstrBlocks, i, currentBlock);
                currseq.AddInstruction(instrseq.GetInstr(i), instrseq.GetOffset(i) - blockoffset);
                lstOffs.Add(instrseq.GetOffset(i));
            }
            last_id = counter;
            return(col);
        }
 public CreatedEmptyMethod(MethodDefDeclaration methodDeclaration, InstructionBlock principalBlock, LocalVariableSymbol returnVariable, InstructionSequence returnSequence)
 {
     this.MethodDeclaration = methodDeclaration;
     this.PrincipalBlock    = principalBlock;
     this.ReturnVariable    = returnVariable;
     this.ReturnSequence    = returnSequence;
 }
                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 bool ProcessSequence(InstructionSequence sequence, string extensionMethodName, Func <AutoPropertyInfo, Instruction> createInstruction)
            {
                for (var index = 0; index < sequence.Count; index++)
                {
                    var instruction = sequence[index];

                    if (!instruction.IsExtensionMethodCall(extensionMethodName))
                    {
                        continue;
                    }

                    if (sequence.Count < 4 ||
                        sequence[0].OpCode != OpCodes.Ldarg_0 ||
                        !sequence[1].IsPropertyGetterCall(out string?propertyName) ||
                        sequence.Skip(index + 1).Any(inst => inst?.OpCode != OpCodes.Nop) ||
                        !_autoPropertyToBackingFieldMap.TryGetValue(propertyName, out var propertyInfo))
                    {
                        var message = $"Invalid usage of extension method '{extensionMethodName}()': '{extensionMethodName}()' is only valid on auto-properties of class {_method.DeclaringType?.Name}";
                        _logger.LogError(message, sequence.Point);
                        return(false);
                    }

                    _logger.LogInfo($"Replace {extensionMethodName}() on property {propertyName} in method {_method}.");

                    sequence[index] = createInstruction(propertyInfo !);
                    sequence.RemoveAt(1);
                    return(true);
                }

                return(true);
            }
        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);
        }
                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();
                }
 public static void RedirectBranchInstructions(this InstructionBlock block, InstructionReader reader, InstructionWriter writer, InstructionSequence branchTargetSequence, Predicate<Instruction> predicate)
 {
     if (block.HasChildrenBlocks) {
         for (InstructionBlock block1 = block.FirstChildBlock; block1 != null; block1 = block1.NextSiblingBlock) {
             if (!block1.HasExceptionHandlers)
                 RedirectBranchInstructions(block1, reader, writer, branchTargetSequence, predicate);
         }
     }
     reader.JumpToInstructionBlock(block);
     if (block.HasInstructionSequences) {
         for (InstructionSequence sequence = block.FirstInstructionSequence; sequence != null; sequence = sequence.NextSiblingSequence) {
             bool commit = false;
             writer.AttachInstructionSequence(sequence);
             reader.EnterInstructionSequence(sequence);
             while (reader.ReadInstruction()) {
                 var opCode = reader.CurrentInstruction.OpCodeNumber;
                 var opCodeInfo = reader.CurrentInstruction.OpCodeInfo;
                 if ((opCodeInfo.FlowControl == FlowControl.Branch
                     || opCodeInfo.FlowControl == FlowControl.Cond_Branch)
                     && (predicate == null || predicate(reader.CurrentInstruction))) {
                     commit = true;
                     writer.EmitBranchingInstruction(opCode, branchTargetSequence);
                 } else {
                     reader.CurrentInstruction.Write(writer);
                 }
             }
             reader.LeaveInstructionSequence();
             writer.DetachInstructionSequence(commit);
         }
     }
     reader.LeaveInstructionBlock();
 }
        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);
        }
        private void SetExceptionEdges(InstructionSequence instrseq, Dictionary <int, BasicBlock
                                                                                 > instrBlocks)
        {
            exceptions = new List <ExceptionRangeCFG>();
            Dictionary <string, ExceptionRangeCFG> mapRanges = new Dictionary <string, ExceptionRangeCFG
                                                                               >();

            foreach (ExceptionHandler handler in instrseq.GetExceptionTable().GetHandlers())
            {
                BasicBlock from   = instrBlocks.GetOrNull(handler.from_instr);
                BasicBlock to     = instrBlocks.GetOrNull(handler.to_instr);
                BasicBlock handle = instrBlocks.GetOrNull(handler.handler_instr);
                string     key    = from.id + ":" + to.id + ":" + handle.id;
                if (mapRanges.ContainsKey(key))
                {
                    ExceptionRangeCFG range = mapRanges.GetOrNull(key);
                    range.AddExceptionType(handler.exceptionClass);
                }
                else
                {
                    List <BasicBlock> protectedRange = new List <BasicBlock>();
                    for (int j = from.id; j < to.id; j++)
                    {
                        BasicBlock block = blocks.GetWithKey(j);
                        protectedRange.Add(block);
                        block.AddSuccessorException(handle);
                    }
                    ExceptionRangeCFG range = new ExceptionRangeCFG(protectedRange, handle, handler.exceptionClass
                                                                    == null ? null : System.Linq.Enumerable.ToList(new [] { handler.exceptionClass })
                                                                    );
                    Sharpen.Collections.Put(mapRanges, key, range);
                    exceptions.Add(range);
                }
            }
        }
        private static short[] FindStartInstructions(InstructionSequence seq)
        {
            int len = seq.Length();

            short[]       inststates = new short[len];
            HashSet <int> excSet     = new HashSet <int>();

            foreach (ExceptionHandler handler in seq.GetExceptionTable().GetHandlers())
            {
                excSet.Add(handler.from_instr);
                excSet.Add(handler.to_instr);
                excSet.Add(handler.handler_instr);
            }
            for (int i = 0; i < len; i++)
            {
                // exception blocks
                if (excSet.Contains(i))
                {
                    inststates[i] = 1;
                }
                Instruction instr = seq.GetInstr(i);
                switch (instr.group)
                {
                case Group_Jump:
                {
                    inststates[((JumpInstruction)instr).destination] = 1;
                    goto case Group_Return;
                }

                case Group_Return:
                {
                    if (i + 1 < len)
                    {
                        inststates[i + 1] = 1;
                    }
                    break;
                }

                case Group_Switch:
                {
                    SwitchInstruction swinstr = (SwitchInstruction)instr;
                    int[]             dests   = swinstr.GetDestinations();
                    for (int j = dests.Length - 1; j >= 0; j--)
                    {
                        inststates[dests[j]] = 1;
                    }
                    inststates[swinstr.GetDefaultDestination()] = 1;
                    if (i + 1 < len)
                    {
                        inststates[i + 1] = 1;
                    }
                    break;
                }
                }
            }
            // first instruction
            inststates[0] = 1;
            return(inststates);
        }
Beispiel #11
0
        public void Emit(InstructionWriter writer, InstructionBlock block, TypeInitializationClientScopes scope)
        {
            InstructionSequence sequence = block.AddInstructionSequence();

            writer.AttachInstructionSequence(sequence);
            writer.EmitInstructionMethod(OpCodeNumber.Call, attachMethod);
            writer.DetachInstructionSequence();
        }
Beispiel #12
0
 public virtual void ReleaseResources()
 {
     if (containsCode__ && expanded)
     {
         seq      = null;
         expanded = false;
     }
 }
        private static void RemoveJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint
                                                  data)
        {
            ListStack <VarType> stack = data.GetStack();
            InstructionSequence seq   = block.GetSeq();

            for (int i = 0; i < seq.Length(); i++)
            {
                Instruction instr = seq.GetInstr(i);
                VarType     var   = null;
                if (instr.opcode == ICodeConstants.opc_astore || instr.opcode == ICodeConstants.opc_pop)
                {
                    var = stack.GetByOffset(-1);
                }
                InstructionImpact.StepTypes(data, instr, pool);
                switch (instr.opcode)
                {
                case ICodeConstants.opc_jsr:
                case ICodeConstants.opc_ret:
                {
                    seq.RemoveInstruction(i);
                    i--;
                    break;
                }

                case ICodeConstants.opc_astore:
                case ICodeConstants.opc_pop:
                {
                    if (var.type == ICodeConstants.Type_Address)
                    {
                        seq.RemoveInstruction(i);
                        i--;
                    }
                    break;
                }
                }
            }
            block.mark = 1;
            for (int i = 0; i < block.GetSuccs().Count; i++)
            {
                BasicBlock suc = block.GetSuccs()[i];
                if (suc.mark != 1)
                {
                    RemoveJsrInstructions(pool, suc, data.Copy());
                }
            }
            for (int i = 0; i < block.GetSuccExceptions().Count; i++)
            {
                BasicBlock suc = block.GetSuccExceptions()[i];
                if (suc.mark != 1)
                {
                    DataPoint point = new DataPoint();
                    point.SetLocalVariables(new List <VarType>(data.GetLocalVariables()));
                    point.GetStack().Push(new VarType(ICodeConstants.Type_Object, 0, null));
                    RemoveJsrInstructions(pool, suc, point);
                }
            }
        }
Beispiel #14
0
        public virtual void BuildMonitorFlags()
        {
            foreach (Statement st in stats)
            {
                st.BuildMonitorFlags();
            }
            switch (type)
            {
            case Type_Basicblock:
            {
                BasicBlockStatement bblock = (BasicBlockStatement)this;
                InstructionSequence seq    = bblock.GetBlock().GetSeq();
                if (seq != null && seq.Length() > 0)
                {
                    for (int i = 0; i < seq.Length(); i++)
                    {
                        if (seq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                        {
                            containsMonitorExit = true;
                            break;
                        }
                    }
                    isMonitorEnter__ = (seq.GetLastInstr().opcode == ICodeConstants.opc_monitorenter);
                }
                break;
            }

            case Type_Sequence:
            case Type_If:
            {
                containsMonitorExit = false;
                foreach (Statement st in stats)
                {
                    containsMonitorExit |= st.IsContainsMonitorExit();
                }
                break;
            }

            case Type_Syncronized:
            case Type_Root:
            case Type_General:
            {
                break;
            }

            default:
            {
                containsMonitorExit = false;
                foreach (Statement st in stats)
                {
                    containsMonitorExit |= st.IsContainsMonitorExit();
                }
                break;
            }
            }
        }
 private void EmitContstructorBlock(MethodDefDeclaration staticConstructor)
 {
     this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
     this.returnSequence   = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null,
                                                                                                      NodePosition.After,
                                                                                                      null);
     this.writer.AttachInstructionSequence(this.returnSequence);
     this.writer.EmitInstruction(OpCodeNumber.Ret);
     this.writer.DetachInstructionSequence();
 }
Beispiel #16
0
 /// <exception cref="System.IO.IOException"/>
 public virtual void ExpandData()
 {
     if (containsCode__ && !expanded)
     {
         byte[] code = classStruct.GetLoader().LoadBytecode(this, codeFullLength);
         seq = ParseBytecode(new DataInputFullStream(code), codeLength, classStruct.GetPool
                                 ());
         expanded = true;
     }
 }
        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 ControlFlowGraph(InstructionSequence seq)
 {
     // *****************************************************************************
     // private fields
     // *****************************************************************************
     // *****************************************************************************
     // constructors
     // *****************************************************************************
     BuildBlocks(seq);
 }
        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();
        }
        //return ranges.isEmpty() ? null : ranges;
        //	public String getExceptionsUniqueString(BasicBlock handler, BasicBlock block) {
        //
        //		List<ExceptionRangeCFG> ranges = getExceptionRange(handler, block);
        //
        //		if(ranges == null) {
        //			return null;
        //		} else {
        //			Set<String> setExceptionStrings = new HashSet<String>();
        //			for(ExceptionRangeCFG range : ranges) {
        //				setExceptionStrings.add(range.getExceptionType());
        //			}
        //
        //			String ret = "";
        //			for(String exception : setExceptionStrings) {
        //				ret += exception;
        //			}
        //
        //			return ret;
        //		}
        //	}
        // *****************************************************************************
        // private methods
        // *****************************************************************************
        private void BuildBlocks(InstructionSequence instrseq)
        {
            short[] states = FindStartInstructions(instrseq);
            Dictionary <int, BasicBlock>        mapInstrBlocks = new Dictionary <int, BasicBlock>();
            VBStyleCollection <BasicBlock, int> colBlocks      = CreateBasicBlocks(states, instrseq
                                                                                   , mapInstrBlocks);

            blocks = colBlocks;
            ConnectBlocks(colBlocks, mapInstrBlocks);
            SetExceptionEdges(instrseq, mapInstrBlocks);
            SetSubroutineEdges();
            SetFirstAndLastBlocks();
        }
Beispiel #21
0
 public static void MergeBasicBlocks(ControlFlowGraph graph)
 {
     while (true)
     {
         bool merged = false;
         foreach (BasicBlock block in graph.GetBlocks())
         {
             InstructionSequence seq = block.GetSeq();
             if (block.GetSuccs().Count == 1)
             {
                 BasicBlock next = block.GetSuccs()[0];
                 if (next != graph.GetLast() && (seq.IsEmpty() || seq.GetLastInstr().group != ICodeConstants
                                                 .Group_Switch))
                 {
                     if (next.GetPreds().Count == 1 && (next.GetPredExceptions().Count == 0) && next !=
                         graph.GetFirst())
                     {
                         // TODO: implement a dummy start block
                         bool sameRanges = true;
                         foreach (ExceptionRangeCFG range in graph.GetExceptions())
                         {
                             if (range.GetProtectedRange().Contains(block) ^ range.GetProtectedRange().Contains
                                     (next))
                             {
                                 sameRanges = false;
                                 break;
                             }
                         }
                         if (sameRanges)
                         {
                             seq.AddSequence(next.GetSeq());
                             Sharpen.Collections.AddAll(block.GetInstrOldOffsets(), next.GetInstrOldOffsets());
                             next.GetSeq().Clear();
                             RemoveEmptyBlock(graph, next, true);
                             merged = true;
                             break;
                         }
                     }
                 }
             }
         }
         if (!merged)
         {
             break;
         }
     }
 }
Beispiel #22
0
        static void Main(string[] args)
        {
            var expressionManager = new InstructionSequence();

            var rd3s = Radh3aParser.Parse(@"D:\radh3a.txt");

            foreach (var rd3 in rd3s)
            {
                if (rd3 == "rd3.rd3?")
                {
                    expressionManager.Add(new MovePointerForwardInstruction());
                }
                else if (rd3 == "rd3?rd3.")
                {
                    expressionManager.Add(new MovePointerBackwardInstruction());
                }
                else if (rd3 == "rd3.rd3.")
                {
                    expressionManager.Add(new IncrementCellInstruction());
                }
                else if (rd3 == "rd3!rd3!")
                {
                    expressionManager.Add(new DecrementCellInstruction());
                }
                else if (rd3 == "rd3.rd3!")
                {
                    expressionManager.Add(new ReadCharInstruction());
                }
                else if (rd3 == "rd3!rd3.")
                {
                    expressionManager.Add(new PrintCharInstruction());
                }
                else if (rd3 == "rd3!rd3?")
                {
                    expressionManager.Add(new MoveForwardToWhenZeroInstruction(expressionManager));
                }
                else if (rd3 == "rd3?rd3!")
                {
                    expressionManager.Add(new MoveBackwardToIfNotZeroInstruction(expressionManager));
                }
            }

            expressionManager.Run();

            Console.ReadLine();
        }
        private TypeDefDeclaration CreateContainingType()
        {
            string uniqueName = this.module.Types.GetUniqueName(
                DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}"));

            TypeDefDeclaration logCategoriesType = new TypeDefDeclaration
            {
                Name       = uniqueName,
                Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract,
                BaseType   = ((IType)this.module.Cache.GetType("System.Object, mscorlib"))
            };

            this.module.Types.Add(logCategoriesType);

            // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type
            this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes);
            this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes);

            MethodDefDeclaration staticConstructor = new MethodDefDeclaration
            {
                Name       = ".cctor",
                Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName |
                             MethodAttributes.SpecialName | MethodAttributes.HideBySig,
            };

            logCategoriesType.Methods.Add(staticConstructor);

            staticConstructor.ReturnParameter = new ParameterDeclaration
            {
                Attributes    = ParameterAttributes.Retval,
                ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void)
            };

            this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
            this.returnSequence   = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null);

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

            return(logCategoriesType);
        }
Beispiel #24
0
        /// <summary>
        /// Emits:
        /// <code>
        ///   brfalse elseBranch;
        ///   thenStatement();
        ///   br end;
        /// elseBranch:
        ///   elseStatement();
        /// end:
        /// </code>
        /// </summary>
        public static void IfNotZero(this InstructionWriter writer,
                                     Action <InstructionWriter> thenStatement,
                                     Action <InstructionWriter> elseStatement)
        {
            InstructionSequence elseSequence =
                writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence();
            InstructionSequence endSequence =
                writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence();

            writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, elseSequence);

            thenStatement(writer);
            writer.EmitBranchingInstruction(OpCodeNumber.Br, endSequence);
            writer.DetachInstructionSequence();
            writer.AttachInstructionSequence(elseSequence);
            elseStatement(writer);
            writer.EmitBranchingInstruction(OpCodeNumber.Br, endSequence);
            writer.DetachInstructionSequence();
            writer.AttachInstructionSequence(endSequence);
        }
        /// <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 static void RemoveExceptionInstructionsEx(BasicBlock block, int blocktype
                                                          , int finallytype)
        {
            InstructionSequence seq = block.GetSeq();

            if (finallytype == 3)
            {
                // empty finally handler
                for (int i = seq.Length() - 1; i >= 0; i--)
                {
                    seq.RemoveInstruction(i);
                }
            }
            else
            {
                if ((blocktype & 1) > 0)
                {
                    // first
                    if (finallytype == 2 || finallytype == 1)
                    {
                        // astore or pop
                        seq.RemoveInstruction(0);
                    }
                }
                if ((blocktype & 2) > 0)
                {
                    // last
                    if (finallytype == 2 || finallytype == 0)
                    {
                        seq.RemoveLast();
                    }
                    if (finallytype == 2)
                    {
                        // astore
                        seq.RemoveLast();
                    }
                }
            }
        }
Beispiel #27
0
        /// <summary>
        /// Emits:
        /// <code>
        ///   br begin;
        /// begin:
        ///   condition();
        ///   brfalse end;
        ///   body();
        ///   br begin;
        /// end:
        /// </code>
        /// </summary>
        public static void WhileNotZero(this InstructionWriter writer,
                                        Action <InstructionWriter> condition,
                                        Action <InstructionWriter> body)
        {
            InstructionSequence loopBegin =
                writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence();
            InstructionSequence loopEnd =
                writer.CurrentInstructionSequence.ParentInstructionBlock.AddInstructionSequence();

            writer.EmitBranchingInstruction(OpCodeNumber.Br, loopBegin);
            writer.DetachInstructionSequence();
            writer.AttachInstructionSequence(loopBegin);

            condition(writer);

            writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, loopEnd);

            body(writer);

            writer.EmitBranchingInstruction(OpCodeNumber.Br, loopBegin);
            writer.DetachInstructionSequence();
            writer.AttachInstructionSequence(loopEnd);
        }
        private FieldDefDeclaration CreateCategoryField(ITypeSignature fieldType, Action <InstructionWriter> initializeFieldAction)
        {
            string fieldName = string.Format("l{0}", this.containingType.Fields.Count + 1);

            FieldDefDeclaration loggerFieldDef = new FieldDefDeclaration
            {
                Name       = fieldName,
                Attributes = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly,
                FieldType  = fieldType
            };

            this.containingType.Fields.Add(loggerFieldDef);

            InstructionSequence sequence = this.constructorBlock.AddInstructionSequence(null,
                                                                                        NodePosition.Before,
                                                                                        this.returnSequence);

            this.writer.AttachInstructionSequence(sequence);
            initializeFieldAction(this.writer);
            this.writer.EmitInstructionField(OpCodeNumber.Stsfld, loggerFieldDef);
            this.writer.DetachInstructionSequence();

            return(loggerFieldDef);
        }
        /// <summary>
        /// Emits the MSIL code that jumps to the specified label if logging is disabled.
        /// </summary>
        /// <param name="emitter">IL emitter.</param>
        /// <param name="logLevelSupportItem">Item for the logging level.</param>
        /// <param name="perTypeLoggingData">Data for the type being woven.</param>
        /// <param name="afterLoggingSequence">Sequence to jump to if logging is disabled.</param>
        /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="logLevelSupportItem"/>, <paramref name="perTypeLoggingData"/> or <paramref name="afterLoggingSequence"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack 
        /// and it leaves the stack unmodified.</para>
        /// </remarks>
        private static void EmitLoggingEnabledCheck(InstructionWriter emitter, LogLevelSupportItem logLevelSupportItem, PerTypeLoggingData perTypeLoggingData, InstructionSequence afterLoggingSequence)
        {
            if (emitter == null)
              {
            throw new ArgumentNullException("emitter");
              }
              if (logLevelSupportItem == null)
              {
            throw new ArgumentNullException("logLevelSupportItem");
              }
              if (perTypeLoggingData == null)
              {
            throw new ArgumentNullException("perTypeLoggingData");
              }
              if (afterLoggingSequence == null)
              {
            throw new ArgumentNullException("afterLoggingSequence");
              }

              emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetCanonicalGenericInstance(perTypeLoggingData.Log));
              emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, logLevelSupportItem.IsLoggingEnabledGetter);
              emitter.EmitInstruction(OpCodeNumber.Ldc_I4_0);
              emitter.EmitInstruction(OpCodeNumber.Ceq);
              emitter.EmitBranchingInstruction(OpCodeNumber.Brtrue_S, afterLoggingSequence);
        }
 public void LeaveInstructionSequence(InstructionSequence instructionSequence)
 {
 }
 public void EnterInstructionSequence(InstructionSequence instructionSequence)
 {
 }
                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();
                    }
                }
 public static void Leave_IfTrue(this InstructionWriter instructionWriter, InstructionSequence leaveTarget)
 {
     instructionWriter.EmitBranchingInstruction(OpCodeNumber.Brtrue, leaveTarget);
 }
 public static void RedirectBranchInstructions(this InstructionBlock block, InstructionReader reader, InstructionWriter writer, InstructionSequence branchTargetSequence)
 {
     RedirectBranchInstructions(block, reader, writer, branchTargetSequence, null);
 }
 public InstructionSequenceTreeNode( InstructionSequence sequence )
     : base( TreeViewImage.Field, sequence )
 {
     this.Text = sequence.ToString();
 }
Beispiel #36
0
 public void LeaveInstructionSequence(InstructionSequence instructionSequence)
 {
 }
Beispiel #37
0
 public void EnterInstructionSequence(InstructionSequence instructionSequence)
 {
 }
 /// <summary>
 /// Emits instruction that invoke <b>InitializeAspects</b>.
 /// </summary>
 /// <param name="initializeMethodDef">The <b>InitializeAspects</b> method.</param>
 /// <param name="sequence"><see cref="InstructionSequence"/> where instructions have to be emitted.</param>
 /// <param name="writer">The <see cref="InstructionWriter"/> to be used.</param>
 private static void EmitCallInitialize( MethodDefDeclaration initializeMethodDef, InstructionSequence sequence, InstructionWriter writer )
 {
     writer.AttachInstructionSequence( sequence );
     writer.EmitSymbolSequencePoint( SymbolSequencePoint.Hidden );
     writer.EmitInstruction( OpCodeNumber.Ldarg_0 );
     writer.EmitInstructionMethod( OpCodeNumber.Callvirt, GenericHelper.GetMethodCanonicalGenericInstance( initializeMethodDef ) );
     writer.DetachInstructionSequence();
 }
 private void EmitContstructorBlock( MethodDefDeclaration staticConstructor )
 {
     this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
     this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence( null,
                                                                                                     NodePosition.After,
                                                                                                     null );
     this.writer.AttachInstructionSequence( this.returnSequence );
     this.writer.EmitInstruction( OpCodeNumber.Ret );
     this.writer.DetachInstructionSequence();
 }
        private TypeDefDeclaration CreateContainingType()
        {
            string uniqueName = this.module.Types.GetUniqueName(
                DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}"));

            TypeDefDeclaration logCategoriesType = new TypeDefDeclaration
            {
                Name = uniqueName,
                Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract,
                BaseType = ((IType)this.module.Cache.GetType("System.Object, mscorlib"))
            };
            this.module.Types.Add(logCategoriesType);

            // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type
            this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes);
            this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes);

            MethodDefDeclaration staticConstructor = new MethodDefDeclaration
            {
                Name = ".cctor",
                Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName |
                             MethodAttributes.SpecialName | MethodAttributes.HideBySig,
            };
            logCategoriesType.Methods.Add(staticConstructor);

            staticConstructor.ReturnParameter = new ParameterDeclaration
            {
                Attributes = ParameterAttributes.Retval,
                ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void)
            };

            this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
            this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null);

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

            return logCategoriesType;
        }