示例#1
0
 /// <summary>
 /// For an iterator method, find the closure class' MoveNext method and return its body.
 /// </summary>
 /// <param name="host"></param>
 /// <param name="possibleIterator">The (potential) iterator method.</param>
 /// <returns>Dummy.MethodBody if <paramref name="possibleIterator"/> does not fit into the code pattern of an iterator method, 
 /// or the body of the MoveNext method of the corresponding closure class if it does.
 /// </returns>
 public static IMethodBody/*?*/ FindClosureMoveNext(IMetadataHost host, ISourceMethodBody/*!*/ possibleIterator) {
   if (possibleIterator is Dummy) return null;
   var nameTable = host.NameTable;
   var possibleIteratorBody = possibleIterator.Block;
   foreach (var statement in possibleIteratorBody.Statements) {
     var expressionStatement = statement as IExpressionStatement;
     if (expressionStatement != null)
       return FirstStatementIsIteratorCreation(host, possibleIterator, nameTable, statement);
     break;
   }
   foreach (var statement in possibleIteratorBody.Statements){
     //var lds = statement as ILocalDeclarationStatement;
     //if (lds != null) {
     //  if (lds.InitialValue != null)
     //    return null;
     //  else
     //    continue;
     //}
     var returnStatement = statement as IReturnStatement;
     if (returnStatement == null) return null;
     var blockExpression = returnStatement.Expression as IBlockExpression;
     if (blockExpression == null) return null;
     foreach (var s in blockExpression.BlockStatement.Statements) {
       return FirstStatementIsIteratorCreation(host, possibleIterator, nameTable, s);
     }
   }
   return null;
 }
示例#2
0
        internal void Process()
        {
            if (Definition.IsExternal)
            {
                return;
            }
            ISourceMethodBody sourceMethodBody = null;

            if (Definition.Body is ISourceMethodBody)
            {
                sourceMethodBody = (ISourceMethodBody)Definition.Body;
            }
            else
            {
                sourceMethodBody = Decompiler.GetCodeModelFromMetadataModel(HLDomain.Host, Definition.Body, null);
            }

            mCurrentBlock = CreateBlock(CreateLabel());
            ProcessStatement(sourceMethodBody.Block);
            mCurrentBlock.Terminate(null);

            List <string> buf = new List <string>();

            foreach (HLInstructionBlock block in mBlocks)
            {
                foreach (HLInstruction instruction in block.Instructions)
                {
                    buf.Add(instruction.ToString());
                }
            }
        }
示例#3
0
 private static IMethodBody/*?*/ FirstStatementIsIteratorCreation(IMetadataHost host, ISourceMethodBody possibleIterator, INameTable nameTable, IStatement statement) {
   ICreateObjectInstance createObjectInstance = GetICreateObjectInstance(statement);
   if (createObjectInstance == null) {
     // If the first statement in the method body is not the creation of iterator closure, return a dummy.
     // Possible corner case not handled: a local is used to hold the constant value for the initial state of the closure.
     return null;
   }
   ITypeReference closureType/*?*/ = createObjectInstance.MethodToCall.ContainingType;
   ITypeReference unspecializedClosureType = ContractHelper.Unspecialized(closureType);
   if (!AttributeHelper.Contains(unspecializedClosureType.Attributes, host.PlatformType.SystemRuntimeCompilerServicesCompilerGeneratedAttribute))
     return null;
   INestedTypeReference closureTypeAsNestedTypeReference = unspecializedClosureType as INestedTypeReference;
   if (closureTypeAsNestedTypeReference == null) return null;
   ITypeReference unspecializedClosureContainingType = ContractHelper.Unspecialized(closureTypeAsNestedTypeReference.ContainingType);
   if (closureType != null && TypeHelper.TypesAreEquivalent(possibleIterator.MethodDefinition.ContainingTypeDefinition, unspecializedClosureContainingType)) {
     IName MoveNextName = nameTable.GetNameFor("MoveNext");
     foreach (ITypeDefinitionMember member in closureType.ResolvedType.GetMembersNamed(MoveNextName, false)) {
       IMethodDefinition moveNext = member as IMethodDefinition;
       if (moveNext != null) {
         ISpecializedMethodDefinition moveNextGeneric = moveNext as ISpecializedMethodDefinition;
         if (moveNextGeneric != null)
           moveNext = moveNextGeneric.UnspecializedVersion.ResolvedMethod;
         return moveNext.Body;
       }
     }
   }
   return null;
 }
