KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > sc > StackModel


1 /***
2  * StackModel.java
3  *
4  * Description: Model Flash engine stack for peep-hole optimizer
5  */

6
7 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
8 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
9 * Use is subject to license terms. *
10 * J_LZ_COPYRIGHT_END *********************************************************/

11
12 package org.openlaszlo.sc;
13 import java.io.*;
14 import java.util.*;
15 import org.openlaszlo.sc.Instructions.*;
16
17
18 /***
19  * StackModel models the stack in the peephole block. It obeys
20  * List operations and is manipulated as a List by all
21  * instructions other than PUSH. PUSH uses a special entry to annotate
22  * the data it pushes with the push responsible for the data. This
23  * annotation is used by the push merging logic. Any modification of
24  * the data in the model by a normal instruction will clear the
25  * associated push annotation
26  */

27 public class StackModel extends ArrayList {
28   // Why protected is stupid!
29
private static class RemovableArrayList extends ArrayList {
30     public RemovableArrayList(Collection c) {
31       super(c);
32     }
33     
34     public void removeRange(int fromIndex, int toIndex) {
35       super.removeRange(fromIndex, toIndex);
36     }
37   }
38   
39   RemovableArrayList pushes;
40
41   public StackModel(Collection c) {
42     // model of stack for computing arity of vararg instr's
43
super(c);
44     // push instruction that created corresponding data
45
// Note that a push is not cleared until the stack is
46
// popped below it
47
this.pushes = new RemovableArrayList(Collections.nCopies(c.size() + 1, null));
48   }
49
50   public StackModel() {
51     this(Collections.EMPTY_LIST);
52   }
53
54   public void add(int index, Object JavaDoc value) {
55     if (index < 0) index += this.size();
56     // don't clobber the push at i, to permit the prepend
57
// optimization
58
this.pushes.add(index + 1, null);
59     super.add(index, value);
60   }
61
62   public boolean add(Object JavaDoc value) {
63     this.add(this.size(), value);
64     return true;
65   }
66
67   public boolean addAll(int index, Collection c) {
68     if (index < 0) index += this.size();
69     // don't clobber the push at i, to permit the prepend
70
// optimization
71
int l = c.size();
72     // Interior add should not clobber successor
73
if (index != this.size()) l -= 1;
74     this.pushes.addAll(index + 1, Collections.nCopies(l, null));
75     return super.addAll(index, c);
76   }
77
78   public boolean addAll(Collection c) {
79     return this.addAll(this.size(), c);
80   }
81
82   public void clear() {
83     this.pushes.clear();
84     super.clear();
85   }
86
87   public Object JavaDoc clone() {
88     return new StackModel(this);
89   }
90
91   // contains just works
92

93   public void ensureCapacity(int minCapacity) {
94     super.ensureCapacity(minCapacity);
95     this.pushes.ensureCapacity(minCapacity + 1);
96   }
97
98   public Object JavaDoc get(int index) {
99     if (index < 0) index += this.size();
100     return super.get(index);
101   }
102
103   // indexOf just works
104

105   // isEmpty just works
106

107   // lastIndexOf just works
108

109   public Object JavaDoc remove(int index) {
110     if (index < 0) index += this.size();
111     // don't clobber the push at i, to permit the prepend
112
// optimization
113
this.pushes.remove(index + 1);
114     return super.remove(index);
115   }
116
117   protected void removeRange(int fromIndex, int toIndex) {
118     int l = this.size();
119     if (fromIndex < 0) fromIndex += l;
120     if (fromIndex > l) fromIndex = l;
121     if (toIndex < 0) toIndex += l;
122     if (toIndex > l) toIndex = l;
123     // don't clobber the push at i, to permit the prepend
124
// optimization
125
this.pushes.removeRange(fromIndex + 1, toIndex + 1);
126     super.removeRange(fromIndex, toIndex);
127   }
128
129   public Object JavaDoc set(int index, Object JavaDoc value) {
130     if (index < 0) index += this.size();
131     // don't clobber the push at i, to permit the prepend
132
// optimization
133
this.pushes.set(index + 1, null);
134     return super.set(index, value);
135   }
136
137   // toArray just works
138

139   public void trimToSize() {
140     this.pushes.trimToSize();
141     super.trimToSize();
142   }
143
144   public void notePush(PUSHInstruction instr, List data) {
145     // System.out.println("notePush: " + instr + " || " + data);
146
// Replace the last instruction noted with this instruction
147
this.pushes.removeRange(this.size(), this.pushes.size());
148     this.pushes.addAll(this.size(), Collections.nCopies(data.size() + 1, instr));
149     super.addAll(data);
150   }
151
152   public PUSHInstruction lastPush() {
153     if (this.pushes.size() > this.size()) {
154       return (PUSHInstruction)(this.pushes.get(this.size()));
155     } else {
156       return null;
157     }
158   }
159
160   // How many arguments from this instruction are still on the stack.
161
// (instr must be the last instruction)
162
public int pushDepth(PUSHInstruction instr) {
163     // --- slow for deep models
164
// return this.size() - this.pushes.indexOf(instr);
165
int l = this.size();
166     List p = this.pushes;
167     // search from top of stack down
168
for (int i = l - 1; i >= 0; i--) {
169       if (p.get(i) != instr) {
170         return l - (i + 1);
171       }
172     }
173     return l;
174   }
175
176   public String JavaDoc toString() {
177     StringBuffer JavaDoc b = new StringBuffer JavaDoc();
178     int i = -1;
179     for (ListIterator li = super.listIterator(); li.hasNext(); ) {
180       i = li.nextIndex();
181       Object JavaDoc v = li.next();
182       b.append(v != null ? v.toString() : "None");
183       b.append("(");
184       Object JavaDoc p = this.pushes.get(i);
185       b.append(p != null ? "" + this.pushes.indexOf(p) : "None");
186       b.append(")");
187       if (li.hasNext()) b.append(", ");
188     }
189     for (i++; i < this.pushes.size(); i++) {
190       if (i > 0) b.append(", ");
191       b.append("None (");
192       Object JavaDoc p = this.pushes.get(i);
193       b.append(p != null ? "" + this.pushes.indexOf(p) : "None");
194       b.append(")");
195     }
196     return b.toString();
197   }
198 }
199
200
Popular Tags