コード例 #1
0
    private void EmitInstructions(ControlAndDataFlowGraph<EnhancedBasicBlock<Instruction>, Instruction> cdfg) {
      Contract.Requires(cdfg != null);

      foreach (var block in cdfg.AllBlocks) {
        Contract.Assume(block != null);
        this.sourceEmitter.EmitLabel("l" + block.Offset.ToString("x4") + ":");
        this.sourceEmitter.EmitNewLine();

        bool first = true;
        this.previousInstruction = null;

        foreach (var instruction in block.Instructions) {
          Contract.Assume(instruction != null);
          if (first && this.catchHandlerOffsets.Contains(instruction.Operation.Offset+1)) {
            this.sourceEmitter.EmitString("originalException = exception;");
            this.sourceEmitter.EmitNewLine();
          }
          first = false;
          if (!this.EmitInstruction(instruction)) continue;
          if (instruction.Operation.OperationCode != OperationCode.Unaligned_)
            this.previousInstruction = instruction;
          this.sourceEmitter.EmitString(";");
          this.sourceEmitter.EmitNewLine();
        }
      }
    }
コード例 #2
0
    internal InstructionParser(SourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);

      this.sourceMethodBody = sourceMethodBody;
      this.host = sourceMethodBody.host; Contract.Assume(this.host != null);
      this.ilMethodBody = sourceMethodBody.ilMethodBody; Contract.Assume(this.ilMethodBody != null);
      this.MethodDefinition = sourceMethodBody.MethodDefinition;
      this.nameTable = sourceMethodBody.nameTable; Contract.Assume(this.nameTable != null);
      this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider;
      this.localScopeProvider = sourceMethodBody.localScopeProvider;
      this.options = sourceMethodBody.options;
      this.platformType = sourceMethodBody.platformType; Contract.Assume(this.platformType != null);
      this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(this.numberOfAssignmentsToLocal != null);
      this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(this.numberOfReferencesToLocal != null);
      this.gotosThatTarget = sourceMethodBody.gotosThatTarget; Contract.Assume(this.gotosThatTarget != null);
      this.cdfg = sourceMethodBody.cdfg; Contract.Assume(this.cdfg != null);
      this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(this.bindingsThatMakeALastUseOfALocalVersion != null);

      if (this.localScopeProvider != null) {
        var syncInfo = this.localScopeProvider.GetSynchronizationInformation(sourceMethodBody);
        if (syncInfo != null) {
          var syncPointFor = this.synchronizatonPointLocationFor = new Hashtable<SynchronizationPointLocation>();
          IDocument doc = Dummy.Document;
          foreach (var loc in this.MethodDefinition.Locations) { doc = loc.Document; break; }
          foreach (var syncPoint in syncInfo.SynchronizationPoints) {
            Contract.Assume(syncPoint != null);
            var syncLoc = new SynchronizationPointLocation(doc, syncPoint);
            syncPointFor[syncPoint.SynchronizeOffset] = syncLoc;
            if (syncPoint.ContinuationMethod == null)
              syncPointFor[syncPoint.ContinuationOffset] = syncLoc;
          }
        }
      }
    }
コード例 #3
0
        /// <summary>
        ///
        /// </summary>
        internal static void FillInTypes(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cfg)
        {
            Contract.Requires(host != null);
            Contract.Requires(cfg != null);
            var stack                = new Stack <Instruction>(cfg.MethodBody.MaxStack, new List <Instruction>(0));
            var numberOfBlocks       = cfg.BlockFor.Count;
            var blocksToVisit        = new Queue <BasicBlock>((int)numberOfBlocks);
            var blocksAlreadyVisited = new SetOfObjects(numberOfBlocks);
            var inferencer           = new TypeInferencer <BasicBlock, Instruction>(host, cfg, stack, blocksToVisit, blocksAlreadyVisited);

            foreach (var root in cfg.RootBlocks)
            {
                blocksToVisit.Enqueue(root);
                while (blocksToVisit.Count != 0)
                {
                    inferencer.DequeueBlockAndFillInItsTypes();
                }
            }
            //At this point, all reachable code blocks have had their types inferred. Now look for unreachable blocks.
            foreach (var block in cfg.AllBlocks)
            {
                if (blocksAlreadyVisited.Contains(block))
                {
                    continue;
                }
                blocksToVisit.Enqueue(block);
                while (blocksToVisit.Count != 0)
                {
                    inferencer.DequeueBlockAndFillInItsTypes();
                }
            }
        }
コード例 #4
0
        public override void Traverse(IMethodBody methodBody)
        {
            sourceEmitterOutput.WriteLine("");
            this.sourceEmitterOutput.WriteLine(MemberHelper.GetMethodSignature(methodBody.MethodDefinition,
                                                                               NameFormattingOptions.Signature | NameFormattingOptions.ReturnType | NameFormattingOptions.ParameterModifiers | NameFormattingOptions.ParameterName));
            sourceEmitterOutput.WriteLine("");
            if (this.pdbReader != null)
            {
                PrintScopes(methodBody);
            }
            else
            {
                PrintLocals(methodBody.LocalVariables);
            }

            this.cdfg = ControlAndDataFlowGraph <AiBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);

            this.cfgQueries = new ControlGraphQueries <AiBasicBlock <Instruction>, Instruction>(this.cdfg);
            SingleAssigner <AiBasicBlock <Instruction>, Instruction> .GetInSingleAssignmentForm(host.NameTable, this.cdfg, this.cfgQueries, this.pdbReader);

            this.valueMappings = new ValueMappings <Instruction>(this.host.PlatformType, new Z3Wrapper.Wrapper(host.PlatformType));
            AbstractInterpreter <AiBasicBlock <Instruction>, Instruction> .InterpretUsingAbstractValues(this.cdfg, this.cfgQueries, this.valueMappings);

            var numberOfBlocks = this.cdfg.BlockFor.Count;

            foreach (var block in this.cdfg.AllBlocks)
            {
                this.PrintBlock(block);
            }

            sourceEmitterOutput.WriteLine("**************************************************************");
            sourceEmitterOutput.WriteLine();
        }