示例#4
0
        public override void Traverse(IMethodBody methodBody)
        {
            PrintToken(CSharpToken.LeftCurly);

            ISourceMethodBody /*?*/ sourceMethodBody = methodBody as ISourceMethodBody;

            if (sourceMethodBody == null)
            {
                var options = DecompilerOptions.Loops;
                if (!this.printCompilerGeneratedMembers)
                {
                    options |= (DecompilerOptions.AnonymousDelegates | DecompilerOptions.Iterators);
                }
                if (this.noStack)
                {
                    options |= DecompilerOptions.Unstack;
                }
                sourceMethodBody = new SourceMethodBody(methodBody, this.host, this.pdbReader, this.pdbReader, options);
            }
            if (this.noIL)
            {
                this.Traverse(sourceMethodBody.Block.Statements);
            }
            else
            {
                this.Traverse(sourceMethodBody.Block);
                PrintToken(CSharpToken.NewLine);

                if (this.pdbReader != null)
                {
                    PrintScopes(methodBody);
                }
                else
                {
                    PrintLocals(methodBody.LocalVariables);
                }

                int currentIndex = -1; // a number no index matches
                foreach (IOperation operation in methodBody.Operations)
                {
                    if (this.pdbReader != null)
                    {
                        foreach (IPrimarySourceLocation psloc in this.pdbReader.GetPrimarySourceLocationsFor(operation.Location))
                        {
                            if (psloc.StartIndex != currentIndex)
                            {
                                PrintSourceLocation(psloc);
                                currentIndex = psloc.StartIndex;
                            }
                        }
                    }
                    PrintOperation(operation);
                }
            }

            PrintToken(CSharpToken.RightCurly);
        }
示例#5
0
文件: MoveNext.cs 项目: xornand/cci
 private HermansAlwaysRight(IContractAwareHost contractAwareHost, ContractExtractor extractor, ISourceMethodBody sourceMethodBody, bool methodIsInReferenceAssembly, OldAndResultExtractor oldAndResultExtractor, PdbReader /*?*/ pdbReader)
     : base(contractAwareHost)
 {
     this.contractAwareHost           = contractAwareHost;
     this.extractor                   = extractor;
     this.sourceMethodBody            = sourceMethodBody;
     this.methodIsInReferenceAssembly = methodIsInReferenceAssembly;
     this.oldAndResultExtractor       = oldAndResultExtractor;
     this.pdbReader                   = pdbReader;
 }
示例#6
0
文件: MoveNext.cs 项目: xornand/cci
        /// <summary>
        /// For an iterator method, find the closure class' MoveNext method and return its body.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="possibleIterator">The (potential) iterator method.</param>
        /// <returns>Dummy.MethodBody if <paramref name="possibleIterator"/> does not fit into the code pattern of an iterator method,
        /// or the body of the MoveNext method of the corresponding closure class if it does.
        /// </returns>
        public static IMethodBody /*?*/ FindClosureMoveNext(IMetadataHost host, ISourceMethodBody /*!*/ possibleIterator)
        {
            if (possibleIterator is Dummy)
            {
                return(null);
            }
            var nameTable            = host.NameTable;
            var possibleIteratorBody = possibleIterator.Block;

            foreach (var statement in possibleIteratorBody.Statements)
            {
                var expressionStatement = statement as IExpressionStatement;
                if (expressionStatement != null)
                {
                    return(FirstStatementIsIteratorCreation(host, possibleIterator, nameTable, statement));
                }
                break;
            }
            foreach (var statement in possibleIteratorBody.Statements)
            {
                //var lds = statement as ILocalDeclarationStatement;
                //if (lds != null) {
                //  if (lds.InitialValue != null)
                //    return null;
                //  else
                //    continue;
                //}
                var returnStatement = statement as IReturnStatement;
                if (returnStatement == null)
                {
                    return(null);
                }
                var blockExpression = returnStatement.Expression as IBlockExpression;
                if (blockExpression == null)
                {
                    return(null);
                }
                foreach (var s in blockExpression.BlockStatement.Statements)
                {
                    return(FirstStatementIsIteratorCreation(host, possibleIterator, nameTable, s));
                }
            }
            return(null);
        }
示例#7
0
 /// <summary>
 /// For a client (e.g., the decompiler) that has a source method body and wants to have its
 /// contract extracted and added to the contract provider.
 /// </summary>
 public MethodContractAndMethodBody SplitMethodBodyIntoContractAndCode(ISourceMethodBody sourceMethodBody)
 {
     return(this.primaryExtractor.SplitMethodBodyIntoContractAndCode(sourceMethodBody));
 }
示例#8
0
 /// <summary>
 /// Traverses the the given source method body.
 /// </summary>
 public void Traverse(ISourceMethodBody sourceMethodBody)
 {
     Contract.Requires(sourceMethodBody != null);
       if (this.preorderVisitor != null) this.preorderVisitor.Visit(sourceMethodBody);
       if (this.StopTraversal) return;
       this.TraverseChildren(sourceMethodBody);
       if (this.StopTraversal) return;
       if (this.postorderVisitor != null) this.postorderVisitor.Visit(sourceMethodBody);
 }
        public override void TraverseChildren(ISourceMethodBody sourceMethodBody)
{ MethodEnter(sourceMethodBody);
            base.TraverseChildren(sourceMethodBody);
     MethodExit();   }
示例#10
0
 private SourceMethodBody Copy(ISourceMethodBody sourceMethodBody, IMethodDefinition method)
 {
     var mutableCopy = this.shallowCopier.Copy(sourceMethodBody);
       mutableCopy.Block = this.Copy(mutableCopy.Block);
       mutableCopy.MethodDefinition = method;
       return mutableCopy;
 }
