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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.codegen;
15 * This type is a port of smalltalks JavaLabel
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;
27 * @param codeStream net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
29 //public Label(CodeStream codeStream) {
30 // this.codeStream = codeStream;
33 * Add a forward refrence for the array.
35 void addForwardReference(int iPos) {
37 if (forwardReferenceCount >= (length = forwardReferences.length))
38 System.arraycopy(forwardReferences, 0, (forwardReferences = new int[2*length]), 0, length);
39 forwardReferences[forwardReferenceCount++] = iPos;
42 * Add a forward refrence for the array.
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);
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;
57 * Put down a refernece to the array at the location in the codestream.
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;
67 // * Position is set. Write it if it is not a wide branch.
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);
73 // codeStream.writeSignedShort((short) offset);
77 * No support for wide branches yet
80 // if (position == POS_NOT_SET) {
81 // addForwardReference(codeStream.position);
82 // // Leave 4 bytes free to generate the jump offset afterwards
84 // codeStream.position += 4;
85 // codeStream.classFileOffset += 4;
86 // } else { //Position is set. Write it!
87 // codeStream.writeSignedWord(position - codeStream.position + 1);
93 public boolean hasForwardReferences() {
94 return forwardReferenceCount != 0;
97 * Some placed labels might be branching to a goto bytecode which we can optimize better.
99 //public void inlineForwardReferencesFromLabelsTargeting(int gotoLocation) {
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()){
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);
120 // Code required to optimized unreachable gotos.
121 // label.position = POS_NOT_SET;
124 // break; // same target labels should be contiguous
128 public boolean isStandardLabel(){
132 * Place the label. If we have forward references resolve them.
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
148 // int index = codeStream.pcToSourceMapSize - 1;
149 // while ((index >= 0) && (codeStream.pcToSourceMap[index][1] == oldPosition)) {
150 // codeStream.pcToSourceMap[index--][1] = position;
153 // // Beginning of new code
154 // int index = codeStream.pcToSourceMapSize - 2;
155 // if (codeStream.lastEntryPC == oldPosition) {
156 // codeStream.lastEntryPC = position;
158 // if ((index >= 0) && (codeStream.pcToSourceMap[index] == position)) {
159 // codeStream.pcToSourceMapSize-=2;
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;
172 // if (local.initializationPCs[(local.initializationCount - 1) << 1] == oldPosition) {
173 // local.initializationPCs[(local.initializationCount - 1) << 1] = position;
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);
185 // if (this.codeStream.wideMode) {
186 // if (this.isWide) {
187 // codeStream.writeSignedWord(forwardReferences[i], offset);
189 // codeStream.writeSignedShort(forwardReferences[i], (short) offset);
192 // codeStream.writeSignedShort(forwardReferences[i], (short) offset);
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);
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);
216 // if (this.codeStream.wideMode) {
217 // if (this.isWide) {
218 // codeStream.writeSignedWord(forwardPosition, offset);
220 // codeStream.writeSignedShort(forwardPosition, (short) offset);
223 // codeStream.writeSignedShort(forwardPosition, (short) offset);
233 * Print out the receiver
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();
247 public void resetStateForCodeGeneration() {
248 this.position = POS_NOT_SET;
249 this.forwardReferenceCount = 0;