関連するプロパティ間の伝播を追跡するための手法として Correlation Tracking [Sridharan] が実装されている。

この手法を利用するためには CorrelatedPairExtractorFactory クラスと PropertyNameContextSelector クラスを利用する。

  • CorrelatedPairExtractorFactory クラス (package: com.ibm.wala.cast.js.ipa.callgraph.correlations.extraction)

  • PropertyNameContextSelector クラス (package: com.ibm.wala.cast.js.ipa.callgraph)

import com.ibm.wala.cast.ir.ssa.AstIRFactory;
import com.ibm.wala.cast.js.ipa.callgraph.*;
import com.ibm.wala.cast.js.ipa.callgraph.correlations.extraction.CorrelatedPairExtractorFactory;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
import com.ibm.wala.cast.tree.rewrite.CAstRewriterFactory;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.IRFactory;
import com.ibm.wala.util.io.FileProvider;

import java.io.File;

public class Correlated {
  public static void main(String[] args) {
    String fileName = "correlation-tracking-example.js";
    try {
      File f = new FileProvider().getFile(fileName);
      SourceModule[] modules = new SourceModule[] {
        (SourceModule)  JSCallGraphUtil.getPrologueFile("prologue.js"),
          new SourceFileModule(f, fileName, null)
      };
      JavaScriptTranslatorFactory translatorFactory = new CAstRhinoTranslatorFactory();
      JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());

      // x[name] = y[name]となるペアをみつける
      CAstRewriterFactory preprocessor = new CorrelatedPairExtractorFactory(translatorFactory, modules);

      // ※JSCallGraphUtil.getPrologueFile()のストリームを一度使ったので、再生成
      SourceModule[] files = new SourceModule[] {
        (SourceModule)  JSCallGraphUtil.getPrologueFile("prologue.js"),
          new SourceFileModule(f, fileName, null)
      };

      // 生成したCorrelatedPairExtractorFactoryをpreprocessorとして設定
      JavaScriptLoaderFactory loaderFactory = JSCallGraphUtil.makeLoaders(preprocessor);
      AnalysisScope scope = JSCallGraphUtil.makeScope(files, loaderFactory, JavaScriptLoader.JS);
      IClassHierarchy cha = JSCallGraphUtil.makeHierarchy(scope, loaderFactory);

      JavaScriptEntryPoints roots = JSCallGraphUtil.makeScriptRoots(cha);

      JSAnalysisOptions options = JSCallGraphUtil.makeOptions(scope, cha, roots);

      IRFactory<IMethod> irFactory = AstIRFactory.makeDefaultFactory();
      AnalysisCache cache = (AnalysisCache) JSCallGraphUtil.makeCache(irFactory);

      JSCFABuilder builder = new JSZeroOrOneXCFABuilder(
          cha,
          options,
          cache,
          null,
          null,
          ZeroXInstanceKeys.ALLOCATIONS,
          true
          );
      // プロパティ名に紐づくコンテキスト設定
      ContextSelector contextSelector = new PropertyNameContextSelector(cache, 2, builder.getContextSelector());
      builder.setContextSelector(contextSelector);

      CallGraph callGraph = builder.makeCallGraph(options, null);
      PointerAnalysis pointerAnalysis = builder.getPointerAnalysis();
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
}

参考文献

  • Sridharan, Manu, et al. "Correlation tracking for points-to analysis of JavaScript." European Conference on Object-Oriented Programming. Springer, Berlin, Heidelberg, 2012.