示例#11
0
文件: MoveNext.cs 项目: xornand/cci
        private static IMethodBody /*?*/ FirstStatementIsIteratorCreation(IMetadataHost host, ISourceMethodBody possibleIterator, INameTable nameTable, IStatement statement)
        {
            ICreateObjectInstance createObjectInstance = GetICreateObjectInstance(statement);

            if (createObjectInstance == null)
            {
                // If the first statement in the method body is not the creation of iterator closure, return a dummy.
                // Possible corner case not handled: a local is used to hold the constant value for the initial state of the closure.
                return(null);
            }
            ITypeReference closureType /*?*/        = createObjectInstance.MethodToCall.ContainingType;
            ITypeReference unspecializedClosureType = ContractHelper.Unspecialized(closureType);

            if (!AttributeHelper.Contains(unspecializedClosureType.Attributes, host.PlatformType.SystemRuntimeCompilerServicesCompilerGeneratedAttribute))
            {
                return(null);
            }
            INestedTypeReference closureTypeAsNestedTypeReference = unspecializedClosureType as INestedTypeReference;

            if (closureTypeAsNestedTypeReference == null)
            {
                return(null);
            }
            ITypeReference unspecializedClosureContainingType = ContractHelper.Unspecialized(closureTypeAsNestedTypeReference.ContainingType);

            if (closureType != null && TypeHelper.TypesAreEquivalent(possibleIterator.MethodDefinition.ContainingTypeDefinition, unspecializedClosureContainingType))
            {
                IName MoveNextName = nameTable.GetNameFor("MoveNext");
                foreach (ITypeDefinitionMember member in closureType.ResolvedType.GetMembersNamed(MoveNextName, false))
                {
                    IMethodDefinition moveNext = member as IMethodDefinition;
                    if (moveNext != null)
                    {
                        ISpecializedMethodDefinition moveNextGeneric = moveNext as ISpecializedMethodDefinition;
                        if (moveNextGeneric != null)
                        {
                            moveNext = moveNextGeneric.UnspecializedVersion.ResolvedMethod;
                        }
                        return(moveNext.Body);
                    }
                }
            }
            return(null);
        }
示例#12
0
        /// <summary>
        /// Returns the method contract, if any, that has been associated with the given object. Returns null if no association exits.
        /// </summary>
        /// <param name="method">An object that might have been associated with a method contract. This can be any kind of object.</param>
        /// <returns></returns>
        public IMethodContract /*?*/ GetMethodContractFor(object method)
        {
            IMethodContract contract = this.underlyingContractProvider.GetMethodContractFor(method);

            if (contract != null)
            {
                return(contract == ContractDummy.MethodContract ? null : contract);
            }

            IMethodReference methodReference = method as IMethodReference;

            if (methodReference == null)
            {
                this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract);
                return(null);
            }

            IMethodDefinition methodDefinition = methodReference.ResolvedMethod;

            if (methodDefinition is Dummy)
            {
                this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract);
                return(null);
            }

            if (methodDefinition.IsAbstract || methodDefinition.IsExternal) // precondition of Body getter
            // Need to see if the method is marked with any attributes that impact the contract
            {
                if (ContractHelper.IsPure(this.host, methodDefinition))
                {
                    var pureMC = new MethodContract()
                    {
                        IsPure = true,
                    };
                    this.underlyingContractProvider.AssociateMethodWithContract(method, pureMC);
                    return(pureMC);
                }
                else
                {
                    this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract);
                    return(null);
                }
            }

            var unspecializedMethodDefintion = ContractHelper.UninstantiateAndUnspecializeMethodDefinition(methodDefinition);

            if (unspecializedMethodDefintion != methodDefinition)
            {
                contract = this.underlyingContractProvider.GetMethodContractFor(unspecializedMethodDefintion);
                if (contract != null)
                {
                    return(ContractHelper.InstantiateAndSpecializeContract(this.host, contract, methodDefinition, unspecializedMethodDefintion));
                }
            }

            IMethodBody methodBody = unspecializedMethodDefintion.Body;

            if (methodBody is Dummy)
            {
                this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract);
                return(null);
            }

            ISourceMethodBody /*?*/ sourceMethodBody = methodBody as ISourceMethodBody;

            if (sourceMethodBody == null)
            {
                sourceMethodBody = Decompiler.GetCodeModelFromMetadataModel(this.host, methodBody, this.pdbReader, DecompilerOptions.AnonymousDelegates);
            }

            MethodContractAndMethodBody result = this.SplitMethodBodyIntoContractAndCode(sourceMethodBody);

            var methodContract = result.MethodContract;

            if (methodContract != null && unspecializedMethodDefintion != methodDefinition)
            {
                var instantiatedContract = ContractHelper.InstantiateAndSpecializeContract(this.host, result.MethodContract, methodDefinition, unspecializedMethodDefintion);
                methodContract = instantiatedContract;
            }

            #region Auto-properties get their contract from mining the invariant
            if (ContractHelper.IsAutoPropertyMember(host, unspecializedMethodDefintion))
            {
                var            tc = this.GetTypeContractFor(unspecializedMethodDefintion.ContainingTypeDefinition);
                MethodContract mc = ContractHelper.GetAutoPropertyContract(this.host, tc, unspecializedMethodDefintion);
                if (mc != null)
                {
                    if (unspecializedMethodDefintion != methodDefinition)
                    {
                        var mutableContract = ContractHelper.InstantiateAndSpecializeContract(this.host, mc, methodDefinition, unspecializedMethodDefintion);
                        mc = mutableContract;
                    }

                    if (methodContract == null)
                    {
                        methodContract = mc;
                    }
                    else
                    {
                        ContractHelper.AddMethodContract(mc, methodContract);
                    }
                }
            }
            #endregion

            if (methodContract == null)
            {
                this.underlyingContractProvider.AssociateMethodWithContract(method, ContractDummy.MethodContract); // so we don't try to extract more than once
            }
            else
            {
                this.underlyingContractProvider.AssociateMethodWithContract(method, methodContract);
            }

            // Notify all interested parties
            foreach (var c in this.callbacks)
            {
                c.ProvideResidualMethodBody(methodDefinition, result.BlockStatement);
            }

            return(methodContract);
        }
