Beispiel #1
0
        private IMethodSummarizer GetBytecodeSummarizerForMethod(IMethodDefinition methodDefinition)
        {
            //return simpleBytecodeSummarizer;


            TypesLocalFlowMethodSummarizer localFlowSummarizer = new TypesLocalFlowMethodSummarizer();

            if (localFlowSummarizer.CanSummarizeMethod(methodDefinition))
            {
                countUsedFlowBasedSummarizer++;
                return(localFlowSummarizer);
            }
            else
            {
                return(simpleBytecodeSummarizer);
            }
        }
    public void TestJoinedLocalVariableLocalFlow() {

      string source =
@"internal class Super {
    internal virtual int M(bool f) {return 17;}
  }

  internal class Sub1 : Super {
    internal Sub1(int param) {
    }

    internal override int M(bool f) {
      return 32;
    }
  }

  internal class Sub2 : Super {
    internal Sub2(int param) {
    }

    internal override int M(bool f) {
      return 3622;
    }
  }

 class Foo {
   void Run(bool flag) {
    Super s;

      if (flag) {
         s = new Sub1(17);
      } else {
         s = new Sub2(32);
      }
      
      s.M(false);
   }
 }
";

      ConstructWholeProgramForSources(new string[] { source }, (compilerResults, wholeProgram) => {
        IMethodDefinition fooRunMethod = compilerResults.FindMethodWithName("Foo::Run");
        Assert.IsNotNull(fooRunMethod);

        LocalFlowMethodSummarizer summarizer = new TypesLocalFlowMethodSummarizer();

        Assert.IsTrue(summarizer.CanSummarizeMethod(fooRunMethod));

        ReachabilitySummary summary = summarizer.SummarizeMethod(fooRunMethod, wholeProgram);
        Assert.IsNotNull(summary);

        Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Sub1::M")));
        Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Sub2::M")));

        Assert.IsTrue(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Super::M")));

      });
    }
    public void TestJoinedOperandStackLocalFlow() {

      string source =
@"internal class Super {
    public Super() {}
    internal virtual int M(bool f) {return 17;}
  }

  internal class Sub1 : Super {
    internal Sub1(int param) {}

    internal override int M(bool f) {
      return 32;
    }
  }

  internal class SubSub1 : Sub1 {
    internal SubSub1(int param) :base(param) {}

    internal override int M(bool f) {
      return 66;
    }
  }

 class Foo {
   void Run(bool flag) {
      (flag? new Sub1(17) : new SubSub1(3)).M(false);

      (flag? new SubSub1(3) : new Sub1(17)).M(false);
   }
 }
";

      ConstructWholeProgramForSources(new string[] { source }, (compilerResults, wholeProgram) => {
        IMethodDefinition fooRunMethod = compilerResults.FindMethodWithName("Foo::Run");
        Assert.IsNotNull(fooRunMethod);

        LocalFlowMethodSummarizer summarizer = new TypesLocalFlowMethodSummarizer();

        Assert.IsTrue(summarizer.CanSummarizeMethod(fooRunMethod));

        ReachabilitySummary summary = summarizer.SummarizeMethod(fooRunMethod, wholeProgram);
        Assert.IsNotNull(summary);

        Assert.IsTrue(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Sub1::M")));

        // Note: although this method could be called, we don't actually want to dispatch on it, but rather Sub1::M
        Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("SubSub1::M")));

        Assert.IsFalse(summary.VirtuallyCalledMethods.Contains(compilerResults.FindMethodWithName("Super::M")));

      });
    }
    private IMethodSummarizer GetBytecodeSummarizerForMethod(IMethodDefinition methodDefinition) {
      //return simpleBytecodeSummarizer;

      
      TypesLocalFlowMethodSummarizer localFlowSummarizer = new TypesLocalFlowMethodSummarizer();

      if (localFlowSummarizer.CanSummarizeMethod(methodDefinition)) {
        countUsedFlowBasedSummarizer++;
        return localFlowSummarizer;
      }
      else {
        return simpleBytecodeSummarizer;
      }
    }