1+ package lang .jimple .internal ;
2+
3+ import java .util .ArrayList ;
4+ import java .util .Collection ;
5+ import java .util .List ;
6+
7+ import lang .jimple .internal .generated .Expression ;
8+ import lang .jimple .internal .generated .Statement ;
9+
10+ public class BranchInstructionFlow implements InstructionFlow {
11+
12+ private Environment left ;
13+ private Environment right ;
14+
15+ private Expression condition ;
16+
17+ private String targetStatement ;
18+ private String mergeStatement ;
19+
20+ private BranchState status ;
21+
22+ private Statement gotoMergeStmt ;
23+
24+ enum BranchState {
25+ LEFT ,
26+ RIGHT ,
27+ ReadyToMerge
28+ }
29+
30+ public BranchInstructionFlow (Expression condition , String target ) {
31+ this .condition = condition ;
32+ this .targetStatement = target ;
33+ left = new Environment ();
34+ right = new Environment ();
35+ status = BranchState .LEFT ;
36+ }
37+
38+
39+ @ Override
40+ public Collection <Statement > merge () {
41+ List <Statement > res = new ArrayList <>();
42+
43+ res .add (Statement .ifStmt (condition , targetStatement ));
44+ res .addAll (left .instructions );
45+
46+ if (gotoMergeStmt != null ) {
47+ res .add (gotoMergeStmt );
48+ }
49+
50+ res .add (Statement .label (targetStatement ));
51+ res .addAll (right .instructions );
52+
53+ if (mergeStatement != null ) {
54+ res .add (Statement .label (mergeStatement ));
55+ }
56+
57+ return res ;
58+ }
59+
60+ @ Override
61+ public boolean matchMergePoint (String label ) {
62+ if (status .equals (BranchState .LEFT )) {
63+ return this .targetStatement .equals (label );
64+ }
65+ else if (status .equals (BranchState .RIGHT )) {
66+ return this .mergeStatement .equals (label );
67+ }
68+ return false ;
69+ }
70+
71+ @ Override
72+ public List <Environment > environments () {
73+ List <Environment > res = new ArrayList <>();
74+ switch (status ) {
75+ case LEFT : res .add (left ); break ;
76+ case RIGHT : res .add (right ); break ;
77+ case ReadyToMerge :
78+ if (mergeStatement != null ) {
79+ res .add (left );
80+ res .add (right );
81+ }
82+ else {
83+ res .add (left );
84+ }
85+ }
86+ return res ;
87+ }
88+
89+ @ Override
90+ public void notifyGotoStmt (Statement stmt , String label ) {
91+ if (status .equals (BranchState .LEFT )) {
92+ mergeStatement = label ;
93+ gotoMergeStmt = stmt ;
94+ }
95+ else if (status .equals (BranchState .RIGHT )) {
96+ right .instructions .add (stmt );
97+ }
98+ else if (status .equals (BranchState .ReadyToMerge )) {
99+ left .instructions .add (stmt );
100+ right .instructions .add (stmt );
101+ }
102+ }
103+
104+ @ Override
105+ public void nextBranch () {
106+ switch (status ) {
107+ case LEFT :
108+ if (mergeStatement != null ) {
109+ status = BranchState .RIGHT ;
110+ }
111+ else {
112+ left .instructions .add (Statement .label (targetStatement ));
113+ status = BranchState .ReadyToMerge ;
114+ }
115+ break ;
116+ case RIGHT : status = BranchState .ReadyToMerge ; break ;
117+ case ReadyToMerge : //
118+ }
119+ }
120+
121+ @ Override
122+ public boolean isBranch () {
123+ return true ;
124+ }
125+
126+ @ Override
127+ public boolean readyToMerge (String label ) {
128+ return status .equals (BranchState .ReadyToMerge );
129+ }
130+ }
0 commit comments