示例#13
0
 /// <summary>
 /// For each method body, use the extractor to split it into the codeand contract.
 /// </summary>
 public override void TraverseChildren(ISourceMethodBody sourceMethodBody) {
   var codeAndContractPair = ContractExtractor.SplitMethodBodyIntoContractAndCode(this.contractAwareHost, sourceMethodBody,
   this.pdbReader);
   this.contractProvider.AssociateMethodWithContract(sourceMethodBody.MethodDefinition, codeAndContractPair.MethodContract);
 }
示例#14
0
 public override ISourceMethodBody Rewrite(ISourceMethodBody sourceMethodBody)
 {
     return(base.Rewrite(sourceMethodBody));
 }
示例#15
0
 public static Dictionary<ILocalDefinition, IBoundExpression> FindSetOfLocals(ISourceMethodBody s) {
   var fl = new FindLocals();
   fl.Traverse(s);
   return fl.localsToInitializers;
 }
示例#16
0
      public static MethodContract/*?*/ ExtractContracts(IContractAwareHost contractAwareHost, PdbReader/*?*/ pdbReader, ContractExtractor extractor, ISourceMethodBody methodBody) {
        var definingUnit = TypeHelper.GetDefiningUnit(methodBody.MethodDefinition.ContainingType.ResolvedType);
        var methodIsInReferenceAssembly = ContractHelper.IsContractReferenceAssembly(contractAwareHost, definingUnit);
        var oldAndResultExtractor = new OldAndResultExtractor(contractAwareHost, methodBody, extractor.IsContractMethod);
        var localsInitializedWithFields = FindLocals.FindSetOfLocals(methodBody);

        var har = new HermansAlwaysRight(contractAwareHost, extractor, methodBody, methodIsInReferenceAssembly, oldAndResultExtractor, pdbReader);
        har.Rewrite(methodBody);

        if (har.extractor.currentMethodContract == null) return null;

        // The decompiler will have introduced locals if there were any anonymous delegates in the contracts
        // Such locals are initialized with the fields of the iterator class.
        // The contract that comes back from here will have those fields replaced with whatever the iterator captured
        // (parameters, locals). So the locals in the contract need to be replaced with the iterator fields so that
        // next replacement will see the right thing (i.e., the fields) and replace them! Phew!
        var localReplacer = new LocalReplacer(contractAwareHost, localsInitializedWithFields);
        localReplacer.Rewrite(har.extractor.currentMethodContract);
        // also need to rewrite the remainder of the body
        localReplacer.Rewrite(methodBody);

        return har.extractor.currentMethodContract;
      }
示例#17
0
 private HermansAlwaysRight(IContractAwareHost contractAwareHost, ContractExtractor extractor, ISourceMethodBody sourceMethodBody, bool methodIsInReferenceAssembly, OldAndResultExtractor oldAndResultExtractor, PdbReader/*?*/ pdbReader)
   : base(contractAwareHost)
 {
   this.contractAwareHost = contractAwareHost;
   this.extractor = extractor;
   this.sourceMethodBody = sourceMethodBody;
   this.methodIsInReferenceAssembly = methodIsInReferenceAssembly;
   this.oldAndResultExtractor = oldAndResultExtractor;
   this.pdbReader = pdbReader;
 }
