/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;

import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.problem.AbortMethod;

/**
 * This type is a port of smalltalks JavaLabel
 */
public class Label {
	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 forwardReferenceCount = 0;
	private boolean isWide = false;
	
public Label() {
	// for creating labels ahead of code generation
}
/**
 * @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);
	}
	// 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 reference 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, null);
		}
		codeStream.writeSignedShort(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 void initialize(CodeStream stream) {
    this.codeStream = stream;
   	this.position = POS_NOT_SET;
	this.forwardReferenceCount = 0; 
}
public boolean isStandardLabel(){
	return true;
}
/*
* Place the label. If we have forward references resolve them.
*/
public void place() { // Currently lacking wide support.
	if (CodeStream.DEBUG) System.out.println("\t\t\t\t<place at: "+codeStream.position+" - "+ this); //$NON-NLS-1$ //$NON-NLS-2$

	if (position == POS_NOT_SET) {
		position = codeStream.position;
		codeStream.addLabel(this);
		int oldPosition = position;
		boolean isOptimizedBranch = false;
		// TURNED OFF since fail on 1F4IRD9
		if (forwardReferenceCount != 0) {
			isOptimizedBranch = (forwardReferences[forwardReferenceCount - 1] + 2 == position) && (codeStream.bCodeStream[codeStream.classFileOffset - 3] == Opcodes.OPC_goto);
			if (isOptimizedBranch) {
				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, null);
			}
			if (this.codeStream.wideMode) {
				if (this.isWide) {
					codeStream.writeSignedWord(forwardReferences[i], offset);
				} else {
					codeStream.writeSignedShort(forwardReferences[i], offset);
				}
			} else {
				codeStream.writeSignedShort(forwardReferences[i], 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 (isOptimizedBranch) {
			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, null);
							}
							if (this.codeStream.wideMode) {
								if (this.isWide) {
									codeStream.writeSignedWord(forwardPosition, offset);
								} else {
									codeStream.writeSignedShort(forwardPosition, offset);
								}
							} else {
								codeStream.writeSignedShort(forwardPosition, offset);
							}
						}
					}
				}
			}
		}
	}
}
/**
 * Print out the receiver
 */
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(position); //$NON-NLS-1$
	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();
}
}
