private LispList <Pair <EdgeTag, Subroutine> > InsertInvariant(CFGBlock from, LispList <Pair <EdgeTag, Subroutine> > list, Method calledMethod, ref TypeNode type, LispList <Edge <CFGBlock, EdgeTag> > context) { IMetaDataProvider metadataDecoder = this.SubroutineFacade.MetaDataProvider; Property property; if (metadataDecoder.IsPropertySetter(calledMethod, out property) && (metadataDecoder.IsAutoPropertyMember(calledMethod) || WithinConstructor(from, context))) { return(list); } if (metadataDecoder.IsConstructor(calledMethod)) { type = metadataDecoder.DeclaringType(calledMethod); } Subroutine invariant = this.SubroutineFacade.GetInvariant(type); if (invariant != null) { var methodCallBlock = from as MethodCallBlock <Label>; if (methodCallBlock != null) { EdgeTag first = methodCallBlock.IsNewObj ? EdgeTag.AfterNewObj : EdgeTag.AfterCall; return(list.Cons(new Pair <EdgeTag, Subroutine> (first, invariant))); } } return(list); }
public MethodSubroutine(SubroutineFacade SubroutineFacade, Method method, Label startLabel, SubroutineWithHandlersBuilder <Label, Handler> builder) : base(SubroutineFacade, startLabel, builder) { this.method = method; IMetaDataProvider metaDataProvider = this.SubroutineFacade.MetaDataProvider; builder.BuildBlocks(startLabel, this); BlockWithLabels <Label> targetBlock = GetTargetBlock(startLabel); Commit(); TypeNode type = metaDataProvider.DeclaringType(method); Subroutine invariant = this.SubroutineFacade.GetInvariant(type); if (invariant != null && !metaDataProvider.IsConstructor(method) && !metaDataProvider.IsStatic(method)) { AddEdgeSubroutine(Entry, targetBlock, invariant, EdgeTag.Entry); Subroutine requires = this.SubroutineFacade.GetRequires(method); if (requires != null) { AddEdgeSubroutine(Entry, targetBlock, requires, EdgeTag.Entry); } } else { AddEdgeSubroutine(Entry, targetBlock, this.SubroutineFacade.GetRequires(method), EdgeTag.Entry); } if (this.blocks_ending_in_return_point == null) { return; } Subroutine ensures = this.SubroutineFacade.GetEnsures(method); bool putInvariantAfterExit = !metaDataProvider.IsStatic(method) && !metaDataProvider.IsFinalizer(method) && !metaDataProvider.IsDispose(method); foreach (var block in this.blocks_ending_in_return_point) { if (putInvariantAfterExit) { AddEdgeSubroutine(block, Exit, invariant, EdgeTag.Exit); } AddEdgeSubroutine(block, Exit, ensures, EdgeTag.Exit); } if (ensures != null) { throw new NotImplementedException(); } this.blocks_ending_in_return_point = null; }
public override LispList <Pair <EdgeTag, Subroutine> > GetOrdinaryEdgeSubroutines(CFGBlock from, CFGBlock to, LispList <Edge <CFGBlock, EdgeTag> > context) { IMetaDataProvider metadataDecoder = this.SubroutineFacade.MetaDataProvider; var apc = new APC(to, 0, context); DecoratorHelper.Push(this); try { LispList <Pair <EdgeTag, Subroutine> > list = DecoratorHelper.Dispatch <IEdgeSubroutineAdaptor> (this).GetOrdinaryEdgeSubroutinesInternal(from, to, context); if (apc.InsideContract) { if (context != null && !list.IsEmpty()) { Method calledMethod; bool isNewObj; bool isVirtual; if (@from.IsMethodCallBlock(out calledMethod, out isNewObj, out isVirtual) && isVirtual && ((IStackInfo)this).IsCallOnThis(new APC(@from, 0, null))) { TypeNode type = metadataDecoder.DeclaringType(calledMethod); do { if (context.Head.Tag.Is(EdgeTag.InheritedMask) || context.Head.Tag.Is(EdgeTag.ExtraMask) || context.Head.Tag.Is(EdgeTag.OldMask)) { context = context.Tail; } else { Method calledMethod2; bool isNewObj2; bool isVirtual2; if (context.Head.Tag.Is(EdgeTag.AfterMask) && context.Head.From.IsMethodCallBlock(out calledMethod2, out isNewObj2, out isVirtual2)) { TypeNode sub = metadataDecoder.DeclaringType(calledMethod2); if (metadataDecoder.DerivesFrom(sub, type)) { type = sub; } if (!DecoratorHelper.Dispatch <IStackInfo> (this).IsCallOnThis(new APC(context.Head.From, 0, null))) { break; } } else if (context.Head.Tag.Is(EdgeTag.BeforeMask) && context.Head.To.IsMethodCallBlock(out calledMethod2, out isNewObj2, out isVirtual2)) { TypeNode sub = metadataDecoder.DeclaringType(calledMethod2); if (metadataDecoder.DerivesFrom(sub, type)) { type = sub; } if (!DecoratorHelper.Dispatch <IStackInfo> (this).IsCallOnThis(new APC(context.Head.To, 0, null))) { break; } } else if (context.Head.Tag == EdgeTag.Exit) { var methodInfo = context.Head.From.Subroutine as IMethodInfo; if (methodInfo != null) { TypeNode sub = metadataDecoder.DeclaringType(methodInfo.Method); if (metadataDecoder.DerivesFrom(sub, type)) { type = sub; } } break; } else { if (context.Head.Tag != EdgeTag.Entry) { return(list); } var methodInfo = context.Head.From.Subroutine as IMethodInfo; if (methodInfo != null) { TypeNode sub = metadataDecoder.DeclaringType(methodInfo.Method); if (metadataDecoder.DerivesFrom(sub, type)) { type = sub; } } break; } context = context.Tail; } } while (!context.IsEmpty()); Method implementingMethod; if (!metadataDecoder.Equal(type, metadataDecoder.DeclaringType(calledMethod)) && metadataDecoder.TryGetImplementingMethod(type, calledMethod, out implementingMethod)) { list = SpecializedEnsures(list, this.SubroutineFacade.GetEnsures(calledMethod), this.SubroutineFacade.GetEnsures(implementingMethod)); } } } } else { Method calledMethod; bool isNewObj; bool isVirtual; if (@from.IsMethodCallBlock(out calledMethod, out isNewObj, out isVirtual)) { if (DecoratorHelper.Dispatch <IStackInfo> (this).IsCallOnThis(new APC(@from, 0, null))) { var methodInfo = @from.Subroutine as IMethodInfo; if (methodInfo != null) { TypeNode bestType = metadataDecoder.DeclaringType(methodInfo.Method); Method implementingMethod; if (isVirtual && metadataDecoder.TryGetImplementingMethod(bestType, calledMethod, out implementingMethod)) { list = SpecializedEnsures(list, this.SubroutineFacade.GetEnsures(calledMethod), this.SubroutineFacade.GetEnsures(implementingMethod)); } list = InsertInvariant(@from, list, calledMethod, ref bestType, context); } } } } return(list); } finally { DecoratorHelper.Pop(); } }
public override bool TrySetType(TypeNode expectedType, IMetaDataProvider metaDataProvider, out TypeNode resultType) { if (typeof(T) == typeof(Parameter)) { var p = (Parameter)(object)this.Element; TypeNode type = metaDataProvider.ParameterType(p); this.isManagedPointer = metaDataProvider.IsManagedPointer(type); ResultType = resultType = metaDataProvider.ManagedPointer(type); return(true); } if (typeof(T) == typeof(Field)) { var f = (Field)(object)this.Element; TypeNode type = metaDataProvider.FieldType(f); this.isStatic = metaDataProvider.IsStatic(f); this.isManagedPointer = metaDataProvider.IsManagedPointer(type); ResultType = resultType = metaDataProvider.ManagedPointer(type); TypeNode declaringType = metaDataProvider.DeclaringType(f); if (metaDataProvider.IsManagedPointer(expectedType)) { expectedType = metaDataProvider.ElementType(expectedType); } expectedType = metaDataProvider.Unspecialized(expectedType); if (!metaDataProvider.IsStatic(f) && declaringType.Equals(expectedType) && (!metaDataProvider.DerivesFrom(expectedType, declaringType) || !metaDataProvider.IsProtected(f) && !metaDataProvider.IsPublic(f))) { this.castTo = metaDataProvider.FullName(declaringType); } return(true); } if (typeof(T) == typeof(Local)) { var local = (Local)(object)this.Element; TypeNode type = metaDataProvider.LocalType(local); this.isManagedPointer = metaDataProvider.IsManagedPointer(type); ResultType = resultType = metaDataProvider.ManagedPointer(type); return(true); } if (typeof(T) == typeof(Method)) { var method = (Method)(object)this.Element; ResultType = resultType = !IsAddressOf ? metaDataProvider.ReturnType(method) : metaDataProvider.ManagedPointer(metaDataProvider.ReturnType(method)); if (metaDataProvider.IsManagedPointer(expectedType)) { expectedType = metaDataProvider.ElementType(expectedType); } expectedType = metaDataProvider.Unspecialized(expectedType); TypeNode declaringType = metaDataProvider.DeclaringType(method); if (!metaDataProvider.IsStatic(method) && declaringType.Equals(expectedType) && (!metaDataProvider.DerivesFrom(expectedType, declaringType) || !metaDataProvider.IsProtected(method) && !metaDataProvider.IsPublic(method))) { this.castTo = metaDataProvider.FullName(declaringType); } return(true); } ResultType = resultType = default(TypeNode); return(false); }