示例#18
0
    // TODO: First search the moveNextBody to see if there are any contracts at all.
    /// <summary>
    /// 
    /// </summary>
    /// <param name="host"></param>
    /// <param name="extractor"></param>
    /// <param name="iteratorMethodBody"></param>
    /// <param name="moveNextBody"></param>
    /// <param name="pdbReader"></param>
    /// <returns></returns>
    public static MethodContract GetMethodContractFromMoveNext(
      IContractAwareHost host,
      ContractExtractor extractor,
      ISourceMethodBody iteratorMethodBody,
      ISourceMethodBody moveNextBody,
      PdbReader pdbReader
      ) {
      // Walk the iterator method and collect all of the state that is assigned to fields in the iterator class
      // That state needs to replace any occurrences of the fields in the contracts (if they exist...)
      var iteratorStmts = new List<IStatement>(iteratorMethodBody.Block.Statements);
      Dictionary<uint, IExpression> capturedThings = new Dictionary<uint, IExpression>();
      // Find all of the state captured for the IEnumerable
      // REVIEW: Is this state ever used in the contracts? Since they're all sitting in the MoveNext
      // method, maybe they always use the IEnumerator state?
      if (1 < iteratorStmts.Count) {
        // First statement should be the creation of the iterator class
        int j = 1;
        while (j < iteratorStmts.Count) {
          var es = iteratorStmts[j++] as IExpressionStatement;
          if (es == null) break;
          var assign = es.Expression as IAssignment;
          if (assign == null) break;
          var field = assign.Target.Definition as IFieldReference;
          var capturedThing = assign.Source;
          var k = field.InternedKey;
          var spec = field as ISpecializedFieldReference;
          if (spec != null) k = spec.UnspecializedVersion.InternedKey;
          capturedThings.Add(k, capturedThing);
        }
      } else {
        var ret = iteratorStmts[0] as IReturnStatement;
        if (ret != null) {
          var be = ret.Expression as IBlockExpression;
          if (be != null) {
            var beStmts = new List<IStatement>(be.BlockStatement.Statements);
            var j = 1;
            while (j < beStmts.Count) {
              var es = beStmts[j++] as IExpressionStatement;
              if (es == null) break;
              var assign = es.Expression as IAssignment;
              if (assign == null) break;
              var field = assign.Target.Definition as IFieldReference;
              var capturedThing = assign.Source;
              var k = field.InternedKey;
              var spec = field as ISpecializedFieldReference;
              if (spec != null) k = spec.UnspecializedVersion.InternedKey;
              capturedThings.Add(k, capturedThing);
            }
          }
        }
      }
      // Find all of the state captured for the IEnumerator
      // That state is captured at the beginning of the IEnumerable<T>.GetEnumerator method
      IMethodDefinition getEnumerator = null;
      var t = moveNextBody.MethodDefinition.ContainingTypeDefinition;
      foreach (IMethodImplementation methodImplementation in t.ExplicitImplementationOverrides) {
        if (methodImplementation.ImplementedMethod.Name == host.NameTable.GetNameFor("GetEnumerator")) {
          var gtir = methodImplementation.ImplementedMethod.ContainingType as IGenericTypeInstanceReference;
          if (gtir != null && TypeHelper.TypesAreEquivalent(gtir.GenericType, host.PlatformType.SystemCollectionsGenericIEnumerable)) {
            getEnumerator = methodImplementation.ImplementingMethod.ResolvedMethod as IMethodDefinition;
            break;
          }
        }
      }
      if (getEnumerator != null) {
        IMethodBody geBody = getEnumerator.Body;
        var sourceGeBody = geBody as ISourceMethodBody;
        if (sourceGeBody == null)
          sourceGeBody = Decompiler.GetCodeModelFromMetadataModel(host, geBody, pdbReader, DecompilerOptions.AnonymousDelegates);
        foreach (var stmt in sourceGeBody.Block.Statements) {
          var es = stmt as IExpressionStatement;
          if (es == null) continue;
          var assign = es.Expression as IAssignment;
          if (assign == null) continue;
          var field2 = assign.Target.Definition as IFieldReference;
          if (field2 == null) continue;
          var k = field2.InternedKey;
          var spec = field2 as ISpecializedFieldReference;
          if (spec != null) k = spec.UnspecializedVersion.InternedKey;

          var sourceBe = assign.Source as IBoundExpression;
          if (sourceBe == null) continue;
          var field3 = sourceBe.Definition as IFieldReference;
          if (field3 == null) continue;
          var k3 = field3.InternedKey;
          var spec3 = field3 as ISpecializedFieldReference;
          if (spec3 != null) k3 = spec3.UnspecializedVersion.InternedKey;
          IExpression capturedThing = null;
          if (!capturedThings.TryGetValue(k3, out capturedThing)) continue;
          capturedThings[k] = capturedThing;
        }
      }

      var mc = HermansAlwaysRight.ExtractContracts(host, pdbReader, extractor, moveNextBody);

      if (mc == null) return mc;

      // substitute all field references in contract with the captured state
      var replacer = new Replacer(host, capturedThings, iteratorMethodBody.MethodDefinition, moveNextBody.MethodDefinition);
      replacer.RewriteChildren(mc);

      if (moveNextBody.MethodDefinition.ContainingTypeDefinition.IsGeneric) {
        var genericParameterMapper = new GenericMethodParameterMapper(host, iteratorMethodBody.MethodDefinition, moveNextBody.MethodDefinition.ContainingType as INestedTypeReference);
        mc = genericParameterMapper.Rewrite(mc) as MethodContract;
      }

      return mc;

    }
 public override void TraverseChildren(ISourceMethodBody methodBody) {
   base.TraverseChildren(methodBody);
 }
示例#20
0
 public void MethodBodyEnter(ISourceMethodBody method)
 {
     _currentBody       = method;
     _currentDescriptor = _currentDescriptor.GoDown();
 }
