/// <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; }
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()); } } }
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; }
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); }
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; }
/// <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); }
/// <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)); }
/// <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(); }
private SourceMethodBody Copy(ISourceMethodBody sourceMethodBody, IMethodDefinition method) { var mutableCopy = this.shallowCopier.Copy(sourceMethodBody); mutableCopy.Block = this.Copy(mutableCopy.Block); mutableCopy.MethodDefinition = method; return mutableCopy; }
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); }
/// <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); }
/// <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); }
public override ISourceMethodBody Rewrite(ISourceMethodBody sourceMethodBody) { return(base.Rewrite(sourceMethodBody)); }
public static Dictionary<ILocalDefinition, IBoundExpression> FindSetOfLocals(ISourceMethodBody s) { var fl = new FindLocals(); fl.Traverse(s); return fl.localsToInitializers; }
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; }
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; }
// 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); }
public void MethodBodyEnter(ISourceMethodBody method) { _currentBody = method; _currentDescriptor = _currentDescriptor.GoDown(); }
// 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 AstDescriptor MethodBodyExit(ISourceMethodBody method) { _currentBody = null; _currentDescriptor = _currentDescriptor.GoUp(); return(_currentDescriptor); }
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); }
public void MethodBodyEnter(ISourceMethodBody method) { _processor.MethodBodyEnter(method); }
public static Dictionary <ILocalDefinition, IBoundExpression> FindSetOfLocals(ISourceMethodBody s) { var fl = new FindLocals(); fl.Traverse(s); return(fl.localsToInitializers); }
public AstDescriptor MethodBodyExit(ISourceMethodBody method) { return(_processor.MethodBodyExit(method)); // _currentMethodObj = null; }
/// <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; }
/// <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; }
/// <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); }
//^ 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(); }
/// <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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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; }
/// <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)); }
/// <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); }
/// <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; }