5f8ee65f681d76716b91574efec5b0c43ae4759c
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / codegen / Label.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.codegen;
12
13
14 /**
15  * This type is a port of smalltalks JavaLabel
16  */
17 public class Label {
18 //      public CodeStream codeStream;
19         final static int POS_NOT_SET = -1;
20         public int position = POS_NOT_SET; // position=POS_NOT_SET Then it's pos is not set.
21         public int[] forwardReferences = new int[10]; // Add an overflow check here.
22         public int forwardReferenceCount = 0;
23         private boolean isWide = false;
24 public Label() {
25 }
26 /**
27  * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
28  */
29 //public Label(CodeStream codeStream) {
30 //      this.codeStream = codeStream;
31 //}
32 /**
33  * Add a forward refrence for the array.
34  */
35 void addForwardReference(int iPos) {
36         int length;
37         if (forwardReferenceCount >= (length = forwardReferences.length))
38                 System.arraycopy(forwardReferences, 0, (forwardReferences = new int[2*length]), 0, length);
39         forwardReferences[forwardReferenceCount++] = iPos;
40 }
41 /**
42  * Add a forward refrence for the array.
43  */
44 public void appendForwardReferencesFrom(Label otherLabel) {
45         int otherCount = otherLabel.forwardReferenceCount;
46         if (otherCount == 0) return;
47         int length = forwardReferences.length;
48         int neededSpace = otherCount + forwardReferenceCount;
49         if (neededSpace >= length){
50                 System.arraycopy(forwardReferences, 0, (forwardReferences = new int[neededSpace]), 0, forwardReferenceCount);
51         }
52         // append other forward references at the end, so they will get updated as well
53         System.arraycopy(otherLabel.forwardReferences, 0, forwardReferences, forwardReferenceCount, otherCount);
54         forwardReferenceCount = neededSpace;
55 }
56 /*
57 * Put down  a refernece to the array at the location in the codestream.
58 */
59 //void branch() {
60 //      if (position == POS_NOT_SET) {
61 //              addForwardReference(codeStream.position);
62 //              // Leave two bytes free to generate the jump afterwards
63 //              codeStream.position += 2;
64 //              codeStream.classFileOffset += 2;
65 //      } else {
66 //              /*
67 //               * Position is set. Write it if it is not a wide branch.
68 //               */
69 //              int offset = position - codeStream.position + 1;
70 //              if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) {
71 //                      throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE);
72 //              }
73 //              codeStream.writeSignedShort((short) offset);
74 //      }
75 //}
76 /*
77 * No support for wide branches yet
78 */
79 //void branchWide() {
80 //      if (position == POS_NOT_SET) {
81 //              addForwardReference(codeStream.position);
82 //              // Leave 4 bytes free to generate the jump offset afterwards
83 //              isWide = true;
84 //              codeStream.position += 4;
85 //              codeStream.classFileOffset += 4;
86 //      } else { //Position is set. Write it!
87 //              codeStream.writeSignedWord(position - codeStream.position + 1);
88 //      }
89 //}
90 /**
91  * @return boolean
92  */
93 public boolean hasForwardReferences() {
94         return forwardReferenceCount != 0;
95 }
96 /*
97  * Some placed labels might be branching to a goto bytecode which we can optimize better.
98  */
99 //public void inlineForwardReferencesFromLabelsTargeting(int gotoLocation) {
100 ///*
101 // Code required to optimized unreachable gotos.
102 //      public boolean isBranchTarget(int location) {
103 //              Label[] labels = codeStream.labels;
104 //              for (int i = codeStream.countLabels - 1; i >= 0; i--){
105 //                      Label label = labels[i];
106 //                      if ((label.position == location) && label.isStandardLabel()){
107 //                              return true;
108 //                      }
109 //              }
110 //              return false;
111 //      }
112 // */
113 //      
114 //      Label[] labels = codeStream.labels;
115 //      for (int i = codeStream.countLabels - 1; i >= 0; i--){
116 //              Label label = labels[i];
117 //              if ((label.position == gotoLocation) && label.isStandardLabel()){
118 //                      this.appendForwardReferencesFrom(label);
119 //                      /*
120 //                       Code required to optimized unreachable gotos.
121 //                              label.position = POS_NOT_SET;
122 //                      */
123 //              } else {
124 //                      break; // same target labels should be contiguous
125 //              }
126 //      }
127 //}
128 public boolean isStandardLabel(){
129         return true;
130 }
131 /*
132 * Place the label. If we have forward references resolve them.
133 */
134 //public void place() { // Currently lacking wide support.
135 //      if (position == POS_NOT_SET) {
136 //              position = codeStream.position;
137 //              codeStream.addLabel(this);
138 //              int oldPosition = position;
139 //              boolean optimizedBranch = false;
140 //              // TURNED OFF since fail on 1F4IRD9
141 //              if (forwardReferenceCount != 0) {
142 //                      if (optimizedBranch = (forwardReferences[forwardReferenceCount - 1] + 2 == position) && (codeStream.bCodeStream[codeStream.classFileOffset - 3] == CodeStream.OPC_goto)) {
143 //                              codeStream.position = (position -= 3);
144 //                              codeStream.classFileOffset -= 3;
145 //                              forwardReferenceCount--;
146 //                              // also update the PCs in the related debug attributes
147 //                              /** OLD CODE
148 //                                      int index = codeStream.pcToSourceMapSize - 1;
149 //                                              while ((index >= 0) && (codeStream.pcToSourceMap[index][1] == oldPosition)) {
150 //                                                      codeStream.pcToSourceMap[index--][1] = position;
151 //                                              }
152 //                              */
153 //                              // Beginning of new code
154 //                              int index = codeStream.pcToSourceMapSize - 2;
155 //                              if (codeStream.lastEntryPC == oldPosition) {
156 //                                      codeStream.lastEntryPC = position;
157 //                              }
158 //                              if ((index >= 0) && (codeStream.pcToSourceMap[index] == position)) {
159 //                                      codeStream.pcToSourceMapSize-=2;
160 //                              }
161 //                              // end of new code
162 //                              if (codeStream.generateLocalVariableTableAttributes) {
163 //                                      LocalVariableBinding locals[] = codeStream.locals;
164 //                                      for (int i = 0, max = locals.length; i < max; i++) {
165 //                                              LocalVariableBinding local = locals[i];
166 //                                              if ((local != null) && (local.initializationCount > 0)) {
167 //                                                      if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == oldPosition) {
168 //                                                              // we want to prevent interval of size 0 to have a negative size.
169 //                                                              // see PR 1GIRQLA: ITPJCORE:ALL - ClassFormatError for local variable attribute
170 //                                                              local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position;
171 //                                                      }
172 //                                                      if (local.initializationPCs[(local.initializationCount - 1) << 1] == oldPosition) {
173 //                                                              local.initializationPCs[(local.initializationCount - 1) << 1] = position;
174 //                                                      }
175 //                                              }
176 //                                      }
177 //                              }
178 //                      }
179 //              }
180 //              for (int i = 0; i < forwardReferenceCount; i++) {
181 //                      int offset = position - forwardReferences[i] + 1;
182 //                      if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) {
183 //                              throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE);
184 //                      }
185 //                      if (this.codeStream.wideMode) {
186 //                              if (this.isWide) {
187 //                                      codeStream.writeSignedWord(forwardReferences[i], offset);
188 //                              } else {
189 //                                      codeStream.writeSignedShort(forwardReferences[i], (short) offset);
190 //                              }
191 //                      } else {
192 //                              codeStream.writeSignedShort(forwardReferences[i], (short) offset);
193 //                      }
194 //              }
195 //              // For all labels placed at that position we check if we need to rewrite the jump
196 //              // offset. It is the case each time a label had a forward reference to the current position.
197 //              // Like we change the current position, we have to change the jump offset. See 1F4IRD9 for more details.
198 //              if (optimizedBranch) {
199 //                      for (int i = 0; i < codeStream.countLabels; i++) {
200 //                              Label label = codeStream.labels[i];
201 //                              if (oldPosition == label.position) {
202 //                                      label.position = position;
203 //                                      if (label instanceof CaseLabel) {
204 //                                              int offset = position - ((CaseLabel) label).instructionPosition;
205 //                                              for (int j = 0; j < label.forwardReferenceCount; j++) {
206 //                                                      int forwardPosition = label.forwardReferences[j];
207 //                                                      codeStream.writeSignedWord(forwardPosition, offset);
208 //                                              }
209 //                                      } else {
210 //                                              for (int j = 0; j < label.forwardReferenceCount; j++) {
211 //                                                      int forwardPosition = label.forwardReferences[j];
212 //                                                      int offset = position - forwardPosition + 1;
213 //                                                      if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) {
214 //                                                              throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE);
215 //                                                      }
216 //                                                      if (this.codeStream.wideMode) {
217 //                                                              if (this.isWide) {
218 //                                                                      codeStream.writeSignedWord(forwardPosition, offset);
219 //                                                              } else {
220 //                                                                      codeStream.writeSignedShort(forwardPosition, (short) offset);
221 //                                                              }
222 //                                                      } else {
223 //                                                              codeStream.writeSignedShort(forwardPosition, (short) offset);
224 //                                                      }
225 //                                              }
226 //                                      }
227 //                              }
228 //                      }
229 //              }
230 //      }
231 //}
232 /**
233  * Print out the receiver
234  */
235 public String toString() {
236         StringBuffer buffer = new StringBuffer("(position="); //$NON-NLS-1$
237         buffer.append(position);
238         buffer.append(", forwards = ["); //$NON-NLS-1$
239         for (int i = 0; i < forwardReferenceCount - 1; i++)
240                 buffer.append(forwardReferences[i] + ", "); //$NON-NLS-1$
241         if (forwardReferenceCount >= 1)
242                 buffer.append(forwardReferences[forwardReferenceCount-1]);
243         buffer.append("] )"); //$NON-NLS-1$
244         return buffer.toString();
245 }
246
247 public void resetStateForCodeGeneration() {
248         this.position = POS_NOT_SET;
249         this.forwardReferenceCount = 0;
250 }
251 }