コード例 #5
0
    public override void Traverse(IMethodBody methodBody) {
      sourceEmitterOutput.WriteLine("");
      this.sourceEmitterOutput.WriteLine(MemberHelper.GetMethodSignature(methodBody.MethodDefinition,
        NameFormattingOptions.Signature|NameFormattingOptions.ReturnType|NameFormattingOptions.ParameterModifiers|NameFormattingOptions.ParameterName));
      sourceEmitterOutput.WriteLine("");
      if (this.pdbReader != null)
        PrintScopes(methodBody);
      else
        PrintLocals(methodBody.LocalVariables);

      this.cdfg = ControlAndDataFlowGraph<AiBasicBlock<Instruction>, Instruction>.GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);
      this.cfgQueries = new ControlGraphQueries<AiBasicBlock<Instruction>, Instruction>(this.cdfg);
      SingleAssigner<AiBasicBlock<Instruction>, Instruction>.GetInSingleAssignmentForm(host.NameTable, this.cdfg, this.cfgQueries, this.pdbReader);
      this.valueMappings = new ValueMappings<Instruction>(this.host.PlatformType, new Z3Wrapper.Wrapper(host.PlatformType));
      AbstractInterpreter<AiBasicBlock<Instruction>, Instruction>.InterpretUsingAbstractValues(this.cdfg, this.cfgQueries, this.valueMappings);

      var numberOfBlocks = this.cdfg.BlockFor.Count;

      foreach (var block in this.cdfg.AllBlocks) {
        this.PrintBlock(block);
      }

      sourceEmitterOutput.WriteLine("**************************************************************");
      sourceEmitterOutput.WriteLine();
    }
コード例 #6
0
        public void RunOnControlFlowGraph(ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> cfg, BasicBlock <Instruction> entryBlock)
        {
            stateAbstraction = StateInterpreter.StateAbstraction;

            ControlFlowGraph = cfg;

            // factor this out into a static method
            // CFG only gives us successors, but we want predecessors too. So we stash those in a dictionary
            foreach (BasicBlock <Instruction> block in cfg.AllBlocks)
            {
                foreach (BasicBlock <Instruction> successor in cfg.SuccessorsFor(block))
                {
                    ISet <BasicBlock <Instruction> > predecessorsOfSuccessor;

                    if (!predecessorsByBlock.TryGetValue(successor, out predecessorsOfSuccessor))
                    {
                        predecessorsOfSuccessor        = new HashSet <BasicBlock <Instruction> >();
                        predecessorsByBlock[successor] = predecessorsOfSuccessor;
                    }

                    predecessorsOfSuccessor.Add(block);
                }
            }

            this.entryBlock = entryBlock;

            // This needn't actually be true.
            //Contract.Assert(PredecessorsOfBlock(entryBlock).Count() == 0);
            // We still might want to assert something like: "the entry block dominates all blocks reachable from it"?

            Run();
        }
コード例 #7
0
        /// <summary>
        /// Allocates a metadata (IL) representation along with a source level representation of the body of a method or of a property/event accessor.
        /// </summary>
        /// <param name="ilMethodBody">A method body whose IL operations should be decompiled into a block of statements that will be the
        /// result of the Block property of the resulting source method body.</param>
        /// <param name="host">An object representing the application that is hosting the converter. It is used to obtain access to some global
        /// objects and services such as the shared name table and the table for interning references.</param>
        /// <param name="sourceLocationProvider">An object that can map some kinds of ILocation objects to IPrimarySourceLocation objects. May be null.</param>
        /// <param name="localScopeProvider">An object that can provide information about the local scopes of a method.</param>
        /// <param name="options">Set of options that control decompilation.</param>
        public SourceMethodBody(IMethodBody ilMethodBody, IMetadataHost host, ISourceLocationProvider /*?*/ sourceLocationProvider,
                                ILocalScopeProvider /*?*/ localScopeProvider, DecompilerOptions options = DecompilerOptions.None)
            : base(host, sourceLocationProvider, localScopeProvider)
        {
            Contract.Requires(ilMethodBody != null);
            Contract.Requires(host != null);

            this.ilMethodBody           = ilMethodBody;
            this.host                   = host;
            this.nameTable              = host.NameTable;
            this.sourceLocationProvider = sourceLocationProvider;
            this.pdbReader              = sourceLocationProvider as PdbReader;
            this.localScopeProvider     = localScopeProvider;
            this.options                = options;
            this.platformType           = ilMethodBody.MethodDefinition.ContainingTypeDefinition.PlatformType;
            if (IteratorHelper.EnumerableIsNotEmpty(ilMethodBody.LocalVariables))
            {
                this.LocalsAreZeroed = ilMethodBody.LocalsAreZeroed;
            }
            else
            {
                this.LocalsAreZeroed = true;
            }
            this.MethodDefinition             = ilMethodBody.MethodDefinition;
            this.privateHelperFieldsToRemove  = null;
            this.privateHelperMethodsToRemove = null;
            this.privateHelperTypesToRemove   = null;
            this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, ilMethodBody, localScopeProvider);
        }