示例#21
0
文件: MoveNext.cs 项目: xornand/cci
        // TODO: First search the moveNextBody to see if there are any contracts at all.
        /// <summary>
        ///
        /// </summary>
        /// <param name="host"></param>
        /// <param name="extractor"></param>
        /// <param name="iteratorMethodBody"></param>
        /// <param name="moveNextBody"></param>
        /// <param name="pdbReader"></param>
        /// <returns></returns>
        public static MethodContract GetMethodContractFromMoveNext(
            IContractAwareHost host,
            ContractExtractor extractor,
            ISourceMethodBody iteratorMethodBody,
            ISourceMethodBody moveNextBody,
            PdbReader pdbReader
            )
        {
            // Walk the iterator method and collect all of the state that is assigned to fields in the iterator class
            // That state needs to replace any occurrences of the fields in the contracts (if they exist...)
            var iteratorStmts = new List <IStatement>(iteratorMethodBody.Block.Statements);
            Dictionary <uint, IExpression> capturedThings = new Dictionary <uint, IExpression>();

            // Find all of the state captured for the IEnumerable
            // REVIEW: Is this state ever used in the contracts? Since they're all sitting in the MoveNext
            // method, maybe they always use the IEnumerator state?
            if (1 < iteratorStmts.Count)
            {
                // First statement should be the creation of the iterator class
                int j = 1;
                while (j < iteratorStmts.Count)
                {
                    var es = iteratorStmts[j++] as IExpressionStatement;
                    if (es == null)
                    {
                        break;
                    }
                    var assign = es.Expression as IAssignment;
                    if (assign == null)
                    {
                        break;
                    }
                    var field         = assign.Target.Definition as IFieldReference;
                    var capturedThing = assign.Source;
                    var k             = field.InternedKey;
                    var spec          = field as ISpecializedFieldReference;
                    if (spec != null)
                    {
                        k = spec.UnspecializedVersion.InternedKey;
                    }
                    capturedThings.Add(k, capturedThing);
                }
            }
            else
            {
                var ret = iteratorStmts[0] as IReturnStatement;
                if (ret != null)
                {
                    var be = ret.Expression as IBlockExpression;
                    if (be != null)
                    {
                        var beStmts = new List <IStatement>(be.BlockStatement.Statements);
                        var j       = 1;
                        while (j < beStmts.Count)
                        {
                            var es = beStmts[j++] as IExpressionStatement;
                            if (es == null)
                            {
                                break;
                            }
                            var assign = es.Expression as IAssignment;
                            if (assign == null)
                            {
                                break;
                            }
                            var field         = assign.Target.Definition as IFieldReference;
                            var capturedThing = assign.Source;
                            var k             = field.InternedKey;
                            var spec          = field as ISpecializedFieldReference;
                            if (spec != null)
                            {
                                k = spec.UnspecializedVersion.InternedKey;
                            }
                            capturedThings.Add(k, capturedThing);
                        }
                    }
                }
            }
            // Find all of the state captured for the IEnumerator
            // That state is captured at the beginning of the IEnumerable<T>.GetEnumerator method
            IMethodDefinition getEnumerator = null;
            var t = moveNextBody.MethodDefinition.ContainingTypeDefinition;

            foreach (IMethodImplementation methodImplementation in t.ExplicitImplementationOverrides)
            {
                if (methodImplementation.ImplementedMethod.Name == host.NameTable.GetNameFor("GetEnumerator"))
                {
                    var gtir = methodImplementation.ImplementedMethod.ContainingType as IGenericTypeInstanceReference;
                    if (gtir != null && TypeHelper.TypesAreEquivalent(gtir.GenericType, host.PlatformType.SystemCollectionsGenericIEnumerable))
                    {
                        getEnumerator = methodImplementation.ImplementingMethod.ResolvedMethod as IMethodDefinition;
                        break;
                    }
                }
            }
            if (getEnumerator != null)
            {
                IMethodBody geBody       = getEnumerator.Body;
                var         sourceGeBody = geBody as ISourceMethodBody;
                if (sourceGeBody == null)
                {
                    sourceGeBody = Decompiler.GetCodeModelFromMetadataModel(host, geBody, pdbReader, DecompilerOptions.AnonymousDelegates);
                }
                foreach (var stmt in sourceGeBody.Block.Statements)
                {
                    var es = stmt as IExpressionStatement;
                    if (es == null)
                    {
                        continue;
                    }
                    var assign = es.Expression as IAssignment;
                    if (assign == null)
                    {
                        continue;
                    }
                    var field2 = assign.Target.Definition as IFieldReference;
                    if (field2 == null)
                    {
                        continue;
                    }
                    var k    = field2.InternedKey;
                    var spec = field2 as ISpecializedFieldReference;
                    if (spec != null)
                    {
                        k = spec.UnspecializedVersion.InternedKey;
                    }

                    var sourceBe = assign.Source as IBoundExpression;
                    if (sourceBe == null)
                    {
                        continue;
                    }
                    var field3 = sourceBe.Definition as IFieldReference;
                    if (field3 == null)
                    {
                        continue;
                    }
                    var k3    = field3.InternedKey;
                    var spec3 = field3 as ISpecializedFieldReference;
                    if (spec3 != null)
                    {
                        k3 = spec3.UnspecializedVersion.InternedKey;
                    }
                    IExpression capturedThing = null;
                    if (!capturedThings.TryGetValue(k3, out capturedThing))
                    {
                        continue;
                    }
                    capturedThings[k] = capturedThing;
                }
            }

            var mc = HermansAlwaysRight.ExtractContracts(host, pdbReader, extractor, moveNextBody);

            if (mc == null)
            {
                return(mc);
            }

            // substitute all field references in contract with the captured state
            var replacer = new Replacer(host, capturedThings, iteratorMethodBody.MethodDefinition, moveNextBody.MethodDefinition);

            replacer.RewriteChildren(mc);

            if (moveNextBody.MethodDefinition.ContainingTypeDefinition.IsGeneric)
            {
                var genericParameterMapper = new GenericMethodParameterMapper(host, iteratorMethodBody.MethodDefinition, moveNextBody.MethodDefinition.ContainingType as INestedTypeReference);
                mc = genericParameterMapper.Rewrite(mc) as MethodContract;
            }

            return(mc);
        }
