Beispiel #1
0
        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);
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        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();
            }
        }
Beispiel #4
0
        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);
        }