コード例 #8
0
        public override void Visit(IMethodBody methodBody)
        {
            Console.WriteLine();
            Console.WriteLine("==========================");
            Console.WriteLine("{0}", MemberHelper.GetMemberSignature(methodBody.MethodDefinition, NameFormattingOptions.DocumentationId));

            var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader);

            var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);

            var numberOfBlocks = cdfg.BlockFor.Count;

            Console.WriteLine("# blocks: {0}", numberOfBlocks);
            Console.WriteLine("CFG");
            foreach (var block in cdfg.AllBlocks)
            {
                Console.WriteLine("{0:X}, Successors: {1}", block.Offset, Offsets(cdfg.SuccessorsFor(block)));
            }

            Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > > dominators = new Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > >();

            foreach (var b in cdfg.AllBlocks)
            {
                var dom = new List <EnhancedBasicBlock <Instruction> >();
                foreach (var c in cdfg.AllBlocks)
                {
                    if (cfgQueries.Dominates(c, b))
                    {
                        dom.Add(c);
                    }
                }
                dominators.Add(b, dom);
            }

            var surroundingLoops = LoopFinder.GetLoopInformation(cdfg, cfgQueries, methodBody);

            Console.WriteLine("\nLoop information");
            foreach (var b in cdfg.AllBlocks)
            {
                List <EnhancedBasicBlock <Instruction> > loops;
                if (surroundingLoops.TryGetValue(b, out loops))
                {
                    Console.WriteLine("{0:X}: ({1} loop{3}) {2}",
                                      b.Offset,
                                      loops.Count(),
                                      String.Join(",", loops.Select(l => String.Format("{0:X}", l.Offset))),
                                      loops.Count() > 1 ? "s" : ""
                                      );
                }
                else
                {
                    //Console.WriteLine("{0:X} is not contained in a loop", b.Offset);
                }
            }

            return;
        }
コード例 #9
0
    public override IMethodBody Rewrite(IMethodBody methodBody) {
      this.cdfg = ControlAndDataFlowGraph<BasicBlock<Instruction>, Instruction>.GetControlAndDataFlowGraphFor(this.host, methodBody);
      this.ilGenerator = new ILGenerator(host, methodBody.MethodDefinition);

      var numberOfBlocks = this.cdfg.BlockFor.Count;
      this.labelFor = new Hashtable<ILGeneratorLabel>(numberOfBlocks);
      this.counterFieldsForCurrentMethod = new NestedTypeDefinition() {
        BaseClasses = new List<ITypeReference>(1) { this.host.PlatformType.SystemObject },
        ContainingTypeDefinition = methodBody.MethodDefinition.ContainingTypeDefinition,
        Fields = new List<IFieldDefinition>((int)numberOfBlocks*2),
        Methods = new List<IMethodDefinition>(1),
        InternFactory = this.host.InternFactory,
        IsBeforeFieldInit = true,
        IsClass = true,
        IsSealed = true,
        IsAbstract = true,
        Name = this.host.NameTable.GetNameFor(methodBody.MethodDefinition.Name+"_Counters"+methodBody.MethodDefinition.InternedKey),
        Visibility = TypeMemberVisibility.Assembly,
      };
      this.fieldOffsets = new List<uint>((int)numberOfBlocks*2);

      foreach (var exceptionInfo in methodBody.OperationExceptionInformation) {
        this.ilGenerator.AddExceptionHandlerInformation(exceptionInfo.HandlerKind, exceptionInfo.ExceptionType,
          this.GetLabelFor(exceptionInfo.TryStartOffset), this.GetLabelFor(exceptionInfo.TryEndOffset),
          this.GetLabelFor(exceptionInfo.HandlerStartOffset), this.GetLabelFor(exceptionInfo.HandlerEndOffset),
          exceptionInfo.HandlerKind == HandlerKind.Filter ? this.GetLabelFor(exceptionInfo.FilterDecisionStartOffset) : null);
      }

      if (this.pdbReader == null) {
        foreach (var localDef in methodBody.LocalVariables)
          this.ilGenerator.AddVariableToCurrentScope(localDef);
      } else {
        foreach (var ns in this.pdbReader.GetNamespaceScopes(methodBody)) {
          foreach (var uns in ns.UsedNamespaces)
            this.ilGenerator.UseNamespace(uns.NamespaceName.Value);
        }
        this.scopeEnumerator = this.pdbReader.GetLocalScopes(methodBody).GetEnumerator();
        this.scopeEnumeratorIsValid = this.scopeEnumerator.MoveNext();
      }

      foreach (var block in this.cdfg.AllBlocks)
        this.InstrumentBlock(block);

      while (this.scopeStack.Count > 0) {
        this.ilGenerator.EndScope();
        this.scopeStack.Pop();
      }

      this.ilGenerator.AdjustBranchSizesToBestFit();

      this.InjectMethodToDumpCounters();

      return new ILGeneratorMethodBody(this.ilGenerator, methodBody.LocalsAreZeroed, (ushort)(methodBody.MaxStack+2), methodBody.MethodDefinition,
        methodBody.LocalVariables, IteratorHelper.GetSingletonEnumerable((ITypeDefinition)this.counterFieldsForCurrentMethod));
    }
