X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/Label.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/Label.java index 5f8ee65..3e09f1c 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/Label.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/codegen/Label.java @@ -10,242 +10,272 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.codegen; - /** * This type is a port of smalltalks JavaLabel */ public class Label { -// public CodeStream codeStream; + // public CodeStream codeStream; final static int POS_NOT_SET = -1; - public int position = POS_NOT_SET; // position=POS_NOT_SET Then it's pos is not set. - public int[] forwardReferences = new int[10]; // Add an overflow check here. + + public int position = POS_NOT_SET; // position=POS_NOT_SET Then it's pos is + // not set. + + public int[] forwardReferences = new int[10]; // Add an overflow check + // here. + public int forwardReferenceCount = 0; - private boolean isWide = false; -public Label() { -} -/** - * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream - */ -//public Label(CodeStream codeStream) { -// this.codeStream = codeStream; -//} -/** - * Add a forward refrence for the array. - */ -void addForwardReference(int iPos) { - int length; - if (forwardReferenceCount >= (length = forwardReferences.length)) - System.arraycopy(forwardReferences, 0, (forwardReferences = new int[2*length]), 0, length); - forwardReferences[forwardReferenceCount++] = iPos; -} -/** - * Add a forward refrence for the array. - */ -public void appendForwardReferencesFrom(Label otherLabel) { - int otherCount = otherLabel.forwardReferenceCount; - if (otherCount == 0) return; - int length = forwardReferences.length; - int neededSpace = otherCount + forwardReferenceCount; - if (neededSpace >= length){ - System.arraycopy(forwardReferences, 0, (forwardReferences = new int[neededSpace]), 0, forwardReferenceCount); + + //private boolean isWide = false; + + public Label() { } - // append other forward references at the end, so they will get updated as well - System.arraycopy(otherLabel.forwardReferences, 0, forwardReferences, forwardReferenceCount, otherCount); - forwardReferenceCount = neededSpace; -} -/* -* Put down a refernece to the array at the location in the codestream. -*/ -//void branch() { -// if (position == POS_NOT_SET) { -// addForwardReference(codeStream.position); -// // Leave two bytes free to generate the jump afterwards -// codeStream.position += 2; -// codeStream.classFileOffset += 2; -// } else { -// /* -// * Position is set. Write it if it is not a wide branch. -// */ -// int offset = position - codeStream.position + 1; -// if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { -// throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); -// } -// codeStream.writeSignedShort((short) offset); -// } -//} -/* -* No support for wide branches yet -*/ -//void branchWide() { -// if (position == POS_NOT_SET) { -// addForwardReference(codeStream.position); -// // Leave 4 bytes free to generate the jump offset afterwards -// isWide = true; -// codeStream.position += 4; -// codeStream.classFileOffset += 4; -// } else { //Position is set. Write it! -// codeStream.writeSignedWord(position - codeStream.position + 1); -// } -//} -/** - * @return boolean - */ -public boolean hasForwardReferences() { - return forwardReferenceCount != 0; -} -/* - * Some placed labels might be branching to a goto bytecode which we can optimize better. - */ -//public void inlineForwardReferencesFromLabelsTargeting(int gotoLocation) { -///* -// Code required to optimized unreachable gotos. -// public boolean isBranchTarget(int location) { -// Label[] labels = codeStream.labels; -// for (int i = codeStream.countLabels - 1; i >= 0; i--){ -// Label label = labels[i]; -// if ((label.position == location) && label.isStandardLabel()){ -// return true; -// } -// } -// return false; -// } -// */ -// -// Label[] labels = codeStream.labels; -// for (int i = codeStream.countLabels - 1; i >= 0; i--){ -// Label label = labels[i]; -// if ((label.position == gotoLocation) && label.isStandardLabel()){ -// this.appendForwardReferencesFrom(label); -// /* -// Code required to optimized unreachable gotos. -// label.position = POS_NOT_SET; -// */ -// } else { -// break; // same target labels should be contiguous -// } -// } -//} -public boolean isStandardLabel(){ - return true; -} -/* -* Place the label. If we have forward references resolve them. -*/ -//public void place() { // Currently lacking wide support. -// if (position == POS_NOT_SET) { -// position = codeStream.position; -// codeStream.addLabel(this); -// int oldPosition = position; -// boolean optimizedBranch = false; -// // TURNED OFF since fail on 1F4IRD9 -// if (forwardReferenceCount != 0) { -// if (optimizedBranch = (forwardReferences[forwardReferenceCount - 1] + 2 == position) && (codeStream.bCodeStream[codeStream.classFileOffset - 3] == CodeStream.OPC_goto)) { -// codeStream.position = (position -= 3); -// codeStream.classFileOffset -= 3; -// forwardReferenceCount--; -// // also update the PCs in the related debug attributes -// /** OLD CODE -// int index = codeStream.pcToSourceMapSize - 1; -// while ((index >= 0) && (codeStream.pcToSourceMap[index][1] == oldPosition)) { -// codeStream.pcToSourceMap[index--][1] = position; -// } -// */ -// // Beginning of new code -// int index = codeStream.pcToSourceMapSize - 2; -// if (codeStream.lastEntryPC == oldPosition) { -// codeStream.lastEntryPC = position; -// } -// if ((index >= 0) && (codeStream.pcToSourceMap[index] == position)) { -// codeStream.pcToSourceMapSize-=2; -// } -// // end of new code -// if (codeStream.generateLocalVariableTableAttributes) { -// LocalVariableBinding locals[] = codeStream.locals; -// for (int i = 0, max = locals.length; i < max; i++) { -// LocalVariableBinding local = locals[i]; -// if ((local != null) && (local.initializationCount > 0)) { -// if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == oldPosition) { -// // we want to prevent interval of size 0 to have a negative size. -// // see PR 1GIRQLA: ITPJCORE:ALL - ClassFormatError for local variable attribute -// local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position; -// } -// if (local.initializationPCs[(local.initializationCount - 1) << 1] == oldPosition) { -// local.initializationPCs[(local.initializationCount - 1) << 1] = position; -// } -// } -// } -// } -// } -// } -// for (int i = 0; i < forwardReferenceCount; i++) { -// int offset = position - forwardReferences[i] + 1; -// if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { -// throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); -// } -// if (this.codeStream.wideMode) { -// if (this.isWide) { -// codeStream.writeSignedWord(forwardReferences[i], offset); -// } else { -// codeStream.writeSignedShort(forwardReferences[i], (short) offset); -// } -// } else { -// codeStream.writeSignedShort(forwardReferences[i], (short) offset); -// } -// } -// // For all labels placed at that position we check if we need to rewrite the jump -// // offset. It is the case each time a label had a forward reference to the current position. -// // Like we change the current position, we have to change the jump offset. See 1F4IRD9 for more details. -// if (optimizedBranch) { -// for (int i = 0; i < codeStream.countLabels; i++) { -// Label label = codeStream.labels[i]; -// if (oldPosition == label.position) { -// label.position = position; -// if (label instanceof CaseLabel) { -// int offset = position - ((CaseLabel) label).instructionPosition; -// for (int j = 0; j < label.forwardReferenceCount; j++) { -// int forwardPosition = label.forwardReferences[j]; -// codeStream.writeSignedWord(forwardPosition, offset); -// } -// } else { -// for (int j = 0; j < label.forwardReferenceCount; j++) { -// int forwardPosition = label.forwardReferences[j]; -// int offset = position - forwardPosition + 1; -// if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { -// throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); -// } -// if (this.codeStream.wideMode) { -// if (this.isWide) { -// codeStream.writeSignedWord(forwardPosition, offset); -// } else { -// codeStream.writeSignedShort(forwardPosition, (short) offset); -// } -// } else { -// codeStream.writeSignedShort(forwardPosition, (short) offset); -// } -// } -// } -// } -// } -// } -// } -//} -/** - * Print out the receiver - */ -public String toString() { - StringBuffer buffer = new StringBuffer("(position="); //$NON-NLS-1$ - buffer.append(position); - buffer.append(", forwards = ["); //$NON-NLS-1$ - for (int i = 0; i < forwardReferenceCount - 1; i++) - buffer.append(forwardReferences[i] + ", "); //$NON-NLS-1$ - if (forwardReferenceCount >= 1) - buffer.append(forwardReferences[forwardReferenceCount-1]); - buffer.append("] )"); //$NON-NLS-1$ - return buffer.toString(); -} -public void resetStateForCodeGeneration() { - this.position = POS_NOT_SET; - this.forwardReferenceCount = 0; -} + /** + * @param codeStream + * net.sourceforge.phpdt.internal.compiler.codegen.CodeStream + */ + // public Label(CodeStream codeStream) { + // this.codeStream = codeStream; + // } + /** + * Add a forward refrence for the array. + */ + void addForwardReference(int iPos) { + int length; + if (forwardReferenceCount >= (length = forwardReferences.length)) + System.arraycopy(forwardReferences, 0, + (forwardReferences = new int[2 * length]), 0, length); + forwardReferences[forwardReferenceCount++] = iPos; + } + + /** + * Add a forward refrence for the array. + */ + public void appendForwardReferencesFrom(Label otherLabel) { + int otherCount = otherLabel.forwardReferenceCount; + if (otherCount == 0) + return; + int length = forwardReferences.length; + int neededSpace = otherCount + forwardReferenceCount; + if (neededSpace >= length) { + System.arraycopy(forwardReferences, 0, + (forwardReferences = new int[neededSpace]), 0, + forwardReferenceCount); + } + // append other forward references at the end, so they will get updated + // as well + System.arraycopy(otherLabel.forwardReferences, 0, forwardReferences, + forwardReferenceCount, otherCount); + forwardReferenceCount = neededSpace; + } + + /* + * Put down a refernece to the array at the location in the codestream. + */ + // void branch() { + // if (position == POS_NOT_SET) { + // addForwardReference(codeStream.position); + // // Leave two bytes free to generate the jump afterwards + // codeStream.position += 2; + // codeStream.classFileOffset += 2; + // } else { + // /* + // * Position is set. Write it if it is not a wide branch. + // */ + // int offset = position - codeStream.position + 1; + // if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { + // throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); + // } + // codeStream.writeSignedShort((short) offset); + // } + // } + /* + * No support for wide branches yet + */ + // void branchWide() { + // if (position == POS_NOT_SET) { + // addForwardReference(codeStream.position); + // // Leave 4 bytes free to generate the jump offset afterwards + // isWide = true; + // codeStream.position += 4; + // codeStream.classFileOffset += 4; + // } else { //Position is set. Write it! + // codeStream.writeSignedWord(position - codeStream.position + 1); + // } + // } + /** + * @return boolean + */ + public boolean hasForwardReferences() { + return forwardReferenceCount != 0; + } + + /* + * Some placed labels might be branching to a goto bytecode which we can + * optimize better. + */ + // public void inlineForwardReferencesFromLabelsTargeting(int gotoLocation) + // { + // /* + // Code required to optimized unreachable gotos. + // public boolean isBranchTarget(int location) { + // Label[] labels = codeStream.labels; + // for (int i = codeStream.countLabels - 1; i >= 0; i--){ + // Label label = labels[i]; + // if ((label.position == location) && label.isStandardLabel()){ + // return true; + // } + // } + // return false; + // } + // */ + // + // Label[] labels = codeStream.labels; + // for (int i = codeStream.countLabels - 1; i >= 0; i--){ + // Label label = labels[i]; + // if ((label.position == gotoLocation) && label.isStandardLabel()){ + // this.appendForwardReferencesFrom(label); + // /* + // Code required to optimized unreachable gotos. + // label.position = POS_NOT_SET; + // */ + // } else { + // break; // same target labels should be contiguous + // } + // } + // } + public boolean isStandardLabel() { + return true; + } + + /* + * Place the label. If we have forward references resolve them. + */ + // public void place() { // Currently lacking wide support. + // if (position == POS_NOT_SET) { + // position = codeStream.position; + // codeStream.addLabel(this); + // int oldPosition = position; + // boolean optimizedBranch = false; + // // TURNED OFF since fail on 1F4IRD9 + // if (forwardReferenceCount != 0) { + // if (optimizedBranch = (forwardReferences[forwardReferenceCount - 1] + 2 + // == position) && (codeStream.bCodeStream[codeStream.classFileOffset - 3] + // == CodeStream.OPC_goto)) { + // codeStream.position = (position -= 3); + // codeStream.classFileOffset -= 3; + // forwardReferenceCount--; + // // also update the PCs in the related debug attributes + // /** OLD CODE + // int index = codeStream.pcToSourceMapSize - 1; + // while ((index >= 0) && (codeStream.pcToSourceMap[index][1] == + // oldPosition)) { + // codeStream.pcToSourceMap[index--][1] = position; + // } + // */ + // // Beginning of new code + // int index = codeStream.pcToSourceMapSize - 2; + // if (codeStream.lastEntryPC == oldPosition) { + // codeStream.lastEntryPC = position; + // } + // if ((index >= 0) && (codeStream.pcToSourceMap[index] == position)) { + // codeStream.pcToSourceMapSize-=2; + // } + // // end of new code + // if (codeStream.generateLocalVariableTableAttributes) { + // LocalVariableBinding locals[] = codeStream.locals; + // for (int i = 0, max = locals.length; i < max; i++) { + // LocalVariableBinding local = locals[i]; + // if ((local != null) && (local.initializationCount > 0)) { + // if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] + // == oldPosition) { + // // we want to prevent interval of size 0 to have a negative size. + // // see PR 1GIRQLA: ITPJCORE:ALL - ClassFormatError for local variable + // attribute + // local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = + // position; + // } + // if (local.initializationPCs[(local.initializationCount - 1) << 1] == + // oldPosition) { + // local.initializationPCs[(local.initializationCount - 1) << 1] = position; + // } + // } + // } + // } + // } + // } + // for (int i = 0; i < forwardReferenceCount; i++) { + // int offset = position - forwardReferences[i] + 1; + // if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { + // throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); + // } + // if (this.codeStream.wideMode) { + // if (this.isWide) { + // codeStream.writeSignedWord(forwardReferences[i], offset); + // } else { + // codeStream.writeSignedShort(forwardReferences[i], (short) offset); + // } + // } else { + // codeStream.writeSignedShort(forwardReferences[i], (short) offset); + // } + // } + // // For all labels placed at that position we check if we need to rewrite + // the jump + // // offset. It is the case each time a label had a forward reference to + // the current position. + // // Like we change the current position, we have to change the jump + // offset. See 1F4IRD9 for more details. + // if (optimizedBranch) { + // for (int i = 0; i < codeStream.countLabels; i++) { + // Label label = codeStream.labels[i]; + // if (oldPosition == label.position) { + // label.position = position; + // if (label instanceof CaseLabel) { + // int offset = position - ((CaseLabel) label).instructionPosition; + // for (int j = 0; j < label.forwardReferenceCount; j++) { + // int forwardPosition = label.forwardReferences[j]; + // codeStream.writeSignedWord(forwardPosition, offset); + // } + // } else { + // for (int j = 0; j < label.forwardReferenceCount; j++) { + // int forwardPosition = label.forwardReferences[j]; + // int offset = position - forwardPosition + 1; + // if (Math.abs(offset) > 0x7FFF && !this.codeStream.wideMode) { + // throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE); + // } + // if (this.codeStream.wideMode) { + // if (this.isWide) { + // codeStream.writeSignedWord(forwardPosition, offset); + // } else { + // codeStream.writeSignedShort(forwardPosition, (short) offset); + // } + // } else { + // codeStream.writeSignedShort(forwardPosition, (short) offset); + // } + // } + // } + // } + // } + // } + // } + // } + /** + * Print out the receiver + */ + public String toString() { + StringBuffer buffer = new StringBuffer("(position="); //$NON-NLS-1$ + buffer.append(position); + buffer.append(", forwards = ["); //$NON-NLS-1$ + for (int i = 0; i < forwardReferenceCount - 1; i++) + buffer.append(forwardReferences[i] + ", "); //$NON-NLS-1$ + if (forwardReferenceCount >= 1) + buffer.append(forwardReferences[forwardReferenceCount - 1]); + buffer.append("] )"); //$NON-NLS-1$ + return buffer.toString(); + } + + public void resetStateForCodeGeneration() { + this.position = POS_NOT_SET; + this.forwardReferenceCount = 0; + } }