示例#22
0
 public AstDescriptor MethodBodyExit(ISourceMethodBody method)
 {
     _currentBody       = null;
     _currentDescriptor = _currentDescriptor.GoUp();
     return(_currentDescriptor);
 }
示例#23
0
文件: MoveNext.cs 项目: xornand/cci
            public static MethodContract /*?*/ ExtractContracts(IContractAwareHost contractAwareHost, PdbReader /*?*/ pdbReader, ContractExtractor extractor, ISourceMethodBody methodBody)
            {
                var definingUnit = TypeHelper.GetDefiningUnit(methodBody.MethodDefinition.ContainingType.ResolvedType);
                var methodIsInReferenceAssembly = ContractHelper.IsContractReferenceAssembly(contractAwareHost, definingUnit);
                var oldAndResultExtractor       = new OldAndResultExtractor(contractAwareHost, methodBody, extractor.IsContractMethod);
                var localsInitializedWithFields = FindLocals.FindSetOfLocals(methodBody);

                var har = new HermansAlwaysRight(contractAwareHost, extractor, methodBody, methodIsInReferenceAssembly, oldAndResultExtractor, pdbReader);

                har.Rewrite(methodBody);

                if (har.extractor.currentMethodContract == null)
                {
                    return(null);
                }

                // The decompiler will have introduced locals if there were any anonymous delegates in the contracts
                // Such locals are initialized with the fields of the iterator class.
                // The contract that comes back from here will have those fields replaced with whatever the iterator captured
                // (parameters, locals). So the locals in the contract need to be replaced with the iterator fields so that
                // next replacement will see the right thing (i.e., the fields) and replace them! Phew!
                var localReplacer = new LocalReplacer(contractAwareHost, localsInitializedWithFields);

                localReplacer.Rewrite(har.extractor.currentMethodContract);
                // also need to rewrite the remainder of the body
                localReplacer.Rewrite(methodBody);

                return(har.extractor.currentMethodContract);
            }
示例#24
0
 public void MethodBodyEnter(ISourceMethodBody method)
 {
     _processor.MethodBodyEnter(method);
 }
示例#25
0
文件: MoveNext.cs 项目: xornand/cci
                public static Dictionary <ILocalDefinition, IBoundExpression> FindSetOfLocals(ISourceMethodBody s)
                {
                    var fl = new FindLocals();

                    fl.Traverse(s);
                    return(fl.localsToInitializers);
                }
示例#26
0
 public AstDescriptor MethodBodyExit(ISourceMethodBody method)
 {
     return(_processor.MethodBodyExit(method));
     // _currentMethodObj = null;
 }
示例#27
0
 /// <summary>
 /// Returns a deep copy of the given source method body.
 /// </summary>
 /// <param name="sourceMethodBody"></param>
 public SourceMethodBody Copy(ISourceMethodBody sourceMethodBody)
 {
     return this.Copy(sourceMethodBody, sourceMethodBody.MethodDefinition);
 }
 /// <summary>
 /// Rewrites the the given source method body.
 /// </summary>
 /// <param name="sourceMethodBody"></param>
 public virtual ISourceMethodBody Rewrite(ISourceMethodBody sourceMethodBody)
 {
     return sourceMethodBody;
 }
示例#29
0
 /// <summary>
 /// Returns a shallow copy of the given source method body.
 /// </summary>
 /// <param name="sourceMethodBody"></param>
 public SourceMethodBody Copy(ISourceMethodBody sourceMethodBody)
 {
     var copy = new SourceMethodBody(this.targetHost, this.sourceLocationProvider);
       copy.Block = sourceMethodBody.Block;
       copy.LocalsAreZeroed = sourceMethodBody.LocalsAreZeroed;
       copy.MethodDefinition = sourceMethodBody.MethodDefinition;
       return copy;
 }
