Logo Search packages:      
Sourcecode: eclipse version File versions  Download package

CodeStream.java

/*******************************************************************************
 * Copyright (c) 2000, 2005 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.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.*;

import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.*;
import org.eclipse.jdt.internal.compiler.env.IConstants;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;

public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, BaseTypes, TypeConstants, TypeIds {

      public static final boolean DEBUG = false;
      
      // It will be responsible for the following items.
      // -> Tracking Max Stack.

      public int stackMax; // Use Ints to keep from using extra bc when adding
      public int stackDepth; // Use Ints to keep from using extra bc when adding
      public int maxLocals;
      public static final int LABELS_INCREMENT = 5;
      public byte[] bCodeStream;
      public int pcToSourceMapSize;
      public int[] pcToSourceMap = new int[24];
      public int lastEntryPC; // last entry recorded 
      public int[] lineSeparatorPositions;
      public int position; // So when first set can be incremented
      public int classFileOffset;
      public int startingClassFileOffset; // I need to keep the starting point inside the byte array
      public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
      public ClassFile classFile; // The current classfile it is associated to.
      // local variable attributes output
      public static final int LOCALS_INCREMENT = 10;
      public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
      static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
      public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
      static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
      int visibleLocalsCount;
      public AbstractMethodDeclaration methodDeclaration;
      public ExceptionLabel[] exceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
      static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
      public int exceptionHandlersIndex;
      public int exceptionHandlersCounter;
      
      public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
      public boolean generateLineNumberAttributes;
      public boolean generateLocalVariableTableAttributes;
      public boolean preserveUnusedLocals;
      // store all the labels placed at the current position to be able to optimize
      // a jump to the next bytecode.
      public Label[] labels = new Label[LABELS_INCREMENT];
      static Label[] noLabels = new Label[LABELS_INCREMENT];
      public int countLabels;
      public int allLocalsCounter;
      public int maxFieldCount;
      // to handle goto_w
      public boolean wideMode = false;
      public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
      
      // target level to manage different code generation between different target levels
      private long targetLevel;
      
public CodeStream(ClassFile classFile, long targetLevel) {
      this.targetLevel = targetLevel;
      this.generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0;
      this.generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0;
      if (this.generateLineNumberAttributes) {
            this.lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions;
      }
}
final public void aaload() {
      if (DEBUG) System.out.println(position + "\t\taaload"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_aaload;
}
final public void aastore() {
      if (DEBUG) System.out.println(position + "\t\taastore"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_aastore;
}
final public void aconst_null() {
      if (DEBUG) System.out.println(position + "\t\taconst_null"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax) {
            stackMax = stackDepth;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_aconst_null;
}
public final void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
      // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
      if (!generateLocalVariableTableAttributes)
            return;
/*    if (initStateIndex == lastInitStateIndexWhenAddingInits)
            return;
      lastInitStateIndexWhenAddingInits = initStateIndex;
      if (lastInitStateIndexWhenRemovingInits != initStateIndex){
            lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index 
            // remove(1)-add(1)-remove(1) -> ignore second remove
            // remove(1)-add(2)-remove(1) -> perform second remove
      }
      
*/    for (int i = 0; i < visibleLocalsCount; i++) {
            LocalVariableBinding localBinding = visibleLocals[i];
            if (localBinding != null) {
                  // Check if the local is definitely assigned
                  if ((initStateIndex != -1) && isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
                        if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
                              /* There are two cases:
                               * 1) there is no initialization interval opened ==> add an opened interval
                               * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
                               * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
                               * is equals to -1.
                               * initializationPCs is a collection of pairs of int:
                               *    first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
                               *    is not closed yet.
                               */
                              localBinding.recordInitializationStartPC(position);
                        }
                  }
            }
      }
}
public void addLabel(Label aLabel) {
      if (countLabels == labels.length)
            System.arraycopy(labels, 0, labels = new Label[countLabels + LABELS_INCREMENT], 0, countLabels);
      labels[countLabels++] = aLabel;
}
public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
      if (!generateLocalVariableTableAttributes)
            return;

      if (visibleLocalsCount >= visibleLocals.length)
            System.arraycopy(visibleLocals, 0, visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2], 0, visibleLocalsCount);
      visibleLocals[visibleLocalsCount++] = localBinding;
}
final public void aload(int iArg) {
      if (DEBUG) System.out.println(position + "\t\taload:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals <= iArg) {
            maxLocals = iArg + 1;
      }
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_aload;
            writeUnsignedShort(iArg);
      } else {
            // Don't need to use the wide bytecode
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_aload;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void aload_0() {
      if (DEBUG) System.out.println(position + "\t\taload_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax) {
            stackMax = stackDepth;
      }
      if (maxLocals == 0) {
            maxLocals = 1;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_aload_0;
}
final public void aload_1() {
      if (DEBUG) System.out.println(position + "\t\taload_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals <= 1) {
            maxLocals = 2;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_aload_1;
}
final public void aload_2() {
      if (DEBUG) System.out.println(position + "\t\taload_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals <= 2) {
            maxLocals = 3;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_aload_2;
}
final public void aload_3() {
      if (DEBUG) System.out.println(position + "\t\taload_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals <= 3) {
            maxLocals = 4;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_aload_3;
}
public final void anewarray(TypeBinding typeBinding) {
      if (DEBUG) System.out.println(position + "\t\tanewarray: " + typeBinding); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_anewarray;
      writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
final public void areturn() {
      if (DEBUG) System.out.println(position + "\t\tareturn"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      // the stackDepth should be equal to 0 
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_areturn;
}
public void arrayAt(int typeBindingID) {
      switch (typeBindingID) {
            case T_int :
                  this.iaload();
                  break;
            case T_byte :
            case T_boolean :
                  this.baload();
                  break;
            case T_short :
                  this.saload();
                  break;
            case T_char :
                  this.caload();
                  break;
            case T_long :
                  this.laload();
                  break;
            case T_float :
                  this.faload();
                  break;
            case T_double :
                  this.daload();
                  break;
            default :
                  this.aaload();
      }
}
public void arrayAtPut(int elementTypeID, boolean valueRequired) {
      switch (elementTypeID) {
            case T_int :
                  if (valueRequired)
                        dup_x2();
                  iastore();
                  break;
            case T_byte :
            case T_boolean :
                  if (valueRequired)
                        dup_x2();
                  bastore();
                  break;
            case T_short :
                  if (valueRequired)
                        dup_x2();
                  sastore();
                  break;
            case T_char :
                  if (valueRequired)
                        dup_x2();
                  castore();
                  break;
            case T_long :
                  if (valueRequired)
                        dup2_x2();
                  lastore();
                  break;
            case T_float :
                  if (valueRequired)
                        dup_x2();
                  fastore();
                  break;
            case T_double :
                  if (valueRequired)
                        dup2_x2();
                  dastore();
                  break;
            default :
                  if (valueRequired)
                        dup_x2();
                  aastore();
      }
}
final public void arraylength() {
      if (DEBUG) System.out.println(position + "\t\tarraylength"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_arraylength;
}
final public void astore(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tastore:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= iArg) {
            maxLocals = iArg + 1;
      }
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position+=2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_astore;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position+=2;
            bCodeStream[classFileOffset++] = OPC_astore;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void astore_0() {
      if (DEBUG) System.out.println(position + "\t\tastore_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals == 0) {
            maxLocals = 1;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_astore_0;
}
final public void astore_1() {
      if (DEBUG) System.out.println(position + "\t\tastore_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 1) {
            maxLocals = 2;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_astore_1;
}
final public void astore_2() {
      if (DEBUG) System.out.println(position + "\t\tastore_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 2) {
            maxLocals = 3;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_astore_2;
}
final public void astore_3() {
      if (DEBUG) System.out.println(position + "\t\tastore_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 3) {
            maxLocals = 4;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_astore_3;
}
final public void athrow() {
      if (DEBUG) System.out.println(position + "\t\tathrow"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_athrow;
}
final public void baload() {
      if (DEBUG) System.out.println(position + "\t\tbaload"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_baload;
}
final public void bastore() {
      if (DEBUG) System.out.println(position + "\t\tbastore"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_bastore;
}
final public void bipush(byte b) {
      if (DEBUG) System.out.println(position + "\t\tbipush "+b); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset + 1 >= bCodeStream.length) {
            resizeByteArray();
      }
      position += 2;
      bCodeStream[classFileOffset++] = OPC_bipush;
      bCodeStream[classFileOffset++] = b;
}
final public void caload() {
      if (DEBUG) System.out.println(position + "\t\tcaload"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_caload;
}
final public void castore() {
      if (DEBUG) System.out.println(position + "\t\tcastore"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_castore;
}
public final void checkcast(TypeBinding typeBinding) {
      if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding.debugName()); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_checkcast;
      writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
final public void d2f() {
      if (DEBUG) System.out.println(position + "\t\td2f"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_d2f;
}
final public void d2i() {
      if (DEBUG) System.out.println(position + "\t\td2i"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_d2i;
}
final public void d2l() {
      if (DEBUG) System.out.println(position + "\t\td2l"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_d2l;
}
final public void dadd() {
      if (DEBUG) System.out.println(position + "\t\tdadd"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dadd;
}
final public void daload() {
      if (DEBUG) System.out.println(position + "\t\tdaload"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_daload;
}
final public void dastore() {
      if (DEBUG) System.out.println(position + "\t\tdastore"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 4;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dastore;
}
final public void dcmpg() {
      if (DEBUG) System.out.println(position + "\t\tdcmpg"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dcmpg;
}
final public void dcmpl() {
      if (DEBUG) System.out.println(position + "\t\tdcmpl"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dcmpl;
}
final public void dconst_0() {
      if (DEBUG) System.out.println(position + "\t\tdconst_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dconst_0;
}
final public void dconst_1() {
      if (DEBUG) System.out.println(position + "\t\tdconst_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dconst_1;
}
final public void ddiv() {
      if (DEBUG) System.out.println(position + "\t\tddiv"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ddiv;
}
public void decrStackSize(int offset) {
      stackDepth -= offset;
}
final public void dload(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tdload:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals < iArg + 2) {
            maxLocals = iArg + 2; // + 2 because it is a double
      }
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_dload;
            writeUnsignedShort(iArg);
      } else {
            // Don't need to use the wide bytecode
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_dload;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void dload_0() {
      if (DEBUG) System.out.println(position + "\t\tdload_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals < 2) {
            maxLocals = 2;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dload_0;
}
final public void dload_1() {
      if (DEBUG) System.out.println(position + "\t\tdload_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals < 3) {
            maxLocals = 3;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dload_1;
}
final public void dload_2() {
      if (DEBUG) System.out.println(position + "\t\tdload_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals < 4) {
            maxLocals = 4;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dload_2;
}
final public void dload_3() {
      if (DEBUG) System.out.println(position + "\t\tdload_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (maxLocals < 5) {
            maxLocals = 5;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dload_3;
}
final public void dmul() {
      if (DEBUG) System.out.println(position + "\t\tdmul"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dmul;
}
final public void dneg() {
      if (DEBUG) System.out.println(position + "\t\tdneg"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dneg;
}
final public void drem() {
      if (DEBUG) System.out.println(position + "\t\tdrem"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_drem;
}
final public void dreturn() {
      if (DEBUG) System.out.println(position + "\t\tdreturn"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      // the stackDepth should be equal to 0 
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dreturn;
}
final public void dstore(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tdstore:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals <= iArg + 1) {
            maxLocals = iArg + 2;
      }
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_dstore;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_dstore;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void dstore_0() {
      if (DEBUG) System.out.println(position + "\t\tdstore_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 2) {
            maxLocals = 2;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dstore_0;
}
final public void dstore_1() {
      if (DEBUG) System.out.println(position + "\t\tdstore_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 3) {
            maxLocals = 3;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dstore_1;
}
final public void dstore_2() {
      if (DEBUG) System.out.println(position + "\t\tdstore_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 4) {
            maxLocals = 4;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dstore_2;
}
final public void dstore_3() {
      if (DEBUG) System.out.println(position + "\t\tdstore_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 5) {
            maxLocals = 5;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dstore_3;
}
final public void dsub() {
      if (DEBUG) System.out.println(position + "\t\tdsub"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dsub;
}
final public void dup() {
      if (DEBUG) System.out.println(position + "\t\tdup"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax) {
            stackMax = stackDepth;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dup;
}
final public void dup_x1() {
      if (DEBUG) System.out.println(position + "\t\tdup_x1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dup_x1;
}
final public void dup_x2() {
      if (DEBUG) System.out.println(position + "\t\tdup_x2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dup_x2;
}
final public void dup2() {
      if (DEBUG) System.out.println(position + "\t\tdup2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dup2;
}
final public void dup2_x1() {
      if (DEBUG) System.out.println(position + "\t\tdup2_x1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dup2_x1;
}
final public void dup2_x2() {
      if (DEBUG) System.out.println(position + "\t\tdup2_x2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_dup2_x2;
}
public void exitUserScope(BlockScope currentScope) {
      // mark all the scope's locals as loosing their definite assignment

      if (!generateLocalVariableTableAttributes)
            return;
      while (visibleLocalsCount > 0) {
            LocalVariableBinding visibleLocal = visibleLocals[this.visibleLocalsCount - 1];
            if (visibleLocal == null)
                  continue;
            if (visibleLocal.declaringScope != currentScope) // left currentScope
                  break;

            // there maybe some some preserved locals never initialized
            if (visibleLocal.initializationCount > 0){
                  visibleLocal.recordInitializationEndPC(position);
            }
            visibleLocals[--this.visibleLocalsCount] = null; // this variable is no longer visible afterwards
      }
}
final public void f2d() {
      if (DEBUG) System.out.println(position + "\t\tf2d"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_f2d;
}
final public void f2i() {
      if (DEBUG) System.out.println(position + "\t\tf2i"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_f2i;
}
final public void f2l() {
      if (DEBUG) System.out.println(position + "\t\tf2l"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_f2l;
}
final public void fadd() {
      if (DEBUG) System.out.println(position + "\t\tfadd"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fadd;
}
final public void faload() {
      if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_faload;
}
final public void fastore() {
      if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fastore;
}
final public void fcmpg() {
      if (DEBUG) System.out.println(position + "\t\tfcmpg"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fcmpg;
}
final public void fcmpl() {
      if (DEBUG) System.out.println(position + "\t\tfcmpl"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fcmpl;
}
final public void fconst_0() {
      if (DEBUG) System.out.println(position + "\t\tfconst_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fconst_0;
}
final public void fconst_1() {
      if (DEBUG) System.out.println(position + "\t\tfconst_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fconst_1;
}
final public void fconst_2() {
      if (DEBUG) System.out.println(position + "\t\tfconst_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fconst_2;
}
final public void fdiv() {
      if (DEBUG) System.out.println(position + "\t\tfdiv"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fdiv;
}
final public void fload(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tfload:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= iArg) {
            maxLocals = iArg + 1;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_fload;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_fload;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void fload_0() {
      if (DEBUG) System.out.println(position + "\t\tfload_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals == 0) {
            maxLocals = 1;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fload_0;
}
final public void fload_1() {
      if (DEBUG) System.out.println(position + "\t\tfload_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= 1) {
            maxLocals = 2;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fload_1;
}
final public void fload_2() {
      if (DEBUG) System.out.println(position + "\t\tfload_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= 2) {
            maxLocals = 3;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fload_2;
}
final public void fload_3() {
      if (DEBUG) System.out.println(position + "\t\tfload_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= 3) {
            maxLocals = 4;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fload_3;
}
final public void fmul() {
      if (DEBUG) System.out.println(position + "\t\tfmul"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fmul;
}
final public void fneg() {
      if (DEBUG) System.out.println(position + "\t\tfneg"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fneg;
}
final public void frem() {
      if (DEBUG) System.out.println(position + "\t\tfrem"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_frem;
}
final public void freturn() {
      if (DEBUG) System.out.println(position + "\t\tfreturn"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      // the stackDepth should be equal to 0 
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_freturn;
}
final public void fstore(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tfstore:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= iArg) {
            maxLocals = iArg + 1;
      }
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_fstore;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_fstore;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void fstore_0() {
      if (DEBUG) System.out.println(position + "\t\tfstore_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals == 0) {
            maxLocals = 1;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fstore_0;
}
final public void fstore_1() {
      if (DEBUG) System.out.println(position + "\t\tfstore_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 1) {
            maxLocals = 2;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fstore_1;
}
final public void fstore_2() {
      if (DEBUG) System.out.println(position + "\t\tfstore_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 2) {
            maxLocals = 3;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fstore_2;
}
final public void fstore_3() {
      if (DEBUG) System.out.println(position + "\t\tfstore_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 3) {
            maxLocals = 4;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fstore_3;
}
final public void fsub() {
      if (DEBUG) System.out.println(position + "\t\tfsub"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_fsub;
}
/**
 * Macro for building a class descriptor object
 */
public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
      Label endLabel;
      ExceptionLabel anyExceptionHandler;
      int saveStackSize;
      if (accessedType.isBaseType() && accessedType != NullBinding) {
            this.getTYPE(accessedType.id);
            return;
      }

      if (this.targetLevel >= ClassFileConstants.JDK1_5) {
            // generation using the new ldc_w bytecode
            this.ldc(accessedType);
      } else {
            endLabel = new Label(this);
            if (syntheticFieldBinding != null) { // non interface case
                  this.getstatic(syntheticFieldBinding);
                  this.dup();
                  this.ifnonnull(endLabel);
                  this.pop();
            }

            /* Macro for building a class descriptor object... using or not a field cache to store it into...
            this sequence is responsible for building the actual class descriptor.
            
            If the fieldCache is set, then it is supposed to be the body of a synthetic access method
            factoring the actual descriptor creation out of the invocation site (saving space).
            If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
            we have no way to get a hand on the field cache to do better. */
      
      
            // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
      
            anyExceptionHandler = new ExceptionLabel(this, BaseTypes.NullBinding /* represents ClassNotFoundException*/);
            this.ldc(accessedType == BaseTypes.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
            this.invokeClassForName();
      
            /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
            if (accessedType == BaseTypes.NullBinding) {
                  this.ldc("java.lang.Object"); //$NON-NLS-1$
            } else if (accessedType.isArrayType()) {
                  this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
            } else {
                  // we make it an array type (to avoid class initialization)
                  this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
            }
            this.invokeClassForName();
            if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
                  this.invokeJavaLangClassGetComponentType();
            }     
            */
            /* We need to protect the runtime code from binary inconsistencies
            in case the accessedType is missing, the ClassNotFoundException has to be converted
            into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
            anyExceptionHandler.placeEnd();
      
            if (syntheticFieldBinding != null) { // non interface case
                  this.dup();
                  this.putstatic(syntheticFieldBinding);
            }
            this.goto_(endLabel);
      
      
            // Generate the body of the exception handler
            saveStackSize = stackDepth;
            stackDepth = 1;
            /* ClassNotFoundException on stack -- the class literal could be doing more things
            on the stack, which means that the stack may not be empty at this point in the
            above code gen. So we save its state and restart it from 1. */
      
            anyExceptionHandler.place();
      
            // Transform the current exception, and repush and throw a 
            // NoClassDefFoundError(ClassNotFound.getMessage())
      
            this.newNoClassDefFoundError();
            this.dup_x1();
            this.swap();
      
            // Retrieve the message from the old exception
            this.invokeThrowableGetMessage();
      
            // Send the constructor taking a message string as an argument
            this.invokeNoClassDefFoundErrorStringConstructor();
            this.athrow();
            stackDepth = saveStackSize;
            endLabel.place();
      }
}
/**
 * This method generates the code attribute bytecode
 */
final public void generateCodeAttributeForProblemMethod(String problemMessage) {
      newJavaLangError();
      dup();
      ldc(problemMessage);
      invokeJavaLangErrorConstructor();
      athrow();
}
public void generateConstant(Constant constant, int implicitConversionCode) {
      int targetTypeID = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
      if (targetTypeID != 0) {
            switch (targetTypeID) {
                  case T_boolean :
                        generateInlinedValue(constant.booleanValue());
                        break;
                  case T_char :
                        generateInlinedValue(constant.charValue());
                        break;
                  case T_byte :
                        generateInlinedValue(constant.byteValue());
                        break;
                  case T_short :
                        generateInlinedValue(constant.shortValue());
                        break;
                  case T_int :
                        generateInlinedValue(constant.intValue());
                        break;
                  case T_long :
                        generateInlinedValue(constant.longValue());
                        break;
                  case T_float :
                        generateInlinedValue(constant.floatValue());
                        break;
                  case T_double :
                        generateInlinedValue(constant.doubleValue());
                        break;
                  case T_JavaLangString :
                        ldc(constant.stringValue());
            }
      } else {
            ldc(constant.stringValue());
      }
      if ((implicitConversionCode & BOXING) != 0) {
            // need boxing
            generateBoxingConversion(targetTypeID);
      }
}

/**
 * Generates the sequence of instructions which will perform the conversion of the expression
 * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
 * @param implicitConversionCode int
 */
public void generateImplicitConversion(int implicitConversionCode) {
      if ((implicitConversionCode & UNBOXING) != 0) {
            final int typeId = implicitConversionCode & COMPILE_TYPE_MASK;
            generateUnboxingConversion(typeId);
            // unboxing can further involve base type conversions
      }
      switch (implicitConversionCode & IMPLICIT_CONVERSION_MASK) {
            case Float2Char :
                  this.f2i();
                  this.i2c();
                  break;
            case Double2Char :
                  this.d2i();
                  this.i2c();
                  break;
            case Int2Char :
            case Short2Char :
            case Byte2Char :
                  this.i2c();
                  break;
            case Long2Char :
                  this.l2i();
                  this.i2c();
                  break;
            case Char2Float :
            case Short2Float :
            case Int2Float :
            case Byte2Float :
                  this.i2f();
                  break;
            case Double2Float :
                  this.d2f();
                  break;
            case Long2Float :
                  this.l2f();
                  break;
            case Float2Byte :
                  this.f2i();
                  this.i2b();
                  break;
            case Double2Byte :
                  this.d2i();
                  this.i2b();
                  break;
            case Int2Byte :
            case Short2Byte :
            case Char2Byte :
                  this.i2b();
                  break;
            case Long2Byte :
                  this.l2i();
                  this.i2b();
                  break;
            case Byte2Double :
            case Char2Double :
            case Short2Double :
            case Int2Double :
                  this.i2d();
                  break;
            case Float2Double :
                  this.f2d();
                  break;
            case Long2Double :
                  this.l2d();
                  break;
            case Byte2Short :
            case Char2Short :
            case Int2Short :
                  this.i2s();
                  break;
            case Double2Short :
                  this.d2i();
                  this.i2s();
                  break;
            case Long2Short :
                  this.l2i();
                  this.i2s();
                  break;
            case Float2Short :
                  this.f2i();
                  this.i2s();
                  break;
            case Double2Int :
                  this.d2i();
                  break;
            case Float2Int :
                  this.f2i();
                  break;
            case Long2Int :
                  this.l2i();
                  break;
            case Int2Long :
            case Char2Long :
            case Byte2Long :
            case Short2Long :
                  this.i2l();
                  break;
            case Double2Long :
                  this.d2l();
                  break;
            case Float2Long :
                  this.f2l();
      }
      if ((implicitConversionCode & BOXING) != 0) {
            // need to unbox/box the constant
            final int typeId = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
            generateBoxingConversion(typeId);
      }
}
public void generateInlinedValue(byte inlinedValue) {
      switch (inlinedValue) {
            case -1 :
                  this.iconst_m1();
                  break;
            case 0 :
                  this.iconst_0();
                  break;
            case 1 :
                  this.iconst_1();
                  break;
            case 2 :
                  this.iconst_2();
                  break;
            case 3 :
                  this.iconst_3();
                  break;
            case 4 :
                  this.iconst_4();
                  break;
            case 5 :
                  this.iconst_5();
                  break;
            default :
                  if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
                        this.bipush(inlinedValue);
                        return;
                  }
      }
}
public void generateInlinedValue(char inlinedValue) {
      switch (inlinedValue) {
            case 0 :
                  this.iconst_0();
                  break;
            case 1 :
                  this.iconst_1();
                  break;
            case 2 :
                  this.iconst_2();
                  break;
            case 3 :
                  this.iconst_3();
                  break;
            case 4 :
                  this.iconst_4();
                  break;
            case 5 :
                  this.iconst_5();
                  break;
            default :
                  if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
                        this.bipush((byte) inlinedValue);
                        return;
                  }
                  if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
                        this.sipush(inlinedValue);
                        return;
                  }
                  this.ldc(inlinedValue);
      }
}
public void generateInlinedValue(double inlinedValue) {
      if (inlinedValue == 0.0) {
            if (Double.doubleToLongBits(inlinedValue) != 0L)
                  this.ldc2_w(inlinedValue);
            else
                  this.dconst_0();
            return;
      }
      if (inlinedValue == 1.0) {
            this.dconst_1();
            return;
      }
      this.ldc2_w(inlinedValue);
}
public void generateInlinedValue(float inlinedValue) {
      if (inlinedValue == 0.0f) {
            if (Float.floatToIntBits(inlinedValue) != 0)
                  this.ldc(inlinedValue);
            else
                  this.fconst_0();
            return;
      }
      if (inlinedValue == 1.0f) {
            this.fconst_1();
            return;
      }
      if (inlinedValue == 2.0f) {
            this.fconst_2();
            return;
      }
      this.ldc(inlinedValue);
}
public void generateInlinedValue(int inlinedValue) {
      switch (inlinedValue) {
            case -1 :
                  this.iconst_m1();
                  break;
            case 0 :
                  this.iconst_0();
                  break;
            case 1 :
                  this.iconst_1();
                  break;
            case 2 :
                  this.iconst_2();
                  break;
            case 3 :
                  this.iconst_3();
                  break;
            case 4 :
                  this.iconst_4();
                  break;
            case 5 :
                  this.iconst_5();
                  break;
            default :
                  if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
                        this.bipush((byte) inlinedValue);
                        return;
                  }
                  if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
                        this.sipush(inlinedValue);
                        return;
                  }
                  this.ldc(inlinedValue);
      }
}
public void generateInlinedValue(long inlinedValue) {
      if (inlinedValue == 0) {
            this.lconst_0();
            return;
      }
      if (inlinedValue == 1) {
            this.lconst_1();
            return;
      }
      this.ldc2_w(inlinedValue);
}
public void generateInlinedValue(short inlinedValue) {
      switch (inlinedValue) {
            case -1 :
                  this.iconst_m1();
                  break;
            case 0 :
                  this.iconst_0();
                  break;
            case 1 :
                  this.iconst_1();
                  break;
            case 2 :
                  this.iconst_2();
                  break;
            case 3 :
                  this.iconst_3();
                  break;
            case 4 :
                  this.iconst_4();
                  break;
            case 5 :
                  this.iconst_5();
                  break;
            default :
                  if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
                        this.bipush((byte) inlinedValue);
                        return;
                  }
                  this.sipush(inlinedValue);
      }
}
public void generateInlinedValue(boolean inlinedValue) {
      if (inlinedValue)
            this.iconst_1();
      else
            this.iconst_0();
}
public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
      if (mappingSequence == null) {
            if (target instanceof LocalVariableBinding) {
                  scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
            } else {
                  scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
            }
            return;
      }
      if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
            scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
            return;
      } else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
            scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
            return;
      }
      
      if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
            this.aload_0();
            return;
      } else if (mappingSequence[0] instanceof FieldBinding) {
            FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
            this.aload_0();
            this.getfield(fieldBinding);
      } else {
            load((LocalVariableBinding) mappingSequence[0]);
      }
      for (int i = 1, length = mappingSequence.length; i < length; i++) {
            if (mappingSequence[i] instanceof FieldBinding) {
                  FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
                  this.getfield(fieldBinding);
            } else {
                  this.invokestatic((MethodBinding) mappingSequence[i]);
            }
      }
}
public void generateReturnBytecode(Expression expression) {
      
      if (expression == null) {
            this.return_();
      } else {
            final int implicitConversion = expression.implicitConversion;
            if ((implicitConversion & BOXING) != 0) {
                  this.areturn();
                  return;
            }
            int runtimeType = (implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
            switch (runtimeType) {
                  case T_boolean :
                  case T_int :
                        this.ireturn();
                        break;
                  case T_float :
                        this.freturn();
                        break;
                  case T_long :
                        this.lreturn();
                        break;
                  case T_double :
                        this.dreturn();
                        break;
                  default :
                        this.areturn();
            }
      }
}
/**
 * The equivalent code performs a string conversion:
 *
 * @param blockScope the given blockScope
 * @param oper1 the first expression
 * @param oper2 the second expression
 */
public void generateStringConcatenationAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
      int pc;
      if (oper1 == null) {
            /* Operand is already on the stack, and maybe nil:
            note type1 is always to  java.lang.String here.*/
            this.newStringContatenation();
            this.dup_x1();
            this.swap();
            // If argument is reference type, need to transform it 
            // into a string (handles null case)
            this.invokeStringValueOf(T_JavaLangObject);
            this.invokeStringConcatenationStringConstructor();
      } else {
            pc = position;
            oper1.generateOptimizedStringConcatenationCreation(blockScope, this, oper1.implicitConversion & COMPILE_TYPE_MASK);
            this.recordPositionsFrom(pc, oper1.sourceStart);
      }
      pc = position;
      oper2.generateOptimizedStringConcatenation(blockScope, this, oper2.implicitConversion & COMPILE_TYPE_MASK);
      this.recordPositionsFrom(pc, oper2.sourceStart);
      this.invokeStringConcatenationToString();
}
/**
 * Code responsible to generate the suitable code to supply values for the synthetic enclosing
 * instance arguments of a constructor invocation of a nested type.
 */
public void generateSyntheticEnclosingInstanceValues(
            BlockScope currentScope, 
            ReferenceBinding targetType, 
            Expression enclosingInstance, 
            ASTNode invocationSite) {

      // supplying enclosing instance for the anonymous type's superclass
      ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? (ReferenceBinding)targetType.superclass().erasure() : targetType;
      boolean hasExtraEnclosingInstance = enclosingInstance != null;
      if (hasExtraEnclosingInstance 
                  && (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
            currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
            return;
      }

      // perform some emulation work in case there is some and we are inside a local type only
      ReferenceBinding[] syntheticArgumentTypes;
      if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {

            ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
            long compliance = currentScope.compilerOptions().complianceLevel;

            // deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
            // always consider it if complying to 1.5
            boolean denyEnclosingArgInConstructorCall;
            if (compliance <= JDK1_3) {
                  denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression;
            } else if (compliance == JDK1_4){
                  denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
                        || invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess();
            } else {
                  //compliance >= JDK1_5
                  denyEnclosingArgInConstructorCall = (invocationSite instanceof AllocationExpression
                              || invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess()) 
                        && !targetType.isLocalType();
            }
            
            boolean complyTo14 = compliance >= ClassFileConstants.JDK1_4;
            for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
                  ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
                  if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
                        hasExtraEnclosingInstance = false;
                        enclosingInstance.generateCode(currentScope, this, true);
                        if (complyTo14){
                              dup();
                              invokeObjectGetClass(); // will perform null check
                              pop();
                        }
                  } else {
                        Object[] emulationPath = currentScope.getEmulationPath(
                                    syntheticArgType, 
                                    false /*not only exact match (that is, allow compatible)*/,
                                    denyEnclosingArgInConstructorCall);
                        this.generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
                  }
            }
            if (hasExtraEnclosingInstance){
                  currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
            }
      }
}

/**
 * Code responsible to generate the suitable code to supply values for the synthetic outer local
 * variable arguments of a constructor invocation of a nested type.
 * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
 */
public void generateSyntheticOuterArgumentValues(BlockScope currentScope, ReferenceBinding targetType, ASTNode invocationSite) {

      // generate the synthetic outer arguments then
      SyntheticArgumentBinding syntheticArguments[];
      if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
            for (int i = 0, max = syntheticArguments.length; i < max; i++) {
                  LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
                  VariableBinding[] emulationPath = currentScope.getEmulationPath(targetVariable);
                  this.generateOuterAccess(emulationPath, invocationSite, targetVariable, currentScope);
            }
      }
}

/**
 * @param accessBinding the access method binding to generate
 */
public void generateSyntheticBodyForConstructorAccess(SyntheticMethodBinding accessBinding) {

      initializeMaxLocals(accessBinding);

      MethodBinding constructorBinding = accessBinding.targetMethod;
      TypeBinding[] parameters = constructorBinding.parameters;
      int length = parameters.length;
      int resolvedPosition = 1;
      this.aload_0();
      // special name&ordinal argument generation for enum constructors
      TypeBinding declaringClass = constructorBinding.declaringClass;
      if (declaringClass.erasure().id == T_JavaLangEnum || declaringClass.isEnum()) {
            this.aload_1(); // pass along name param as name arg
            this.iload_2(); // pass along ordinal param as ordinal arg
        resolvedPosition += 2;
      }     
      if (declaringClass.isNestedType()) {
            NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
            SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
            for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
                  TypeBinding type;
                  load((type = syntheticArguments[i].type), resolvedPosition);
                  if ((type == DoubleBinding) || (type == LongBinding))
                        resolvedPosition += 2;
                  else
                        resolvedPosition++;
            }
      }
      for (int i = 0; i < length; i++) {
            load(parameters[i], resolvedPosition);
            if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
                  resolvedPosition += 2;
            else
                  resolvedPosition++;
      }
      
      if (declaringClass.isNestedType()) {
            NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
            SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
            for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
                  TypeBinding type;
                  load((type = syntheticArguments[i].type), resolvedPosition);
                  if ((type == DoubleBinding) || (type == LongBinding))
                        resolvedPosition += 2;
                  else
                        resolvedPosition++;
            }
      }
      this.invokespecial(constructorBinding);
      this.return_();
}
//static X[] values() {
// X[] values;
// int length;
// X[] result;
// System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length)
// return result;
//}
public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
      ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
      FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
      initializeMaxLocals(methodBinding);
      TypeBinding enumArray = methodBinding.returnType;
      
      this.getstatic(enumValuesSyntheticfield);
      this.dup();
      this.astore_0();
      this.iconst_0();
      this.aload_0();
      this.arraylength();
      this.dup();
      this.istore_1();
      this.newArray((ArrayBinding) enumArray);
      this.dup();
      this.astore_2();
      this.iconst_0();
      this.iload_1();
      this.invokeSystemArraycopy();
      this.aload_2();
      this.areturn();
}
//static X valueOf(String name) {
// X[] values;
// for (int i = (values = $VALUES).length; --i >= 0;) {
//           X value;
//           if (name.equals(value = values[i].name())) return value;
// }
// throw new IllegalArgumentException(name);
//}         
public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
      ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
      FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
      initializeMaxLocals(methodBinding);
      Label loopCond = new Label(this);
      Label loopStart = new Label(this);
      Label wrongConstant = new Label(this);

      this.getstatic(enumValuesSyntheticfield);
      this.dup();
      this.astore_1();
      this.arraylength();
      this.istore_2();
      this.goto_(loopCond);
      loopStart.place();
      this.aload_0();
      this.aload_1();
      this.iload_2();
      this.aaload();
      this.dup();
      this.astore_3();
      this.invokeJavaLangEnumname(this.classFile.referenceBinding);
      this.invokeStringEquals();
      this.ifeq(wrongConstant);
      this.aload_3();
      this.areturn();
      wrongConstant.place();
      loopCond.place();
      this.iinc(2, -1);       
      this.iload_2();
      this.ifge(loopStart);
      this.newJavaLangIllegalArgumentException();
      this.dup();
      this.aload_0();
      this.invokeJavaLangIllegalArgumentExceptionStringConstructor();
      this.athrow();
}
public void generateSyntheticBodyForSwitchTable(SyntheticMethodBinding methodBinding) {
      ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
      initializeMaxLocals(methodBinding);
      final Label nullLabel = new Label(this);
      FieldBinding syntheticFieldBinding = methodBinding.targetReadField;

      this.getstatic(syntheticFieldBinding);
      this.dup();
      this.ifnull(nullLabel);
      final int stackSizeForIf = this.stackDepth;
      this.areturn();
      nullLabel.place();
      this.stackDepth = stackSizeForIf;
      this.pop();
      ReferenceBinding enumBinding = (ReferenceBinding) methodBinding.targetEnumType;
      char[] signature = "()".toCharArray(); //$NON-NLS-1$
      ArrayBinding arrayBinding = scope.createArrayType(enumBinding, 1);
      signature = CharOperation.concat(signature, arrayBinding.constantPoolName());
      this.invoke(OPC_invokestatic, 0, 1, enumBinding.constantPoolName(), TypeConstants.VALUES, signature);
      this.arraylength();
      this.newarray(INT_ARRAY);
      this.astore_0();
      final FieldBinding[] fields = enumBinding.fields();
      if (fields != null) {
            for (int i = 0, max = fields.length; i < max; i++) {
                  FieldBinding fieldBinding = fields[i];
                  if ((fieldBinding.getAccessFlags() & IConstants.AccEnum) != 0) {
                        final Label endLabel = new Label(this);
                        final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, BaseTypes.LongBinding /* represents NoSuchFieldError*/);
                        this.aload_0();
                        this.getstatic(fieldBinding);
                        this.invokeEnumOrdinal(enumBinding.constantPoolName());
                        this.generateInlinedValue(fieldBinding.id);
                        this.iastore();
                        anyExceptionHandler.placeEnd();
                        this.goto_(endLabel);
                        // Generate the body of the exception handler
                        final int saveStackSize = stackDepth;
                        stackDepth = 1;
                        anyExceptionHandler.place();
                        this.pop(); // we don't use it so we can pop it
                        stackDepth = saveStackSize;
                        endLabel.place();                   
                  }
            }
      }
      this.aload_0();
      this.dup();
      this.putstatic(syntheticFieldBinding);
      areturn();
}
public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
      initializeMaxLocals(accessBinding);
      FieldBinding fieldBinding = accessBinding.targetReadField;
      if (fieldBinding.isStatic())
            this.getstatic(fieldBinding);
      else {
            this.aload_0();
            this.getfield(fieldBinding);
      }
      switch (fieldBinding.type.id) {
//          case T_void :
//                this.return_();
//                break;
            case T_boolean :
            case T_byte :
            case T_char :
            case T_short :
            case T_int :
                  this.ireturn();
                  break;
            case T_long :
                  this.lreturn();
                  break;
            case T_float :
                  this.freturn();
                  break;
            case T_double :
                  this.dreturn();
                  break;
            default :
                  this.areturn();
      }     
}
public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding accessBinding) {
      initializeMaxLocals(accessBinding);
      FieldBinding fieldBinding = accessBinding.targetWriteField;
      if (fieldBinding.isStatic()) {
            load(fieldBinding.type, 0);
            this.putstatic(fieldBinding);
      } else {
            this.aload_0();
            load(fieldBinding.type, 1);
            this.putfield(fieldBinding);
      }
      this.return_();
}
public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessMethod) {

      initializeMaxLocals(accessMethod);
      MethodBinding targetMethod = accessMethod.targetMethod;
      TypeBinding[] parameters = targetMethod.parameters;
      int length = parameters.length;
      TypeBinding[] arguments = accessMethod.kind == SyntheticMethodBinding.BridgeMethod 
                                                                              ? accessMethod.parameters
                                                                              : null;
      int resolvedPosition;
      if (targetMethod.isStatic())
            resolvedPosition = 0;
      else {
            this.aload_0();
            resolvedPosition = 1;
      }
      for (int i = 0; i < length; i++) {
          TypeBinding parameter = parameters[i];
          if (arguments != null) { // for bridge methods
                TypeBinding argument = arguments[i];
                  load(argument, resolvedPosition);
                  if (argument != parameter) 
                      checkcast(parameter);
          } else {
                  load(parameter, resolvedPosition);
            }
            if ((parameter == DoubleBinding) || (parameter == LongBinding))
                  resolvedPosition += 2;
            else
                  resolvedPosition++;
      }
      if (targetMethod.isStatic())
            this.invokestatic(targetMethod);
      else {
            if (targetMethod.isConstructor()
                  || targetMethod.isPrivate()
                  // qualified super "X.super.foo()" targets methods from superclass
                  || accessMethod.kind == SyntheticMethodBinding.SuperMethodAccess){
                  this.invokespecial(targetMethod);
            } else {
                  if (targetMethod.declaringClass.isInterface()) { // interface or annotation type
                        this.invokeinterface(targetMethod);
                  } else {
                        this.invokevirtual(targetMethod);
                  }
            }
      }
      switch (targetMethod.returnType.id) {
            case T_void :
                  this.return_();
                  break;
            case T_boolean :
            case T_byte :
            case T_char :
            case T_short :
            case T_int :
                  this.ireturn();
                  break;
            case T_long :
                  this.lreturn();
                  break;
            case T_float :
                  this.freturn();
                  break;
            case T_double :
                  this.dreturn();
                  break;
            default :
                  TypeBinding accessErasure = accessMethod.returnType.erasure();
                  if (!targetMethod.returnType.isCompatibleWith(accessErasure))
                        this.checkcast(accessErasure); // for bridge methods
                  this.areturn();
      }
}
public void generateBoxingConversion(int unboxedTypeID) {
      switch (unboxedTypeID) {
            case T_byte :
                  // invokestatic: Byte.valueOf(byte)
                  this.invoke(
                        OPC_invokestatic,
                        1, // argCount
                        1, // return type size
                        ConstantPool.JavaLangByteConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.byteByteSignature);
                  break;
            case T_short :
                  // invokestatic: Short.valueOf(short)
                  this.invoke(
                        OPC_invokestatic,
                        1, // argCount
                        1, // return type size
                        ConstantPool.JavaLangShortConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.shortShortSignature);
                  break;
            case T_char :
                  // invokestatic: Character.valueOf(char)
                  this.invoke(
                        OPC_invokestatic,
                        1, // argCount
                        1, // return type size
                        ConstantPool.JavaLangCharacterConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.charCharacterSignature);
                  break;
            case T_int :
                  // invokestatic: Integer.valueOf(int)
                  this.invoke(
                        OPC_invokestatic,
                        1, // argCount
                        1, // return type size
                        ConstantPool.JavaLangIntegerConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.IntIntegerSignature);
                  break;
            case T_long :
                  // invokestatic: Long.valueOf(long)
                  this.invoke(
                        OPC_invokestatic,
                        2, // argCount
                        1, // return type size
                        ConstantPool.JavaLangLongConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.longLongSignature);
                  break;
            case T_float :
                  // invokestatic: Float.valueOf(float)
                  this.invoke(
                        OPC_invokestatic,
                        1, // argCount
                        1, // return type size
                        ConstantPool.JavaLangFloatConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.floatFloatSignature);
                  break;
            case T_double :
                  // invokestatic: Double.valueOf(double)
                  this.invoke(
                        OPC_invokestatic,
                        2, // argCount
                        1, // return type size
                        ConstantPool.JavaLangDoubleConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.doubleDoubleSignature);
                  break;
            case T_boolean :
                  // invokestatic: Boolean.valueOf(boolean)
                  this.invoke(
                        OPC_invokestatic,
                        1, // argCount
                        1, // return type size
                        ConstantPool.JavaLangBooleanConstantPoolName,
                        ConstantPool.ValueOf,
                        ConstantPool.booleanBooleanSignature);
      }
}
public void generateUnboxingConversion(int unboxedTypeID) {
      switch (unboxedTypeID) {
            case T_byte :
                  // invokevirtual: byteValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              1, // return type size
                              ConstantPool.JavaLangByteConstantPoolName,
                              ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
                              ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
                  break;
            case T_short :
                  // invokevirtual: shortValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              1, // return type size
                              ConstantPool.JavaLangShortConstantPoolName,
                              ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
                              ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
                  break;
            case T_char :
                  // invokevirtual: charValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              1, // return type size
                              ConstantPool.JavaLangCharacterConstantPoolName,
                              ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
                              ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
                  break;
            case T_int :
                  // invokevirtual: intValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              1, // return type size
                              ConstantPool.JavaLangIntegerConstantPoolName,
                              ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
                              ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
                  break;
            case T_long :
                  // invokevirtual: longValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              2, // return type size
                              ConstantPool.JavaLangLongConstantPoolName,
                              ConstantPool.LONGVALUE_LONG_METHOD_NAME,
                              ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
                  break;
            case T_float :
                  // invokevirtual: floatValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              1, // return type size
                              ConstantPool.JavaLangFloatConstantPoolName,
                              ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
                              ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
                  break;
            case T_double :
                  // invokevirtual: doubleValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              2, // return type size
                              ConstantPool.JavaLangDoubleConstantPoolName,
                              ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
                              ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
                  break;
            case T_boolean :
                  // invokevirtual: booleanValue()
                  this.invoke(
                              OPC_invokevirtual,
                              0, // argCount
                              1, // return type size
                              ConstantPool.JavaLangBooleanConstantPoolName,
                              ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
                              ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
      }
}
final public byte[] getContents() {
      byte[] contents;
      System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
      return contents;
}
final public void getfield(FieldBinding fieldBinding) {
      if (DEBUG) System.out.println(position + "\t\tgetfield:"+fieldBinding); //$NON-NLS-1$
      int returnTypeSize = 1;
      if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
            returnTypeSize = 2;
      }
      generateFieldAccess(
                  OPC_getfield,
                  returnTypeSize,
                  fieldBinding.declaringClass.constantPoolName(),
                  fieldBinding.name,
                  fieldBinding.type.signature());
}
private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) {
      countLabels = 0;
      switch(opcode) {
            case OPC_getfield :
                  if (returnTypeSize == 2) {
                        stackDepth++;
                  }
                  break;
            case OPC_getstatic :
                  if (returnTypeSize == 2) {
                        stackDepth += 2;
                  } else {
                        stackDepth++;
                  }
                  break;
            case OPC_putfield :
                  if (returnTypeSize == 2) {
                        stackDepth -= 3;
                  } else {
                        stackDepth -= 2;
                  }
                  break;
            case OPC_putstatic :
                  if (returnTypeSize == 2) {
                        stackDepth -= 2;
                  } else {
                        stackDepth--;
                  }
      }
      if (stackDepth > stackMax) {
            stackMax = stackDepth;
      }
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = opcode;
      writeUnsignedShort(constantPool.literalIndexForField(declaringClass, name, signature));
}
final public void getstatic(FieldBinding fieldBinding) {
      if (DEBUG) System.out.println(position + "\t\tgetstatic:"+fieldBinding); //$NON-NLS-1$
      int returnTypeSize = 1;
      if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
            returnTypeSize = 2;
      }
      generateFieldAccess(
                  OPC_getstatic,
                  returnTypeSize,
                  fieldBinding.declaringClass.constantPoolName(),
                  fieldBinding.name,
                  fieldBinding.type.signature());
}
public void getTYPE(int baseTypeID) {
      countLabels = 0;
      switch (baseTypeID) {
            case T_byte :
                  // getstatic: java.lang.Byte.TYPE               
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangByteConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_short :
                  // getstatic: java.lang.Short.TYPE              
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangShortConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_char :
                  // getstatic: java.lang.Character.TYPE                
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangCharacterConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_int :
                  // getstatic: java.lang.Integer.TYPE                  
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangIntegerConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_long :
                  // getstatic: java.lang.Long.TYPE               
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangLongConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_float :
                  // getstatic: java.lang.Float.TYPE              
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangFloatConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_double :
                  // getstatic: java.lang.Double.TYPE             
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangDoubleConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_boolean :
                  // getstatic: java.lang.Boolean.TYPE                  
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangBooleanConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
            case T_void :
                  // getstatic: java.lang.Void.TYPE
                  if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$
                  generateFieldAccess(
                              OPC_getstatic,
                              1,
                              ConstantPool.JavaLangVoidConstantPoolName,
                              ConstantPool.TYPE,
                              ConstantPool.JavaLangClassSignature);
                  break;
      }
}
/**
 * We didn't call it goto, because there is a conflit with the goto keyword
 */
final public void goto_(Label label) {
      if (this.wideMode) {
            this.goto_w(label);
            return;
      }
      if (DEBUG) System.out.println(position + "\t\tgoto:"+label); //$NON-NLS-1$
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      label.inlineForwardReferencesFromLabelsTargeting(position);
      /*
       Possible optimization for code such as:
       public Object foo() {
            boolean b = true;
            if (b) {
                  if (b)
                        return null;
            } else {
                  if (b) {
                        return null;
                  }
            }
            return null;
      }
      The goto around the else block for the first if will
      be unreachable, because the thenClause of the second if
      returns.
      See inlineForwardReferencesFromLabelsTargeting defined
      on the Label class for the remaining part of this
      optimization.
       if (!lbl.isBranchTarget(position)) {
            switch(bCodeStream[classFileOffset-1]) {
                  case OPC_return :
                  case OPC_areturn:
                        return;
            }
      }*/
      position++;
      bCodeStream[classFileOffset++] = OPC_goto;
      label.branch();
}

final public void goto_w(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tgotow:"+lbl); //$NON-NLS-1$
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_goto_w;
      lbl.branchWide();
}
final public void i2b() {
      if (DEBUG) System.out.println(position + "\t\ti2b"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_i2b;
}
final public void i2c() {
      if (DEBUG) System.out.println(position + "\t\ti2c"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_i2c;
}
final public void i2d() {
      if (DEBUG) System.out.println(position + "\t\ti2d"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_i2d;
}
final public void i2f() {
      if (DEBUG) System.out.println(position + "\t\ti2f"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_i2f;
}
final public void i2l() {
      if (DEBUG) System.out.println(position + "\t\ti2l"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_i2l;
}
final public void i2s() {
      if (DEBUG) System.out.println(position + "\t\ti2s"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_i2s;
}
final public void iadd() {
      if (DEBUG) System.out.println(position + "\t\tiadd"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iadd;
}
final public void iaload() {
      if (DEBUG) System.out.println(position + "\t\tiaload"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iaload;
}
final public void iand() {
      if (DEBUG) System.out.println(position + "\t\tiand"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iand;
}
final public void iastore() {
      if (DEBUG) System.out.println(position + "\t\tiastore"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iastore;
}
final public void iconst_0() {
      if (DEBUG) System.out.println(position + "\t\ticonst_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iconst_0;
}
final public void iconst_1() {
      if (DEBUG) System.out.println(position + "\t\ticonst_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iconst_1;
}
final public void iconst_2() {
      if (DEBUG) System.out.println(position + "\t\ticonst_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iconst_2;
}
final public void iconst_3() {
      if (DEBUG) System.out.println(position + "\t\ticonst_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iconst_3;
}
final public void iconst_4() {
      if (DEBUG) System.out.println(position + "\t\ticonst_4"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iconst_4;
}
final public void iconst_5() {
      if (DEBUG) System.out.println(position + "\t\ticonst_5"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iconst_5;
}
final public void iconst_m1() {
      if (DEBUG) System.out.println(position + "\t\ticonst_m1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iconst_m1;
}
final public void idiv() {
      if (DEBUG) System.out.println(position + "\t\tidiv"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_idiv;
}
final public void if_acmpeq(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_acmpeq:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth-=2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_acmpne, lbl);
      } else {    
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_acmpeq;
            lbl.branch();
      }
}
final public void if_acmpne(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_acmpne:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth-=2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_acmpeq, lbl);
      } else {    
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_acmpne;
            lbl.branch();
      }
}
final public void if_icmpeq(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_cmpeq:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_icmpne, lbl);
      } else {    
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_icmpeq;
            lbl.branch();
      }
}
final public void if_icmpge(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_iacmpge:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_icmplt, lbl);
      } else {    
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_icmpge;
            lbl.branch();
      }
}
final public void if_icmpgt(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_iacmpgt:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_icmple, lbl);
      } else {    
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_icmpgt;
            lbl.branch();
      }
}
final public void if_icmple(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_iacmple:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_icmpgt, lbl);
      } else {    
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_icmple;
            lbl.branch();
      }
}
final public void if_icmplt(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_iacmplt:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_icmpge, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_icmplt;
            lbl.branch();
      }
}
final public void if_icmpne(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tif_iacmpne:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_if_icmpeq, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_if_icmpne;
            lbl.branch();
      }
}
final public void ifeq(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tifeq:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_ifne, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ifeq;
            lbl.branch();
      }
}
final public void ifge(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tifge:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_iflt, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ifge;
            lbl.branch();
      }
}
final public void ifgt(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tifgt:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_ifle, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ifgt;
            lbl.branch();
      }
}
final public void ifle(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tifle:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_ifgt, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ifle;
            lbl.branch();
      }
}
final public void iflt(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tiflt:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_ifge, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_iflt;
            lbl.branch();
      }
}
final public void ifne(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tifne:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_ifeq, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ifne;
            lbl.branch();
      }
}
final public void ifnonnull(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tifnonnull:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_ifnull, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ifnonnull;
            lbl.branch();
      }
}
final public void ifnull(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tifnull:"+lbl); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (this.wideMode) {
            generateWideRevertedConditionalBranch(OPC_ifnonnull, lbl);
      } else {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ifnull;
            lbl.branch();
      }
}
final public void iinc(int index, int value) {
      if (DEBUG) System.out.println(position + "\t\tiinc:"+index+","+value); //$NON-NLS-1$ //$NON-NLS-2$
      countLabels = 0;
      if ((index > 255) || (value < -128 || value > 127)) { // have to widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_iinc;
            writeUnsignedShort(index);
            writeSignedShort(value);
      } else {
            if (classFileOffset + 2 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 3;
            bCodeStream[classFileOffset++] = OPC_iinc;
            bCodeStream[classFileOffset++] = (byte) index;
            bCodeStream[classFileOffset++] = (byte) value;
      }
}
final public void iload(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tiload:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= iArg) {
            maxLocals = iArg + 1;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_iload;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_iload;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void iload_0() {
      if (DEBUG) System.out.println(position + "\t\tiload_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= 0) {
            maxLocals = 1;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iload_0;
}
final public void iload_1() {
      if (DEBUG) System.out.println(position + "\t\tiload_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= 1) {
            maxLocals = 2;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iload_1;
}
final public void iload_2() {
      if (DEBUG) System.out.println(position + "\t\tiload_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= 2) {
            maxLocals = 3;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iload_2;
}
final public void iload_3() {
      if (DEBUG) System.out.println(position + "\t\tiload_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (maxLocals <= 3) {
            maxLocals = 4;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iload_3;
}
final public void imul() {
      if (DEBUG) System.out.println(position + "\t\timul"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_imul;
}
public void incrementTemp(LocalVariableBinding localBinding, int value) {
      if (value == (short) value) {
            this.iinc(localBinding.resolvedPosition, value);
            return;
      }
      load(localBinding);
      this.ldc(value);
      this.iadd();
      store(localBinding, false);
}
public void incrStackSize(int offset) {
      if ((stackDepth += offset) > stackMax)
            stackMax = stackDepth;
}
public int indexOfSameLineEntrySincePC(int pc, int line) {
      for (int index = pc, max = pcToSourceMapSize; index < max; index+=2) {
            if (pcToSourceMap[index+1] == line)
                  return index;
      }
      return -1;
}
final public void ineg() {
      if (DEBUG) System.out.println(position + "\t\tineg"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ineg;
}
public void init(ClassFile targetClassFile) {
      this.classFile = targetClassFile;
      this.constantPool = targetClassFile.constantPool;
      this.bCodeStream = targetClassFile.contents;
      this.classFileOffset = targetClassFile.contentsOffset;
      this.startingClassFileOffset = this.classFileOffset;
      pcToSourceMapSize = 0;
      lastEntryPC = 0;
      int length = visibleLocals.length;
      if (noVisibleLocals.length < length) {
            noVisibleLocals = new LocalVariableBinding[length];
      }
      System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
      visibleLocalsCount = 0;
      
      length = locals.length;
      if (noLocals.length < length) {
            noLocals = new LocalVariableBinding[length];
      }
      System.arraycopy(noLocals, 0, locals, 0, length);
      allLocalsCounter = 0;

      length = exceptionHandlers.length;
      if (noExceptionHandlers.length < length) {
            noExceptionHandlers = new ExceptionLabel[length];
      }
      System.arraycopy(noExceptionHandlers, 0, exceptionHandlers, 0, length);
      exceptionHandlersIndex = 0;
      exceptionHandlersCounter = 0;
      
      length = labels.length;
      if (noLabels.length < length) {
            noLabels = new Label[length];
      }
      System.arraycopy(noLabels, 0, labels, 0, length);
      countLabels = 0;

      stackMax = 0;
      stackDepth = 0;
      maxLocals = 0;
      position = 0;
}
/**
 * @param methodBinding the given method binding to initialize the max locals
 */
public void initializeMaxLocals(MethodBinding methodBinding) {

      if (methodBinding == null) {
            this.maxLocals = 0;
            return;
      }
      
      this.maxLocals = methodBinding.isStatic() ? 0 : 1;
      
      // take into account enum constructor synthetic name+ordinal
      if (methodBinding.isConstructor() && methodBinding.declaringClass.isEnum()) {
            this.maxLocals += 2; // String and int (enum constant name+ordinal)
      }
      
      // take into account the synthetic parameters
      if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
            ReferenceBinding enclosingInstanceTypes[];
            if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
                  for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
                        this.maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
                        // LongBinding or DoubleBinding
                  }
            }
            SyntheticArgumentBinding syntheticArguments[];
            if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
                  for (int i = 0, max = syntheticArguments.length; i < max; i++) {
                        TypeBinding argType;
                        if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) {
                              this.maxLocals += 2;
                        } else {
                              this.maxLocals++;
                        }
                  }
            }
      }
      TypeBinding[] arguments;
      if ((arguments = methodBinding.parameters) != null) {
            for (int i = 0, max = arguments.length; i < max; i++) {
                  TypeBinding argType;
                  if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) {
                        this.maxLocals += 2;
                  } else {
                        this.maxLocals++;
                  }
            }
      }
}
/**
 * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
 * If there is an existing entry it returns -1 (no insertion required).
 * Otherwise it returns the index where the entry for the pc has to be inserted.
 * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
 *
 * @param pcToSourceMap the given pcToSourceMap array
 * @param length the given length
 * @param pc the given pc
 * @return int
 */
public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
      int g = 0;
      int d = length - 2;
      int m = 0;
      while (g <= d) {
            m = (g + d) / 2;
            // we search only on even indexes
            if ((m % 2) != 0)
                  m--;
            int currentPC = pcToSourceMap[m];
            if (pc < currentPC) {
                  d = m - 2;
            } else
                  if (pc > currentPC) {
                        g = m + 2;
                  } else {
                        return -1;
                  }
      }
      if (pc < pcToSourceMap[m])
            return m;
      return m + 2;
}
/**
 * We didn't call it instanceof because there is a conflit with the
 * instanceof keyword
 */
final public void instance_of(TypeBinding typeBinding) {
      if (DEBUG) System.out.println(position + "\t\tinstance_of:"+typeBinding); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_instanceof;
      writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
public void invokeClassForName() {
      // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
      if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$
      this.invoke(
            OPC_invokestatic,
            1, // argCount
            1, // return type size
            ConstantPool.JavaLangClassConstantPoolName,
            ConstantPool.ForName,
            ConstantPool.ForNameSignature);
}
public void invokeJavaLangClassDesiredAssertionStatus() {
      // invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokevirtual,
                  0, // argCount
                  1, // return type size
                  ConstantPool.JavaLangClassConstantPoolName,
                  ConstantPool.DesiredAssertionStatus,
                  ConstantPool.DesiredAssertionStatusSignature);
}

public void invokeJavaLangClassGetComponentType() {
      // invokevirtual: java.lang.Class.getComponentType()java.lang.Class;
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.getComponentType()java.lang.Class;"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokevirtual,
                  0, // argCount
                  1, // return type size
                  ConstantPool.JavaLangClassConstantPoolName,
                  ConstantPool.GetComponentType,
                  ConstantPool.GetComponentTypeSignature);
}
public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
      // invokevirtual: <enumConstantPoolName>.ordinal()
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: "+new String(enumTypeConstantPoolName)+".ordinal()"); //$NON-NLS-1$ //$NON-NLS-2$
      this.invoke(
                  OPC_invokevirtual,
                  0, // argCount
                  1, // return type size
                  enumTypeConstantPoolName,
                  ConstantPool.Ordinal,
                  ConstantPool.OrdinalSignature);
}
final public void invokeinterface(MethodBinding methodBinding) {
      // initialized to 1 to take into account this  immediately
      if (DEBUG) System.out.println(position + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$
      countLabels = 0;
      int argCount = 1;
      int id;
      if (classFileOffset + 4 >= bCodeStream.length) {
            resizeByteArray();
      }
      position += 3;
      bCodeStream[classFileOffset++] = OPC_invokeinterface;
      writeUnsignedShort(constantPool.literalIndex(methodBinding));
      for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
            if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
                  argCount += 2;
            else
                  argCount += 1;
      bCodeStream[classFileOffset++] = (byte) argCount;
      // Generate a  0 into the byte array. Like the array is already fill with 0, we just need to increment
      // the number of bytes.
      bCodeStream[classFileOffset++] = 0;
      if (((id = methodBinding.returnType.id) == T_double) || (id == T_long)) {
            stackDepth += (2 - argCount);
      } else {
            if (id == T_void) {
                  stackDepth -= argCount;
            } else {
                  stackDepth += (1 - argCount);
            }
      }
      if (stackDepth > stackMax) {
            stackMax = stackDepth;
      }
}
public void invokeJavaLangErrorConstructor() {
      // invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
      if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.Error<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokespecial,
                  1, // argCount
                  0, // return type size
                  ConstantPool.JavaLangErrorConstantPoolName,
                  ConstantPool.Init,
                  ConstantPool.StringConstructorSignature);
}
public void invokeNoClassDefFoundErrorStringConstructor() {
      // invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
      if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokespecial,
                  1, // argCount
                  0, // return type size
                  ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName,
                  ConstantPool.Init,
                  ConstantPool.StringConstructorSignature);
}
public void invokeObjectGetClass() {
      // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokevirtual,
                  0, // argCount
                  1, // return type size
                  ConstantPool.JavaLangObjectConstantPoolName,
                  ConstantPool.GetClass,
                  ConstantPool.GetClassSignature);
}

final public void invokespecial(MethodBinding methodBinding) {
      if (DEBUG) System.out.println(position + "\t\tinvokespecial:"+methodBinding); //$NON-NLS-1$
      // initialized to 1 to take into account this  immediately
      countLabels = 0;
      int argCount = 1;
      int id;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_invokespecial;
      writeUnsignedShort(constantPool.literalIndex(methodBinding));
      if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
            // enclosing instances
            TypeBinding[] syntheticArgumentTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes();
            if (syntheticArgumentTypes != null) {
                  for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
                        if (((id = syntheticArgumentTypes[i].id) == T_double) || (id == T_long)) {
                              argCount += 2;
                        } else {
                              argCount++;
                        }
                  }
            }
            // outer local variables
            SyntheticArgumentBinding[] syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables();
            if (syntheticArguments != null) {
                  for (int i = 0, max = syntheticArguments.length; i < max; i++) {
                        if (((id = syntheticArguments[i].type.id) == T_double) || (id == T_long)) {
                              argCount += 2;
                        } else {
                              argCount++;
                        }
                  }
            }
      }
      for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
            if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
                  argCount += 2;
            else
                  argCount++;
      if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
            stackDepth += (2 - argCount);
      else
            if (id == T_void)
                  stackDepth -= argCount;
            else
                  stackDepth += (1 - argCount);
      if (stackDepth > stackMax)
            stackMax = stackDepth;
}
final public void invokestatic(MethodBinding methodBinding) {
      if (DEBUG) System.out.println(position + "\t\tinvokestatic:"+methodBinding); //$NON-NLS-1$
      // initialized to 0 to take into account that there is no this for
      // a static method
      countLabels = 0;
      int argCount = 0;
      int id;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_invokestatic;
      writeUnsignedShort(constantPool.literalIndex(methodBinding));
      for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
            if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
                  argCount += 2;
            else
                  argCount += 1;
      if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
            stackDepth += (2 - argCount);
      else
            if (id == T_void)
                  stackDepth -= argCount;
            else
                  stackDepth += (1 - argCount);
      if (stackDepth > stackMax)
            stackMax = stackDepth;
}
/**
 * The equivalent code performs a string conversion of the TOS
 * @param typeID <CODE>int</CODE>
 */
public void invokeStringConcatenationAppendForType(int typeID) {
      if (DEBUG) {
            if (this.targetLevel >= JDK1_5) {
                  System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuilder.append(...)"); //$NON-NLS-1$
            } else {
                  System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$
            }
      }
      int argCount = 1;
      int returnType = 1;
      char[] declarinClass = null;
      char[] selector = ConstantPool.Append;
      char[] signature = null;
      switch (typeID) {
            case T_int :
            case T_byte :
            case T_short :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendIntSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendIntSignature;
                  }
                  break;
            case T_long :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendLongSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendLongSignature;
                  }
                  argCount = 2;
                  break;
            case T_float :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendFloatSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendFloatSignature;
                  }
                  break;
            case T_double :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendDoubleSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendDoubleSignature;
                  }
                  argCount = 2;
                  break;
            case T_char :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendCharSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendCharSignature;
                  }
                  break;
            case T_boolean :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendBooleanSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendBooleanSignature;
                  }
                  break;
            case T_undefined :
            case T_JavaLangObject :
            case T_null :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendObjectSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendObjectSignature;
                  }
                  break;
            case T_JavaLangString :
                  if (this.targetLevel >= JDK1_5) {
                        declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
                        signature = ConstantPool.StringBuilderAppendStringSignature;
                  } else {
                        declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
                        signature = ConstantPool.StringBufferAppendStringSignature;
                  }
                  break;
      }
      this.invoke(
                  OPC_invokevirtual,
                  argCount, // argCount
                  returnType, // return type size
                  declarinClass,
                  selector,
                  signature);
}

public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
      // invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
      if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>(typeBindingID)V"); //$NON-NLS-1$
      int argCount = 1;
      char[] signature = null;
      switch (typeBindingID) {
            case T_int :
            case T_byte :
            case T_short :
                  signature = ConstantPool.IntConstrSignature;
                  break;
            case T_long :
                  signature = ConstantPool.LongConstrSignature;
                  argCount = 2;
                  break;
            case T_float :
                  signature = ConstantPool.FloatConstrSignature;
                  break;
            case T_double :
                  signature = ConstantPool.DoubleConstrSignature;
                  argCount = 2;
                  break;
            case T_char :
                  signature = ConstantPool.CharConstrSignature;
                  break;
            case T_boolean :
                  signature = ConstantPool.BooleanConstrSignature;
                  break;
            case T_JavaLangObject :
            case T_JavaLangString :
            case T_null :
                  signature = ConstantPool.ObjectConstrSignature;
                  break;
      }
      this.invoke(
                  OPC_invokespecial,
                  argCount, // argCount
                  0, // return type size
                  ConstantPool.JavaLangAssertionErrorConstantPoolName,
                  ConstantPool.Init,
                  signature);
}

public void invokeJavaLangAssertionErrorDefaultConstructor() {
      // invokespecial: java.lang.AssertionError.<init>()V
      if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>()V"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokespecial,
                  0, // argCount
                  0, // return type size
                  ConstantPool.JavaLangAssertionErrorConstantPoolName,
                  ConstantPool.Init,
                  ConstantPool.DefaultConstructorSignature);
}
public void invokeJavaLangEnumname(TypeBinding typeBinding) {
      // invokevirtual: java.lang.Enum.name()String
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Enum.name()Ljava/lang/String;"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokevirtual,
                  0,
                  1,
                  typeBinding.constantPoolName(),
                  ConstantPool.Name,
                  ConstantPool.NameSignature);
}
public void invokeJavaLangIllegalArgumentExceptionStringConstructor() {
      // invokespecial: java.lang.IllegalArgumentException.<init>(String)V
      if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.IllegalArgumentException.<init>(java.lang.String)V"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokespecial,
                  1, // argCount
                  0, // return type size
                  ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName,
                  ConstantPool.Init,
                  ConstantPool.StringConstructorSignature);
}

public void invokeJavaUtilIteratorHasNext() {
      // invokeinterface java.util.Iterator.hasNext()Z
      if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.hasNext()Z"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokeinterface,
                  0, // argCount
                  1, // return type size
                  ConstantPool.JavaUtilIteratorConstantPoolName,
                  ConstantPool.HasNext,
                  ConstantPool.HasNextSignature);
}
public void invokeJavaUtilIteratorNext() {
      // invokeinterface java.util.Iterator.next()java.lang.Object
      if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.next()java.lang.Object"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokeinterface,
                  0, // argCount
                  1, // return type size
                  ConstantPool.JavaUtilIteratorConstantPoolName,
                  ConstantPool.Next,
                  ConstantPool.NextSignature);
}
public void invokeStringConcatenationDefaultConstructor() {
      // invokespecial: java.lang.StringBuffer.<init>()V
      if (DEBUG) {
            if (this.targetLevel >= JDK1_5) {
                  System.out.println(position + "\t\tinvokespecial: java.lang.StringBuilder.<init>()V"); //$NON-NLS-1$
            } else {
                  System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.<init>()V"); //$NON-NLS-1$
            }
      }
      char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
      if (this.targetLevel >= JDK1_5) {
            declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
      }
      this.invoke(
                  OPC_invokespecial,
                  0, // argCount
                  0, // return type size
                  declaringClass,
                  ConstantPool.Init,
                  ConstantPool.DefaultConstructorSignature);
}
public void invokeStringConcatenationStringConstructor() {
      if (DEBUG) {
            if (this.targetLevel >= JDK1_5) {
                  System.out.println(position + "\t\tjava.lang.StringBuilder.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
            } else {
                  System.out.println(position + "\t\tjava.lang.StringBuffer.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
            }
      }
      char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
      if (this.targetLevel >= JDK1_5) {
            declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
      }
      this.invoke(
                  OPC_invokespecial,
                  1, // argCount
                  0, // return type size
                  declaringClass,
                  ConstantPool.Init,
                  ConstantPool.StringConstructorSignature);
}

public void invokeStringConcatenationToString() {
      if (DEBUG) {
            if (this.targetLevel >= JDK1_5) {
                  System.out.println(position + "\t\tinvokevirtual: StringBuilder.toString()Ljava.lang.String;"); //$NON-NLS-1$
            } else {
                  System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$
            }
      }
      char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
      if (this.targetLevel >= JDK1_5) {
            declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
      }
      this.invoke(
                  OPC_invokevirtual,
                  0, // argCount
                  1, // return type size
                  declaringClass,
                  ConstantPool.ToString,
                  ConstantPool.ToStringSignature);
}
public void invokeStringEquals() {
      // invokevirtual: java.lang.String.equals(java.lang.Object)
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.equals(...)"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokevirtual,
                  1, // argCount
                  1, // return type size
                  ConstantPool.JavaLangStringConstantPoolName,
                  ConstantPool.Equals,
                  ConstantPool.EqualsSignature);
}
public void invokeStringIntern() {
      // invokevirtual: java.lang.String.intern()
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokevirtual,
                  0, // argCount
                  1, // return type size
                  ConstantPool.JavaLangStringConstantPoolName,
                  ConstantPool.Intern,
                  ConstantPool.InternSignature);
}
public void invokeStringValueOf(int typeID) {
      // invokestatic: java.lang.String.valueOf(argumentType)
      if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$
      int argCount = 1;
      char[] signature = null;
      switch (typeID) {
            case T_int :
            case T_byte :
            case T_short :
                  signature = ConstantPool.ValueOfIntSignature;
                  break;
            case T_long :
                  signature = ConstantPool.ValueOfLongSignature;
                  argCount = 2;
                  break;
            case T_float :
                  signature = ConstantPool.ValueOfFloatSignature;
                  break;
            case T_double :
                  signature = ConstantPool.ValueOfDoubleSignature;
                  argCount = 2;
                  break;
            case T_char :
                  signature = ConstantPool.ValueOfCharSignature;
                  break;
            case T_boolean :
                  signature = ConstantPool.ValueOfBooleanSignature;
                  break;
            case T_JavaLangObject :
            case T_JavaLangString :
            case T_null :
            case T_undefined :
                  signature = ConstantPool.ValueOfObjectSignature;
                  break;
      }
      this.invoke(
                  OPC_invokestatic,
                  argCount, // argCount
                  1, // return type size
                  ConstantPool.JavaLangStringConstantPoolName,
                  ConstantPool.ValueOf,
                  signature);
}
public void invokeSystemArraycopy() {
      // invokestatic #21 <Method java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokestatic,
                  5, // argCount
                  0, // return type size
                  ConstantPool.JavaLangSystemConstantPoolName,
                  ConstantPool.ArrayCopy,
                  ConstantPool.ArrayCopySignature);
}
public void invokeThrowableGetMessage() {
      // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$
      this.invoke(
                  OPC_invokevirtual,
                  0, // argCount
                  1, // return type size
                  ConstantPool.JavaLangThrowableConstantPoolName,
                  ConstantPool.GetMessage,
                  ConstantPool.GetMessageSignature);
}
final public void invoke(int opcode, int argsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
      countLabels = 0;
      int argCount = argsSize;
      switch(opcode) {
            case OPC_invokeinterface :
                  if (classFileOffset + 4 >= bCodeStream.length) {
                        resizeByteArray();
                  }
                  position +=3;
                  bCodeStream[classFileOffset++] = OPC_invokeinterface;
                  writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
                  argCount++;
                  bCodeStream[classFileOffset++] = (byte) argCount;
                  bCodeStream[classFileOffset++] = 0;
                  break;
            case OPC_invokevirtual :
            case OPC_invokespecial :
                  if (classFileOffset + 2 >= bCodeStream.length) {
                        resizeByteArray();
                  }
                  position++;
                  bCodeStream[classFileOffset++] = (byte) opcode;
                  writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
                  argCount++;
                  break;
            case OPC_invokestatic :
                  if (classFileOffset + 2 >= bCodeStream.length) {
                        resizeByteArray();
                  }
                  position++;
                  bCodeStream[classFileOffset++] = OPC_invokestatic;
                  writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
      }
      stackDepth += returnTypeSize - argCount;
      if (stackDepth > stackMax) {
            stackMax = stackDepth;
      }
}
final public void invokevirtual(MethodBinding methodBinding) {
      if (DEBUG) System.out.println(position + "\t\tinvokevirtual:"+methodBinding); //$NON-NLS-1$
      // initialized to 1 to take into account this  immediately
      countLabels = 0;
      int argCount = 1;
      int id;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_invokevirtual;
      writeUnsignedShort(constantPool.literalIndex(methodBinding));
      for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
            if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
                  argCount += 2;
            else
                  argCount++;
      if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
            stackDepth += (2 - argCount);
      else
            if (id == T_void)
                  stackDepth -= argCount;
            else
                  stackDepth += (1 - argCount);
      if (stackDepth > stackMax)
            stackMax = stackDepth;
}
final public void ior() {
      if (DEBUG) System.out.println(position + "\t\tior"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ior;
}
final public void irem() {
      if (DEBUG) System.out.println(position + "\t\tirem"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_irem;
}
final public void ireturn() {
      if (DEBUG) System.out.println(position + "\t\tireturn"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      // the stackDepth should be equal to 0 
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ireturn;
}
public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
      // Dependant of UnconditionalFlowInfo.isDefinitelyAssigned(..)
      if (initStateIndex == -1)
            return false;
      if (local.isArgument) {
            return true;
      }
      int localPosition = local.id + maxFieldCount;
      MethodScope methodScope = scope.methodScope();
      // id is zero-based
      if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
            return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 0; // use bits
      }
      // use extra vector
      long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
      if (extraInits == null)
            return false; // if vector not yet allocated, then not initialized
      int vectorIndex;
      if ((vectorIndex = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
            return false; // if not enough room in vector, then not initialized 
      return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
}
final public void ishl() {
      if (DEBUG) System.out.println(position + "\t\tishl"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ishl;
}
final public void ishr() {
      if (DEBUG) System.out.println(position + "\t\tishr"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ishr;
}
final public void istore(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tistore:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= iArg) {
            maxLocals = iArg + 1;
      }
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_istore;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_istore;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void istore_0() {
      if (DEBUG) System.out.println(position + "\t\tistore_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals == 0) {
            maxLocals = 1;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_istore_0;
}
final public void istore_1() {
      if (DEBUG) System.out.println(position + "\t\tistore_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 1) {
            maxLocals = 2;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_istore_1;
}
final public void istore_2() {
      if (DEBUG) System.out.println(position + "\t\tistore_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 2) {
            maxLocals = 3;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_istore_2;
}
final public void istore_3() {
      if (DEBUG) System.out.println(position + "\t\tistore_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (maxLocals <= 3) {
            maxLocals = 4;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_istore_3;
}
final public void isub() {
      if (DEBUG) System.out.println(position + "\t\tisub"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_isub;
}
final public void iushr() {
      if (DEBUG) System.out.println(position + "\t\tiushr"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_iushr;
}
final public void ixor() {
      if (DEBUG) System.out.println(position + "\t\tixor"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ixor;
}
final public void jsr(Label lbl) {
      if (this.wideMode) {
            this.jsr_w(lbl);
            return;
      }
      if (DEBUG) System.out.println(position + "\t\tjsr"+lbl); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_jsr;
      lbl.branch();
}
final public void jsr_w(Label lbl) {
      if (DEBUG) System.out.println(position + "\t\tjsr_w"+lbl); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_jsr_w;
      lbl.branchWide();
}
final public void l2d() {
      if (DEBUG) System.out.println(position + "\t\tl2d"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_l2d;
}
final public void l2f() {
      if (DEBUG) System.out.println(position + "\t\tl2f"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_l2f;
}
final public void l2i() {
      if (DEBUG) System.out.println(position + "\t\tl2i"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_l2i;
}
final public void ladd() {
      if (DEBUG) System.out.println(position + "\t\tladd"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ladd;
}
final public void laload() {
      if (DEBUG) System.out.println(position + "\t\tlaload"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_laload;
}
final public void land() {
      if (DEBUG) System.out.println(position + "\t\tland"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_land;
}
final public void lastore() {
      if (DEBUG) System.out.println(position + "\t\tlastore"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 4;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lastore;
}
final public void lcmp() {
      if (DEBUG) System.out.println(position + "\t\tlcmp"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lcmp;
}
final public void lconst_0() {
      if (DEBUG) System.out.println(position + "\t\tlconst_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lconst_0;
}
final public void lconst_1() {
      if (DEBUG) System.out.println(position + "\t\tlconst_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lconst_1;
}
final public void ldc(float constant) {
      countLabels = 0;
      int index = constantPool.literalIndex(constant);
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (index > 255) {
            if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
            // Generate a ldc_w
            if (classFileOffset + 2 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ldc_w;
            writeUnsignedShort(index);
      } else {
            if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
            // Generate a ldc
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_ldc;
            bCodeStream[classFileOffset++] = (byte) index;
      }
}
final public void ldc(int constant) {
      countLabels = 0;
      int index = constantPool.literalIndex(constant);
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (index > 255) {
            if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
            // Generate a ldc_w
            if (classFileOffset + 2 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ldc_w;
            writeUnsignedShort(index);
      } else {
            if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
            // Generate a ldc
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_ldc;
            bCodeStream[classFileOffset++] = (byte) index;
      }
}
final public void ldc(String constant) {
      countLabels = 0;
      int currentConstantPoolIndex = constantPool.currentIndex;
      int currentConstantPoolOffset = constantPool.currentOffset;
      int currentCodeStreamPosition = position;
      int index = constantPool.literalIndexForLdc(constant.toCharArray());
      if (index > 0) {
            // the string already exists inside the constant pool
            // we reuse the same index
            stackDepth++;
            if (stackDepth > stackMax)
                  stackMax = stackDepth;
            if (index > 255) {
                  if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
                  // Generate a ldc_w
                  if (classFileOffset + 2 >= bCodeStream.length) {
                        resizeByteArray();
                  }
                  position++;
                  bCodeStream[classFileOffset++] = OPC_ldc_w;
                  writeUnsignedShort(index);
            } else {
                  if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
                  // Generate a ldc
                  if (classFileOffset + 1 >= bCodeStream.length) {
                        resizeByteArray();
                  }
                  position += 2;
                  bCodeStream[classFileOffset++] = OPC_ldc;
                  bCodeStream[classFileOffset++] = (byte) index;
            }
      } else {
            // the string is too big to be utf8-encoded in one pass.
            // we have to split it into different pieces.
            // first we clean all side-effects due to the code above
            // this case is very rare, so we can afford to lose time to handle it
            char[] constantChars = constant.toCharArray();
            position = currentCodeStreamPosition;
            constantPool.currentIndex = currentConstantPoolIndex;
            constantPool.currentOffset = currentConstantPoolOffset;
            constantPool.stringCache.remove(constantChars);
            constantPool.UTF8Cache.remove(constantChars);
            int i = 0;
            int length = 0;
            int constantLength = constant.length();
            byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
            int utf8encodingLength = 0;
            while ((length < 65532) && (i < constantLength)) {
                  char current = constantChars[i];
                  // we resize the byte array immediately if necessary
                  if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
                        System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
                  }
                  if ((current >= 0x0001) && (current <= 0x007F)) {
                        // we only need one byte: ASCII table
                        utf8encoding[length++] = (byte) current;
                  } else {
                        if (current > 0x07FF) {
                              // we need 3 bytes
                              utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
                              utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
                              utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
                        } else {
                              // we can be 0 or between 0x0080 and 0x07FF
                              // In that case we only need 2 bytes
                              utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
                              utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
                        }
                  }
                  i++;
            }
            // check if all the string is encoded (PR 1PR2DWJ)
            // the string is too big to be encoded in one pass
            newStringContatenation();
            dup();
            // write the first part
            char[] subChars = new char[i];
            System.arraycopy(constantChars, 0, subChars, 0, i);
            System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
            index = constantPool.literalIndex(subChars, utf8encoding);
            stackDepth++;
            if (stackDepth > stackMax)
                  stackMax = stackDepth;
            if (index > 255) {
                  // Generate a ldc_w
                  if (classFileOffset + 2 >= bCodeStream.length) {
                        resizeByteArray();
                  }
                  position++;
                  bCodeStream[classFileOffset++] = OPC_ldc_w;
                  writeUnsignedShort(index);
            } else {
                  // Generate a ldc
                  if (classFileOffset + 1 >= bCodeStream.length) {
                        resizeByteArray();
                  }
                  position += 2;
                  bCodeStream[classFileOffset++] = OPC_ldc;
                  bCodeStream[classFileOffset++] = (byte) index;
            }
            // write the remaining part
            invokeStringConcatenationStringConstructor();
            while (i < constantLength) {
                  length = 0;
                  utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
                  int startIndex = i;
                  while ((length < 65532) && (i < constantLength)) {
                        char current = constantChars[i];
                        // we resize the byte array immediately if necessary
                        if (constantLength + 2 > (utf8encodingLength = utf8encoding.length)) {
                              System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
                        }
                        if ((current >= 0x0001) && (current <= 0x007F)) {
                              // we only need one byte: ASCII table
                              utf8encoding[length++] = (byte) current;
                        } else {
                              if (current > 0x07FF) {
                                    // we need 3 bytes
                                    utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
                                    utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
                                    utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
                              } else {
                                    // we can be 0 or between 0x0080 and 0x07FF
                                    // In that case we only need 2 bytes
                                    utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
                                    utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
                              }
                        }
                        i++;
                  }
                  // the next part is done
                  subChars = new char[i - startIndex];
                  System.arraycopy(constantChars, startIndex, subChars, 0, i - startIndex);
                  System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
                  index = constantPool.literalIndex(subChars, utf8encoding);
                  stackDepth++;
                  if (stackDepth > stackMax)
                        stackMax = stackDepth;
                  if (index > 255) {
                        // Generate a ldc_w
                        if (classFileOffset + 2 >= bCodeStream.length) {
                              resizeByteArray();
                        }
                        position++;
                        bCodeStream[classFileOffset++] = OPC_ldc_w;
                        writeUnsignedShort(index);
                  } else {
                        // Generate a ldc
                        if (classFileOffset + 1 >= bCodeStream.length) {
                              resizeByteArray();
                        }
                        position += 2;
                        bCodeStream[classFileOffset++] = OPC_ldc;
                        bCodeStream[classFileOffset++] = (byte) index;
                  }
                  // now on the stack it should be a StringBuffer and a string.
                  invokeStringConcatenationAppendForType(T_JavaLangString);
            }
            invokeStringConcatenationToString();
            invokeStringIntern();
      }
}
final public void ldc(TypeBinding typeBinding) {
      countLabels = 0;
      int index = constantPool.literalIndexForType(typeBinding.constantPoolName());
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (index > 255) {
            if (DEBUG) System.out.println(position + "\t\tldc_w:"+ typeBinding); //$NON-NLS-1$
            // Generate a ldc_w
            if (classFileOffset + 2 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = OPC_ldc_w;
            writeUnsignedShort(index);
      } else {
            if (DEBUG) System.out.println(position + "\t\tldw:"+ typeBinding); //$NON-NLS-1$
            // Generate a ldc
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_ldc;
            bCodeStream[classFileOffset++] = (byte) index;
      }
}
final public void ldc2_w(double constant) {
      if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
      countLabels = 0;
      int index = constantPool.literalIndex(constant);
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      // Generate a ldc2_w
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ldc2_w;
      writeUnsignedShort(index);
}
final public void ldc2_w(long constant) {
      if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
      countLabels = 0;
      int index = constantPool.literalIndex(constant);
      stackDepth += 2;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      // Generate a ldc2_w
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ldc2_w;
      writeUnsignedShort(index);
}
final public void ldiv() {
      if (DEBUG) System.out.println(position + "\t\tldiv"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_ldiv;
}
final public void lload(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tlload:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (maxLocals <= iArg + 1) {
            maxLocals = iArg + 2;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_lload;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_lload;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void lload_0() {
      if (DEBUG) System.out.println(position + "\t\tlload_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (maxLocals < 2) {
            maxLocals = 2;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lload_0;
}
final public void lload_1() {
      if (DEBUG) System.out.println(position + "\t\tlload_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (maxLocals < 3) {
            maxLocals = 3;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lload_1;
}
final public void lload_2() {
      if (DEBUG) System.out.println(position + "\t\tlload_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (maxLocals < 4) {
            maxLocals = 4;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lload_2;
}
final public void lload_3() {
      if (DEBUG) System.out.println(position + "\t\tlload_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth += 2;
      if (maxLocals < 5) {
            maxLocals = 5;
      }
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lload_3;
}
final public void lmul() {
      if (DEBUG) System.out.println(position + "\t\tlmul"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lmul;
}
final public void lneg() {
      if (DEBUG) System.out.println(position + "\t\tlneg"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lneg;
}
public final void load(LocalVariableBinding localBinding) {
      countLabels = 0;
      TypeBinding typeBinding = localBinding.type;
      int resolvedPosition = localBinding.resolvedPosition;
      // Using dedicated int bytecode
      if (typeBinding == IntBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.iload_0();
                        break;
                  case 1 :
                        this.iload_1();
                        break;
                  case 2 :
                        this.iload_2();
                        break;
                  case 3 :
                        this.iload_3();
                        break;
                  //case -1 :
                  // internal failure: trying to load variable not supposed to be generated
                  //    break;
                  default :
                        this.iload(resolvedPosition);
            }
            return;
      }
      // Using dedicated float bytecode
      if (typeBinding == FloatBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.fload_0();
                        break;
                  case 1 :
                        this.fload_1();
                        break;
                  case 2 :
                        this.fload_2();
                        break;
                  case 3 :
                        this.fload_3();
                        break;
                  default :
                        this.fload(resolvedPosition);
            }
            return;
      }
      // Using dedicated long bytecode
      if (typeBinding == LongBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.lload_0();
                        break;
                  case 1 :
                        this.lload_1();
                        break;
                  case 2 :
                        this.lload_2();
                        break;
                  case 3 :
                        this.lload_3();
                        break;
                  default :
                        this.lload(resolvedPosition);
            }
            return;
      }
      // Using dedicated double bytecode
      if (typeBinding == DoubleBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.dload_0();
                        break;
                  case 1 :
                        this.dload_1();
                        break;
                  case 2 :
                        this.dload_2();
                        break;
                  case 3 :
                        this.dload_3();
                        break;
                  default :
                        this.dload(resolvedPosition);
            }
            return;
      }
      // boolean, byte, char and short are handled as int
      if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
            switch (resolvedPosition) {
                  case 0 :
                        this.iload_0();
                        break;
                  case 1 :
                        this.iload_1();
                        break;
                  case 2 :
                        this.iload_2();
                        break;
                  case 3 :
                        this.iload_3();
                        break;
                  default :
                        this.iload(resolvedPosition);
            }
            return;
      }

      // Reference object
      switch (resolvedPosition) {
            case 0 :
                  this.aload_0();
                  break;
            case 1 :
                  this.aload_1();
                  break;
            case 2 :
                  this.aload_2();
                  break;
            case 3 :
                  this.aload_3();
                  break;
            default :
                  this.aload(resolvedPosition);
      }
}
public final void load(TypeBinding typeBinding, int resolvedPosition) {
      countLabels = 0;
      // Using dedicated int bytecode
      if (typeBinding == IntBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.iload_0();
                        break;
                  case 1 :
                        this.iload_1();
                        break;
                  case 2 :
                        this.iload_2();
                        break;
                  case 3 :
                        this.iload_3();
                        break;
                  default :
                        this.iload(resolvedPosition);
            }
            return;
      }
      // Using dedicated float bytecode
      if (typeBinding == FloatBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.fload_0();
                        break;
                  case 1 :
                        this.fload_1();
                        break;
                  case 2 :
                        this.fload_2();
                        break;
                  case 3 :
                        this.fload_3();
                        break;
                  default :
                        this.fload(resolvedPosition);
            }
            return;
      }
      // Using dedicated long bytecode
      if (typeBinding == LongBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.lload_0();
                        break;
                  case 1 :
                        this.lload_1();
                        break;
                  case 2 :
                        this.lload_2();
                        break;
                  case 3 :
                        this.lload_3();
                        break;
                  default :
                        this.lload(resolvedPosition);
            }
            return;
      }
      // Using dedicated double bytecode
      if (typeBinding == DoubleBinding) {
            switch (resolvedPosition) {
                  case 0 :
                        this.dload_0();
                        break;
                  case 1 :
                        this.dload_1();
                        break;
                  case 2 :
                        this.dload_2();
                        break;
                  case 3 :
                        this.dload_3();
                        break;
                  default :
                        this.dload(resolvedPosition);
            }
            return;
      }
      // boolean, byte, char and short are handled as int
      if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
            switch (resolvedPosition) {
                  case 0 :
                        this.iload_0();
                        break;
                  case 1 :
                        this.iload_1();
                        break;
                  case 2 :
                        this.iload_2();
                        break;
                  case 3 :
                        this.iload_3();
                        break;
                  default :
                        this.iload(resolvedPosition);
            }
            return;
      }

      // Reference object
      switch (resolvedPosition) {
            case 0 :
                  this.aload_0();
                  break;
            case 1 :
                  this.aload_1();
                  break;
            case 2 :
                  this.aload_2();
                  break;
            case 3 :
                  this.aload_3();
                  break;
            default :
                  this.aload(resolvedPosition);
      }
}
public final void loadInt(int resolvedPosition) {
      // Using dedicated int bytecode
      switch (resolvedPosition) {
            case 0 :
                  this.iload_0();
                  break;
            case 1 :
                  this.iload_1();
                  break;
            case 2 :
                  this.iload_2();
                  break;
            case 3 :
                  this.iload_3();
                  break;
            default :
                  this.iload(resolvedPosition);
      }
}
public final void loadObject(int resolvedPosition) {
      switch (resolvedPosition) {
            case 0 :
                  this.aload_0();
                  break;
            case 1 :
                  this.aload_1();
                  break;
            case 2 :
                  this.aload_2();
                  break;
            case 3 :
                  this.aload_3();
                  break;
            default :
                  this.aload(resolvedPosition);
      }
}
final public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
      if (DEBUG) System.out.println(position + "\t\tlookupswitch"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      int length = keys.length;
      int pos = position;
      defaultLabel.placeInstruction();
      for (int i = 0; i < length; i++) {
            casesLabel[i].placeInstruction();
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lookupswitch;
      for (int i = (3 - (pos % 4)); i > 0; i--) {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = 0;
      }
      defaultLabel.branch();
      writeSignedWord(length);
      for (int i = 0; i < length; i++) {
            writeSignedWord(keys[sortedIndexes[i]]);
            casesLabel[sortedIndexes[i]].branch();
      }
}
final public void lor() {
      if (DEBUG) System.out.println(position + "\t\tlor"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lor;
}
final public void lrem() {
      if (DEBUG) System.out.println(position + "\t\tlrem"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lrem;
}
final public void lreturn() {
      if (DEBUG) System.out.println(position + "\t\tlreturn"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      // the stackDepth should be equal to 0 
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lreturn;
}
final public void lshl() {
      if (DEBUG) System.out.println(position + "\t\tlshl"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lshl;
}
final public void lshr() {
      if (DEBUG) System.out.println(position + "\t\tlshr"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lshr;
}
final public void lstore(int iArg) {
      if (DEBUG) System.out.println(position + "\t\tlstore:"+iArg); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals <= iArg + 1) {
            maxLocals = iArg + 2;
      }
      if (iArg > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_lstore;
            writeUnsignedShort(iArg);
      } else {
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_lstore;
            bCodeStream[classFileOffset++] = (byte) iArg;
      }
}
final public void lstore_0() {
      if (DEBUG) System.out.println(position + "\t\tlstore_0"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 2) {
            maxLocals = 2;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lstore_0;
}
final public void lstore_1() {
      if (DEBUG) System.out.println(position + "\t\tlstore_1"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 3) {
            maxLocals = 3;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lstore_1;
}
final public void lstore_2() {
      if (DEBUG) System.out.println(position + "\t\tlstore_2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 4) {
            maxLocals = 4;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lstore_2;
}
final public void lstore_3() {
      if (DEBUG) System.out.println(position + "\t\tlstore_3"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (maxLocals < 5) {
            maxLocals = 5;
      }
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lstore_3;
}
final public void lsub() {
      if (DEBUG) System.out.println(position + "\t\tlsub"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lsub;
}
final public void lushr() {
      if (DEBUG) System.out.println(position + "\t\tlushr"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lushr;
}
final public void lxor() {
      if (DEBUG) System.out.println(position + "\t\tlxor"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_lxor;
}
final public void monitorenter() {
      if (DEBUG) System.out.println(position + "\t\tmonitorenter"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_monitorenter;
}
final public void monitorexit() {
      if (DEBUG) System.out.println(position + "\t\tmonitorexit"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_monitorexit;
}
final public void multianewarray(TypeBinding typeBinding, int dimensions) {
      if (DEBUG) System.out.println(position + "\t\tmultinewarray:"+typeBinding+","+dimensions); //$NON-NLS-1$ //$NON-NLS-2$
      countLabels = 0;
      stackDepth += (1 - dimensions);
      if (classFileOffset + 3 >= bCodeStream.length) {
            resizeByteArray();
      }
      position += 2;
      bCodeStream[classFileOffset++] = OPC_multianewarray;
      writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
      bCodeStream[classFileOffset++] = (byte) dimensions;
}
/**
 * We didn't call it new, because there is a conflit with the new keyword
 */
final public void new_(TypeBinding typeBinding) {
      if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding.debugName()); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_new;
      writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
}
final public void newarray(int array_Type) {
      if (DEBUG) System.out.println(position + "\t\tnewarray:"+array_Type); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset + 1 >= bCodeStream.length) {
            resizeByteArray();
      }
      position += 2;
      bCodeStream[classFileOffset++] = OPC_newarray;
      bCodeStream[classFileOffset++] = (byte) array_Type;
}
public void newArray(ArrayBinding arrayBinding) {
      TypeBinding component = arrayBinding.elementsType();
      switch (component.id) {
            case T_int :
                  this.newarray(INT_ARRAY);
                  break;
            case T_byte :
                  this.newarray(BYTE_ARRAY);
                  break;
            case T_boolean :
                  this.newarray(BOOLEAN_ARRAY);
                  break;
            case T_short :
                  this.newarray(SHORT_ARRAY);
                  break;
            case T_char :
                  this.newarray(CHAR_ARRAY);
                  break;
            case T_long :
                  this.newarray(LONG_ARRAY);
                  break;
            case T_float :
                  this.newarray(FLOAT_ARRAY);
                  break;
            case T_double :
                  this.newarray(DOUBLE_ARRAY);
                  break;
            default :
                  this.anewarray(component);
      }
}
public void newJavaLangError() {
      // new: java.lang.Error
      if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Error"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_new;
      writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
}

public void newJavaLangAssertionError() {
      // new: java.lang.AssertionError
      if (DEBUG) System.out.println(position + "\t\tnew: java.lang.AssertionError"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_new;
      writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName));
}
public void newJavaLangIllegalArgumentException() {
      // new: java.lang.IllegalArgumentException
      if (DEBUG) System.out.println(position + "\t\tnew: java.lang.IllegalArgumentException"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_new;
      writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName));
}
public void newNoClassDefFoundError() {
      // new: java.lang.NoClassDefFoundError
      if (DEBUG) System.out.println(position + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_new;
      writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName));
}
public void newStringContatenation() {
      // new: java.lang.StringBuffer
      // new: java.lang.StringBuilder
      if (DEBUG) {
            if (this.targetLevel >= JDK1_5) {
                  System.out.println(position + "\t\tnew: java.lang.StringBuilder"); //$NON-NLS-1$
            } else {
                  System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$
            }
      }
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax) {
            stackMax = stackDepth;
      }
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_new;
      if (this.targetLevel >= JDK1_5) {
            writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName));
      } else {
            writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName));
      }
}
public void newWrapperFor(int typeID) {
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset + 2 >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_new;
      switch (typeID) {
            case T_int : // new: java.lang.Integer
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
                  break;
            case T_boolean : // new: java.lang.Boolean
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
                  break;
            case T_byte : // new: java.lang.Byte
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
                  break;
            case T_char : // new: java.lang.Character
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Character"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
                  break;
            case T_float : // new: java.lang.Float
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Float"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
                  break;
            case T_double : // new: java.lang.Double
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Double"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
                  break;
            case T_short : // new: java.lang.Short
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Short"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
                  break;
            case T_long : // new: java.lang.Long
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
                  break;
            case T_void : // new: java.lang.Void
                  if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$
                  writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName));
      }
}
final public void nop() {
      if (DEBUG) System.out.println(position + "\t\tnop"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_nop;
}
final public void pop() {
      if (DEBUG) System.out.println(position + "\t\tpop"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_pop;
}
final public void pop2() {
      if (DEBUG) System.out.println(position + "\t\tpop2"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 2;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_pop2;
}
final public void putfield(FieldBinding fieldBinding) {
      if (DEBUG) System.out.println(position + "\t\tputfield:"+fieldBinding); //$NON-NLS-1$
      int returnTypeSize = 1;
      if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
            returnTypeSize = 2;
      }
      generateFieldAccess(
                  OPC_putfield,
                  returnTypeSize,
                  fieldBinding.declaringClass.constantPoolName(),
                  fieldBinding.name,
                  fieldBinding.type.signature());
}
final public void putstatic(FieldBinding fieldBinding) {
      if (DEBUG) System.out.println(position + "\t\tputstatic:"+fieldBinding); //$NON-NLS-1$
      int returnTypeSize = 1;
      if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
            returnTypeSize = 2;
      }
      generateFieldAccess(
                  OPC_putstatic,
                  returnTypeSize,
                  fieldBinding.declaringClass.constantPoolName(),
                  fieldBinding.name,
                  fieldBinding.type.signature());
}
public void record(LocalVariableBinding local) {
      if (!generateLocalVariableTableAttributes)
            return;
      if (allLocalsCounter == locals.length) {
            // resize the collection
            System.arraycopy(locals, 0, locals = new LocalVariableBinding[allLocalsCounter + LOCALS_INCREMENT], 0, allLocalsCounter);
      }
      locals[allLocalsCounter++] = local;
      local.initializationPCs = new int[4];
      local.initializationCount = 0;
}
public void recordPositionsFrom(int startPC, int sourcePos) {

      /* Record positions in the table, only if nothing has 
       * already been recorded. Since we output them on the way 
       * up (children first for more specific info)
       * The pcToSourceMap table is always sorted.
       */

      if (!generateLineNumberAttributes)
            return;
      if (sourcePos == 0)
            return;

      // no code generated for this node. e.g. field without any initialization
      if (position == startPC)
            return;

      // Widening an existing entry that already has the same source positions
      if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
            // resize the array pcToSourceMap
            System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
      }
      int newLine = ClassFile.searchLineNumber(lineSeparatorPositions, sourcePos);
      // lastEntryPC represents the endPC of the lastEntry.
      if (pcToSourceMapSize > 0) {
            // in this case there is already an entry in the table
            if (pcToSourceMap[pcToSourceMapSize - 1] != newLine) {
                  if (startPC < lastEntryPC) {
                        // we forgot to add an entry.
                        // search if an existing entry exists for startPC
                        int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
                        if (insertionIndex != -1) {
                              // there is no existing entry starting with startPC.
                              int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, newLine); // index for PC
                              /* the existingEntryIndex corresponds to en entry with the same line and a PC >= startPC.
                                    in this case it is relevant to widen this entry instead of creating a new one.
                                    line1: this(a,
                                      b,
                                      c);
                                    with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
                                    aload0 bytecode. The first entry is the one for the argument a.
                                    But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
                                    So we widen the existing entry (if there is one) or we create a new entry with the startPC.
                              */
                              if (existingEntryIndex != -1) {
                                    // widen existing entry
                                    pcToSourceMap[existingEntryIndex] = startPC;
                              } else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != newLine) {
                                    // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
                                    System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
                                    pcToSourceMap[insertionIndex++] = startPC;
                                    pcToSourceMap[insertionIndex] = newLine;
                                    pcToSourceMapSize += 2;
                              }
                        } else if (position != lastEntryPC) { // no bytecode since last entry pc
                              pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
                              pcToSourceMap[pcToSourceMapSize++] = newLine;
                        }
                  } else {
                        // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
                        pcToSourceMap[pcToSourceMapSize++] = startPC;
                        pcToSourceMap[pcToSourceMapSize++] = newLine;
                  }
            } else {
                  /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
                     we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
                  */    
                  if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
                        int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
                        if (insertionIndex != -1) {
                              // widen the existing entry
                              // we have to figure out if we need to move the last entry at another location to keep a sorted table
                              /* First we need to check if at the insertion position there is not an existing entry
                               * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
                               * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
                               * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
                               */
                              if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == newLine))) {
                                    if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
                                          System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
                                          pcToSourceMap[insertionIndex++] = startPC;
                                          pcToSourceMap[insertionIndex] = newLine;                                
                                    } else {
                                          pcToSourceMap[pcToSourceMapSize - 2] = startPC;
                                    }
                              }
                        }
                  }
            }
            lastEntryPC = position;
      } else {
            // record the first entry
            pcToSourceMap[pcToSourceMapSize++] = startPC;
            pcToSourceMap[pcToSourceMapSize++] = newLine;
            lastEntryPC = position;
      }
}
/**
 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
 */
public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
      int length;
      if (exceptionHandlersIndex >= (length = exceptionHandlers.length)) {
            // resize the exception handlers table
            System.arraycopy(exceptionHandlers, 0, exceptionHandlers = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
      }
      // no need to resize. So just add the new exception label
      exceptionHandlers[exceptionHandlersIndex++] = anExceptionLabel;
      exceptionHandlersCounter++;
}
public void removeExceptionHandler(ExceptionLabel exceptionLabel) {
      for (int i = 0; i < exceptionHandlersIndex; i++) {
            if (exceptionHandlers[i] == exceptionLabel) {
                  exceptionHandlers[i] = null;
                  exceptionHandlersCounter--;
                  return;
            }
      }
}
public final void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
      // given some flow info, make sure we did not loose some variables initialization
      // if this happens, then we must update their pc entries to reflect it in debug attributes
      if (!generateLocalVariableTableAttributes)
            return;
/*    if (initStateIndex == lastInitStateIndexWhenRemovingInits)
            return;
            
      lastInitStateIndexWhenRemovingInits = initStateIndex;
      if (lastInitStateIndexWhenAddingInits != initStateIndex){
            lastInitStateIndexWhenAddingInits = -2;// reinitialize add index 
            // add(1)-remove(1)-add(1) -> ignore second add
            // add(1)-remove(2)-add(1) -> perform second add
      }*/
      for (int i = 0; i < visibleLocalsCount; i++) {
            LocalVariableBinding localBinding = visibleLocals[i];
            if (localBinding != null) {
                  if (initStateIndex == -1 || !isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
                        if (localBinding.initializationCount > 0) {
                              localBinding.recordInitializationEndPC(position);
                        }
                  }
            }
      }
}
/**
 * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
 * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
 */
public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
      init(targetClassFile);
      this.methodDeclaration = referenceMethod;
      this.preserveUnusedLocals = referenceMethod.scope.compilerOptions().preserveAllLocalVariables;
      initializeMaxLocals(referenceMethod.binding);
}
/**
 * @param targetClassFile The given classfile to reset the code stream
 */
public void resetForProblemClinit(ClassFile targetClassFile) {
      init(targetClassFile);
      maxLocals = 0;
}
private final void resizeByteArray() {
      int length = bCodeStream.length;
      int requiredSize = length + length;
      if (classFileOffset >= requiredSize) {
            // must be sure to grow enough
            requiredSize = classFileOffset + length;
      }
      System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length);
}
final public void ret(int index) {
      if (DEBUG) System.out.println(position + "\t\tret:"+index); //$NON-NLS-1$
      countLabels = 0;
      if (index > 255) { // Widen
            if (classFileOffset + 3 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_wide;
            bCodeStream[classFileOffset++] = OPC_ret;
            writeUnsignedShort(index);
      } else { // Don't Widen
            if (classFileOffset + 1 >= bCodeStream.length) {
                  resizeByteArray();
            }
            position += 2;
            bCodeStream[classFileOffset++] = OPC_ret;
            bCodeStream[classFileOffset++] = (byte) index;
      }
}
final public void return_() {
      if (DEBUG) System.out.println(position + "\t\treturn"); //$NON-NLS-1$
      countLabels = 0;
      // the stackDepth should be equal to 0 
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_return;
}
final public void saload() {
      if (DEBUG) System.out.println(position + "\t\tsaload"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_saload;
}
final public void sastore() {
      if (DEBUG) System.out.println(position + "\t\tsastore"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth -= 3;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_sastore;
}
/**
 * @param operatorConstant int
 * @param type_ID int
 */
public void sendOperator(int operatorConstant, int type_ID) {
      switch (type_ID) {
            case T_int :
            case T_boolean :
            case T_char :
            case T_byte :
            case T_short :
                  switch (operatorConstant) {
                        case PLUS :
                              this.iadd();
                              break;
                        case MINUS :
                              this.isub();
                              break;
                        case MULTIPLY :
                              this.imul();
                              break;
                        case DIVIDE :
                              this.idiv();
                              break;
                        case REMAINDER :
                              this.irem();
                              break;
                        case LEFT_SHIFT :
                              this.ishl();
                              break;
                        case RIGHT_SHIFT :
                              this.ishr();
                              break;
                        case UNSIGNED_RIGHT_SHIFT :
                              this.iushr();
                              break;
                        case AND :
                              this.iand();
                              break;
                        case OR :
                              this.ior();
                              break;
                        case XOR :
                              this.ixor();
                              break;
                  }
                  break;
            case T_long :
                  switch (operatorConstant) {
                        case PLUS :
                              this.ladd();
                              break;
                        case MINUS :
                              this.lsub();
                              break;
                        case MULTIPLY :
                              this.lmul();
                              break;
                        case DIVIDE :
                              this.ldiv();
                              break;
                        case REMAINDER :
                              this.lrem();
                              break;
                        case LEFT_SHIFT :
                              this.lshl();
                              break;
                        case RIGHT_SHIFT :
                              this.lshr();
                              break;
                        case UNSIGNED_RIGHT_SHIFT :
                              this.lushr();
                              break;
                        case AND :
                              this.land();
                              break;
                        case OR :
                              this.lor();
                              break;
                        case XOR :
                              this.lxor();
                              break;
                  }
                  break;
            case T_float :
                  switch (operatorConstant) {
                        case PLUS :
                              this.fadd();
                              break;
                        case MINUS :
                              this.fsub();
                              break;
                        case MULTIPLY :
                              this.fmul();
                              break;
                        case DIVIDE :
                              this.fdiv();
                              break;
                        case REMAINDER :
                              this.frem();
                  }
                  break;
            case T_double :
                  switch (operatorConstant) {
                        case PLUS :
                              this.dadd();
                              break;
                        case MINUS :
                              this.dsub();
                              break;
                        case MULTIPLY :
                              this.dmul();
                              break;
                        case DIVIDE :
                              this.ddiv();
                              break;
                        case REMAINDER :
                              this.drem();
                  }
      }
}
final public void sipush(int s) {
      if (DEBUG) System.out.println(position + "\t\tsipush:"+s); //$NON-NLS-1$
      countLabels = 0;
      stackDepth++;
      if (stackDepth > stackMax)
            stackMax = stackDepth;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_sipush;
      writeSignedShort(s);
}
public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
      int lo = lo0;
      int hi = hi0;
      int mid;
      if (hi0 > lo0) {
            /* Arbitrarily establishing partition element as the midpoint of
              * the array.
              */
            mid = tab[ (lo0 + hi0) / 2];
            // loop through the array until indices cross
            while (lo <= hi) {
                  /* find the first element that is greater than or equal to 
                   * the partition element starting from the left Index.
                   */
                  while ((lo < hi0) && (tab[lo] < mid))
                        ++lo;
                  /* find an element that is smaller than or equal to 
                   * the partition element starting from the right Index.
                   */
                  while ((hi > lo0) && (tab[hi] > mid))
                        --hi;
                  // if the indexes have not crossed, swap
                  if (lo <= hi) {
                        swap(tab, lo, hi, result);
                        ++lo;
                        --hi;
                  }
            }
            /* If the right index has not reached the left side of array
              * must now sort the left partition.
              */
            if (lo0 < hi)
                  sort(tab, lo0, hi, result);
            /* If the left index has not reached the right side of array
              * must now sort the right partition.
              */
            if (lo < hi0)
                  sort(tab, lo, hi0, result);
      }
}

public final void store(LocalVariableBinding localBinding, boolean valueRequired) {
      int localPosition = localBinding.resolvedPosition;
      // Using dedicated int bytecode
      switch(localBinding.type.id) {
            case TypeIds.T_int :
            case TypeIds.T_char :
            case TypeIds.T_byte :
            case TypeIds.T_short :
            case TypeIds.T_boolean :
                  if (valueRequired)
                        this.dup();
                  switch (localPosition) {
                        case 0 :
                              this.istore_0();
                              break;
                        case 1 :
                              this.istore_1();
                              break;
                        case 2 :
                              this.istore_2();
                              break;
                        case 3 :
                              this.istore_3();
                              break;
                        //case -1 :
                        // internal failure: trying to store into variable not supposed to be generated
                        //    break;
                        default :
                              this.istore(localPosition);
                  }
                  break;
            case TypeIds.T_float :
                  if (valueRequired)
                        this.dup();
                  switch (localPosition) {
                        case 0 :
                              this.fstore_0();
                              break;
                        case 1 :
                              this.fstore_1();
                              break;
                        case 2 :
                              this.fstore_2();
                              break;
                        case 3 :
                              this.fstore_3();
                              break;
                        default :
                              this.fstore(localPosition);
                  }
                  break;
            case TypeIds.T_double :
                  if (valueRequired)
                        this.dup2();
                  switch (localPosition) {
                        case 0 :
                              this.dstore_0();
                              break;
                        case 1 :
                              this.dstore_1();
                              break;
                        case 2 :
                              this.dstore_2();
                              break;
                        case 3 :
                              this.dstore_3();
                              break;
                        default :
                              this.dstore(localPosition);
                  }
                  break;
            case TypeIds.T_long :
                  if (valueRequired)
                        this.dup2();
                  switch (localPosition) {
                        case 0 :
                              this.lstore_0();
                              break;
                        case 1 :
                              this.lstore_1();
                              break;
                        case 2 :
                              this.lstore_2();
                              break;
                        case 3 :
                              this.lstore_3();
                              break;
                        default :
                              this.lstore(localPosition);
                  }
                  break;
            default:
                  // Reference object
                  if (valueRequired)
                        this.dup();
                  switch (localPosition) {
                        case 0 :
                              this.astore_0();
                              break;
                        case 1 :
                              this.astore_1();
                              break;
                        case 2 :
                              this.astore_2();
                              break;
                        case 3 :
                              this.astore_3();
                              break;
                        default :
                              this.astore(localPosition);
                  }
      }
}
public final void store(TypeBinding type, int localPosition) {
      // Using dedicated int bytecode
      if ((type == IntBinding) || (type == CharBinding) || (type == ByteBinding) || (type == ShortBinding) || (type == BooleanBinding)) {
            switch (localPosition) {
                  case 0 :
                        this.istore_0();
                        break;
                  case 1 :
                        this.istore_1();
                        break;
                  case 2 :
                        this.istore_2();
                        break;
                  case 3 :
                        this.istore_3();
                        break;
                  default :
                        this.istore(localPosition);
            }
            return;
      }
      // Using dedicated float bytecode
      if (type == FloatBinding) {
            switch (localPosition) {
                  case 0 :
                        this.fstore_0();
                        break;
                  case 1 :
                        this.fstore_1();
                        break;
                  case 2 :
                        this.fstore_2();
                        break;
                  case 3 :
                        this.fstore_3();
                        break;
                  default :
                        this.fstore(localPosition);
            }
            return;
      }
      // Using dedicated long bytecode
      if (type == LongBinding) {
            switch (localPosition) {
                  case 0 :
                        this.lstore_0();
                        break;
                  case 1 :
                        this.lstore_1();
                        break;
                  case 2 :
                        this.lstore_2();
                        break;
                  case 3 :
                        this.lstore_3();
                        break;
                  default :
                        this.lstore(localPosition);
            }
            return;
      }
      // Using dedicated double bytecode
      if (type == DoubleBinding) {
            switch (localPosition) {
                  case 0 :
                        this.dstore_0();
                        break;
                  case 1 :
                        this.dstore_1();
                        break;
                  case 2 :
                        this.dstore_2();
                        break;
                  case 3 :
                        this.dstore_3();
                        break;
                  default :
                        this.dstore(localPosition);
            }
            return;
      }
      // Reference object
      switch (localPosition) {
            case 0 :
                  this.astore_0();
                  break;
            case 1 :
                  this.astore_1();
                  break;
            case 2 :
                  this.astore_2();
                  break;
            case 3 :
                  this.astore_3();
                  break;
            default :
                  this.astore(localPosition);
      }
}
public final void storeInt(int localPosition) {
      switch (localPosition) {
            case 0 :
                  this.istore_0();
                  break;
            case 1 :
                  this.istore_1();
                  break;
            case 2 :
                  this.istore_2();
                  break;
            case 3 :
                  this.istore_3();
                  break;
            default :
                  this.istore(localPosition);
      }
}
public final void storeObject(int localPosition) {
      switch (localPosition) {
            case 0 :
                  this.astore_0();
                  break;
            case 1 :
                  this.astore_1();
                  break;
            case 2 :
                  this.astore_2();
                  break;
            case 3 :
                  this.astore_3();
                  break;
            default :
                  this.astore(localPosition);
      }
}
final public void swap() {
      if (DEBUG) System.out.println(position + "\t\tswap"); //$NON-NLS-1$
      countLabels = 0;
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_swap;
}
private static final void swap(int a[], int i, int j, int result[]) {
      int T;
      T = a[i];
      a[i] = a[j];
      a[j] = T;
      T = result[j];
      result[j] = result[i];
      result[i] = T;
}
final public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
      if (DEBUG) System.out.println(position + "\t\ttableswitch"); //$NON-NLS-1$
      countLabels = 0;
      stackDepth--;
      int length = casesLabel.length;
      int pos = position;
      defaultLabel.placeInstruction();
      for (int i = 0; i < length; i++)
            casesLabel[i].placeInstruction();
      if (classFileOffset >= bCodeStream.length) {
            resizeByteArray();
      }
      position++;
      bCodeStream[classFileOffset++] = OPC_tableswitch;
      for (int i = (3 - (pos % 4)); i > 0; i--) {
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = 0;
      }
      defaultLabel.branch();
      writeSignedWord(low);
      writeSignedWord(high);
      int i = low, j = low;
      // the index j is used to know if the index i is one of the missing entries in case of an 
      // optimized tableswitch
      while (true) {
            int index;
            int key = keys[index = sortedIndexes[j - low]];
            if (key == i) {
                  casesLabel[index].branch();
                  j++;
                  if (i == high) break; // if high is maxint, then avoids wrapping to minint.
            } else {
                  defaultLabel.branch();
            }
            i++;
      }
}
public String toString() {
      StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
      buffer.append(position);
      buffer.append(",\nstackDepth:"); //$NON-NLS-1$
      buffer.append(stackDepth);
      buffer.append(",\nmaxStack:"); //$NON-NLS-1$
      buffer.append(stackMax);
      buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
      buffer.append(maxLocals);
      buffer.append(")"); //$NON-NLS-1$
      return buffer.toString();
}
/**
 * Note: it will walk the locals table and extend the end range for all matching ones, no matter if
 * visible or not.
 * {  int i = 0;
 *    {  int j = 1; }
 * }   <== would process both 'i' and 'j'
 * Processing non-visible ones is mandated in some cases (include goto instruction after if-then block)
 */
public void updateLastRecordedEndPC(Scope scope, int pos) {

      /* Tune positions in the table, this is due to some 
       * extra bytecodes being
       * added to some user code (jumps). */
      /** OLD CODE
            if (!generateLineNumberAttributes)
                  return;
            pcToSourceMap[pcToSourceMapSize - 1][1] = position;
            // need to update the initialization endPC in case of generation of local variable attributes.
            updateLocalVariablesAttribute(pos); 
      */    

      if (!generateLineNumberAttributes)
            return;
      this.lastEntryPC = pos;
      // need to update the initialization endPC in case of generation of local variable attributes.
      if (this.generateLocalVariableTableAttributes) {
            for (int i = 0, max = this.locals.length; i < max; i++) {
                  LocalVariableBinding local = this.locals[i];
                  if (local != null && local.declaringScope == scope && local.initializationCount > 0) {
                        if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
                              local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = this.position;
                        }
                  }
            }
      }
}

/**
 * Write a signed 16 bits value into the byte array
 * @param value the signed short
 */
public final void writeSignedShort(int value) {
      // we keep the resize in here because it is used outside the code stream
      if (classFileOffset + 1 >= bCodeStream.length) {
            resizeByteArray();
      }
      position += 2;
      bCodeStream[classFileOffset++] = (byte) (value >> 8);
      bCodeStream[classFileOffset++] = (byte) value;
}
public final void writeSignedShort(int pos, int value) {
      int currentOffset = startingClassFileOffset + pos;
      if (currentOffset + 1 >= bCodeStream.length) {
            resizeByteArray();
      }
      bCodeStream[currentOffset] = (byte) (value >> 8);
      bCodeStream[currentOffset + 1] = (byte) value;
}
public final void writeSignedWord(int value) {
      // we keep the resize in here because it is used outside the code stream
      if (classFileOffset + 3 >= bCodeStream.length) {
            resizeByteArray();
      }
      position += 4;
      bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
      bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
      bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
      bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
}
public final void writeSignedWord(int pos, int value) {
      int currentOffset = startingClassFileOffset + pos;
      if (currentOffset + 4 >= bCodeStream.length) {
            resizeByteArray();
      }
      bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
      bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
      bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
      bCodeStream[currentOffset++] = (byte) (value & 0xFF);
}
/**
 * Write a unsigned 16 bits value into the byte array
 * @param value the unsigned short
 */
protected final void writeUnsignedShort(int value) {
      position += 2;
      bCodeStream[classFileOffset++] = (byte) (value >>> 8);
      bCodeStream[classFileOffset++] = (byte) value;
}
/*
 * Wide conditional branch compare, improved by swapping comparison opcode
 *   ifeq WideTarget
 * becomes
 *    ifne Intermediate
 *    gotow WideTarget
 *    Intermediate:
 */
public void generateWideRevertedConditionalBranch(byte revertedOpcode, Label wideTarget) {
            Label intermediate = new Label(this);
            if (classFileOffset >= bCodeStream.length) {
                  resizeByteArray();
            }
            position++;
            bCodeStream[classFileOffset++] = revertedOpcode;
            intermediate.branch();
            this.goto_w(wideTarget);
            intermediate.place();
}
}

Generated by  Doxygen 1.6.0   Back to index