<s> package org . eclipse . jdt . internal . compiler . codegen ; import java . util . Arrays ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . lookup . LocalVariableBinding ; public class BranchLabel extends Label { private int [ ] forwardReferences = new int [ 10 ] ; private int forwardReferenceCount = 0 ; BranchLabel delegate ; public int tagBits ; public final static int WIDE = 1 ; public final static int USED = 2 ; public BranchLabel ( ) { } public BranchLabel ( CodeStream codeStream ) { super ( codeStream ) ; } void addForwardReference ( int pos ) { if ( this . delegate != null ) { this . delegate . addForwardReference ( pos ) ; return ; } final int count = this . forwardReferenceCount ; if ( count >= 1 ) { int previousValue = this . forwardReferences [ count - 1 ] ; if ( previousValue < pos ) { int length ; if ( count >= ( length = this . forwardReferences . length ) ) System . arraycopy ( this . forwardReferences , 0 , ( this . forwardReferences = new int [ 2 * length ] ) , 0 , length ) ; this . forwardReferences [ this . forwardReferenceCount ++ ] = pos ; } else if ( previousValue > pos ) { int [ ] refs = this . forwardReferences ; for ( int i = 0 , max = this . forwardReferenceCount ; i < max ; i ++ ) { if ( refs [ i ] == pos ) return ; } int length ; if ( count >= ( length = refs . length ) ) System . arraycopy ( refs , 0 , ( this . forwardReferences = new int [ 2 * length ] ) , 0 , length ) ; this . forwardReferences [ this . forwardReferenceCount ++ ] = pos ; Arrays . sort ( this . forwardReferences , 0 , this . forwardReferenceCount ) ; } } else { int length ; if ( count >= ( length = this . forwardReferences . length ) ) System . arraycopy ( this . forwardReferences , 0 , ( this . forwardReferences = new int [ 2 * length ] ) , 0 , length ) ; this . forwardReferences [ this . forwardReferenceCount ++ ] = pos ; } } public void becomeDelegateFor ( BranchLabel otherLabel ) { otherLabel . delegate = this ; final int otherCount = otherLabel . forwardReferenceCount ; if ( otherCount == 0 ) return ; int [ ] mergedForwardReferences = new int [ this . forwardReferenceCount + otherCount ] ; int indexInMerge = 0 ; int j = 0 ; int i = 0 ; int max = this . forwardReferenceCount ; int max2 = otherLabel . forwardReferenceCount ; loop1 : for ( ; i < max ; i ++ ) { final int value1 = this . forwardReferences [ i ] ; for ( ; j < max2 ; j ++ ) { final int value2 = otherLabel . forwardReferences [ j ] ; if ( value1 < value2 ) { mergedForwardReferences [ indexInMerge ++ ] = value1 ; continue loop1 ; } else if ( value1 == value2 ) { mergedForwardReferences [ indexInMerge ++ ] = value1 ; j ++ ; continue loop1 ; } else { mergedForwardReferences [ indexInMerge ++ ] = value2 ; } } mergedForwardReferences [ indexInMerge ++ ] = value1 ; } for ( ; j < max2 ; j ++ ) { mergedForwardReferences [ indexInMerge ++ ] = otherLabel . forwardReferences [ j ] ; } this . forwardReferences = mergedForwardReferences ; this . forwardReferenceCount = indexInMerge ; } void branch ( ) { this . tagBits |= BranchLabel . USED ; if ( this . delegate != null ) { this . delegate . branch ( ) ; return ; } if ( this . position == Label . POS_NOT_SET ) { addForwardReference ( this . codeStream . position ) ; this . codeStream . position += 2 ; this . codeStream . classFileOffset += 2 ; } else { this . codeStream . writePosition ( this ) ; } } void branchWide ( ) { this . tagBits |= BranchLabel . USED ; if ( this . delegate != null ) { this . delegate . branchWide ( ) ; return ; } if ( this . position == Label . POS_NOT_SET ) { addForwardReference ( this . codeStream . position ) ; this . tagBits |= BranchLabel . WIDE ; this . codeStream . position += 4 ; this . codeStream . classFileOffset += 4 ; } else { this . codeStream . writeWidePosition ( this ) ; } } public int forwardReferenceCount ( ) { if ( this . delegate != null ) this . delegate . forwardReferenceCount ( ) ; return this . forwardReferenceCount ; } public int [ ] forwardReferences ( ) { if ( this . delegate != null ) this . delegate . forwardReferences ( ) ; return this . forwardReferences ; } public void initialize ( CodeStream stream ) { this . codeStream = stream ; this . position = Label . POS_NOT_SET ; this . forwardReferenceCount = 0 ; this . delegate = null ; } public boolean isCaseLabel ( ) { return false ; } public boolean isStandardLabel ( ) { return true ; } public void place ( ) { if ( this . position == Label . POS_NOT_SET ) { this . position = this . codeStream . position ; this . codeStream . addLabel ( this ) ; int oldPosition = this . position ; boolean isOptimizedBranch = false ; if ( this . forwardReferenceCount != 0 ) { isOptimizedBranch = ( this . forwardReferences [ this . forwardReferenceCount - 1 ] + 2 == this . position ) && ( this . codeStream . bCodeStream [ this . codeStream . classFileOffset - 3 ] == Opcodes . OPC_goto ) ; if ( isOptimizedBranch ) { if ( this . codeStream . lastAbruptCompletion == this . position ) { this . codeStream . lastAbruptCompletion = - 1 ; } this . codeStream . position = ( this . position -= 3 ) ; this . codeStream . classFileOffset -= 3 ; this . forwardReferenceCount -- ; if ( this . codeStream . lastEntryPC == oldPosition ) { this . codeStream . lastEntryPC = this . position ; } if ( ( this . codeStream . generateAttributes & ( ClassFileConstants . ATTR_VARS | ClassFileConstants . ATTR_STACK_MAP_TABLE | ClassFileConstants . ATTR_STACK_MAP ) ) != 0 ) { LocalVariableBinding locals [ ] = this . 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 ) { local . initializationPCs [ ( ( local . initializationCount - 1 ) << 1 ) + 1 ] = this . position ; } if ( local . initializationPCs [ ( local . initializationCount - 1 ) << 1 ] == oldPosition ) { local . initializationPCs [ ( local . initializationCount - 1 ) << 1 ] = this . position ; } } } } if ( ( this . codeStream . generateAttributes & ClassFileConstants . ATTR_LINES ) != 0 ) { this . codeStream . removeUnusedPcToSourceMapEntries ( ) ; } } } for ( int i = 0 ; i < this . forwardReferenceCount ; i ++ ) { this . codeStream . writePosition ( this , this . forwardReferences [ i ] ) ; } if ( isOptimizedBranch ) { this . codeStream . optimizeBranch ( oldPosition , this ) ; } } } public String toString ( ) { String basic = getClass ( ) . getName ( ) ; basic = basic . substring ( basic . lastIndexOf ( '.' ) + 1 ) ; StringBuffer buffer = new StringBuffer ( basic ) ; buffer . append ( '@' ) . append ( Integer . toHexString ( hashCode ( ) ) ) ; buffer . append ( "(position=" ) . append ( this . position ) ; if ( this . delegate != null ) buffer . append ( "delegate=" ) . append ( this . delegate ) ; buffer . append ( "" ) ; for ( int i = 0 ; i < this . forwardReferenceCount - 1 ; i ++ ) buffer . append ( this . forwardReferences [ i ] + ", " ) ; if ( this . forwardReferenceCount >= 1 ) buffer . append ( this . forwardReferences [ this . forwardReferenceCount - 1 ] ) ; buffer . append ( "] )" ) ; return buffer . toString ( ) ; } } </s>