11package it .unipr .analysis ;
22
3+ import java .util .ArrayList ;
4+ import java .util .Collections ;
5+ import java .util .Iterator ;
6+ import java .util .List ;
7+ import java .util .ListIterator ;
8+ import java .util .Objects ;
9+ import java .util .function .Predicate ;
10+
311import it .unive .lisa .analysis .BaseLattice ;
412import it .unive .lisa .analysis .Lattice ;
513import it .unive .lisa .analysis .ScopeToken ;
1220import it .unive .lisa .symbolic .value .ValueExpression ;
1321import it .unive .lisa .util .representation .StringRepresentation ;
1422import it .unive .lisa .util .representation .StructuredRepresentation ;
15- import java .util .ArrayList ;
16- import java .util .Collections ;
17- import java .util .Iterator ;
18- import java .util .List ;
19- import java .util .Objects ;
20- import java .util .function .Predicate ;
2123
2224public class AbstractStack implements ValueDomain <AbstractStack >, BaseLattice <AbstractStack > {
2325
@@ -30,7 +32,7 @@ public class AbstractStack implements ValueDomain<AbstractStack>, BaseLattice<Ab
3032 * The top abstract element of this domain.
3133 */
3234 private static final AbstractStack TOP = new AbstractStack (
33- new ArrayList <>(Collections .nCopies (STACK_LIMIT , StackElement .TOP )));
35+ new ArrayList <>(Collections .nCopies (STACK_LIMIT , StackElement .TOP )), STACK_LIMIT );
3436
3537 /**
3638 * The bottom abstract element of this domain.
@@ -42,11 +44,16 @@ public class AbstractStack implements ValueDomain<AbstractStack>, BaseLattice<Ab
4244 */
4345 private final ArrayList <StackElement > stack ;
4446
47+ /**
48+ * The size of this stack (i.e., the number of elements)
49+ */
50+ private int size ;
51+
4552 /**
4653 * Builds an initial symbolic stack.
4754 */
4855 public AbstractStack () {
49- this (new ArrayList <>(Collections .nCopies (STACK_LIMIT , StackElement .BOTTOM )));
56+ this (new ArrayList <>(Collections .nCopies (STACK_LIMIT , StackElement .BOTTOM )), 0 );
5057 }
5158
5259 /**
@@ -56,7 +63,24 @@ public AbstractStack() {
5663 */
5764 public AbstractStack (ArrayList <StackElement > stack ) {
5865 this .stack = stack ;
66+ if (stack != null ) {
67+ int bottomCounter = 0 ;
68+ for (StackElement item : stack ) {
69+ if (item .isBottom ()) {
70+ bottomCounter ++;
71+ }
72+ }
73+ this .size = STACK_LIMIT - bottomCounter ;
74+ } else
75+ this .size = 0 ;
76+
5977 }
78+
79+ AbstractStack (ArrayList <StackElement > stack , int size ) {
80+ this .stack = stack ;
81+ this .size = size ;
82+ }
83+
6084
6185 @ Override
6286 public AbstractStack assign (Identifier id , ValueExpression expression , ProgramPoint pp , SemanticOracle oracle )
@@ -183,7 +207,7 @@ public StackElement getTop() {
183207 public AbstractStack clone () {
184208 if (isBottom () || isTop ())
185209 return this ;
186- return new AbstractStack (new ArrayList <>(stack ));
210+ return new AbstractStack (new ArrayList <>(stack ), this . size );
187211 }
188212
189213 /**
@@ -194,6 +218,7 @@ public AbstractStack clone() {
194218 public void push (StackElement target ) {
195219 stack .remove (0 );
196220 stack .add (target );
221+ this .size ++;
197222 }
198223
199224 /**
@@ -203,9 +228,10 @@ public void push(StackElement target) {
203228 */
204229 public StackElement pop () {
205230 StackElement result = stack .remove (stack .size () - 1 );
206- if (!stack .get (0 ).isTop ())
231+ if (!stack .get (0 ).isTop ()) {
207232 stack .add (0 , StackElement .BOTTOM );
208- else
233+ this .size --;
234+ } else
209235 stack .add (0 , StackElement .TOP );
210236 return result ;
211237 }
@@ -216,13 +242,7 @@ public StackElement pop() {
216242 * @return the number of items in the stack.
217243 */
218244 public int size () {
219- int bottomCounter = 0 ;
220- for (StackElement item : stack ) {
221- if (item .isBottom ()) {
222- bottomCounter ++;
223- }
224- }
225- return stack .size () - bottomCounter ;
245+ return this .size ;
226246 }
227247
228248 /**
@@ -284,14 +304,14 @@ public AbstractStack glbAux(AbstractStack other) throws SemanticException {
284304
285305 @ Override
286306 public boolean lessOrEqualAux (AbstractStack other ) throws SemanticException {
287- Iterator <StackElement > thisIterator = this .stack .iterator ();
288- Iterator <StackElement > otherIterator = other .stack .iterator ();
307+ if (size () > other .size ())
308+ return false ;
309+ ListIterator <StackElement > thisIterator = this .stack .listIterator (this .stack .size ());
310+ ListIterator <StackElement > otherIterator = other .stack .listIterator (other .stack .size ());
289311
290- while (thisIterator .hasNext () && otherIterator .hasNext ()) {
291- if (!thisIterator .next ().lessOrEqual (otherIterator .next ())) {
312+ while (thisIterator .hasPrevious () && otherIterator .hasPrevious ())
313+ if (!thisIterator .previous ().lessOrEqual (otherIterator .previous ()))
292314 return false ;
293- }
294- }
295315
296316 return true ;
297317 }
0 commit comments