コード例 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cdfg"></param>
        /// <param name="ilGenerator"></param>
        /// <param name="localScopeProvider"></param>
        /// <param name="sourceLocationProvider"></param>
        public ControlFlowToMethodBodyConverter(ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg, ILGenerator ilGenerator,
                                                ILocalScopeProvider /*?*/ localScopeProvider, ISourceLocationProvider /*?*/ sourceLocationProvider)
        {
            Contract.Requires(cdfg != null);
            Contract.Requires(ilGenerator != null);

            this.cdfg                   = cdfg;
            this.ilGenerator            = ilGenerator;
            this.localScopeProvider     = localScopeProvider;
            this.sourceLocationProvider = sourceLocationProvider;
        }
コード例 #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="host"></param>
        /// <param name="cdfg"></param>
        /// <param name="localScopeProvider"></param>
        /// <param name="sourceLocationProvider"></param>
        public StackEliminator(IMetadataHost host,
                               ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg, ILocalScopeProvider /*?*/ localScopeProvider, ISourceLocationProvider /*?*/ sourceLocationProvider)
        {
            Contract.Requires(host != null);
            Contract.Requires(cdfg != null);

            this.host = host;
            this.localScopeProvider     = localScopeProvider;
            this.sourceLocationProvider = sourceLocationProvider;
            this.cdfg = cdfg;
        }
コード例 #12
0
            internal ILConverter(ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg, ILGenerator ilGenerator,
                                 ILocalScopeProvider /*?*/ localScopeProvider, ISourceLocationProvider /*?*/ sourceLocationProvider)
                : base(cdfg, ilGenerator, localScopeProvider, sourceLocationProvider)
            {
                Contract.Requires(cdfg != null);
                Contract.Requires(ilGenerator != null);

                this.localFor                   = new Hashtable <object, GeneratorLocal>();
                this.redundantLocals            = new SetOfObjects();
                this.storesThatShouldBecomePops = new SetOfObjects();
                this.useCount                   = new Dictionary <ILocalDefinition, int>();
            }
コード例 #13
0
ファイル: MultipleAssignment.cs プロジェクト: xornand/cci
        /// <summary>
        /// Changes a control flow graph from SSA form to a version where the SSA variables are unified into the smallest number of locals.
        /// This is somewhat like register allocation where the number of registers can grow as large as needed, but registers are typed.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="cdfg"></param>
        /// <param name="cfgQueries"></param>
        public MultipleAssigner(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg, ControlGraphQueries <BasicBlock, Instruction> cfgQueries)
        {
            Contract.Requires(host != null);
            Contract.Requires(cdfg != null);
            Contract.Requires(cfgQueries != null);

            this.host               = host;
            this.cdfg               = cdfg;
            this.cfgQueries         = cfgQueries;
            this.unifiedLocalFor    = new Hashtable <object, GeneratorLocal>();
            this.availableLocalsFor = new MultiHashtable <GeneratorLocal>();
        }
コード例 #14
0
        public void RunOnMethod(IMethodDefinition methodDefinition, IMetadataHost host)
        {
            ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> cfg =
                ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodDefinition.Body);

            // Note: we assume the first root block is the entrypoint of the function (and not, say, an exception handler
            // This may not be warranted; should perhaps check IL offset?

            BasicBlock <Instruction> entryBlock = cfg.RootBlocks.First();

            RunOnControlFlowGraph(cfg, entryBlock);
        }
コード例 #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="host"></param>
        /// <param name="cdfg"></param>
        /// <param name="cfgQueries"></param>
        /// <param name="localScopeProvider"></param>
        /// <param name="sourceLocationProvider"></param>
        public LocalMinimizer(IMetadataHost host,
                              ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg, ControlGraphQueries <BasicBlock, Instruction> cfgQueries,
                              ILocalScopeProvider /*?*/ localScopeProvider, ISourceLocationProvider /*?*/ sourceLocationProvider)
        {
            Contract.Requires(host != null);
            Contract.Requires(cdfg != null);
            Contract.Requires(cfgQueries != null);

            this.host = host;
            this.localScopeProvider     = localScopeProvider;
            this.sourceLocationProvider = sourceLocationProvider;
            this.cdfg       = cdfg;
            this.cfgQueries = cfgQueries;
        }
コード例 #16
0
        private DataFlowInferencer(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg)
        {
            Contract.Requires(host != null);
            Contract.Requires(cdfg != null);

            var numberOfBlocks = cdfg.BlockFor.Count;

            this.platformType = host.PlatformType;
            this.cdfg         = cdfg;
            this.operandStackSetupInstructions = new List <Instruction>(cdfg.MethodBody.MaxStack);
            this.stack                = new Stack <Instruction>(cdfg.MethodBody.MaxStack, this.operandStackSetupInstructions);
            this.blocksToVisit        = new Queue <BasicBlock>((int)numberOfBlocks);
            this.blocksAlreadyVisited = new SetOfObjects(numberOfBlocks);;
            this.internFactory        = host.InternFactory;
        }
コード例 #17
0
        private TypeInferencer(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cfg, Stack <Instruction> stack, Queue <BasicBlock> blocksToVisit, SetOfObjects blocksAlreadyVisited)
        {
            Contract.Requires(host != null);
            Contract.Requires(cfg != null);
            Contract.Requires(stack != null);
            Contract.Requires(blocksToVisit != null);
            Contract.Requires(blocksAlreadyVisited != null);

            this.platformType         = host.PlatformType;
            this.cfg                  = cfg;
            this.stack                = stack;
            this.blocksToVisit        = blocksToVisit;
            this.blocksAlreadyVisited = blocksAlreadyVisited;
            this.internFactory        = host.InternFactory;
        }
