Beispiel #1
0
        public Tuple <DependencyPTGDomain, TimeSpan> AnalyzeMoveNextMethod()
        {
            AnalysisStats.extraAnalysisOverHead = new Stopwatch();
            var sw = new Stopwatch();

            sw.Start();

            // 0) Analyze static fields.
            // DIEGODIEGO: Should I also Include the points-to graph???
            var staticConstructor = processToAnalyze.ProcessorClass.Methods.SingleOrDefault(m => m.Name.Value == ".cctor");

            if (staticConstructor != null)
            {
                var cfgcCtor           = staticConstructor.DoAnalysisPhases(host, sourceLocationProvider);
                var rangeAnalysisCctor = new RangeAnalysis(cfgcCtor, staticConstructor);
                rangeAnalysisCctor.Analyze();
            }

            // The following steps generates a PTG for the MoveNext method that takes into account the context of invocation
            // This is the Producer entry method and the call to GetEnumerator which then is used in the Movenext method

            // 1) Analyze the entry method that creates, populates  and return the clousure
            var cfgEntry      = processToAnalyze.EntryMethod.DoAnalysisPhases(host, sourceLocationProvider);
            var pointsToEntry = new SimplePointsToAnalysis(cfgEntry, processToAnalyze.EntryMethod);
            var entryResult   = pointsToEntry.Analyze();
            var ptgOfEntry    = entryResult[cfgEntry.Exit.Id].Output;

            // 2) Call the GetEnumerator that may create a new clousure and polulate it
            var myGetEnumResult = new LocalVariable("$_temp_it", processToAnalyze.EntryMethod)
            {
                Type = processToAnalyze.GetIteratorMethod.Type
            };

            ptgOfEntry.Add(myGetEnumResult);
            var ptgAfterEnum = this.interprocManager.PTAInterProcAnalysis(ptgOfEntry, new List <IVariable> {
                pointsToEntry.ReturnVariable
            }, myGetEnumResult, processToAnalyze.GetIteratorMethod);

            // These are the nodes that we want to protect/analyze
            var protectedNodes = ptgOfEntry.Nodes.OfType <ParameterNode>()
                                 .Where(n => IsScopeType(n.Type)).Select(n => new ProtectedRowNode(n, ProtectedRowNode.GetKind(n.Type)));

            // Create tables representing the input and output tables
            this.inputTable  = new TraceableTable(protectedNodes.Single(pn => pn.RowKind == ProtectedRowKind.Input));
            this.outputTable = new TraceableTable(protectedNodes.Single(pn => pn.RowKind == ProtectedRowKind.Output));

            // 3) I bing the current PTG with the parameters of MoveNext method on the clousure

            // Well... Inlining is broken we we added the Exceptional control graph. Let's avoid it
            //var cfg = this.moveNextMethod.DoAnalysisPhases(host, this.GetMethodsToInline());

            var cfg = this.interprocManager.GetCFG(processToAnalyze.MoveNextMethod);

            cfg.PropagateExpressions(this.equalities);
            // In general, the variable to bind is going to be pointsToEntry.ReturnVariable which is aliased with "$_temp_it" (myGetEnumResult)
            SimplePointsToGraph calleePTG = InterproceduralManager.PTABindCallerCallee(ptgAfterEnum, new List <IVariable> {
                myGetEnumResult
            }, processToAnalyze.MoveNextMethod);

            this.pointsToAnalyzer = new SimplePointsToAnalysis(cfg, processToAnalyze.MoveNextMethod, calleePTG);


            // Now I analyze the Movenext method with the proper initialization
            var result = this.AnalyzeScopeMethod(cfg, pointsToAnalyzer, protectedNodes);

            sw.Stop();
            //return Tuple.Create(result, sw.Elapsed - AnalysisStats.extraAnalysisOverHead.Elapsed);
            return(Tuple.Create(result, sw.Elapsed));
        }
        public DependencyPTGDomain AnalyzeMoveNextMethod()
        {
            // 1) Analyze the entry method that creates, populates  and return the clousure
            var cfgEntry      = entryMethod.DoAnalysisPhases(host);
            var pointsToEntry = new IteratorPointsToAnalysis(cfgEntry, this.entryMethod); // , this.specialFields);
            var entryResult   = pointsToEntry.Analyze();
            var ptgOfEntry    = entryResult[cfgEntry.Exit.Id].Output;

            // 2) Call the GetEnumerator that may create a new clousure and polulate it
            var myGetEnumResult = new LocalVariable("$_temp_it")
            {
                Type = getEnumMethod.ReturnType
            };

            ptgOfEntry.Add(myGetEnumResult);
            var ptgAfterEnum = this.interprocManager.PTAInterProcAnalysis(ptgOfEntry, new List <IVariable> {
                pointsToEntry.ReturnVariable
            }, myGetEnumResult, this.getEnumMethod);

            // These are the nodes that we want to protect/analyze
            var protectedNodes = ptgOfEntry.Nodes.OfType <ParameterNode>()
                                 .Where(n => IsScopeType(n.Type)).Select(n => new ProtectedRowNode(n, ProtectedRowNode.GetKind(n.Type)));

            // I no longer need this.
            //var specialFields = cfgEntry.ForwardOrder[1].Instructions.OfType<StoreInstruction>()
            //    .Where(st => st.Result is InstanceFieldAccess).Select(st => new KeyValuePair<string,IVariable>((st.Result as InstanceFieldAccess).FieldName,st.Operand) );
            //this.specialFields = specialFields.ToDictionary(item => item.Key, item => item.Value);


            // 3) I bing the current PTG with the parameters of MoveNext method on the clousure

            // Well... Inlining is broken we we added the Exceptional control graph. Let's avoid it
            //var cfg = this.moveNextMethod.DoAnalysisPhases(host, this.GetMethodsToInline());

            var cfg = this.interprocManager.GetCFG(this.moveNextMethod);

            PropagateExpressions(cfg, this.equalities);
            // In general, the variable to bind is going to be pointsToEntry.ReturnVariable which is aliased with "$_temp_it" (myGetEnumResult)
            SimplePointsToGraph calleePTG = InterproceduralManager.PTABindCallerCallee(ptgAfterEnum, new List <IVariable> {
                myGetEnumResult
            }, this.moveNextMethod);

            this.pointsToAnalyzer = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, calleePTG);

            //this.pta= this.interprocManager.PTABindAndRunInterProcAnalysis(ptgAfterEnum, new List<IVariable> { myGetEnumResult }, this.moveNextMethod, cfg);

            //var pointsTo = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, this.specialFields);
            //this.ptAnalysisResult = pointsTo.Analyze();

            // var pointsTo = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, this.specialFields, ptgOfEntry);

            // Now I analyze the Movenext method with the proper initialization
            var result = this.AnalyzeScopeMethod(cfg, pointsToAnalyzer, protectedNodes);


            return(result);
        }