示例#30
0
 /// <summary>
 /// For a client (e.g., the decompiler) that has a source method body and wants to have its
 /// contract extracted and added to the contract provider.
 /// </summary>
 public MethodContractAndMethodBody SplitMethodBodyIntoContractAndCode(ISourceMethodBody sourceMethodBody)
 {
     return this.primaryExtractor.SplitMethodBodyIntoContractAndCode(sourceMethodBody);
 }
示例#31
0
 //^ ensures this.path.Count == old(this.path.Count);
 /// <summary>
 /// Visits the specified method body.
 /// </summary>
 /// <param name="methodBody">The method body.</param>
 public virtual void Visit(ISourceMethodBody methodBody)
 {
     if (this.stopTraversal) return;
       //^ int oldCount = this.path.Count;
       this.path.Push(methodBody);
       if (!methodBody.MethodDefinition.IsAbstract)
     this.Visit(methodBody.Block);
       //^ assume this.path.Count == oldCount+1; //True because all of the virtual methods of this class promise not decrease this.path.Count.
       this.path.Pop();
 }
示例#32
0
 /// <summary>
 /// For a client (e.g., the decompiler) that has a source method body and wants to have its
 /// contract extracted and added to the contract provider.
 /// </summary>
 public MethodContractAndMethodBody SplitMethodBodyIntoContractAndCode(ISourceMethodBody sourceMethodBody)
 {
     return this.underlyingContractProvider.SplitMethodBodyIntoContractAndCode(sourceMethodBody);
 }
示例#33
0
 /// <summary>
 /// Traverses the the given source method body.
 /// </summary>
 public virtual void TraverseChildren(ISourceMethodBody sourceMethodBody)
 {
     Contract.Requires(sourceMethodBody != null);
       //do not traverse the IL via IMethodBody
       this.Traverse(sourceMethodBody.Block);
 }
示例#34
0
 /// <summary>
 /// For a client (e.g., the decompiler) that has a source method body and wants to have its
 /// contract extracted and added to the contract provider.
 /// </summary>
 public MethodContractAndMethodBody SplitMethodBodyIntoContractAndCode(ISourceMethodBody sourceMethodBody)
 {
     return Microsoft.Cci.MutableContracts.ContractExtractor.SplitMethodBodyIntoContractAndCode(this.host, sourceMethodBody, this.pdbReader);
 }
示例#35
0
 /// <summary>
 /// For a client (e.g., the decompiler) that has a source method body and wants to have its
 /// contract extracted and added to the contract provider.
 /// </summary>
 public MethodContractAndMethodBody SplitMethodBodyIntoContractAndCode(ISourceMethodBody sourceMethodBody)
 {
     return(this.underlyingContractProvider.SplitMethodBodyIntoContractAndCode(sourceMethodBody));
 }
示例#36
0
    /// <summary>
    /// Returns a shallow copy of the given source method body.
    /// </summary>
    /// <param name="sourceMethodBody"></param>
    public SourceMethodBody Copy(ISourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);
      Contract.Ensures(Contract.Result<SourceMethodBody>() != null);

      var copy = new SourceMethodBody(this.targetHost, this.sourceLocationProvider, this.localScopeProvider);
      copy.Block = sourceMethodBody.Block;
      copy.LocalsAreZeroed = sourceMethodBody.LocalsAreZeroed;
      copy.MethodDefinition = sourceMethodBody.MethodDefinition;
      return copy;
    }
示例#37
0
 /// <summary>
 /// For a client (e.g., the decompiler) that has a source method body and wants to have its
 /// contract extracted and added to the contract provider.
 /// </summary>
 public MethodContractAndMethodBody SplitMethodBodyIntoContractAndCode(ISourceMethodBody sourceMethodBody)
 {
     return(Microsoft.Cci.MutableContracts.ContractExtractor.SplitMethodBodyIntoContractAndCode(this.host, sourceMethodBody, this.pdbReader));
 }
示例#38
0
    /// <summary>
    /// Returns a deep copy of the given source method body.
    /// </summary>
    /// <param name="sourceMethodBody"></param>
    public SourceMethodBody Copy(ISourceMethodBody sourceMethodBody) {
      Contract.Requires(sourceMethodBody != null);
      Contract.Ensures(Contract.Result<SourceMethodBody>() != null);

      return this.Copy(sourceMethodBody, sourceMethodBody.MethodDefinition);
    }
示例#39
0
 public override void TraverseChildren(ISourceMethodBody sourceMethodBody)
 {
     MethodEnter(sourceMethodBody);
     base.TraverseChildren(sourceMethodBody);
     MethodExit();
 }
示例#40
0
 /// <summary>
 /// Rewrites the the given source method body.
 /// </summary>
 /// <param name="sourceMethodBody"></param>
 public virtual ISourceMethodBody Rewrite(ISourceMethodBody sourceMethodBody)
 {
     var mutableSourceMethodBody = sourceMethodBody as SourceMethodBody;
       if (mutableSourceMethodBody == null) return sourceMethodBody;
       this.RewriteChildren(mutableSourceMethodBody);
       return mutableSourceMethodBody;
 }