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;
 
  14  * This type is a port of smalltalks JavaLabel
 
  17         // public CodeStream codeStream;
 
  18         final static int POS_NOT_SET = -1;
 
  20         public int position = POS_NOT_SET; // position=POS_NOT_SET Then it's pos is
 
  23         public int[] forwardReferences = new int[10]; // Add an overflow check
 
  26         public int forwardReferenceCount = 0;
 
  28         private boolean isWide = false;
 
  35          *            net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
 
  37         // public Label(CodeStream codeStream) {
 
  38         // this.codeStream = codeStream;
 
  41          * Add a forward refrence for the array.
 
  43         void addForwardReference(int iPos) {
 
  45                 if (forwardReferenceCount >= (length = forwardReferences.length))
 
  46                         System.arraycopy(forwardReferences, 0,
 
  47                                         (forwardReferences = new int[2 * length]), 0, length);
 
  48                 forwardReferences[forwardReferenceCount++] = iPos;
 
  52          * Add a forward refrence for the array.
 
  54         public void appendForwardReferencesFrom(Label otherLabel) {
 
  55                 int otherCount = otherLabel.forwardReferenceCount;
 
  58                 int length = forwardReferences.length;
 
  59                 int neededSpace = otherCount + forwardReferenceCount;
 
  60                 if (neededSpace >= length) {
 
  61                         System.arraycopy(forwardReferences, 0,
 
  62                                         (forwardReferences = new int[neededSpace]), 0,
 
  63                                         forwardReferenceCount);
 
  65                 // append other forward references at the end, so they will get updated
 
  67                 System.arraycopy(otherLabel.forwardReferences, 0, forwardReferences,
 
  68                                 forwardReferenceCount, otherCount);
 
  69                 forwardReferenceCount = neededSpace;
 
  73          * Put down a refernece to the array at the location in the codestream.
 
  76         // if (position == POS_NOT_SET) {
 
  77         // addForwardReference(codeStream.position);
 
  78         // // Leave two bytes free to generate the jump afterwards
 
  79         // codeStream.position += 2;
 
  80         // codeStream.classFileOffset += 2;
 
  83         // * Position is set. Write it if it is not a wide branch.
 
  85         // int offset = position - codeStream.position + 1;
 
  86         // if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) {
 
  87         // throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE);
 
  89         // codeStream.writeSignedShort((short) offset);
 
  93          * No support for wide branches yet
 
  95         // void branchWide() {
 
  96         // if (position == POS_NOT_SET) {
 
  97         // addForwardReference(codeStream.position);
 
  98         // // Leave 4 bytes free to generate the jump offset afterwards
 
 100         // codeStream.position += 4;
 
 101         // codeStream.classFileOffset += 4;
 
 102         // } else { //Position is set. Write it!
 
 103         // codeStream.writeSignedWord(position - codeStream.position + 1);
 
 109         public boolean hasForwardReferences() {
 
 110                 return forwardReferenceCount != 0;
 
 114          * Some placed labels might be branching to a goto bytecode which we can
 
 117         // public void inlineForwardReferencesFromLabelsTargeting(int gotoLocation)
 
 120         // Code required to optimized unreachable gotos.
 
 121         // public boolean isBranchTarget(int location) {
 
 122         // Label[] labels = codeStream.labels;
 
 123         // for (int i = codeStream.countLabels - 1; i >= 0; i--){
 
 124         // Label label = labels[i];
 
 125         // if ((label.position == location) && label.isStandardLabel()){
 
 133         // Label[] labels = codeStream.labels;
 
 134         // for (int i = codeStream.countLabels - 1; i >= 0; i--){
 
 135         // Label label = labels[i];
 
 136         // if ((label.position == gotoLocation) && label.isStandardLabel()){
 
 137         // this.appendForwardReferencesFrom(label);
 
 139         // Code required to optimized unreachable gotos.
 
 140         // label.position = POS_NOT_SET;
 
 143         // break; // same target labels should be contiguous
 
 147         public boolean isStandardLabel() {
 
 152          * Place the label. If we have forward references resolve them.
 
 154         // public void place() { // Currently lacking wide support.
 
 155         // if (position == POS_NOT_SET) {
 
 156         // position = codeStream.position;
 
 157         // codeStream.addLabel(this);
 
 158         // int oldPosition = position;
 
 159         // boolean optimizedBranch = false;
 
 160         // // TURNED OFF since fail on 1F4IRD9
 
 161         // if (forwardReferenceCount != 0) {
 
 162         // if (optimizedBranch = (forwardReferences[forwardReferenceCount - 1] + 2
 
 163         // == position) && (codeStream.bCodeStream[codeStream.classFileOffset - 3]
 
 164         // == CodeStream.OPC_goto)) {
 
 165         // codeStream.position = (position -= 3);
 
 166         // codeStream.classFileOffset -= 3;
 
 167         // forwardReferenceCount--;
 
 168         // // also update the PCs in the related debug attributes
 
 170         // int index = codeStream.pcToSourceMapSize - 1;
 
 171         // while ((index >= 0) && (codeStream.pcToSourceMap[index][1] ==
 
 173         // codeStream.pcToSourceMap[index--][1] = position;
 
 176         // // Beginning of new code
 
 177         // int index = codeStream.pcToSourceMapSize - 2;
 
 178         // if (codeStream.lastEntryPC == oldPosition) {
 
 179         // codeStream.lastEntryPC = position;
 
 181         // if ((index >= 0) && (codeStream.pcToSourceMap[index] == position)) {
 
 182         // codeStream.pcToSourceMapSize-=2;
 
 184         // // end of new code
 
 185         // if (codeStream.generateLocalVariableTableAttributes) {
 
 186         // LocalVariableBinding locals[] = codeStream.locals;
 
 187         // for (int i = 0, max = locals.length; i < max; i++) {
 
 188         // LocalVariableBinding local = locals[i];
 
 189         // if ((local != null) && (local.initializationCount > 0)) {
 
 190         // if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1]
 
 192         // // we want to prevent interval of size 0 to have a negative size.
 
 193         // // see PR 1GIRQLA: ITPJCORE:ALL - ClassFormatError for local variable
 
 195         // local.initializationPCs[((local.initializationCount - 1) << 1) + 1] =
 
 198         // if (local.initializationPCs[(local.initializationCount - 1) << 1] ==
 
 200         // local.initializationPCs[(local.initializationCount - 1) << 1] = position;
 
 207         // for (int i = 0; i < forwardReferenceCount; i++) {
 
 208         // int offset = position - forwardReferences[i] + 1;
 
 209         // if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) {
 
 210         // throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE);
 
 212         // if (this.codeStream.wideMode) {
 
 213         // if (this.isWide) {
 
 214         // codeStream.writeSignedWord(forwardReferences[i], offset);
 
 216         // codeStream.writeSignedShort(forwardReferences[i], (short) offset);
 
 219         // codeStream.writeSignedShort(forwardReferences[i], (short) offset);
 
 222         // // For all labels placed at that position we check if we need to rewrite
 
 224         // // offset. It is the case each time a label had a forward reference to
 
 225         // the current position.
 
 226         // // Like we change the current position, we have to change the jump
 
 227         // offset. See 1F4IRD9 for more details.
 
 228         // if (optimizedBranch) {
 
 229         // for (int i = 0; i < codeStream.countLabels; i++) {
 
 230         // Label label = codeStream.labels[i];
 
 231         // if (oldPosition == label.position) {
 
 232         // label.position = position;
 
 233         // if (label instanceof CaseLabel) {
 
 234         // int offset = position - ((CaseLabel) label).instructionPosition;
 
 235         // for (int j = 0; j < label.forwardReferenceCount; j++) {
 
 236         // int forwardPosition = label.forwardReferences[j];
 
 237         // codeStream.writeSignedWord(forwardPosition, offset);
 
 240         // for (int j = 0; j < label.forwardReferenceCount; j++) {
 
 241         // int forwardPosition = label.forwardReferences[j];
 
 242         // int offset = position - forwardPosition + 1;
 
 243         // if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) {
 
 244         // throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE);
 
 246         // if (this.codeStream.wideMode) {
 
 247         // if (this.isWide) {
 
 248         // codeStream.writeSignedWord(forwardPosition, offset);
 
 250         // codeStream.writeSignedShort(forwardPosition, (short) offset);
 
 253         // codeStream.writeSignedShort(forwardPosition, (short) offset);
 
 263          * Print out the receiver
 
 265         public String toString() {
 
 266                 StringBuffer buffer = new StringBuffer("(position="); //$NON-NLS-1$
 
 267                 buffer.append(position);
 
 268                 buffer.append(", forwards = ["); //$NON-NLS-1$
 
 269                 for (int i = 0; i < forwardReferenceCount - 1; i++)
 
 270                         buffer.append(forwardReferences[i] + ", "); //$NON-NLS-1$
 
 271                 if (forwardReferenceCount >= 1)
 
 272                         buffer.append(forwardReferences[forwardReferenceCount - 1]);
 
 273                 buffer.append("] )"); //$NON-NLS-1$
 
 274                 return buffer.toString();
 
 277         public void resetStateForCodeGeneration() {
 
 278                 this.position = POS_NOT_SET;
 
 279                 this.forwardReferenceCount = 0;