コード例 #18
0
        public override void Visit(IMethodBody methodBody)
        {
            var method = methodBody.MethodDefinition;

            this.currentMethod = method;
            if (methodBody.Operations != null)
            {
                var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader);

                var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);
                this.FindObjectSourcesWithoutSinks(method, cdfg);
            }


            return;
        }
コード例 #19
0
    public override void Traverse(IMethodBody methodBody) {
      sourceEmitterOutput.WriteLine("");
      if (this.pdbReader != null)
        PrintScopes(methodBody);
      else
        PrintLocals(methodBody.LocalVariables);

      this.cdfg = ControlAndDataFlowGraph<BasicBlock<Instruction>, Instruction>.GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);
      var numberOfBlocks = this.cdfg.BlockFor.Count;

      foreach (var block in this.cdfg.AllBlocks) {
        this.PrintBlock(block);
      }

      sourceEmitterOutput.WriteLine("**************************************************************");
      sourceEmitterOutput.WriteLine();
    }
コード例 #20
0
ファイル: TypeInferencer.cs プロジェクト: pcalin/Afterthought
        /// <summary>
        ///
        /// </summary>
        internal static void FillInTypes(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cfg)
        {
            Contract.Requires(host != null);
            Contract.Requires(cfg != null);
            var stack                = new Stack <Instruction>(cfg.MethodBody.MaxStack, new List <Instruction>(0));
            var numberOfBlocks       = cfg.BlockFor.Count;
            var blocksToVisit        = new Queue <BasicBlock>((int)numberOfBlocks);
            var blocksAlreadyVisited = new SetOfObjects(numberOfBlocks);
            var inferencer           = new TypeInferencer <BasicBlock, Instruction>(host, cfg, stack, blocksToVisit, blocksAlreadyVisited);

            foreach (var root in cfg.RootBlocks)
            {
                blocksToVisit.Enqueue(root);
                while (blocksToVisit.Count != 0)
                {
                    inferencer.DequeueBlockAndFillInItsTypes();
                }
            }
        }
コード例 #21
0
ファイル: SourceEmitter.cs プロジェクト: sysprogs/CCI
        public override void Traverse(IMethodBody methodBody)
        {
            sourceEmitterOutput.WriteLine("");
            if (this.pdbReader != null)
            {
                PrintScopes(methodBody);
            }
            else
            {
                PrintLocals(methodBody.LocalVariables);
            }

            this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);

            var numberOfBlocks = this.cdfg.BlockFor.Count;

            foreach (var block in this.cdfg.AllBlocks)
            {
                this.PrintBlock(block);
            }

            sourceEmitterOutput.WriteLine("**************************************************************");
            sourceEmitterOutput.WriteLine();
        }
コード例 #22
0
    private void AdjustStackForRet(ControlAndDataFlowGraph<EnhancedBasicBlock<Instruction>, Instruction> cdfg) {
      Contract.Requires(cdfg != null);

      //If ret is unreachable, the stack may already be empty.
      if (cdfg.MethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void && this.operandStack.Count > 0)
        this.operandStack.Pop();
    }
コード例 #23
0
    private void EmitLocalDefinitions(ControlAndDataFlowGraph<EnhancedBasicBlock<Instruction>, Instruction> cdfg) {
      Contract.Requires(cdfg != null);

      bool thereWereLocalsVariables = false;
      foreach (var methodLocal in cdfg.MethodBody.LocalVariables) {
        Contract.Assume(methodLocal != null);
        this.EmitTypeReference(methodLocal.Type, storageLocation: true);
        if (methodLocal.IsReference) this.sourceEmitter.EmitString("*");
        this.sourceEmitter.EmitString(" ");
        this.EmitLocalReference(methodLocal);
        this.sourceEmitter.EmitString(";");
        this.sourceEmitter.EmitNewLine();
        thereWereLocalsVariables = true;
      }
      if (thereWereLocalsVariables)
        this.sourceEmitter.EmitNewLine();
      if (this.mayThrowException) {
        this.sourceEmitter.EmitString("uintptr_t exception;");
        this.sourceEmitter.EmitNewLine();
        this.sourceEmitter.EmitString("uintptr_t originalException;");
        this.sourceEmitter.EmitNewLine();
        this.sourceEmitter.EmitString("uint32_t throwOffset;");
        this.sourceEmitter.EmitNewLine();
        this.mayThrowException = false;
      }
      if (this.generateOverflowCheckTemp) {
        this.sourceEmitter.EmitString("int32_t overflowFlag;");
        this.sourceEmitter.EmitNewLine();
        this.generateOverflowCheckTemp = false;
      }
      if (this.needsTempForArrayElementAddress) {
        this.sourceEmitter.EmitString("uintptr_t element_address;");
        this.sourceEmitter.EmitNewLine();
        this.generateOverflowCheckTemp = false;
      }
      if (this.hasCallVirt) {
        this.sourceEmitter.EmitString("void ** virtualPtr;");
        this.sourceEmitter.EmitNewLine();
        this.hasCallVirt = false;
      }
      
      foreach (var temp in this.temps) this.EmitTemp(temp);
      this.sourceEmitter.EmitNewLine();
    }
