@@ -16,93 +16,56 @@ import maf.modular.taint.scheme.SchemeModFBigStepTaintSemantics
1616import maf .modular .worklist .*
1717import maf .util .Reader
1818import maf .util .benchmarks .{Timeout , Timer }
19+ import maf .modular .scheme .modf ._
20+ import maf .modular .scheme .modf .SchemeModFComponent ._
21+ import maf .language .scheme ._
1922
2023import scala .concurrent .duration .*
2124
2225// null values are used here due to Java interop
2326import scala .language .unsafeNulls
2427
2528object AnalyzeProgram extends App :
26- def runAnalysis [A <: ModAnalysis [SchemeExp ] with GlobalStore [SchemeExp ]](bench : String , analysis : SchemeExp => A , timeout : () => Timeout .T ): A =
27- val text = TaintSchemeParser .parseProgram(Reader .loadFile(bench))
28- val a = analysis(text)
29- print(s " Analysis of $bench " )
30- try {
31- val time = Timer .timeOnly {
32- a.analyzeWithTimeout(timeout())
33- println(a.store.filterNot(_.toString().contains(" PrmAddr" )).size)
34- // println(a.program.prettyString())
35- }
36- println(s " terminated in ${time / 1000000 } ms. " )
37- // a.deps.toSet[(Dependency, Set[a.Component])].flatMap({ case (d, cmps) => cmps.map(c => (d, c).toString()) }).foreach(println)
38- } catch {
39- case t : Throwable =>
40- println(s " raised exception. " )
41- System .err.println(t.getMessage)
42- t.printStackTrace()
43- System .err.flush()
44- }
45- a
4629
47- val bench : List [String ] = List (" test/DEBUG2.scm" )
30+ enum AnalysisResult :
31+ case Terminated (iterationCount : Int , time : Long )
32+ case TimedOut
4833
49- // Used by webviz.
50- def newStandardAnalysis (text : String ) =
51- val program = SchemeParser .parseProgram(text)
52- new SimpleSchemeModFAnalysis (program)
53- with SchemeModFNoSensitivity
54- with SchemeConstantPropagationDomain
55- with DependencyTracking [SchemeExp ]
56- with FIFOWorklistAlgorithm [SchemeExp ] {
57- override def intraAnalysis (cmp : SchemeModFComponent ) =
58- new IntraAnalysis (cmp) with BigStepModFIntra with DependencyTrackingIntra
59- }
34+ // timeout can be set e.g., using Timeout.start(Duration(1, MINUTES))
35+ def analyze (file : String , timeout : Timeout .T = Timeout .none): AnalysisResult =
36+ val text = Reader .loadFile(file)
37+ val prog = SchemeParser .parseProgram(text)
38+ var iterations = 0
39+ val analysis =
40+ new SimpleSchemeModFAnalysis (prog)
41+ with SchemeModFNoSensitivity
42+ with SchemeConstantPropagationDomain
43+ with PriorityQueueWorklistAlgorithm [SchemeExp ]:
44+ /** Example implementation of priority **/
45+ lazy val ordering = Ordering .by(priority) // currently, ordering is based on calculated priority
46+ // alternatively, could also just implement `compare` here
47+ def priority (cmp : Component ): Int =
48+ cmp match
49+ case Main => 0 // "main" (= top-level program code) gets priority 0
50+ case Call ((lam, env), ctx) => priority(lam) // TODO: could also take lexical environment + context into account
51+ def priority (lam : SchemeLambdaExp ): Int =
52+ 42 // TODO: determine the priority for each lambda in the program
53+ /** Analysis setup **/
54+ override def intraAnalysis (cmp : SchemeModFComponent ) =
55+ new IntraAnalysis (cmp) with BigStepModFIntra
56+ override def step (timeout : Timeout .T ) =
57+ iterations += 1
58+ super .step(timeout)
59+ val time = Timer .timeOnly { analysis.analyzeWithTimeout(timeout) }
60+ if analysis.finished then
61+ AnalysisResult .Terminated (iterations, time/ 1000000 )
62+ else
63+ AnalysisResult .TimedOut
6064
61- // Used by incremental analyses.
62- def newNonIncAnalysis (program : SchemeExp ) =
63- new ModAnalysis [SchemeExp ](program)
64- with StandardSchemeModFComponents
65- with SchemeModFNoSensitivity
66- with SchemeModFSemanticsM
67- with LIFOWorklistAlgorithm [SchemeExp ]
68- with BigStepModFSemantics
69- with SchemeTypeDomain
70- with GlobalStore [SchemeExp ] {
71- var cnt = 0
72- override def run (timeout : Timeout .T ) =
73- super .run(timeout)
74- println(cnt)
75- override def intraAnalysis (cmp : Component ) = new IntraAnalysis (cmp) with BigStepModFIntra with GlobalStoreIntra {
76- override def analyzeWithTimeout (timeout : Timeout .T ): Unit =
77- cnt = cnt + 1
78- super .analyzeWithTimeout(timeout)
79- }
80- }
81-
82- def taintAnalysis (program : SchemeExp ) =
83- new ModAnalysis [SchemeExp ](program)
84- with StandardSchemeModFComponents
85- with SchemeModFNoSensitivity
86- with SchemeModFSemanticsM
87- with LIFOWorklistAlgorithm [SchemeExp ]
88- with SchemeModFBigStepTaintSemantics
89- with IncrementalSchemeTypeDomain
90- with GlobalStoreTaint [SchemeExp ] {
91- override def intraAnalysis (
92- cmp : SchemeModFComponent
93- ): SchemeModFBigStepTaintIntra = new IntraAnalysis (cmp) with SchemeModFBigStepTaintIntra with GlobalStoreTaintIntra
94- }
95-
96- bench.foreach({ b =>
97- // for(i <- 1 to 10) {
98- // runAnalysis(b, program => SchemeAnalyses.kCFAAnalysis(program, 0), () => Timeout.start(Duration(2, MINUTES)))
99- val a = runAnalysis(b, program => taintAnalysis(program), () => Timeout .start(Duration (1 , MINUTES )))
100- println(b)
101- println(a.taintResult())
102- println()
103- // println(a.program.prettyString())
104- // a.dataFlowR.foreach(println)
105- // println()
106- // println()
107- // a.implicitFlowsCut.foreach({ case (c, as) => as.foreach(a => println(s"$c $a")) })
108- })
65+ analyze(" test/R5RS/gabriel/boyer.scm" ) match
66+ case AnalysisResult .Terminated (iterations, timeMs) =>
67+ println(" *** Analysis terminated ***" )
68+ println(s " -> iterations: $iterations" )
69+ println(s " -> time: ${timeMs}ms " )
70+ case AnalysisResult .TimedOut =>
71+ println(" *** Analysis timed out ***" )
0 commit comments