コード例 #24
0
        public override IMethodBody Rewrite(IMethodBody methodBody)
        {
            this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody);

            this.ilGenerator = new ILGenerator(host, methodBody.MethodDefinition);

            var numberOfBlocks = this.cdfg.BlockFor.Count;

            this.labelFor = new Hashtable <ILGeneratorLabel>(numberOfBlocks);
            this.counterFieldsForCurrentMethod = new NestedTypeDefinition()
            {
                BaseClasses = new List <ITypeReference>(1)
                {
                    this.host.PlatformType.SystemObject
                },
                ContainingTypeDefinition = methodBody.MethodDefinition.ContainingTypeDefinition,
                Fields            = new List <IFieldDefinition>((int)numberOfBlocks * 2),
                Methods           = new List <IMethodDefinition>(1),
                InternFactory     = this.host.InternFactory,
                IsBeforeFieldInit = true,
                IsClass           = true,
                IsSealed          = true,
                IsAbstract        = true,
                Name       = this.host.NameTable.GetNameFor(methodBody.MethodDefinition.Name + "_Counters" + methodBody.MethodDefinition.InternedKey),
                Visibility = TypeMemberVisibility.Assembly,
            };
            this.fieldOffsets = new List <uint>((int)numberOfBlocks * 2);

            foreach (var exceptionInfo in methodBody.OperationExceptionInformation)
            {
                this.ilGenerator.AddExceptionHandlerInformation(exceptionInfo.HandlerKind, exceptionInfo.ExceptionType,
                                                                this.GetLabelFor(exceptionInfo.TryStartOffset), this.GetLabelFor(exceptionInfo.TryEndOffset),
                                                                this.GetLabelFor(exceptionInfo.HandlerStartOffset), this.GetLabelFor(exceptionInfo.HandlerEndOffset),
                                                                exceptionInfo.HandlerKind == HandlerKind.Filter ? this.GetLabelFor(exceptionInfo.FilterDecisionStartOffset) : null);
            }

            if (this.pdbReader == null)
            {
                foreach (var localDef in methodBody.LocalVariables)
                {
                    this.ilGenerator.AddVariableToCurrentScope(localDef);
                }
            }
            else
            {
                foreach (var ns in this.pdbReader.GetNamespaceScopes(methodBody))
                {
                    foreach (var uns in ns.UsedNamespaces)
                    {
                        this.ilGenerator.UseNamespace(uns.NamespaceName.Value);
                    }
                }
                this.scopeEnumerator        = this.pdbReader.GetLocalScopes(methodBody).GetEnumerator();
                this.scopeEnumeratorIsValid = this.scopeEnumerator.MoveNext();
            }

            foreach (var block in this.cdfg.AllBlocks)
            {
                this.InstrumentBlock(block);
            }

            while (this.scopeStack.Count > 0)
            {
                this.ilGenerator.EndScope();
                this.scopeStack.Pop();
            }

            this.ilGenerator.AdjustBranchSizesToBestFit();

            this.InjectMethodToDumpCounters();

            return(new ILGeneratorMethodBody(this.ilGenerator, methodBody.LocalsAreZeroed, (ushort)(methodBody.MaxStack + 2), methodBody.MethodDefinition,
                                             methodBody.LocalVariables, IteratorHelper.GetSingletonEnumerable((ITypeDefinition)this.counterFieldsForCurrentMethod)));
        }
コード例 #25
0
        /// <summary>
        ///
        /// </summary>
        internal static void SetupDataFlow(IMetadataHost host, IMethodBody methodBody, ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg)
        {
            Contract.Requires(host != null);
            Contract.Requires(methodBody != null);
            Contract.Requires(cdfg != null);

            var dataFlowInferencer = new DataFlowInferencer <BasicBlock, Instruction>(host, cdfg);

            dataFlowInferencer.SetupDataFlowFor(methodBody);
        }
コード例 #26
0
ファイル: Controller.cs プロジェクト: PlumpMath/Ocelot
        public bool AnalyzeMethods()
        {
            foreach (INamedTypeDefinition t in PrimaryModule.GetAllTypes())
            {
                if (t.IsClass && t.Methods.Count() > 0 && !t.Name.Value.StartsWith("<"))
                {
                    Environment.Message("Class {0} has {1} members, {2} methods.", t.Name.Value, t.Members.Count(), t.Methods.Count());
                    List <IMethodDefinition> methods = t.Methods.ToList();
                    foreach (IMethodDefinition m in methods)
                    {
                        ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(MetadataReaderHost, m.Body);

                        ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction> query = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);

                        Environment.Message("  Method {0} has visibility {3}, {1} parameters, {2} local variables in body, {4} total basic blocks or nodes and {5} successor edges in CFG.\n", m.Name.Value, m.ParameterCount,
                                            m.Body.LocalVariables.Count(), m.Visibility.ToString(), cdfg.AllBlocks.Count,
                                            cdfg.SuccessorEdges.Count);
                    }
                }
            }
            return(true);
        }
コード例 #27
0
    private void CreateTempsForOperandStack(ControlAndDataFlowGraph<EnhancedBasicBlock<Instruction>, Instruction> cdfg) {
      Contract.Requires(cdfg != null);

      foreach (var block in cdfg.AllBlocks) {
        Contract.Assume(block != null);
        this.InitializeOperandStack(block);

        foreach (var instruction in block.Instructions) {
          Contract.Assume(instruction != null);
          switch (instruction.Operation.OperationCode) {
            case OperationCode.Add:
            case OperationCode.And:
            case OperationCode.Ceq:
            case OperationCode.Cgt:
            case OperationCode.Cgt_Un:
            case OperationCode.Clt:
            case OperationCode.Clt_Un:
            case OperationCode.Mul:
            case OperationCode.Or:
            case OperationCode.Shl:
            case OperationCode.Shr:
            case OperationCode.Shr_Un:
            case OperationCode.Sub:
            case OperationCode.Xor:
              this.AdjustStackForBinaryOperation(instruction);
              break;

            case OperationCode.Add_Ovf:
            case OperationCode.Add_Ovf_Un:
            case OperationCode.Mul_Ovf:
            case OperationCode.Mul_Ovf_Un:
            case OperationCode.Sub_Ovf:
            case OperationCode.Sub_Ovf_Un:
              this.AdjustStackForBinaryOperation(instruction);
              this.generateOverflowCheckTemp = true;
              this.mayThrowException = true;
              break;

            case OperationCode.Arglist:
            case OperationCode.Ldarg:
            case OperationCode.Ldarg_0:
            case OperationCode.Ldarg_1:
            case OperationCode.Ldarg_2:
            case OperationCode.Ldarg_3:
            case OperationCode.Ldarg_S:
            case OperationCode.Ldloc:
            case OperationCode.Ldloc_0:
            case OperationCode.Ldloc_1:
            case OperationCode.Ldloc_2:
            case OperationCode.Ldloc_3:
            case OperationCode.Ldloc_S:
            case OperationCode.Ldsfld:
            case OperationCode.Ldarga:
            case OperationCode.Ldarga_S:
            case OperationCode.Ldsflda:
            case OperationCode.Ldloca:
            case OperationCode.Ldloca_S:
            case OperationCode.Ldftn:
            case OperationCode.Ldc_I4:
            case OperationCode.Ldc_I4_0:
            case OperationCode.Ldc_I4_1:
            case OperationCode.Ldc_I4_2:
            case OperationCode.Ldc_I4_3:
            case OperationCode.Ldc_I4_4:
            case OperationCode.Ldc_I4_5:
            case OperationCode.Ldc_I4_6:
            case OperationCode.Ldc_I4_7:
            case OperationCode.Ldc_I4_8:
            case OperationCode.Ldc_I4_M1:
            case OperationCode.Ldc_I4_S:
            case OperationCode.Ldc_I8:
            case OperationCode.Ldc_R4:
            case OperationCode.Ldc_R8:
            case OperationCode.Ldnull:
            case OperationCode.Ldstr:
            case OperationCode.Ldtoken:
            case OperationCode.Sizeof:
              this.PushTempForSlotAndAssociateWithInstruction(instruction);
              break;

            case OperationCode.Array_Addr:
            case OperationCode.Array_Get:
              this.AdjustStackForArrayAddr(instruction);
              break;

            case OperationCode.Array_Create:
            case OperationCode.Array_Create_WithLowerBound:
            case OperationCode.Newarr:
              this.AdjustStackForArrayCreate(instruction);
              this.mayThrowException = true;
              break;

            case OperationCode.Array_Set:
              this.AdjustStackForArraySet(instruction);
              break;

            case OperationCode.Beq:
            case OperationCode.Beq_S:
            case OperationCode.Bge:
            case OperationCode.Bge_S:
            case OperationCode.Bge_Un:
            case OperationCode.Bge_Un_S:
            case OperationCode.Bgt:
            case OperationCode.Bgt_S:
            case OperationCode.Bgt_Un:
            case OperationCode.Bgt_Un_S:
            case OperationCode.Ble:
            case OperationCode.Ble_S:
            case OperationCode.Ble_Un:
            case OperationCode.Ble_Un_S:
            case OperationCode.Blt:
            case OperationCode.Blt_S:
            case OperationCode.Blt_Un:
            case OperationCode.Blt_Un_S:
            case OperationCode.Bne_Un:
            case OperationCode.Bne_Un_S:
              this.AdjustStackForBinaryVoidOperation();
              break;

            case OperationCode.Cpobj:
            case OperationCode.Stind_I:
            case OperationCode.Stind_I1:
            case OperationCode.Stind_I2:
            case OperationCode.Stind_I4:
            case OperationCode.Stind_I8:
            case OperationCode.Stind_R4:
            case OperationCode.Stind_R8:
            case OperationCode.Stind_Ref:
            case OperationCode.Stobj:
              this.AdjustStackForBinaryVoidOperation();
              this.mayThrowException = true;
              break;

            case OperationCode.Box:
            case OperationCode.Castclass:
            case OperationCode.Ckfinite:
            case OperationCode.Ldind_I:
            case OperationCode.Ldind_I1:
            case OperationCode.Ldind_I2:
            case OperationCode.Ldind_I4:
            case OperationCode.Ldind_I8:
            case OperationCode.Ldind_R4:
            case OperationCode.Ldind_R8:
            case OperationCode.Ldind_Ref:
            case OperationCode.Ldind_U1:
            case OperationCode.Ldind_U2:
            case OperationCode.Ldind_U4:
            case OperationCode.Ldobj:
            case OperationCode.Ldflda:
            case OperationCode.Ldfld:
            case OperationCode.Ldlen:
            case OperationCode.Localloc:
            case OperationCode.Refanytype:
            case OperationCode.Refanyval:
            case OperationCode.Unbox:
            case OperationCode.Unbox_Any:
              this.AdjustStackForUnaryOperation(instruction);
              this.mayThrowException = true;
              break;

            case OperationCode.Conv_Ovf_I:
            case OperationCode.Conv_Ovf_I_Un:
            case OperationCode.Conv_Ovf_I1:
            case OperationCode.Conv_Ovf_I1_Un:
            case OperationCode.Conv_Ovf_I2:
            case OperationCode.Conv_Ovf_I2_Un:
            case OperationCode.Conv_Ovf_I4:
            case OperationCode.Conv_Ovf_I4_Un:
            case OperationCode.Conv_Ovf_I8:
            case OperationCode.Conv_Ovf_I8_Un:
            case OperationCode.Conv_Ovf_U:
            case OperationCode.Conv_Ovf_U_Un:
            case OperationCode.Conv_Ovf_U1:
            case OperationCode.Conv_Ovf_U1_Un:
            case OperationCode.Conv_Ovf_U2:
            case OperationCode.Conv_Ovf_U2_Un:
            case OperationCode.Conv_Ovf_U4:
            case OperationCode.Conv_Ovf_U4_Un:
            case OperationCode.Conv_Ovf_U8:
            case OperationCode.Conv_Ovf_U8_Un:
              this.AdjustStackForUnaryOperation(instruction);
              this.generateOverflowCheckTemp = true;
              this.mayThrowException = true;
              break;

            case OperationCode.Brfalse:
            case OperationCode.Brfalse_S:
            case OperationCode.Brtrue:
            case OperationCode.Brtrue_S:
            case OperationCode.Endfilter:
            case OperationCode.Initobj:
            case OperationCode.Pop:
            case OperationCode.Starg:
            case OperationCode.Starg_S:
            case OperationCode.Stloc:
            case OperationCode.Stloc_0:
            case OperationCode.Stloc_1:
            case OperationCode.Stloc_2:
            case OperationCode.Stloc_3:
            case OperationCode.Stloc_S:
            case OperationCode.Stsfld:
            case OperationCode.Switch:
              this.AdjustStackForUnaryVoidOperation();
              break;

            case OperationCode.Call:
              this.AdjustStackForCall(instruction);
              this.mayThrowException = true;
              break;

            case OperationCode.Callvirt:
              this.AdjustStackForCall(instruction);
              this.mayThrowException = true;
              this.hasCallVirt = true;
              break;

            case OperationCode.Calli:
              this.AdjustStackForCalli(instruction);
              this.mayThrowException = true;
              break;

            case OperationCode.Conv_I:
            case OperationCode.Conv_I1:
            case OperationCode.Conv_I2:
            case OperationCode.Conv_I4:
            case OperationCode.Conv_I8:
            case OperationCode.Conv_R_Un:
            case OperationCode.Conv_R4:
            case OperationCode.Conv_R8:
            case OperationCode.Conv_U:
            case OperationCode.Conv_U1:
            case OperationCode.Conv_U2:
            case OperationCode.Conv_U4:
            case OperationCode.Conv_U8:
            case OperationCode.Isinst:
            case OperationCode.Mkrefany:
            case OperationCode.Neg:
            case OperationCode.Not:
              this.AdjustStackForUnaryOperation(instruction);
              break;

            case OperationCode.Cpblk:
            case OperationCode.Initblk:
              this.AdjustStackForTernaryVoidOperation();
              this.mayThrowException = true;
              break;

            case OperationCode.Dup:
              this.AdjustStackForDup(instruction);
              break;

            case OperationCode.Div:
            case OperationCode.Div_Un:
            case OperationCode.Rem:
            case OperationCode.Rem_Un:
            case OperationCode.Ldelema:
              this.AdjustStackForBinaryOperation(instruction);
              this.mayThrowException = true;
              break;

            case OperationCode.Ldelem:
            case OperationCode.Ldelem_I:
            case OperationCode.Ldelem_I1:
            case OperationCode.Ldelem_I2:
            case OperationCode.Ldelem_I4:
            case OperationCode.Ldelem_I8:
            case OperationCode.Ldelem_R4:
            case OperationCode.Ldelem_R8:
            case OperationCode.Ldelem_Ref:
            case OperationCode.Ldelem_U1:
            case OperationCode.Ldelem_U2:
            case OperationCode.Ldelem_U4:
              this.AdjustStackForBinaryOperation(instruction);
              this.mayThrowException = true;
              this.needsTempForArrayElementAddress = true;
              break;

            case OperationCode.Ldvirtftn:
              this.AdjustStackForUnaryOperation(instruction);
              this.mayThrowException = true;
              this.hasCallVirt = true;
              break;

            case OperationCode.Leave:
            case OperationCode.Leave_S:
              this.AdjustStackForLeave();
              break;

            case OperationCode.Newobj:
              this.AdjustStackForNewObject(instruction);
              this.mayThrowException = true;
              break;

            case OperationCode.Ret:
              this.AdjustStackForRet(cdfg);
              break;

            case OperationCode.Stelem:
            case OperationCode.Stelem_I:
            case OperationCode.Stelem_I1:
            case OperationCode.Stelem_I2:
            case OperationCode.Stelem_I4:
            case OperationCode.Stelem_I8:
            case OperationCode.Stelem_R4:
            case OperationCode.Stelem_R8:
            case OperationCode.Stelem_Ref:
              this.AdjustStackForTernaryVoidOperation();
              this.mayThrowException = true;
              this.needsTempForArrayElementAddress = true;
              break;

            case OperationCode.Stfld:
              this.AdjustStackForBinaryVoidOperation();
              this.mayThrowException = true;
              break;

            case OperationCode.Throw:
              this.AdjustStackForUnaryVoidOperation();
              this.mayThrowException = true;
              break;
          }
        }
      }

    }