0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.codegen;
0011:
0012: import org.eclipse.jdt.core.compiler.CharOperation;
0013: import org.eclipse.jdt.internal.compiler.ClassFile;
0014: import org.eclipse.jdt.internal.compiler.CompilationResult;
0015: import org.eclipse.jdt.internal.compiler.ast.ASTNode;
0016: import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
0017: import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
0018: import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
0019: import org.eclipse.jdt.internal.compiler.ast.Expression;
0020: import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
0021: import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
0022: import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
0023: import org.eclipse.jdt.internal.compiler.impl.Constant;
0024: import org.eclipse.jdt.internal.compiler.lookup.*;
0025: import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
0026: import org.eclipse.jdt.internal.compiler.util.Util;
0027:
0028: public class CodeStream {
0029: public static final boolean DEBUG = false;
0030:
0031: // It will be responsible for the following items.
0032: // -> Tracking Max Stack.
0033:
0034: public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
0035: public static final int LABELS_INCREMENT = 5;
0036: // local variable attributes output
0037: public static final int LOCALS_INCREMENT = 10;
0038: static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
0039: static BranchLabel[] noLabels = new BranchLabel[LABELS_INCREMENT];
0040: static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
0041: static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
0042: public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult(
0043: (char[]) null, 0, 0, 0);
0044:
0045: /**
0046: * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
0047: * If there is an existing entry it returns -1 (no insertion required).
0048: * Otherwise it returns the index where the entry for the pc has to be inserted.
0049: * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
0050: *
0051: * @param pcToSourceMap the given pcToSourceMap array
0052: * @param length the given length
0053: * @param pc the given pc
0054: * @return int
0055: */
0056: public static int insertionIndex(int[] pcToSourceMap, int length,
0057: int pc) {
0058: int g = 0;
0059: int d = length - 2;
0060: int m = 0;
0061: while (g <= d) {
0062: m = (g + d) / 2;
0063: // we search only on even indexes
0064: if ((m & 1) != 0) // faster than ((m % 2) != 0)
0065: m--;
0066: int currentPC = pcToSourceMap[m];
0067: if (pc < currentPC) {
0068: d = m - 2;
0069: } else if (pc > currentPC) {
0070: g = m + 2;
0071: } else {
0072: return -1;
0073: }
0074: }
0075: if (pc < pcToSourceMap[m])
0076: return m;
0077: return m + 2;
0078: }
0079:
0080: public static final void sort(int[] tab, int lo0, int hi0,
0081: int[] result) {
0082: int lo = lo0;
0083: int hi = hi0;
0084: int mid;
0085: if (hi0 > lo0) {
0086: /* Arbitrarily establishing partition element as the midpoint of
0087: * the array.
0088: */
0089: mid = tab[lo0 + (hi0 - lo0) / 2];
0090: // loop through the array until indices cross
0091: while (lo <= hi) {
0092: /* find the first element that is greater than or equal to
0093: * the partition element starting from the left Index.
0094: */
0095: while ((lo < hi0) && (tab[lo] < mid))
0096: ++lo;
0097: /* find an element that is smaller than or equal to
0098: * the partition element starting from the right Index.
0099: */
0100: while ((hi > lo0) && (tab[hi] > mid))
0101: --hi;
0102: // if the indexes have not crossed, swap
0103: if (lo <= hi) {
0104: swap(tab, lo, hi, result);
0105: ++lo;
0106: --hi;
0107: }
0108: }
0109: /* If the right index has not reached the left side of array
0110: * must now sort the left partition.
0111: */
0112: if (lo0 < hi)
0113: sort(tab, lo0, hi, result);
0114: /* If the left index has not reached the right side of array
0115: * must now sort the right partition.
0116: */
0117: if (lo < hi0)
0118: sort(tab, lo, hi0, result);
0119: }
0120: }
0121:
0122: private static final void swap(int a[], int i, int j, int result[]) {
0123: int T;
0124: T = a[i];
0125: a[i] = a[j];
0126: a[j] = T;
0127: T = result[j];
0128: result[j] = result[i];
0129: result[i] = T;
0130: }
0131:
0132: public int allLocalsCounter;
0133: public byte[] bCodeStream;
0134: public ClassFile classFile; // The current classfile it is associated to.
0135: public int classFileOffset;
0136: public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
0137: public int countLabels;
0138: public ExceptionLabel[] exceptionLabels = new ExceptionLabel[LABELS_INCREMENT];
0139: public int exceptionLabelsCounter;
0140: public int generateAttributes;
0141: // store all the labels placed at the current position to be able to optimize
0142: // a jump to the next bytecode.
0143: static final int L_UNKNOWN = 0, L_OPTIMIZABLE = 2,
0144: L_CANNOT_OPTIMIZE = 4;
0145: public BranchLabel[] labels = new BranchLabel[LABELS_INCREMENT];
0146: public int lastEntryPC; // last entry recorded
0147: public int lastAbruptCompletion; // position of last instruction which abrupts completion: goto/return/athrow
0148: public int[] lineSeparatorPositions;
0149: // line number of the body start and the body end
0150: public int lineNumberStart;
0151: public int lineNumberEnd;
0152:
0153: public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
0154: public int maxFieldCount;
0155:
0156: public int maxLocals;
0157: public AbstractMethodDeclaration methodDeclaration;
0158: public int[] pcToSourceMap = new int[24];
0159: public int pcToSourceMapSize;
0160: public int position; // So when first set can be incremented
0161: public boolean preserveUnusedLocals;
0162: public int stackDepth; // Use Ints to keep from using extra bc when adding
0163: public int stackMax; // Use Ints to keep from using extra bc when adding
0164: public int startingClassFileOffset; // I need to keep the starting point inside the byte array
0165:
0166: // target level to manage different code generation between different target levels
0167: private long targetLevel;
0168:
0169: public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
0170: int visibleLocalsCount;
0171: // to handle goto_w
0172: public boolean wideMode = false;
0173:
0174: public CodeStream(ClassFile givenClassFile) {
0175: this .targetLevel = givenClassFile.targetJDK;
0176: this .generateAttributes = givenClassFile.produceAttributes;
0177: if ((givenClassFile.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
0178: this .lineSeparatorPositions = givenClassFile.referenceBinding.scope
0179: .referenceCompilationUnit().compilationResult
0180: .getLineSeparatorPositions();
0181: }
0182: }
0183:
0184: public void aaload() {
0185: if (DEBUG)
0186: System.out.println(position + "\t\taaload"); //$NON-NLS-1$
0187: countLabels = 0;
0188: stackDepth--;
0189: if (classFileOffset >= bCodeStream.length) {
0190: resizeByteArray();
0191: }
0192: position++;
0193: bCodeStream[classFileOffset++] = Opcodes.OPC_aaload;
0194: }
0195:
0196: public void aastore() {
0197: if (DEBUG)
0198: System.out.println(position + "\t\taastore"); //$NON-NLS-1$
0199: countLabels = 0;
0200: stackDepth -= 3;
0201: if (classFileOffset >= bCodeStream.length) {
0202: resizeByteArray();
0203: }
0204: position++;
0205: bCodeStream[classFileOffset++] = Opcodes.OPC_aastore;
0206: }
0207:
0208: public void aconst_null() {
0209: if (DEBUG)
0210: System.out.println(position + "\t\taconst_null"); //$NON-NLS-1$
0211: countLabels = 0;
0212: stackDepth++;
0213: if (stackDepth > stackMax) {
0214: stackMax = stackDepth;
0215: }
0216: if (classFileOffset >= bCodeStream.length) {
0217: resizeByteArray();
0218: }
0219: position++;
0220: bCodeStream[classFileOffset++] = Opcodes.OPC_aconst_null;
0221: }
0222:
0223: public void addDefinitelyAssignedVariables(Scope scope,
0224: int initStateIndex) {
0225: // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
0226: if ((this .generateAttributes & (ClassFileConstants.ATTR_VARS
0227: | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) == 0)
0228: return;
0229: for (int i = 0; i < visibleLocalsCount; i++) {
0230: LocalVariableBinding localBinding = visibleLocals[i];
0231: if (localBinding != null) {
0232: // Check if the local is definitely assigned
0233: if (isDefinitelyAssigned(scope, initStateIndex,
0234: localBinding)) {
0235: if ((localBinding.initializationCount == 0)
0236: || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
0237: /* There are two cases:
0238: * 1) there is no initialization interval opened ==> add an opened interval
0239: * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
0240: * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
0241: * is equals to -1.
0242: * initializationPCs is a collection of pairs of int:
0243: * first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
0244: * is not closed yet.
0245: */
0246: localBinding
0247: .recordInitializationStartPC(position);
0248: }
0249: }
0250: }
0251: }
0252: }
0253:
0254: public void addLabel(BranchLabel aLabel) {
0255: if (countLabels == labels.length)
0256: System.arraycopy(labels, 0,
0257: labels = new BranchLabel[countLabels
0258: + LABELS_INCREMENT], 0, countLabels);
0259: labels[countLabels++] = aLabel;
0260: }
0261:
0262: public void addVisibleLocalVariable(
0263: LocalVariableBinding localBinding) {
0264: if ((this .generateAttributes & (ClassFileConstants.ATTR_VARS
0265: | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) == 0)
0266: return;
0267:
0268: if (visibleLocalsCount >= visibleLocals.length)
0269: System
0270: .arraycopy(
0271: visibleLocals,
0272: 0,
0273: visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2],
0274: 0, visibleLocalsCount);
0275: visibleLocals[visibleLocalsCount++] = localBinding;
0276: }
0277:
0278: public void addVariable(LocalVariableBinding localBinding) {
0279: /* do nothing */
0280: }
0281:
0282: public void aload(int iArg) {
0283: if (DEBUG)
0284: System.out.println(position + "\t\taload:" + iArg); //$NON-NLS-1$
0285: countLabels = 0;
0286: stackDepth++;
0287: if (stackDepth > stackMax)
0288: stackMax = stackDepth;
0289: if (maxLocals <= iArg) {
0290: maxLocals = iArg + 1;
0291: }
0292: if (iArg > 255) { // Widen
0293: if (classFileOffset + 3 >= bCodeStream.length) {
0294: resizeByteArray();
0295: }
0296: position += 2;
0297: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
0298: bCodeStream[classFileOffset++] = Opcodes.OPC_aload;
0299: writeUnsignedShort(iArg);
0300: } else {
0301: // Don't need to use the wide bytecode
0302: if (classFileOffset + 1 >= bCodeStream.length) {
0303: resizeByteArray();
0304: }
0305: position += 2;
0306: bCodeStream[classFileOffset++] = Opcodes.OPC_aload;
0307: bCodeStream[classFileOffset++] = (byte) iArg;
0308: }
0309: }
0310:
0311: public void aload_0() {
0312: if (DEBUG)
0313: System.out.println(position + "\t\taload_0"); //$NON-NLS-1$
0314: countLabels = 0;
0315: stackDepth++;
0316: if (stackDepth > stackMax) {
0317: stackMax = stackDepth;
0318: }
0319: if (maxLocals == 0) {
0320: maxLocals = 1;
0321: }
0322: if (classFileOffset >= bCodeStream.length) {
0323: resizeByteArray();
0324: }
0325: position++;
0326: bCodeStream[classFileOffset++] = Opcodes.OPC_aload_0;
0327: }
0328:
0329: public void aload_1() {
0330: if (DEBUG)
0331: System.out.println(position + "\t\taload_1"); //$NON-NLS-1$
0332: countLabels = 0;
0333: stackDepth++;
0334: if (stackDepth > stackMax)
0335: stackMax = stackDepth;
0336: if (maxLocals <= 1) {
0337: maxLocals = 2;
0338: }
0339: if (classFileOffset >= bCodeStream.length) {
0340: resizeByteArray();
0341: }
0342: position++;
0343: bCodeStream[classFileOffset++] = Opcodes.OPC_aload_1;
0344: }
0345:
0346: public void aload_2() {
0347: if (DEBUG)
0348: System.out.println(position + "\t\taload_2"); //$NON-NLS-1$
0349: countLabels = 0;
0350: stackDepth++;
0351: if (stackDepth > stackMax)
0352: stackMax = stackDepth;
0353: if (maxLocals <= 2) {
0354: maxLocals = 3;
0355: }
0356: if (classFileOffset >= bCodeStream.length) {
0357: resizeByteArray();
0358: }
0359: position++;
0360: bCodeStream[classFileOffset++] = Opcodes.OPC_aload_2;
0361: }
0362:
0363: public void aload_3() {
0364: if (DEBUG)
0365: System.out.println(position + "\t\taload_3"); //$NON-NLS-1$
0366: countLabels = 0;
0367: stackDepth++;
0368: if (stackDepth > stackMax)
0369: stackMax = stackDepth;
0370: if (maxLocals <= 3) {
0371: maxLocals = 4;
0372: }
0373: if (classFileOffset >= bCodeStream.length) {
0374: resizeByteArray();
0375: }
0376: position++;
0377: bCodeStream[classFileOffset++] = Opcodes.OPC_aload_3;
0378: }
0379:
0380: public void anewarray(TypeBinding typeBinding) {
0381: if (DEBUG)
0382: System.out.println(position
0383: + "\t\tanewarray: " + typeBinding); //$NON-NLS-1$
0384: countLabels = 0;
0385: if (classFileOffset + 2 >= bCodeStream.length) {
0386: resizeByteArray();
0387: }
0388: position++;
0389: bCodeStream[classFileOffset++] = Opcodes.OPC_anewarray;
0390: writeUnsignedShort(constantPool
0391: .literalIndexForType(typeBinding));
0392: }
0393:
0394: public void areturn() {
0395: if (DEBUG)
0396: System.out.println(position + "\t\tareturn"); //$NON-NLS-1$
0397: countLabels = 0;
0398: stackDepth--;
0399: // the stackDepth should be equal to 0
0400: if (classFileOffset >= bCodeStream.length) {
0401: resizeByteArray();
0402: }
0403: position++;
0404: bCodeStream[classFileOffset++] = Opcodes.OPC_areturn;
0405: this .lastAbruptCompletion = this .position;
0406: }
0407:
0408: public void arrayAt(int typeBindingID) {
0409: switch (typeBindingID) {
0410: case TypeIds.T_int:
0411: this .iaload();
0412: break;
0413: case TypeIds.T_byte:
0414: case TypeIds.T_boolean:
0415: this .baload();
0416: break;
0417: case TypeIds.T_short:
0418: this .saload();
0419: break;
0420: case TypeIds.T_char:
0421: this .caload();
0422: break;
0423: case TypeIds.T_long:
0424: this .laload();
0425: break;
0426: case TypeIds.T_float:
0427: this .faload();
0428: break;
0429: case TypeIds.T_double:
0430: this .daload();
0431: break;
0432: default:
0433: this .aaload();
0434: }
0435: }
0436:
0437: public void arrayAtPut(int elementTypeID, boolean valueRequired) {
0438: switch (elementTypeID) {
0439: case TypeIds.T_int:
0440: if (valueRequired)
0441: dup_x2();
0442: iastore();
0443: break;
0444: case TypeIds.T_byte:
0445: case TypeIds.T_boolean:
0446: if (valueRequired)
0447: dup_x2();
0448: bastore();
0449: break;
0450: case TypeIds.T_short:
0451: if (valueRequired)
0452: dup_x2();
0453: sastore();
0454: break;
0455: case TypeIds.T_char:
0456: if (valueRequired)
0457: dup_x2();
0458: castore();
0459: break;
0460: case TypeIds.T_long:
0461: if (valueRequired)
0462: dup2_x2();
0463: lastore();
0464: break;
0465: case TypeIds.T_float:
0466: if (valueRequired)
0467: dup_x2();
0468: fastore();
0469: break;
0470: case TypeIds.T_double:
0471: if (valueRequired)
0472: dup2_x2();
0473: dastore();
0474: break;
0475: default:
0476: if (valueRequired)
0477: dup_x2();
0478: aastore();
0479: }
0480: }
0481:
0482: public void arraylength() {
0483: if (DEBUG)
0484: System.out.println(position + "\t\tarraylength"); //$NON-NLS-1$
0485: countLabels = 0;
0486: if (classFileOffset >= bCodeStream.length) {
0487: resizeByteArray();
0488: }
0489: position++;
0490: bCodeStream[classFileOffset++] = Opcodes.OPC_arraylength;
0491: }
0492:
0493: public void astore(int iArg) {
0494: if (DEBUG)
0495: System.out.println(position + "\t\tastore:" + iArg); //$NON-NLS-1$
0496: countLabels = 0;
0497: stackDepth--;
0498: if (maxLocals <= iArg) {
0499: maxLocals = iArg + 1;
0500: }
0501: if (iArg > 255) { // Widen
0502: if (classFileOffset + 3 >= bCodeStream.length) {
0503: resizeByteArray();
0504: }
0505: position += 2;
0506: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
0507: bCodeStream[classFileOffset++] = Opcodes.OPC_astore;
0508: writeUnsignedShort(iArg);
0509: } else {
0510: if (classFileOffset + 1 >= bCodeStream.length) {
0511: resizeByteArray();
0512: }
0513: position += 2;
0514: bCodeStream[classFileOffset++] = Opcodes.OPC_astore;
0515: bCodeStream[classFileOffset++] = (byte) iArg;
0516: }
0517: }
0518:
0519: public void astore_0() {
0520: if (DEBUG)
0521: System.out.println(position + "\t\tastore_0"); //$NON-NLS-1$
0522: countLabels = 0;
0523: stackDepth--;
0524: if (maxLocals == 0) {
0525: maxLocals = 1;
0526: }
0527: if (classFileOffset >= bCodeStream.length) {
0528: resizeByteArray();
0529: }
0530: position++;
0531: bCodeStream[classFileOffset++] = Opcodes.OPC_astore_0;
0532: }
0533:
0534: public void astore_1() {
0535: if (DEBUG)
0536: System.out.println(position + "\t\tastore_1"); //$NON-NLS-1$
0537: countLabels = 0;
0538: stackDepth--;
0539: if (maxLocals <= 1) {
0540: maxLocals = 2;
0541: }
0542: if (classFileOffset >= bCodeStream.length) {
0543: resizeByteArray();
0544: }
0545: position++;
0546: bCodeStream[classFileOffset++] = Opcodes.OPC_astore_1;
0547: }
0548:
0549: public void astore_2() {
0550: if (DEBUG)
0551: System.out.println(position + "\t\tastore_2"); //$NON-NLS-1$
0552: countLabels = 0;
0553: stackDepth--;
0554: if (maxLocals <= 2) {
0555: maxLocals = 3;
0556: }
0557: if (classFileOffset >= bCodeStream.length) {
0558: resizeByteArray();
0559: }
0560: position++;
0561: bCodeStream[classFileOffset++] = Opcodes.OPC_astore_2;
0562: }
0563:
0564: public void astore_3() {
0565: if (DEBUG)
0566: System.out.println(position + "\t\tastore_3"); //$NON-NLS-1$
0567: countLabels = 0;
0568: stackDepth--;
0569: if (maxLocals <= 3) {
0570: maxLocals = 4;
0571: }
0572: if (classFileOffset >= bCodeStream.length) {
0573: resizeByteArray();
0574: }
0575: position++;
0576: bCodeStream[classFileOffset++] = Opcodes.OPC_astore_3;
0577: }
0578:
0579: public void athrow() {
0580: if (DEBUG)
0581: System.out.println(position + "\t\tathrow"); //$NON-NLS-1$
0582: countLabels = 0;
0583: stackDepth--;
0584: if (classFileOffset >= bCodeStream.length) {
0585: resizeByteArray();
0586: }
0587: position++;
0588: bCodeStream[classFileOffset++] = Opcodes.OPC_athrow;
0589: this .lastAbruptCompletion = this .position;
0590: }
0591:
0592: public void baload() {
0593: if (DEBUG)
0594: System.out.println(position + "\t\tbaload"); //$NON-NLS-1$
0595: countLabels = 0;
0596: stackDepth--;
0597: if (classFileOffset >= bCodeStream.length) {
0598: resizeByteArray();
0599: }
0600: position++;
0601: bCodeStream[classFileOffset++] = Opcodes.OPC_baload;
0602: }
0603:
0604: public void bastore() {
0605: if (DEBUG)
0606: System.out.println(position + "\t\tbastore"); //$NON-NLS-1$
0607: countLabels = 0;
0608: stackDepth -= 3;
0609: if (classFileOffset >= bCodeStream.length) {
0610: resizeByteArray();
0611: }
0612: position++;
0613: bCodeStream[classFileOffset++] = Opcodes.OPC_bastore;
0614: }
0615:
0616: public void bipush(byte b) {
0617: if (DEBUG)
0618: System.out.println(position + "\t\tbipush " + b); //$NON-NLS-1$
0619: countLabels = 0;
0620: stackDepth++;
0621: if (stackDepth > stackMax)
0622: stackMax = stackDepth;
0623: if (classFileOffset + 1 >= bCodeStream.length) {
0624: resizeByteArray();
0625: }
0626: position += 2;
0627: bCodeStream[classFileOffset++] = Opcodes.OPC_bipush;
0628: bCodeStream[classFileOffset++] = b;
0629: }
0630:
0631: public void caload() {
0632: if (DEBUG)
0633: System.out.println(position + "\t\tcaload"); //$NON-NLS-1$
0634: countLabels = 0;
0635: stackDepth--;
0636: if (classFileOffset >= bCodeStream.length) {
0637: resizeByteArray();
0638: }
0639: position++;
0640: bCodeStream[classFileOffset++] = Opcodes.OPC_caload;
0641: }
0642:
0643: public void castore() {
0644: if (DEBUG)
0645: System.out.println(position + "\t\tcastore"); //$NON-NLS-1$
0646: countLabels = 0;
0647: stackDepth -= 3;
0648: if (classFileOffset >= bCodeStream.length) {
0649: resizeByteArray();
0650: }
0651: position++;
0652: bCodeStream[classFileOffset++] = Opcodes.OPC_castore;
0653: }
0654:
0655: public void checkcast(int baseId) {
0656: this .countLabels = 0;
0657: if (classFileOffset + 2 >= bCodeStream.length) {
0658: resizeByteArray();
0659: }
0660: this .position++;
0661: this .bCodeStream[this .classFileOffset++] = Opcodes.OPC_checkcast;
0662: switch (baseId) {
0663: case TypeIds.T_byte:
0664: writeUnsignedShort(this .constantPool
0665: .literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
0666: break;
0667: case TypeIds.T_short:
0668: writeUnsignedShort(this .constantPool
0669: .literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
0670: break;
0671: case TypeIds.T_char:
0672: writeUnsignedShort(this .constantPool
0673: .literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
0674: break;
0675: case TypeIds.T_int:
0676: writeUnsignedShort(this .constantPool
0677: .literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
0678: break;
0679: case TypeIds.T_long:
0680: writeUnsignedShort(this .constantPool
0681: .literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
0682: break;
0683: case TypeIds.T_float:
0684: writeUnsignedShort(this .constantPool
0685: .literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
0686: break;
0687: case TypeIds.T_double:
0688: writeUnsignedShort(this .constantPool
0689: .literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
0690: break;
0691: case TypeIds.T_boolean:
0692: writeUnsignedShort(this .constantPool
0693: .literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
0694: }
0695: }
0696:
0697: public void checkcast(TypeBinding typeBinding) {
0698: if (DEBUG)
0699: System.out.println(position
0700: + "\t\tcheckcast:" + typeBinding.debugName()); //$NON-NLS-1$
0701: countLabels = 0;
0702: if (classFileOffset + 2 >= bCodeStream.length) {
0703: resizeByteArray();
0704: }
0705: position++;
0706: bCodeStream[classFileOffset++] = Opcodes.OPC_checkcast;
0707: writeUnsignedShort(constantPool
0708: .literalIndexForType(typeBinding));
0709: }
0710:
0711: public void d2f() {
0712: if (DEBUG)
0713: System.out.println(position + "\t\td2f"); //$NON-NLS-1$
0714: countLabels = 0;
0715: stackDepth--;
0716: if (classFileOffset >= bCodeStream.length) {
0717: resizeByteArray();
0718: }
0719: position++;
0720: bCodeStream[classFileOffset++] = Opcodes.OPC_d2f;
0721: }
0722:
0723: public void d2i() {
0724: if (DEBUG)
0725: System.out.println(position + "\t\td2i"); //$NON-NLS-1$
0726: countLabels = 0;
0727: stackDepth--;
0728: if (classFileOffset >= bCodeStream.length) {
0729: resizeByteArray();
0730: }
0731: position++;
0732: bCodeStream[classFileOffset++] = Opcodes.OPC_d2i;
0733: }
0734:
0735: public void d2l() {
0736: if (DEBUG)
0737: System.out.println(position + "\t\td2l"); //$NON-NLS-1$
0738: countLabels = 0;
0739: if (classFileOffset >= bCodeStream.length) {
0740: resizeByteArray();
0741: }
0742: position++;
0743: bCodeStream[classFileOffset++] = Opcodes.OPC_d2l;
0744: }
0745:
0746: public void dadd() {
0747: if (DEBUG)
0748: System.out.println(position + "\t\tdadd"); //$NON-NLS-1$
0749: countLabels = 0;
0750: stackDepth -= 2;
0751: if (classFileOffset >= bCodeStream.length) {
0752: resizeByteArray();
0753: }
0754: position++;
0755: bCodeStream[classFileOffset++] = Opcodes.OPC_dadd;
0756: }
0757:
0758: public void daload() {
0759: if (DEBUG)
0760: System.out.println(position + "\t\tdaload"); //$NON-NLS-1$
0761: countLabels = 0;
0762: if (classFileOffset >= bCodeStream.length) {
0763: resizeByteArray();
0764: }
0765: position++;
0766: bCodeStream[classFileOffset++] = Opcodes.OPC_daload;
0767: }
0768:
0769: public void dastore() {
0770: if (DEBUG)
0771: System.out.println(position + "\t\tdastore"); //$NON-NLS-1$
0772: countLabels = 0;
0773: stackDepth -= 4;
0774: if (classFileOffset >= bCodeStream.length) {
0775: resizeByteArray();
0776: }
0777: position++;
0778: bCodeStream[classFileOffset++] = Opcodes.OPC_dastore;
0779: }
0780:
0781: public void dcmpg() {
0782: if (DEBUG)
0783: System.out.println(position + "\t\tdcmpg"); //$NON-NLS-1$
0784: countLabels = 0;
0785: stackDepth -= 3;
0786: if (classFileOffset >= bCodeStream.length) {
0787: resizeByteArray();
0788: }
0789: position++;
0790: bCodeStream[classFileOffset++] = Opcodes.OPC_dcmpg;
0791: }
0792:
0793: public void dcmpl() {
0794: if (DEBUG)
0795: System.out.println(position + "\t\tdcmpl"); //$NON-NLS-1$
0796: countLabels = 0;
0797: stackDepth -= 3;
0798: if (classFileOffset >= bCodeStream.length) {
0799: resizeByteArray();
0800: }
0801: position++;
0802: bCodeStream[classFileOffset++] = Opcodes.OPC_dcmpl;
0803: }
0804:
0805: public void dconst_0() {
0806: if (DEBUG)
0807: System.out.println(position + "\t\tdconst_0"); //$NON-NLS-1$
0808: countLabels = 0;
0809: stackDepth += 2;
0810: if (stackDepth > stackMax)
0811: stackMax = stackDepth;
0812: if (classFileOffset >= bCodeStream.length) {
0813: resizeByteArray();
0814: }
0815: position++;
0816: bCodeStream[classFileOffset++] = Opcodes.OPC_dconst_0;
0817: }
0818:
0819: public void dconst_1() {
0820: if (DEBUG)
0821: System.out.println(position + "\t\tdconst_1"); //$NON-NLS-1$
0822: countLabels = 0;
0823: stackDepth += 2;
0824: if (stackDepth > stackMax)
0825: stackMax = stackDepth;
0826: if (classFileOffset >= bCodeStream.length) {
0827: resizeByteArray();
0828: }
0829: position++;
0830: bCodeStream[classFileOffset++] = Opcodes.OPC_dconst_1;
0831: }
0832:
0833: public void ddiv() {
0834: if (DEBUG)
0835: System.out.println(position + "\t\tddiv"); //$NON-NLS-1$
0836: countLabels = 0;
0837: stackDepth -= 2;
0838: if (classFileOffset >= bCodeStream.length) {
0839: resizeByteArray();
0840: }
0841: position++;
0842: bCodeStream[classFileOffset++] = Opcodes.OPC_ddiv;
0843: }
0844:
0845: public void decrStackSize(int offset) {
0846: stackDepth -= offset;
0847: }
0848:
0849: public void dload(int iArg) {
0850: if (DEBUG)
0851: System.out.println(position + "\t\tdload:" + iArg); //$NON-NLS-1$
0852: countLabels = 0;
0853: stackDepth += 2;
0854: if (stackDepth > stackMax)
0855: stackMax = stackDepth;
0856: if (maxLocals < iArg + 2) {
0857: maxLocals = iArg + 2; // + 2 because it is a double
0858: }
0859: if (iArg > 255) { // Widen
0860: if (classFileOffset + 3 >= bCodeStream.length) {
0861: resizeByteArray();
0862: }
0863: position += 2;
0864: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
0865: bCodeStream[classFileOffset++] = Opcodes.OPC_dload;
0866: writeUnsignedShort(iArg);
0867: } else {
0868: // Don't need to use the wide bytecode
0869: if (classFileOffset + 1 >= bCodeStream.length) {
0870: resizeByteArray();
0871: }
0872: position += 2;
0873: bCodeStream[classFileOffset++] = Opcodes.OPC_dload;
0874: bCodeStream[classFileOffset++] = (byte) iArg;
0875: }
0876: }
0877:
0878: public void dload_0() {
0879: if (DEBUG)
0880: System.out.println(position + "\t\tdload_0"); //$NON-NLS-1$
0881: countLabels = 0;
0882: stackDepth += 2;
0883: if (stackDepth > stackMax)
0884: stackMax = stackDepth;
0885: if (maxLocals < 2) {
0886: maxLocals = 2;
0887: }
0888: if (classFileOffset >= bCodeStream.length) {
0889: resizeByteArray();
0890: }
0891: position++;
0892: bCodeStream[classFileOffset++] = Opcodes.OPC_dload_0;
0893: }
0894:
0895: public void dload_1() {
0896: if (DEBUG)
0897: System.out.println(position + "\t\tdload_1"); //$NON-NLS-1$
0898: countLabels = 0;
0899: stackDepth += 2;
0900: if (stackDepth > stackMax)
0901: stackMax = stackDepth;
0902: if (maxLocals < 3) {
0903: maxLocals = 3;
0904: }
0905: if (classFileOffset >= bCodeStream.length) {
0906: resizeByteArray();
0907: }
0908: position++;
0909: bCodeStream[classFileOffset++] = Opcodes.OPC_dload_1;
0910: }
0911:
0912: public void dload_2() {
0913: if (DEBUG)
0914: System.out.println(position + "\t\tdload_2"); //$NON-NLS-1$
0915: countLabels = 0;
0916: stackDepth += 2;
0917: if (stackDepth > stackMax)
0918: stackMax = stackDepth;
0919: if (maxLocals < 4) {
0920: maxLocals = 4;
0921: }
0922: if (classFileOffset >= bCodeStream.length) {
0923: resizeByteArray();
0924: }
0925: position++;
0926: bCodeStream[classFileOffset++] = Opcodes.OPC_dload_2;
0927: }
0928:
0929: public void dload_3() {
0930: if (DEBUG)
0931: System.out.println(position + "\t\tdload_3"); //$NON-NLS-1$
0932: countLabels = 0;
0933: stackDepth += 2;
0934: if (stackDepth > stackMax)
0935: stackMax = stackDepth;
0936: if (maxLocals < 5) {
0937: maxLocals = 5;
0938: }
0939: if (classFileOffset >= bCodeStream.length) {
0940: resizeByteArray();
0941: }
0942: position++;
0943: bCodeStream[classFileOffset++] = Opcodes.OPC_dload_3;
0944: }
0945:
0946: public void dmul() {
0947: if (DEBUG)
0948: System.out.println(position + "\t\tdmul"); //$NON-NLS-1$
0949: countLabels = 0;
0950: stackDepth -= 2;
0951: if (classFileOffset >= bCodeStream.length) {
0952: resizeByteArray();
0953: }
0954: position++;
0955: bCodeStream[classFileOffset++] = Opcodes.OPC_dmul;
0956: }
0957:
0958: public void dneg() {
0959: if (DEBUG)
0960: System.out.println(position + "\t\tdneg"); //$NON-NLS-1$
0961: countLabels = 0;
0962: if (classFileOffset >= bCodeStream.length) {
0963: resizeByteArray();
0964: }
0965: position++;
0966: bCodeStream[classFileOffset++] = Opcodes.OPC_dneg;
0967: }
0968:
0969: public void drem() {
0970: if (DEBUG)
0971: System.out.println(position + "\t\tdrem"); //$NON-NLS-1$
0972: countLabels = 0;
0973: stackDepth -= 2;
0974: if (classFileOffset >= bCodeStream.length) {
0975: resizeByteArray();
0976: }
0977: position++;
0978: bCodeStream[classFileOffset++] = Opcodes.OPC_drem;
0979: }
0980:
0981: public void dreturn() {
0982: if (DEBUG)
0983: System.out.println(position + "\t\tdreturn"); //$NON-NLS-1$
0984: countLabels = 0;
0985: stackDepth -= 2;
0986: // the stackDepth should be equal to 0
0987: if (classFileOffset >= bCodeStream.length) {
0988: resizeByteArray();
0989: }
0990: position++;
0991: bCodeStream[classFileOffset++] = Opcodes.OPC_dreturn;
0992: this .lastAbruptCompletion = this .position;
0993: }
0994:
0995: public void dstore(int iArg) {
0996: if (DEBUG)
0997: System.out.println(position + "\t\tdstore:" + iArg); //$NON-NLS-1$
0998: countLabels = 0;
0999: stackDepth -= 2;
1000: if (maxLocals <= iArg + 1) {
1001: maxLocals = iArg + 2;
1002: }
1003: if (iArg > 255) { // Widen
1004: if (classFileOffset + 3 >= bCodeStream.length) {
1005: resizeByteArray();
1006: }
1007: position += 2;
1008: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
1009: bCodeStream[classFileOffset++] = Opcodes.OPC_dstore;
1010: writeUnsignedShort(iArg);
1011: } else {
1012: if (classFileOffset + 1 >= bCodeStream.length) {
1013: resizeByteArray();
1014: }
1015: position += 2;
1016: bCodeStream[classFileOffset++] = Opcodes.OPC_dstore;
1017: bCodeStream[classFileOffset++] = (byte) iArg;
1018: }
1019: }
1020:
1021: public void dstore_0() {
1022: if (DEBUG)
1023: System.out.println(position + "\t\tdstore_0"); //$NON-NLS-1$
1024: countLabels = 0;
1025: stackDepth -= 2;
1026: if (maxLocals < 2) {
1027: maxLocals = 2;
1028: }
1029: if (classFileOffset >= bCodeStream.length) {
1030: resizeByteArray();
1031: }
1032: position++;
1033: bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_0;
1034: }
1035:
1036: public void dstore_1() {
1037: if (DEBUG)
1038: System.out.println(position + "\t\tdstore_1"); //$NON-NLS-1$
1039: countLabels = 0;
1040: stackDepth -= 2;
1041: if (maxLocals < 3) {
1042: maxLocals = 3;
1043: }
1044: if (classFileOffset >= bCodeStream.length) {
1045: resizeByteArray();
1046: }
1047: position++;
1048: bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_1;
1049: }
1050:
1051: public void dstore_2() {
1052: if (DEBUG)
1053: System.out.println(position + "\t\tdstore_2"); //$NON-NLS-1$
1054: countLabels = 0;
1055: stackDepth -= 2;
1056: if (maxLocals < 4) {
1057: maxLocals = 4;
1058: }
1059: if (classFileOffset >= bCodeStream.length) {
1060: resizeByteArray();
1061: }
1062: position++;
1063: bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_2;
1064: }
1065:
1066: public void dstore_3() {
1067: if (DEBUG)
1068: System.out.println(position + "\t\tdstore_3"); //$NON-NLS-1$
1069: countLabels = 0;
1070: stackDepth -= 2;
1071: if (maxLocals < 5) {
1072: maxLocals = 5;
1073: }
1074: if (classFileOffset >= bCodeStream.length) {
1075: resizeByteArray();
1076: }
1077: position++;
1078: bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_3;
1079: }
1080:
1081: public void dsub() {
1082: if (DEBUG)
1083: System.out.println(position + "\t\tdsub"); //$NON-NLS-1$
1084: countLabels = 0;
1085: stackDepth -= 2;
1086: if (classFileOffset >= bCodeStream.length) {
1087: resizeByteArray();
1088: }
1089: position++;
1090: bCodeStream[classFileOffset++] = Opcodes.OPC_dsub;
1091: }
1092:
1093: public void dup() {
1094: if (DEBUG)
1095: System.out.println(position + "\t\tdup"); //$NON-NLS-1$
1096: countLabels = 0;
1097: stackDepth++;
1098: if (stackDepth > stackMax) {
1099: stackMax = stackDepth;
1100: }
1101: if (classFileOffset >= bCodeStream.length) {
1102: resizeByteArray();
1103: }
1104: position++;
1105: bCodeStream[classFileOffset++] = Opcodes.OPC_dup;
1106: }
1107:
1108: public void dup_x1() {
1109: if (DEBUG)
1110: System.out.println(position + "\t\tdup_x1"); //$NON-NLS-1$
1111: countLabels = 0;
1112: stackDepth++;
1113: if (stackDepth > stackMax)
1114: stackMax = stackDepth;
1115: if (classFileOffset >= bCodeStream.length) {
1116: resizeByteArray();
1117: }
1118: position++;
1119: bCodeStream[classFileOffset++] = Opcodes.OPC_dup_x1;
1120: }
1121:
1122: public void dup_x2() {
1123: if (DEBUG)
1124: System.out.println(position + "\t\tdup_x2"); //$NON-NLS-1$
1125: countLabels = 0;
1126: stackDepth++;
1127: if (stackDepth > stackMax)
1128: stackMax = stackDepth;
1129: if (classFileOffset >= bCodeStream.length) {
1130: resizeByteArray();
1131: }
1132: position++;
1133: bCodeStream[classFileOffset++] = Opcodes.OPC_dup_x2;
1134: }
1135:
1136: public void dup2() {
1137: if (DEBUG)
1138: System.out.println(position + "\t\tdup2"); //$NON-NLS-1$
1139: countLabels = 0;
1140: stackDepth += 2;
1141: if (stackDepth > stackMax)
1142: stackMax = stackDepth;
1143: if (classFileOffset >= bCodeStream.length) {
1144: resizeByteArray();
1145: }
1146: position++;
1147: bCodeStream[classFileOffset++] = Opcodes.OPC_dup2;
1148: }
1149:
1150: public void dup2_x1() {
1151: if (DEBUG)
1152: System.out.println(position + "\t\tdup2_x1"); //$NON-NLS-1$
1153: countLabels = 0;
1154: stackDepth += 2;
1155: if (stackDepth > stackMax)
1156: stackMax = stackDepth;
1157: if (classFileOffset >= bCodeStream.length) {
1158: resizeByteArray();
1159: }
1160: position++;
1161: bCodeStream[classFileOffset++] = Opcodes.OPC_dup2_x1;
1162: }
1163:
1164: public void dup2_x2() {
1165: if (DEBUG)
1166: System.out.println(position + "\t\tdup2_x2"); //$NON-NLS-1$
1167: countLabels = 0;
1168: stackDepth += 2;
1169: if (stackDepth > stackMax)
1170: stackMax = stackDepth;
1171: if (classFileOffset >= bCodeStream.length) {
1172: resizeByteArray();
1173: }
1174: position++;
1175: bCodeStream[classFileOffset++] = Opcodes.OPC_dup2_x2;
1176: }
1177:
1178: public void exitUserScope(BlockScope currentScope) {
1179: // mark all the scope's locals as losing their definite assignment
1180:
1181: if ((this .generateAttributes & (ClassFileConstants.ATTR_VARS
1182: | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) == 0)
1183: return;
1184: int index = this .visibleLocalsCount - 1;
1185: while (index >= 0) {
1186: LocalVariableBinding visibleLocal = visibleLocals[index];
1187: if (visibleLocal == null
1188: || visibleLocal.declaringScope != currentScope) {
1189: // left currentScope
1190: index--;
1191: continue;
1192: }
1193:
1194: // there may be some preserved locals never initialized
1195: if (visibleLocal.initializationCount > 0) {
1196: visibleLocal.recordInitializationEndPC(position);
1197: }
1198: visibleLocals[index--] = null; // this variable is no longer visible afterwards
1199: }
1200: }
1201:
1202: public void exitUserScope(BlockScope currentScope,
1203: LocalVariableBinding binding) {
1204: // mark all the scope's locals as losing their definite assignment
1205: if ((this .generateAttributes & (ClassFileConstants.ATTR_VARS
1206: | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) == 0)
1207: return;
1208: int index = this .visibleLocalsCount - 1;
1209: while (index >= 0) {
1210: LocalVariableBinding visibleLocal = visibleLocals[index];
1211: if (visibleLocal == null
1212: || visibleLocal.declaringScope != currentScope
1213: || visibleLocal == binding) {
1214: // left currentScope
1215: index--;
1216: continue;
1217: }
1218: // there may be some preserved locals never initialized
1219: if (visibleLocal.initializationCount > 0) {
1220: visibleLocal.recordInitializationEndPC(position);
1221: }
1222: visibleLocals[index--] = null; // this variable is no longer visible afterwards
1223: }
1224: }
1225:
1226: public void f2d() {
1227: if (DEBUG)
1228: System.out.println(position + "\t\tf2d"); //$NON-NLS-1$
1229: countLabels = 0;
1230: stackDepth++;
1231: if (stackDepth > stackMax)
1232: stackMax = stackDepth;
1233: if (classFileOffset >= bCodeStream.length) {
1234: resizeByteArray();
1235: }
1236: position++;
1237: bCodeStream[classFileOffset++] = Opcodes.OPC_f2d;
1238: }
1239:
1240: public void f2i() {
1241: if (DEBUG)
1242: System.out.println(position + "\t\tf2i"); //$NON-NLS-1$
1243: countLabels = 0;
1244: if (classFileOffset >= bCodeStream.length) {
1245: resizeByteArray();
1246: }
1247: position++;
1248: bCodeStream[classFileOffset++] = Opcodes.OPC_f2i;
1249: }
1250:
1251: public void f2l() {
1252: if (DEBUG)
1253: System.out.println(position + "\t\tf2l"); //$NON-NLS-1$
1254: countLabels = 0;
1255: stackDepth++;
1256: if (stackDepth > stackMax)
1257: stackMax = stackDepth;
1258: if (classFileOffset >= bCodeStream.length) {
1259: resizeByteArray();
1260: }
1261: position++;
1262: bCodeStream[classFileOffset++] = Opcodes.OPC_f2l;
1263: }
1264:
1265: public void fadd() {
1266: if (DEBUG)
1267: System.out.println(position + "\t\tfadd"); //$NON-NLS-1$
1268: countLabels = 0;
1269: stackDepth--;
1270: if (classFileOffset >= bCodeStream.length) {
1271: resizeByteArray();
1272: }
1273: position++;
1274: bCodeStream[classFileOffset++] = Opcodes.OPC_fadd;
1275: }
1276:
1277: public void faload() {
1278: if (DEBUG)
1279: System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
1280: countLabels = 0;
1281: stackDepth--;
1282: if (classFileOffset >= bCodeStream.length) {
1283: resizeByteArray();
1284: }
1285: position++;
1286: bCodeStream[classFileOffset++] = Opcodes.OPC_faload;
1287: }
1288:
1289: public void fastore() {
1290: if (DEBUG)
1291: System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
1292: countLabels = 0;
1293: stackDepth -= 3;
1294: if (classFileOffset >= bCodeStream.length) {
1295: resizeByteArray();
1296: }
1297: position++;
1298: bCodeStream[classFileOffset++] = Opcodes.OPC_fastore;
1299: }
1300:
1301: public void fcmpg() {
1302: if (DEBUG)
1303: System.out.println(position + "\t\tfcmpg"); //$NON-NLS-1$
1304: countLabels = 0;
1305: stackDepth--;
1306: if (classFileOffset >= bCodeStream.length) {
1307: resizeByteArray();
1308: }
1309: position++;
1310: bCodeStream[classFileOffset++] = Opcodes.OPC_fcmpg;
1311: }
1312:
1313: public void fcmpl() {
1314: if (DEBUG)
1315: System.out.println(position + "\t\tfcmpl"); //$NON-NLS-1$
1316: countLabels = 0;
1317: stackDepth--;
1318: if (classFileOffset >= bCodeStream.length) {
1319: resizeByteArray();
1320: }
1321: position++;
1322: bCodeStream[classFileOffset++] = Opcodes.OPC_fcmpl;
1323: }
1324:
1325: public void fconst_0() {
1326: if (DEBUG)
1327: System.out.println(position + "\t\tfconst_0"); //$NON-NLS-1$
1328: countLabels = 0;
1329: stackDepth++;
1330: if (stackDepth > stackMax)
1331: stackMax = stackDepth;
1332: if (classFileOffset >= bCodeStream.length) {
1333: resizeByteArray();
1334: }
1335: position++;
1336: bCodeStream[classFileOffset++] = Opcodes.OPC_fconst_0;
1337: }
1338:
1339: public void fconst_1() {
1340: if (DEBUG)
1341: System.out.println(position + "\t\tfconst_1"); //$NON-NLS-1$
1342: countLabels = 0;
1343: stackDepth++;
1344: if (stackDepth > stackMax)
1345: stackMax = stackDepth;
1346: if (classFileOffset >= bCodeStream.length) {
1347: resizeByteArray();
1348: }
1349: position++;
1350: bCodeStream[classFileOffset++] = Opcodes.OPC_fconst_1;
1351: }
1352:
1353: public void fconst_2() {
1354: if (DEBUG)
1355: System.out.println(position + "\t\tfconst_2"); //$NON-NLS-1$
1356: countLabels = 0;
1357: stackDepth++;
1358: if (stackDepth > stackMax)
1359: stackMax = stackDepth;
1360: if (classFileOffset >= bCodeStream.length) {
1361: resizeByteArray();
1362: }
1363: position++;
1364: bCodeStream[classFileOffset++] = Opcodes.OPC_fconst_2;
1365: }
1366:
1367: public void fdiv() {
1368: if (DEBUG)
1369: System.out.println(position + "\t\tfdiv"); //$NON-NLS-1$
1370: countLabels = 0;
1371: stackDepth--;
1372: if (classFileOffset >= bCodeStream.length) {
1373: resizeByteArray();
1374: }
1375: position++;
1376: bCodeStream[classFileOffset++] = Opcodes.OPC_fdiv;
1377: }
1378:
1379: public void fload(int iArg) {
1380: if (DEBUG)
1381: System.out.println(position + "\t\tfload:" + iArg); //$NON-NLS-1$
1382: countLabels = 0;
1383: stackDepth++;
1384: if (maxLocals <= iArg) {
1385: maxLocals = iArg + 1;
1386: }
1387: if (stackDepth > stackMax)
1388: stackMax = stackDepth;
1389: if (iArg > 255) { // Widen
1390: if (classFileOffset + 3 >= bCodeStream.length) {
1391: resizeByteArray();
1392: }
1393: position += 2;
1394: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
1395: bCodeStream[classFileOffset++] = Opcodes.OPC_fload;
1396: writeUnsignedShort(iArg);
1397: } else {
1398: if (classFileOffset + 1 >= bCodeStream.length) {
1399: resizeByteArray();
1400: }
1401: position += 2;
1402: bCodeStream[classFileOffset++] = Opcodes.OPC_fload;
1403: bCodeStream[classFileOffset++] = (byte) iArg;
1404: }
1405: }
1406:
1407: public void fload_0() {
1408: if (DEBUG)
1409: System.out.println(position + "\t\tfload_0"); //$NON-NLS-1$
1410: countLabels = 0;
1411: stackDepth++;
1412: if (maxLocals == 0) {
1413: maxLocals = 1;
1414: }
1415: if (stackDepth > stackMax)
1416: stackMax = stackDepth;
1417: if (classFileOffset >= bCodeStream.length) {
1418: resizeByteArray();
1419: }
1420: position++;
1421: bCodeStream[classFileOffset++] = Opcodes.OPC_fload_0;
1422: }
1423:
1424: public void fload_1() {
1425: if (DEBUG)
1426: System.out.println(position + "\t\tfload_1"); //$NON-NLS-1$
1427: countLabels = 0;
1428: stackDepth++;
1429: if (maxLocals <= 1) {
1430: maxLocals = 2;
1431: }
1432: if (stackDepth > stackMax)
1433: stackMax = stackDepth;
1434: if (classFileOffset >= bCodeStream.length) {
1435: resizeByteArray();
1436: }
1437: position++;
1438: bCodeStream[classFileOffset++] = Opcodes.OPC_fload_1;
1439: }
1440:
1441: public void fload_2() {
1442: if (DEBUG)
1443: System.out.println(position + "\t\tfload_2"); //$NON-NLS-1$
1444: countLabels = 0;
1445: stackDepth++;
1446: if (maxLocals <= 2) {
1447: maxLocals = 3;
1448: }
1449: if (stackDepth > stackMax)
1450: stackMax = stackDepth;
1451: if (classFileOffset >= bCodeStream.length) {
1452: resizeByteArray();
1453: }
1454: position++;
1455: bCodeStream[classFileOffset++] = Opcodes.OPC_fload_2;
1456: }
1457:
1458: public void fload_3() {
1459: if (DEBUG)
1460: System.out.println(position + "\t\tfload_3"); //$NON-NLS-1$
1461: countLabels = 0;
1462: stackDepth++;
1463: if (maxLocals <= 3) {
1464: maxLocals = 4;
1465: }
1466: if (stackDepth > stackMax)
1467: stackMax = stackDepth;
1468: if (classFileOffset >= bCodeStream.length) {
1469: resizeByteArray();
1470: }
1471: position++;
1472: bCodeStream[classFileOffset++] = Opcodes.OPC_fload_3;
1473: }
1474:
1475: public void fmul() {
1476: if (DEBUG)
1477: System.out.println(position + "\t\tfmul"); //$NON-NLS-1$
1478: countLabels = 0;
1479: stackDepth--;
1480: if (classFileOffset >= bCodeStream.length) {
1481: resizeByteArray();
1482: }
1483: position++;
1484: bCodeStream[classFileOffset++] = Opcodes.OPC_fmul;
1485: }
1486:
1487: public void fneg() {
1488: if (DEBUG)
1489: System.out.println(position + "\t\tfneg"); //$NON-NLS-1$
1490: countLabels = 0;
1491: if (classFileOffset >= bCodeStream.length) {
1492: resizeByteArray();
1493: }
1494: position++;
1495: bCodeStream[classFileOffset++] = Opcodes.OPC_fneg;
1496: }
1497:
1498: public void frem() {
1499: if (DEBUG)
1500: System.out.println(position + "\t\tfrem"); //$NON-NLS-1$
1501: countLabels = 0;
1502: stackDepth--;
1503: if (classFileOffset >= bCodeStream.length) {
1504: resizeByteArray();
1505: }
1506: position++;
1507: bCodeStream[classFileOffset++] = Opcodes.OPC_frem;
1508: }
1509:
1510: public void freturn() {
1511: if (DEBUG)
1512: System.out.println(position + "\t\tfreturn"); //$NON-NLS-1$
1513: countLabels = 0;
1514: stackDepth--;
1515: // the stackDepth should be equal to 0
1516: if (classFileOffset >= bCodeStream.length) {
1517: resizeByteArray();
1518: }
1519: position++;
1520: bCodeStream[classFileOffset++] = Opcodes.OPC_freturn;
1521: this .lastAbruptCompletion = this .position;
1522: }
1523:
1524: public void fstore(int iArg) {
1525: if (DEBUG)
1526: System.out.println(position + "\t\tfstore:" + iArg); //$NON-NLS-1$
1527: countLabels = 0;
1528: stackDepth--;
1529: if (maxLocals <= iArg) {
1530: maxLocals = iArg + 1;
1531: }
1532: if (iArg > 255) { // Widen
1533: if (classFileOffset + 3 >= bCodeStream.length) {
1534: resizeByteArray();
1535: }
1536: position += 2;
1537: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
1538: bCodeStream[classFileOffset++] = Opcodes.OPC_fstore;
1539: writeUnsignedShort(iArg);
1540: } else {
1541: if (classFileOffset + 1 >= bCodeStream.length) {
1542: resizeByteArray();
1543: }
1544: position += 2;
1545: bCodeStream[classFileOffset++] = Opcodes.OPC_fstore;
1546: bCodeStream[classFileOffset++] = (byte) iArg;
1547: }
1548: }
1549:
1550: public void fstore_0() {
1551: if (DEBUG)
1552: System.out.println(position + "\t\tfstore_0"); //$NON-NLS-1$
1553: countLabels = 0;
1554: stackDepth--;
1555: if (maxLocals == 0) {
1556: maxLocals = 1;
1557: }
1558: if (classFileOffset >= bCodeStream.length) {
1559: resizeByteArray();
1560: }
1561: position++;
1562: bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_0;
1563: }
1564:
1565: public void fstore_1() {
1566: if (DEBUG)
1567: System.out.println(position + "\t\tfstore_1"); //$NON-NLS-1$
1568: countLabels = 0;
1569: stackDepth--;
1570: if (maxLocals <= 1) {
1571: maxLocals = 2;
1572: }
1573: if (classFileOffset >= bCodeStream.length) {
1574: resizeByteArray();
1575: }
1576: position++;
1577: bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_1;
1578: }
1579:
1580: public void fstore_2() {
1581: if (DEBUG)
1582: System.out.println(position + "\t\tfstore_2"); //$NON-NLS-1$
1583: countLabels = 0;
1584: stackDepth--;
1585: if (maxLocals <= 2) {
1586: maxLocals = 3;
1587: }
1588: if (classFileOffset >= bCodeStream.length) {
1589: resizeByteArray();
1590: }
1591: position++;
1592: bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_2;
1593: }
1594:
1595: public void fstore_3() {
1596: if (DEBUG)
1597: System.out.println(position + "\t\tfstore_3"); //$NON-NLS-1$
1598: countLabels = 0;
1599: stackDepth--;
1600: if (maxLocals <= 3) {
1601: maxLocals = 4;
1602: }
1603: if (classFileOffset >= bCodeStream.length) {
1604: resizeByteArray();
1605: }
1606: position++;
1607: bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_3;
1608: }
1609:
1610: public void fsub() {
1611: if (DEBUG)
1612: System.out.println(position + "\t\tfsub"); //$NON-NLS-1$
1613: countLabels = 0;
1614: stackDepth--;
1615: if (classFileOffset >= bCodeStream.length) {
1616: resizeByteArray();
1617: }
1618: position++;
1619: bCodeStream[classFileOffset++] = Opcodes.OPC_fsub;
1620: }
1621:
1622: public void generateBoxingConversion(int unboxedTypeID) {
1623: switch (unboxedTypeID) {
1624: case TypeIds.T_byte:
1625: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1626: if (DEBUG)
1627: System.out
1628: .println(position
1629: + "\t\tinvokestatic java.lang.Byte.valueOf(byte)"); //$NON-NLS-1$
1630: // invokestatic: Byte.valueOf(byte)
1631: this .invoke(
1632: Opcodes.OPC_invokestatic,
1633: 1, // argCount
1634: 1, // return type size
1635: ConstantPool.JavaLangByteConstantPoolName,
1636: ConstantPool.ValueOf,
1637: ConstantPool.byteByteSignature);
1638: } else {
1639: // new Byte( byte )
1640: if (DEBUG)
1641: System.out.println(position
1642: + "\t\tinvokespecial java.lang.Byte(byte)"); //$NON-NLS-1$
1643: newWrapperFor(unboxedTypeID);
1644: dup_x1();
1645: swap();
1646: this .invoke(
1647: Opcodes.OPC_invokespecial,
1648: 1, // argCount
1649: 0, // return type size
1650: ConstantPool.JavaLangByteConstantPoolName,
1651: ConstantPool.Init,
1652: ConstantPool.ByteConstrSignature);
1653: }
1654: break;
1655: case TypeIds.T_short:
1656: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1657: // invokestatic: Short.valueOf(short)
1658: if (DEBUG)
1659: System.out
1660: .println(position
1661: + "\t\tinvokestatic java.lang.Short.valueOf(short)"); //$NON-NLS-1$
1662: this .invoke(
1663: Opcodes.OPC_invokestatic,
1664: 1, // argCount
1665: 1, // return type size
1666: ConstantPool.JavaLangShortConstantPoolName,
1667: ConstantPool.ValueOf,
1668: ConstantPool.shortShortSignature);
1669: } else {
1670: // new Short(short)
1671: if (DEBUG)
1672: System.out
1673: .println(position
1674: + "\t\tinvokespecial java.lang.Short(short)"); //$NON-NLS-1$
1675: newWrapperFor(unboxedTypeID);
1676: dup_x1();
1677: swap();
1678: this .invoke(
1679: Opcodes.OPC_invokespecial,
1680: 1, // argCount
1681: 0, // return type size
1682: ConstantPool.JavaLangShortConstantPoolName,
1683: ConstantPool.Init,
1684: ConstantPool.ShortConstrSignature);
1685: }
1686: break;
1687: case TypeIds.T_char:
1688: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1689: // invokestatic: Character.valueOf(char)
1690: if (DEBUG)
1691: System.out
1692: .println(position
1693: + "\t\tinvokestatic java.lang.Character.valueOf(char)"); //$NON-NLS-1$
1694: this .invoke(
1695: Opcodes.OPC_invokestatic,
1696: 1, // argCount
1697: 1, // return type size
1698: ConstantPool.JavaLangCharacterConstantPoolName,
1699: ConstantPool.ValueOf,
1700: ConstantPool.charCharacterSignature);
1701: } else {
1702: // new Char( char )
1703: if (DEBUG)
1704: System.out
1705: .println(position
1706: + "\t\tinvokespecial java.lang.Character(char)"); //$NON-NLS-1$
1707: newWrapperFor(unboxedTypeID);
1708: dup_x1();
1709: swap();
1710: this .invoke(
1711: Opcodes.OPC_invokespecial,
1712: 1, // argCount
1713: 0, // return type size
1714: ConstantPool.JavaLangCharacterConstantPoolName,
1715: ConstantPool.Init,
1716: ConstantPool.CharConstrSignature);
1717: }
1718: break;
1719: case TypeIds.T_int:
1720: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1721: // invokestatic: Integer.valueOf(int)
1722: if (DEBUG)
1723: System.out
1724: .println(position
1725: + "\t\tinvokestatic java.lang.Integer.valueOf(int)"); //$NON-NLS-1$
1726: this .invoke(
1727: Opcodes.OPC_invokestatic,
1728: 1, // argCount
1729: 1, // return type size
1730: ConstantPool.JavaLangIntegerConstantPoolName,
1731: ConstantPool.ValueOf,
1732: ConstantPool.IntIntegerSignature);
1733: } else {
1734: // new Integer(int)
1735: if (DEBUG)
1736: System.out
1737: .println(position
1738: + "\t\tinvokespecial java.lang.Integer(int)"); //$NON-NLS-1$
1739: newWrapperFor(unboxedTypeID);
1740: dup_x1();
1741: swap();
1742: this .invoke(
1743: Opcodes.OPC_invokespecial,
1744: 1, // argCount
1745: 0, // return type size
1746: ConstantPool.JavaLangIntegerConstantPoolName,
1747: ConstantPool.Init,
1748: ConstantPool.IntConstrSignature);
1749: }
1750: break;
1751: case TypeIds.T_long:
1752: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1753: // invokestatic: Long.valueOf(long)
1754: if (DEBUG)
1755: System.out
1756: .println(position
1757: + "\t\tinvokestatic java.lang.Long.valueOf(long)"); //$NON-NLS-1$
1758: this .invoke(
1759: Opcodes.OPC_invokestatic,
1760: 2, // argCount
1761: 1, // return type size
1762: ConstantPool.JavaLangLongConstantPoolName,
1763: ConstantPool.ValueOf,
1764: ConstantPool.longLongSignature);
1765: } else {
1766: // new Long( long )
1767: if (DEBUG)
1768: System.out.println(position
1769: + "\t\tinvokespecial java.lang.Long(long)"); //$NON-NLS-1$
1770: newWrapperFor(unboxedTypeID);
1771: dup_x2();
1772: dup_x2();
1773: pop();
1774: this .invoke(
1775: Opcodes.OPC_invokespecial,
1776: 2, // argCount
1777: 0, // return type size
1778: ConstantPool.JavaLangLongConstantPoolName,
1779: ConstantPool.Init,
1780: ConstantPool.LongConstrSignature);
1781: }
1782: break;
1783: case TypeIds.T_float:
1784: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1785: // invokestatic: Float.valueOf(float)
1786: if (DEBUG)
1787: System.out
1788: .println(position
1789: + "\t\tinvokestatic java.lang.Float.valueOf(float)"); //$NON-NLS-1$
1790: this .invoke(
1791: Opcodes.OPC_invokestatic,
1792: 1, // argCount
1793: 1, // return type size
1794: ConstantPool.JavaLangFloatConstantPoolName,
1795: ConstantPool.ValueOf,
1796: ConstantPool.floatFloatSignature);
1797: } else {
1798: // new Float(float)
1799: if (DEBUG)
1800: System.out
1801: .println(position
1802: + "\t\tinvokespecial java.lang.Float(float)"); //$NON-NLS-1$
1803: newWrapperFor(unboxedTypeID);
1804: dup_x1();
1805: swap();
1806: this .invoke(
1807: Opcodes.OPC_invokespecial,
1808: 1, // argCount
1809: 0, // return type size
1810: ConstantPool.JavaLangFloatConstantPoolName,
1811: ConstantPool.Init,
1812: ConstantPool.FloatConstrSignature);
1813: }
1814: break;
1815: case TypeIds.T_double:
1816: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1817: // invokestatic: Double.valueOf(double)
1818: if (DEBUG)
1819: System.out
1820: .println(position
1821: + "\t\tinvokestatic java.lang.Double.valueOf(double)"); //$NON-NLS-1$
1822: this .invoke(
1823: Opcodes.OPC_invokestatic,
1824: 2, // argCount
1825: 1, // return type size
1826: ConstantPool.JavaLangDoubleConstantPoolName,
1827: ConstantPool.ValueOf,
1828: ConstantPool.doubleDoubleSignature);
1829: } else {
1830: // new Double( double )
1831: if (DEBUG)
1832: System.out
1833: .println(position
1834: + "\t\tinvokespecial java.lang.Double(double)"); //$NON-NLS-1$
1835: newWrapperFor(unboxedTypeID);
1836: dup_x2();
1837: dup_x2();
1838: pop();
1839:
1840: this .invoke(
1841: Opcodes.OPC_invokespecial,
1842: 2, // argCount
1843: 0, // return type size
1844: ConstantPool.JavaLangDoubleConstantPoolName,
1845: ConstantPool.Init,
1846: ConstantPool.DoubleConstrSignature);
1847: }
1848:
1849: break;
1850: case TypeIds.T_boolean:
1851: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1852: // invokestatic: Boolean.valueOf(boolean)
1853: if (DEBUG)
1854: System.out
1855: .println(position
1856: + "\t\tinvokestatic java.lang.Boolean.valueOf(boolean)"); //$NON-NLS-1$
1857: this .invoke(
1858: Opcodes.OPC_invokestatic,
1859: 1, // argCount
1860: 1, // return type size
1861: ConstantPool.JavaLangBooleanConstantPoolName,
1862: ConstantPool.ValueOf,
1863: ConstantPool.booleanBooleanSignature);
1864: } else {
1865: // new Boolean(boolean)
1866: if (DEBUG)
1867: System.out
1868: .println(position
1869: + "\t\tinvokespecial java.lang.Boolean(boolean)"); //$NON-NLS-1$
1870: newWrapperFor(unboxedTypeID);
1871: dup_x1();
1872: swap();
1873: this .invoke(
1874: Opcodes.OPC_invokespecial,
1875: 1, // argCount
1876: 0, // return type size
1877: ConstantPool.JavaLangBooleanConstantPoolName,
1878: ConstantPool.Init,
1879: ConstantPool.BooleanConstrSignature);
1880: }
1881: }
1882: }
1883:
1884: /**
1885: * Macro for building a class descriptor object
1886: */
1887: public void generateClassLiteralAccessForType(
1888: TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
1889: BranchLabel endLabel;
1890: ExceptionLabel anyExceptionHandler;
1891: int saveStackSize;
1892: if (accessedType.isBaseType()
1893: && accessedType != TypeBinding.NULL) {
1894: this .getTYPE(accessedType.id);
1895: return;
1896: }
1897:
1898: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
1899: // generation using the new ldc_w bytecode
1900: this .ldc(accessedType);
1901: } else {
1902: endLabel = new BranchLabel(this );
1903: if (syntheticFieldBinding != null) { // non interface case
1904: this .getstatic(syntheticFieldBinding);
1905: this .dup();
1906: this .ifnonnull(endLabel);
1907: this .pop();
1908: }
1909:
1910: /* Macro for building a class descriptor object... using or not a field cache to store it into...
1911: this sequence is responsible for building the actual class descriptor.
1912:
1913: If the fieldCache is set, then it is supposed to be the body of a synthetic access method
1914: factoring the actual descriptor creation out of the invocation site (saving space).
1915: If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
1916: we have no way to get a hand on the field cache to do better. */
1917:
1918: // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
1919: anyExceptionHandler = new ExceptionLabel(this ,
1920: TypeBinding.NULL /*represents ClassNotFoundException*/);
1921: anyExceptionHandler.placeStart();
1922: this
1923: .ldc(accessedType == TypeBinding.NULL ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
1924: this .invokeClassForName();
1925:
1926: /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
1927: if (accessedType == BaseTypes.NullBinding) {
1928: this.ldc("java.lang.Object"); //$NON-NLS-1$
1929: } else if (accessedType.isArrayType()) {
1930: this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
1931: } else {
1932: // we make it an array type (to avoid class initialization)
1933: this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
1934: }
1935: this.invokeClassForName();
1936: if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
1937: this.invokeJavaLangClassGetComponentType();
1938: }
1939: */
1940: /* We need to protect the runtime code from binary inconsistencies
1941: in case the accessedType is missing, the ClassNotFoundException has to be converted
1942: into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
1943: anyExceptionHandler.placeEnd();
1944:
1945: if (syntheticFieldBinding != null) { // non interface case
1946: this .dup();
1947: this .putstatic(syntheticFieldBinding);
1948: }
1949: this .goto_(endLabel);
1950:
1951: // Generate the body of the exception handler
1952: saveStackSize = stackDepth;
1953: stackDepth = 1;
1954: /* ClassNotFoundException on stack -- the class literal could be doing more things
1955: on the stack, which means that the stack may not be empty at this point in the
1956: above code gen. So we save its state and restart it from 1. */
1957:
1958: anyExceptionHandler.place();
1959:
1960: // Transform the current exception, and repush and throw a
1961: // NoClassDefFoundError(ClassNotFound.getMessage())
1962:
1963: this .newNoClassDefFoundError();
1964: this .dup_x1();
1965: this .swap();
1966:
1967: // Retrieve the message from the old exception
1968: this .invokeThrowableGetMessage();
1969:
1970: // Send the constructor taking a message string as an argument
1971: this .invokeNoClassDefFoundErrorStringConstructor();
1972: this .athrow();
1973: stackDepth = saveStackSize;
1974: endLabel.place();
1975: }
1976: }
1977:
1978: /**
1979: * This method generates the code attribute bytecode
1980: */
1981: final public void generateCodeAttributeForProblemMethod(
1982: String problemMessage) {
1983: newJavaLangError();
1984: dup();
1985: ldc(problemMessage);
1986: invokeJavaLangErrorConstructor();
1987: athrow();
1988: }
1989:
1990: public void generateConstant(Constant constant,
1991: int implicitConversionCode) {
1992: int targetTypeID = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
1993: if (targetTypeID == 0)
1994: targetTypeID = constant.typeID(); // use default constant type
1995: switch (targetTypeID) {
1996: case TypeIds.T_boolean:
1997: generateInlinedValue(constant.booleanValue());
1998: break;
1999: case TypeIds.T_char:
2000: generateInlinedValue(constant.charValue());
2001: break;
2002: case TypeIds.T_byte:
2003: generateInlinedValue(constant.byteValue());
2004: break;
2005: case TypeIds.T_short:
2006: generateInlinedValue(constant.shortValue());
2007: break;
2008: case TypeIds.T_int:
2009: generateInlinedValue(constant.intValue());
2010: break;
2011: case TypeIds.T_long:
2012: generateInlinedValue(constant.longValue());
2013: break;
2014: case TypeIds.T_float:
2015: generateInlinedValue(constant.floatValue());
2016: break;
2017: case TypeIds.T_double:
2018: generateInlinedValue(constant.doubleValue());
2019: break;
2020: case TypeIds.T_JavaLangString:
2021: ldc(constant.stringValue());
2022: }
2023: if ((implicitConversionCode & TypeIds.BOXING) != 0) {
2024: // need boxing
2025: generateBoxingConversion(targetTypeID);
2026: }
2027: }
2028:
2029: public void generateEmulatedReadAccessForField(
2030: FieldBinding fieldBinding) {
2031: this .generateEmulationForField(fieldBinding);
2032: // swap the field with the receiver
2033: this .swap();
2034: this .invokeJavaLangReflectFieldGetter(fieldBinding.type.id);
2035: if (!fieldBinding.type.isBaseType()) {
2036: this .checkcast(fieldBinding.type);
2037: }
2038: }
2039:
2040: public void generateEmulatedWriteAccessForField(
2041: FieldBinding fieldBinding) {
2042: this .invokeJavaLangReflectFieldSetter(fieldBinding.type.id);
2043: }
2044:
2045: public void generateEmulationForConstructor(Scope scope,
2046: MethodBinding methodBinding) {
2047: // leave a java.lang.reflect.Field object on the stack
2048: this .ldc(String.valueOf(
2049: methodBinding.declaringClass.constantPoolName())
2050: .replace('/', '.'));
2051: this .invokeClassForName();
2052: int paramLength = methodBinding.parameters.length;
2053: this .generateInlinedValue(paramLength);
2054: this .newArray(scope.createArrayType(scope.getType(
2055: TypeConstants.JAVA_LANG_CLASS, 3), 1));
2056: if (paramLength > 0) {
2057: this .dup();
2058: for (int i = 0; i < paramLength; i++) {
2059: this .generateInlinedValue(i);
2060: TypeBinding parameter = methodBinding.parameters[i];
2061: if (parameter.isBaseType()) {
2062: this .getTYPE(parameter.id);
2063: } else if (parameter.isArrayType()) {
2064: ArrayBinding array = (ArrayBinding) parameter;
2065: if (array.leafComponentType.isBaseType()) {
2066: this .getTYPE(array.leafComponentType.id);
2067: } else {
2068: this .ldc(String.valueOf(
2069: array.leafComponentType
2070: .constantPoolName()).replace(
2071: '/', '.'));
2072: this .invokeClassForName();
2073: }
2074: int dimensions = array.dimensions;
2075: this .generateInlinedValue(dimensions);
2076: this .newarray(TypeIds.T_int);
2077: this .invokeArrayNewInstance();
2078: this .invokeObjectGetClass();
2079: } else {
2080: // parameter is a reference binding
2081: this .ldc(String.valueOf(
2082: methodBinding.declaringClass
2083: .constantPoolName()).replace('/',
2084: '.'));
2085: this .invokeClassForName();
2086: }
2087: this .aastore();
2088: if (i < paramLength - 1) {
2089: this .dup();
2090: }
2091: }
2092: }
2093: this .invokeClassGetDeclaredConstructor();
2094: this .dup();
2095: this .iconst_1();
2096: this .invokeAccessibleObjectSetAccessible();
2097: }
2098:
2099: public void generateEmulationForField(FieldBinding fieldBinding) {
2100: // leave a java.lang.reflect.Field object on the stack
2101: this .ldc(String.valueOf(
2102: fieldBinding.declaringClass.constantPoolName())
2103: .replace('/', '.'));
2104: this .invokeClassForName();
2105: this .ldc(String.valueOf(fieldBinding.name));
2106: this .invokeClassGetDeclaredField();
2107: this .dup();
2108: this .iconst_1();
2109: this .invokeAccessibleObjectSetAccessible();
2110: }
2111:
2112: public void generateEmulationForMethod(Scope scope,
2113: MethodBinding methodBinding) {
2114: // leave a java.lang.reflect.Field object on the stack
2115: this .ldc(String.valueOf(
2116: methodBinding.declaringClass.constantPoolName())
2117: .replace('/', '.'));
2118: this .invokeClassForName();
2119: this .ldc(String.valueOf(methodBinding.selector));
2120: int paramLength = methodBinding.parameters.length;
2121: this .generateInlinedValue(paramLength);
2122: this .newArray(scope.createArrayType(scope.getType(
2123: TypeConstants.JAVA_LANG_CLASS, 3), 1));
2124: if (paramLength > 0) {
2125: this .dup();
2126: for (int i = 0; i < paramLength; i++) {
2127: this .generateInlinedValue(i);
2128: TypeBinding parameter = methodBinding.parameters[i];
2129: if (parameter.isBaseType()) {
2130: this .getTYPE(parameter.id);
2131: } else if (parameter.isArrayType()) {
2132: ArrayBinding array = (ArrayBinding) parameter;
2133: if (array.leafComponentType.isBaseType()) {
2134: this .getTYPE(array.leafComponentType.id);
2135: } else {
2136: this .ldc(String.valueOf(
2137: array.leafComponentType
2138: .constantPoolName()).replace(
2139: '/', '.'));
2140: this .invokeClassForName();
2141: }
2142: int dimensions = array.dimensions;
2143: this .generateInlinedValue(dimensions);
2144: this .newarray(TypeIds.T_int);
2145: this .invokeArrayNewInstance();
2146: this .invokeObjectGetClass();
2147: } else {
2148: // parameter is a reference binding
2149: this .ldc(String.valueOf(
2150: methodBinding.declaringClass
2151: .constantPoolName()).replace('/',
2152: '.'));
2153: this .invokeClassForName();
2154: }
2155: this .aastore();
2156: if (i < paramLength - 1) {
2157: this .dup();
2158: }
2159: }
2160: }
2161: this .invokeClassGetDeclaredMethod();
2162: this .dup();
2163: this .iconst_1();
2164: this .invokeAccessibleObjectSetAccessible();
2165: }
2166:
2167: private void generateFieldAccess(byte opcode, int returnTypeSize,
2168: char[] declaringClass, char[] name, char[] signature) {
2169: countLabels = 0;
2170: switch (opcode) {
2171: case Opcodes.OPC_getfield:
2172: if (returnTypeSize == 2) {
2173: stackDepth++;
2174: }
2175: break;
2176: case Opcodes.OPC_getstatic:
2177: if (returnTypeSize == 2) {
2178: stackDepth += 2;
2179: } else {
2180: stackDepth++;
2181: }
2182: break;
2183: case Opcodes.OPC_putfield:
2184: if (returnTypeSize == 2) {
2185: stackDepth -= 3;
2186: } else {
2187: stackDepth -= 2;
2188: }
2189: break;
2190: case Opcodes.OPC_putstatic:
2191: if (returnTypeSize == 2) {
2192: stackDepth -= 2;
2193: } else {
2194: stackDepth--;
2195: }
2196: }
2197: if (stackDepth > stackMax) {
2198: stackMax = stackDepth;
2199: }
2200: if (classFileOffset + 2 >= bCodeStream.length) {
2201: resizeByteArray();
2202: }
2203: position++;
2204: bCodeStream[classFileOffset++] = opcode;
2205: writeUnsignedShort(constantPool.literalIndexForField(
2206: declaringClass, name, signature));
2207: }
2208:
2209: private void generateFieldAccess(byte opcode, int returnTypeSize,
2210: ReferenceBinding binding, char[] name, TypeBinding type) {
2211: if (binding.isNestedType()) {
2212: this .classFile.recordInnerClasses(binding);
2213: }
2214: TypeBinding leafComponentType = type.leafComponentType();
2215: if (leafComponentType.isNestedType()) {
2216: this .classFile.recordInnerClasses(leafComponentType);
2217: }
2218: this .generateFieldAccess(opcode, returnTypeSize, binding
2219: .constantPoolName(), name, type.signature());
2220: }
2221:
2222: /**
2223: * Generates the sequence of instructions which will perform the conversion of the expression
2224: * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
2225: * @param implicitConversionCode int
2226: */
2227: public void generateImplicitConversion(int implicitConversionCode) {
2228: if ((implicitConversionCode & TypeIds.UNBOXING) != 0) {
2229: final int typeId = implicitConversionCode
2230: & TypeIds.COMPILE_TYPE_MASK;
2231: generateUnboxingConversion(typeId);
2232: // unboxing can further involve base type conversions
2233: }
2234: switch (implicitConversionCode
2235: & TypeIds.IMPLICIT_CONVERSION_MASK) {
2236: case TypeIds.Float2Char:
2237: this .f2i();
2238: this .i2c();
2239: break;
2240: case TypeIds.Double2Char:
2241: this .d2i();
2242: this .i2c();
2243: break;
2244: case TypeIds.Int2Char:
2245: case TypeIds.Short2Char:
2246: case TypeIds.Byte2Char:
2247: this .i2c();
2248: break;
2249: case TypeIds.Long2Char:
2250: this .l2i();
2251: this .i2c();
2252: break;
2253: case TypeIds.Char2Float:
2254: case TypeIds.Short2Float:
2255: case TypeIds.Int2Float:
2256: case TypeIds.Byte2Float:
2257: this .i2f();
2258: break;
2259: case TypeIds.Double2Float:
2260: this .d2f();
2261: break;
2262: case TypeIds.Long2Float:
2263: this .l2f();
2264: break;
2265: case TypeIds.Float2Byte:
2266: this .f2i();
2267: this .i2b();
2268: break;
2269: case TypeIds.Double2Byte:
2270: this .d2i();
2271: this .i2b();
2272: break;
2273: case TypeIds.Int2Byte:
2274: case TypeIds.Short2Byte:
2275: case TypeIds.Char2Byte:
2276: this .i2b();
2277: break;
2278: case TypeIds.Long2Byte:
2279: this .l2i();
2280: this .i2b();
2281: break;
2282: case TypeIds.Byte2Double:
2283: case TypeIds.Char2Double:
2284: case TypeIds.Short2Double:
2285: case TypeIds.Int2Double:
2286: this .i2d();
2287: break;
2288: case TypeIds.Float2Double:
2289: this .f2d();
2290: break;
2291: case TypeIds.Long2Double:
2292: this .l2d();
2293: break;
2294: case TypeIds.Byte2Short:
2295: case TypeIds.Char2Short:
2296: case TypeIds.Int2Short:
2297: this .i2s();
2298: break;
2299: case TypeIds.Double2Short:
2300: this .d2i();
2301: this .i2s();
2302: break;
2303: case TypeIds.Long2Short:
2304: this .l2i();
2305: this .i2s();
2306: break;
2307: case TypeIds.Float2Short:
2308: this .f2i();
2309: this .i2s();
2310: break;
2311: case TypeIds.Double2Int:
2312: this .d2i();
2313: break;
2314: case TypeIds.Float2Int:
2315: this .f2i();
2316: break;
2317: case TypeIds.Long2Int:
2318: this .l2i();
2319: break;
2320: case TypeIds.Int2Long:
2321: case TypeIds.Char2Long:
2322: case TypeIds.Byte2Long:
2323: case TypeIds.Short2Long:
2324: this .i2l();
2325: break;
2326: case TypeIds.Double2Long:
2327: this .d2l();
2328: break;
2329: case TypeIds.Float2Long:
2330: this .f2l();
2331: }
2332: if ((implicitConversionCode & TypeIds.BOXING) != 0) {
2333: // need to unbox/box the constant
2334: final int typeId = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
2335: generateBoxingConversion(typeId);
2336: }
2337: }
2338:
2339: public void generateInlinedValue(boolean inlinedValue) {
2340: if (inlinedValue)
2341: this .iconst_1();
2342: else
2343: this .iconst_0();
2344: }
2345:
2346: public void generateInlinedValue(byte inlinedValue) {
2347: switch (inlinedValue) {
2348: case -1:
2349: this .iconst_m1();
2350: break;
2351: case 0:
2352: this .iconst_0();
2353: break;
2354: case 1:
2355: this .iconst_1();
2356: break;
2357: case 2:
2358: this .iconst_2();
2359: break;
2360: case 3:
2361: this .iconst_3();
2362: break;
2363: case 4:
2364: this .iconst_4();
2365: break;
2366: case 5:
2367: this .iconst_5();
2368: break;
2369: default:
2370: if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
2371: this .bipush(inlinedValue);
2372: return;
2373: }
2374: }
2375: }
2376:
2377: public void generateInlinedValue(char inlinedValue) {
2378: switch (inlinedValue) {
2379: case 0:
2380: this .iconst_0();
2381: break;
2382: case 1:
2383: this .iconst_1();
2384: break;
2385: case 2:
2386: this .iconst_2();
2387: break;
2388: case 3:
2389: this .iconst_3();
2390: break;
2391: case 4:
2392: this .iconst_4();
2393: break;
2394: case 5:
2395: this .iconst_5();
2396: break;
2397: default:
2398: if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
2399: this .bipush((byte) inlinedValue);
2400: return;
2401: }
2402: if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
2403: this .sipush(inlinedValue);
2404: return;
2405: }
2406: this .ldc(inlinedValue);
2407: }
2408: }
2409:
2410: public void generateInlinedValue(double inlinedValue) {
2411: if (inlinedValue == 0.0) {
2412: if (Double.doubleToLongBits(inlinedValue) != 0L)
2413: this .ldc2_w(inlinedValue);
2414: else
2415: this .dconst_0();
2416: return;
2417: }
2418: if (inlinedValue == 1.0) {
2419: this .dconst_1();
2420: return;
2421: }
2422: this .ldc2_w(inlinedValue);
2423: }
2424:
2425: public void generateInlinedValue(float inlinedValue) {
2426: if (inlinedValue == 0.0f) {
2427: if (Float.floatToIntBits(inlinedValue) != 0)
2428: this .ldc(inlinedValue);
2429: else
2430: this .fconst_0();
2431: return;
2432: }
2433: if (inlinedValue == 1.0f) {
2434: this .fconst_1();
2435: return;
2436: }
2437: if (inlinedValue == 2.0f) {
2438: this .fconst_2();
2439: return;
2440: }
2441: this .ldc(inlinedValue);
2442: }
2443:
2444: public void generateInlinedValue(int inlinedValue) {
2445: switch (inlinedValue) {
2446: case -1:
2447: this .iconst_m1();
2448: break;
2449: case 0:
2450: this .iconst_0();
2451: break;
2452: case 1:
2453: this .iconst_1();
2454: break;
2455: case 2:
2456: this .iconst_2();
2457: break;
2458: case 3:
2459: this .iconst_3();
2460: break;
2461: case 4:
2462: this .iconst_4();
2463: break;
2464: case 5:
2465: this .iconst_5();
2466: break;
2467: default:
2468: if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
2469: this .bipush((byte) inlinedValue);
2470: return;
2471: }
2472: if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
2473: this .sipush(inlinedValue);
2474: return;
2475: }
2476: this .ldc(inlinedValue);
2477: }
2478: }
2479:
2480: public void generateInlinedValue(long inlinedValue) {
2481: if (inlinedValue == 0) {
2482: this .lconst_0();
2483: return;
2484: }
2485: if (inlinedValue == 1) {
2486: this .lconst_1();
2487: return;
2488: }
2489: this .ldc2_w(inlinedValue);
2490: }
2491:
2492: public void generateInlinedValue(short inlinedValue) {
2493: switch (inlinedValue) {
2494: case -1:
2495: this .iconst_m1();
2496: break;
2497: case 0:
2498: this .iconst_0();
2499: break;
2500: case 1:
2501: this .iconst_1();
2502: break;
2503: case 2:
2504: this .iconst_2();
2505: break;
2506: case 3:
2507: this .iconst_3();
2508: break;
2509: case 4:
2510: this .iconst_4();
2511: break;
2512: case 5:
2513: this .iconst_5();
2514: break;
2515: default:
2516: if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
2517: this .bipush((byte) inlinedValue);
2518: return;
2519: }
2520: this .sipush(inlinedValue);
2521: }
2522: }
2523:
2524: public void generateOuterAccess(Object[] mappingSequence,
2525: ASTNode invocationSite, Binding target, Scope scope) {
2526: if (mappingSequence == null) {
2527: if (target instanceof LocalVariableBinding) {
2528: scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
2529: } else {
2530: scope.problemReporter().noSuchEnclosingInstance(
2531: (ReferenceBinding) target, invocationSite,
2532: false);
2533: }
2534: return;
2535: }
2536: if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
2537: scope.problemReporter().noSuchEnclosingInstance(
2538: (ReferenceBinding) target, invocationSite, true);
2539: return;
2540: } else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
2541: scope.problemReporter().noSuchEnclosingInstance(
2542: (ReferenceBinding) target, invocationSite, false);
2543: return;
2544: }
2545:
2546: if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
2547: this .aload_0();
2548: return;
2549: } else if (mappingSequence[0] instanceof FieldBinding) {
2550: FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
2551: this .aload_0();
2552: this .getfield(fieldBinding);
2553: } else {
2554: load((LocalVariableBinding) mappingSequence[0]);
2555: }
2556: for (int i = 1, length = mappingSequence.length; i < length; i++) {
2557: if (mappingSequence[i] instanceof FieldBinding) {
2558: FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
2559: this .getfield(fieldBinding);
2560: } else {
2561: this .invokestatic((MethodBinding) mappingSequence[i]);
2562: }
2563: }
2564: }
2565:
2566: public void generateReturnBytecode(Expression expression) {
2567:
2568: if (expression == null) {
2569: this .return_();
2570: } else {
2571: final int implicitConversion = expression.implicitConversion;
2572: if ((implicitConversion & TypeIds.BOXING) != 0) {
2573: this .areturn();
2574: return;
2575: }
2576: int runtimeType = (implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
2577: switch (runtimeType) {
2578: case TypeIds.T_boolean:
2579: case TypeIds.T_int:
2580: this .ireturn();
2581: break;
2582: case TypeIds.T_float:
2583: this .freturn();
2584: break;
2585: case TypeIds.T_long:
2586: this .lreturn();
2587: break;
2588: case TypeIds.T_double:
2589: this .dreturn();
2590: break;
2591: default:
2592: this .areturn();
2593: }
2594: }
2595: }
2596:
2597: /**
2598: * The equivalent code performs a string conversion:
2599: *
2600: * @param blockScope the given blockScope
2601: * @param oper1 the first expression
2602: * @param oper2 the second expression
2603: */
2604: public void generateStringConcatenationAppend(
2605: BlockScope blockScope, Expression oper1, Expression oper2) {
2606: int pc;
2607: if (oper1 == null) {
2608: /* Operand is already on the stack, and maybe nil:
2609: note type1 is always to java.lang.String here.*/
2610: this .newStringContatenation();
2611: this .dup_x1();
2612: this .swap();
2613: // If argument is reference type, need to transform it
2614: // into a string (handles null case)
2615: this .invokeStringValueOf(TypeIds.T_JavaLangObject);
2616: this .invokeStringConcatenationStringConstructor();
2617: } else {
2618: pc = position;
2619: oper1.generateOptimizedStringConcatenationCreation(
2620: blockScope, this , oper1.implicitConversion
2621: & TypeIds.COMPILE_TYPE_MASK);
2622: this .recordPositionsFrom(pc, oper1.sourceStart);
2623: }
2624: pc = position;
2625: oper2.generateOptimizedStringConcatenation(blockScope, this ,
2626: oper2.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
2627: this .recordPositionsFrom(pc, oper2.sourceStart);
2628: this .invokeStringConcatenationToString();
2629: }
2630:
2631: /**
2632: * @param accessBinding the access method binding to generate
2633: */
2634: public void generateSyntheticBodyForConstructorAccess(
2635: SyntheticMethodBinding accessBinding) {
2636:
2637: initializeMaxLocals(accessBinding);
2638:
2639: MethodBinding constructorBinding = accessBinding.targetMethod;
2640: TypeBinding[] parameters = constructorBinding.parameters;
2641: int length = parameters.length;
2642: int resolvedPosition = 1;
2643: this .aload_0();
2644: // special name&ordinal argument generation for enum constructors
2645: TypeBinding declaringClass = constructorBinding.declaringClass;
2646: if (declaringClass.erasure().id == TypeIds.T_JavaLangEnum
2647: || declaringClass.isEnum()) {
2648: this .aload_1(); // pass along name param as name arg
2649: this .iload_2(); // pass along ordinal param as ordinal arg
2650: resolvedPosition += 2;
2651: }
2652: if (declaringClass.isNestedType()) {
2653: NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
2654: SyntheticArgumentBinding[] syntheticArguments = nestedType
2655: .syntheticEnclosingInstances();
2656: for (int i = 0; i < (syntheticArguments == null ? 0
2657: : syntheticArguments.length); i++) {
2658: TypeBinding type;
2659: load((type = syntheticArguments[i].type),
2660: resolvedPosition);
2661: if ((type == TypeBinding.DOUBLE)
2662: || (type == TypeBinding.LONG))
2663: resolvedPosition += 2;
2664: else
2665: resolvedPosition++;
2666: }
2667: }
2668: for (int i = 0; i < length; i++) {
2669: load(parameters[i], resolvedPosition);
2670: if ((parameters[i] == TypeBinding.DOUBLE)
2671: || (parameters[i] == TypeBinding.LONG))
2672: resolvedPosition += 2;
2673: else
2674: resolvedPosition++;
2675: }
2676:
2677: if (declaringClass.isNestedType()) {
2678: NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
2679: SyntheticArgumentBinding[] syntheticArguments = nestedType
2680: .syntheticOuterLocalVariables();
2681: for (int i = 0; i < (syntheticArguments == null ? 0
2682: : syntheticArguments.length); i++) {
2683: TypeBinding type;
2684: load((type = syntheticArguments[i].type),
2685: resolvedPosition);
2686: if ((type == TypeBinding.DOUBLE)
2687: || (type == TypeBinding.LONG))
2688: resolvedPosition += 2;
2689: else
2690: resolvedPosition++;
2691: }
2692: }
2693: this .invokespecial(constructorBinding);
2694: this .return_();
2695: }
2696:
2697: //static X valueOf(String name) {
2698: // return (X) Enum.valueOf(X.class, name);
2699: //}
2700: public void generateSyntheticBodyForEnumValueOf(
2701: SyntheticMethodBinding methodBinding) {
2702: initializeMaxLocals(methodBinding);
2703: final ReferenceBinding declaringClass = methodBinding.declaringClass;
2704: this .ldc(declaringClass);
2705: this .aload_0();
2706: this .invokeJavaLangEnumvalueOf(declaringClass);
2707: this .checkcast(declaringClass);
2708: this .areturn();
2709: }
2710:
2711: //static X[] values() {
2712: // X[] values;
2713: // int length;
2714: // X[] result;
2715: // System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length)
2716: // return result;
2717: //}
2718: public void generateSyntheticBodyForEnumValues(
2719: SyntheticMethodBinding methodBinding) {
2720: ClassScope scope = ((SourceTypeBinding) methodBinding.declaringClass).scope;
2721: FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
2722: initializeMaxLocals(methodBinding);
2723: TypeBinding enumArray = methodBinding.returnType;
2724:
2725: this .getstatic(enumValuesSyntheticfield);
2726: this .dup();
2727: this .astore_0();
2728: this .iconst_0();
2729: this .aload_0();
2730: this .arraylength();
2731: this .dup();
2732: this .istore_1();
2733: this .newArray((ArrayBinding) enumArray);
2734: this .dup();
2735: this .astore_2();
2736: this .iconst_0();
2737: this .iload_1();
2738: this .invokeSystemArraycopy();
2739: this .aload_2();
2740: this .areturn();
2741: }
2742:
2743: public void generateSyntheticBodyForFieldReadAccess(
2744: SyntheticMethodBinding accessBinding) {
2745: initializeMaxLocals(accessBinding);
2746: FieldBinding fieldBinding = accessBinding.targetReadField;
2747: if (fieldBinding.isStatic())
2748: this .getstatic(fieldBinding);
2749: else {
2750: this .aload_0();
2751: this .getfield(fieldBinding);
2752: }
2753: switch (fieldBinding.type.id) {
2754: // case T_void :
2755: // this.return_();
2756: // break;
2757: case TypeIds.T_boolean:
2758: case TypeIds.T_byte:
2759: case TypeIds.T_char:
2760: case TypeIds.T_short:
2761: case TypeIds.T_int:
2762: this .ireturn();
2763: break;
2764: case TypeIds.T_long:
2765: this .lreturn();
2766: break;
2767: case TypeIds.T_float:
2768: this .freturn();
2769: break;
2770: case TypeIds.T_double:
2771: this .dreturn();
2772: break;
2773: default:
2774: this .areturn();
2775: }
2776: }
2777:
2778: public void generateSyntheticBodyForFieldWriteAccess(
2779: SyntheticMethodBinding accessBinding) {
2780: initializeMaxLocals(accessBinding);
2781: FieldBinding fieldBinding = accessBinding.targetWriteField;
2782: if (fieldBinding.isStatic()) {
2783: load(fieldBinding.type, 0);
2784: this .putstatic(fieldBinding);
2785: } else {
2786: this .aload_0();
2787: load(fieldBinding.type, 1);
2788: this .putfield(fieldBinding);
2789: }
2790: this .return_();
2791: }
2792:
2793: public void generateSyntheticBodyForMethodAccess(
2794: SyntheticMethodBinding accessMethod) {
2795:
2796: initializeMaxLocals(accessMethod);
2797: MethodBinding targetMethod = accessMethod.targetMethod;
2798: TypeBinding[] parameters = targetMethod.parameters;
2799: int length = parameters.length;
2800: TypeBinding[] arguments = accessMethod.kind == SyntheticMethodBinding.BridgeMethod ? accessMethod.parameters
2801: : null;
2802: int resolvedPosition;
2803: if (targetMethod.isStatic())
2804: resolvedPosition = 0;
2805: else {
2806: this .aload_0();
2807: resolvedPosition = 1;
2808: }
2809: for (int i = 0; i < length; i++) {
2810: TypeBinding parameter = parameters[i];
2811: if (arguments != null) { // for bridge methods
2812: TypeBinding argument = arguments[i];
2813: load(argument, resolvedPosition);
2814: if (argument != parameter)
2815: checkcast(parameter);
2816: } else {
2817: load(parameter, resolvedPosition);
2818: }
2819: if ((parameter == TypeBinding.DOUBLE)
2820: || (parameter == TypeBinding.LONG))
2821: resolvedPosition += 2;
2822: else
2823: resolvedPosition++;
2824: }
2825: if (targetMethod.isStatic())
2826: this .invokestatic(targetMethod);
2827: else {
2828: if (targetMethod.isConstructor()
2829: || targetMethod.isPrivate()
2830: // qualified super "X.super.foo()" targets methods from superclass
2831: || accessMethod.kind == SyntheticMethodBinding.SuperMethodAccess) {
2832: this .invokespecial(targetMethod);
2833: } else {
2834: if (targetMethod.declaringClass.isInterface()) { // interface or annotation type
2835: this .invokeinterface(targetMethod);
2836: } else {
2837: this .invokevirtual(targetMethod);
2838: }
2839: }
2840: }
2841: switch (targetMethod.returnType.id) {
2842: case TypeIds.T_void:
2843: this .return_();
2844: break;
2845: case TypeIds.T_boolean:
2846: case TypeIds.T_byte:
2847: case TypeIds.T_char:
2848: case TypeIds.T_short:
2849: case TypeIds.T_int:
2850: this .ireturn();
2851: break;
2852: case TypeIds.T_long:
2853: this .lreturn();
2854: break;
2855: case TypeIds.T_float:
2856: this .freturn();
2857: break;
2858: case TypeIds.T_double:
2859: this .dreturn();
2860: break;
2861: default:
2862: TypeBinding accessErasure = accessMethod.returnType
2863: .erasure();
2864: if (!targetMethod.returnType
2865: .isCompatibleWith(accessErasure))
2866: this .checkcast(accessErasure); // for bridge methods
2867: this .areturn();
2868: }
2869: }
2870:
2871: public void generateSyntheticBodyForSwitchTable(
2872: SyntheticMethodBinding methodBinding) {
2873: ClassScope scope = ((SourceTypeBinding) methodBinding.declaringClass).scope;
2874: initializeMaxLocals(methodBinding);
2875: final BranchLabel nullLabel = new BranchLabel(this );
2876: FieldBinding syntheticFieldBinding = methodBinding.targetReadField;
2877:
2878: this .getstatic(syntheticFieldBinding);
2879: this .dup();
2880: this .ifnull(nullLabel);
2881: this .areturn();
2882: this .pushOnStack(syntheticFieldBinding.type);
2883: nullLabel.place();
2884: this .pop();
2885: ReferenceBinding enumBinding = (ReferenceBinding) methodBinding.targetEnumType;
2886: ArrayBinding arrayBinding = scope.createArrayType(enumBinding,
2887: 1);
2888: this .invokeJavaLangEnumValues(enumBinding, arrayBinding);
2889: this .arraylength();
2890: this .newarray(ClassFileConstants.INT_ARRAY);
2891: this .astore_0();
2892: LocalVariableBinding localVariableBinding = new LocalVariableBinding(
2893: " tab".toCharArray(), scope.createArrayType(TypeBinding.INT, 1), 0, false); //$NON-NLS-1$
2894: this .addVariable(localVariableBinding);
2895: final FieldBinding[] fields = enumBinding.fields();
2896: if (fields != null) {
2897: for (int i = 0, max = fields.length; i < max; i++) {
2898: FieldBinding fieldBinding = fields[i];
2899: if ((fieldBinding.getAccessFlags() & ClassFileConstants.AccEnum) != 0) {
2900: final BranchLabel endLabel = new BranchLabel(this );
2901: final ExceptionLabel anyExceptionHandler = new ExceptionLabel(
2902: this , TypeBinding.LONG /* represents NoSuchFieldError*/);
2903: anyExceptionHandler.placeStart();
2904: this .aload_0();
2905: this .getstatic(fieldBinding);
2906: this .invokeEnumOrdinal(enumBinding
2907: .constantPoolName());
2908: this .generateInlinedValue(fieldBinding.id + 1); // zero should not be returned see bug 141810
2909: this .iastore();
2910: anyExceptionHandler.placeEnd();
2911: this .goto_(endLabel);
2912: // Generate the body of the exception handler
2913: this
2914: .pushExceptionOnStack(TypeBinding.LONG /*represents NoSuchFieldError*/);
2915: anyExceptionHandler.place();
2916: this .pop(); // we don't use it so we can pop it
2917: endLabel.place();
2918: }
2919: }
2920: }
2921: this .aload_0();
2922: this .dup();
2923: this .putstatic(syntheticFieldBinding);
2924: areturn();
2925: this .removeVariable(localVariableBinding);
2926: }
2927:
2928: /**
2929: * Code responsible to generate the suitable code to supply values for the synthetic enclosing
2930: * instance arguments of a constructor invocation of a nested type.
2931: */
2932: public void generateSyntheticEnclosingInstanceValues(
2933: BlockScope currentScope, ReferenceBinding targetType,
2934: Expression enclosingInstance, ASTNode invocationSite) {
2935:
2936: // supplying enclosing instance for the anonymous type's superclass
2937: ReferenceBinding checkedTargetType = targetType
2938: .isAnonymousType() ? (ReferenceBinding) targetType
2939: .super class().erasure() : targetType;
2940: boolean hasExtraEnclosingInstance = enclosingInstance != null;
2941: if (hasExtraEnclosingInstance
2942: && (!checkedTargetType.isNestedType() || checkedTargetType
2943: .isStatic())) {
2944: currentScope.problemReporter()
2945: .unnecessaryEnclosingInstanceSpecification(
2946: enclosingInstance, checkedTargetType);
2947: return;
2948: }
2949:
2950: // perform some emulation work in case there is some and we are inside a local type only
2951: ReferenceBinding[] syntheticArgumentTypes;
2952: if ((syntheticArgumentTypes = targetType
2953: .syntheticEnclosingInstanceTypes()) != null) {
2954:
2955: ReferenceBinding targetEnclosingType = checkedTargetType
2956: .enclosingType();
2957: long compliance = currentScope.compilerOptions().complianceLevel;
2958:
2959: // deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
2960: // always consider it if complying to 1.5
2961: boolean denyEnclosingArgInConstructorCall;
2962: if (compliance <= ClassFileConstants.JDK1_3) {
2963: denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression;
2964: } else if (compliance == ClassFileConstants.JDK1_4) {
2965: denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
2966: || invocationSite instanceof ExplicitConstructorCall
2967: && ((ExplicitConstructorCall) invocationSite)
2968: .isSuperAccess();
2969: } else {
2970: //compliance >= JDK1_5
2971: denyEnclosingArgInConstructorCall = (invocationSite instanceof AllocationExpression || invocationSite instanceof ExplicitConstructorCall
2972: && ((ExplicitConstructorCall) invocationSite)
2973: .isSuperAccess())
2974: && !targetType.isLocalType();
2975: }
2976:
2977: boolean complyTo14 = compliance >= ClassFileConstants.JDK1_4;
2978: for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
2979: ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
2980: if (hasExtraEnclosingInstance
2981: && syntheticArgType == targetEnclosingType) {
2982: hasExtraEnclosingInstance = false;
2983: enclosingInstance.generateCode(currentScope, this ,
2984: true);
2985: if (complyTo14) {
2986: dup();
2987: invokeObjectGetClass(); // will perform null check
2988: pop();
2989: }
2990: } else {
2991: Object[] emulationPath = currentScope
2992: .getEmulationPath(
2993: syntheticArgType,
2994: false /*not only exact match (that is, allow compatible)*/,
2995: denyEnclosingArgInConstructorCall);
2996: this .generateOuterAccess(emulationPath,
2997: invocationSite, syntheticArgType,
2998: currentScope);
2999: }
3000: }
3001: if (hasExtraEnclosingInstance) {
3002: currentScope.problemReporter()
3003: .unnecessaryEnclosingInstanceSpecification(
3004: enclosingInstance, checkedTargetType);
3005: }
3006: }
3007: }
3008:
3009: /**
3010: * Code responsible to generate the suitable code to supply values for the synthetic outer local
3011: * variable arguments of a constructor invocation of a nested type.
3012: * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
3013: */
3014: public void generateSyntheticOuterArgumentValues(
3015: BlockScope currentScope, ReferenceBinding targetType,
3016: ASTNode invocationSite) {
3017:
3018: // generate the synthetic outer arguments then
3019: SyntheticArgumentBinding syntheticArguments[];
3020: if ((syntheticArguments = targetType
3021: .syntheticOuterLocalVariables()) != null) {
3022: for (int i = 0, max = syntheticArguments.length; i < max; i++) {
3023: LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
3024: VariableBinding[] emulationPath = currentScope
3025: .getEmulationPath(targetVariable);
3026: this .generateOuterAccess(emulationPath, invocationSite,
3027: targetVariable, currentScope);
3028: }
3029: }
3030: }
3031:
3032: public void generateUnboxingConversion(int unboxedTypeID) {
3033: switch (unboxedTypeID) {
3034: case TypeIds.T_byte:
3035: // invokevirtual: byteValue()
3036: this .invoke(
3037: Opcodes.OPC_invokevirtual,
3038: 0, // argCount
3039: 1, // return type size
3040: ConstantPool.JavaLangByteConstantPoolName,
3041: ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
3042: ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
3043: break;
3044: case TypeIds.T_short:
3045: // invokevirtual: shortValue()
3046: this .invoke(
3047: Opcodes.OPC_invokevirtual,
3048: 0, // argCount
3049: 1, // return type size
3050: ConstantPool.JavaLangShortConstantPoolName,
3051: ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
3052: ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
3053: break;
3054: case TypeIds.T_char:
3055: // invokevirtual: charValue()
3056: this .invoke(
3057: Opcodes.OPC_invokevirtual,
3058: 0, // argCount
3059: 1, // return type size
3060: ConstantPool.JavaLangCharacterConstantPoolName,
3061: ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
3062: ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
3063: break;
3064: case TypeIds.T_int:
3065: // invokevirtual: intValue()
3066: this .invoke(
3067: Opcodes.OPC_invokevirtual,
3068: 0, // argCount
3069: 1, // return type size
3070: ConstantPool.JavaLangIntegerConstantPoolName,
3071: ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
3072: ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
3073: break;
3074: case TypeIds.T_long:
3075: // invokevirtual: longValue()
3076: this .invoke(
3077: Opcodes.OPC_invokevirtual,
3078: 0, // argCount
3079: 2, // return type size
3080: ConstantPool.JavaLangLongConstantPoolName,
3081: ConstantPool.LONGVALUE_LONG_METHOD_NAME,
3082: ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
3083: break;
3084: case TypeIds.T_float:
3085: // invokevirtual: floatValue()
3086: this .invoke(
3087: Opcodes.OPC_invokevirtual,
3088: 0, // argCount
3089: 1, // return type size
3090: ConstantPool.JavaLangFloatConstantPoolName,
3091: ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
3092: ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
3093: break;
3094: case TypeIds.T_double:
3095: // invokevirtual: doubleValue()
3096: this .invoke(
3097: Opcodes.OPC_invokevirtual,
3098: 0, // argCount
3099: 2, // return type size
3100: ConstantPool.JavaLangDoubleConstantPoolName,
3101: ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
3102: ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
3103: break;
3104: case TypeIds.T_boolean:
3105: // invokevirtual: booleanValue()
3106: this .invoke(
3107: Opcodes.OPC_invokevirtual,
3108: 0, // argCount
3109: 1, // return type size
3110: ConstantPool.JavaLangBooleanConstantPoolName,
3111: ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
3112: ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
3113: }
3114: }
3115:
3116: /*
3117: * Wide conditional branch compare, improved by swapping comparison opcode
3118: * ifeq WideTarget
3119: * becomes
3120: * ifne Intermediate
3121: * gotow WideTarget
3122: * Intermediate:
3123: */
3124: public void generateWideRevertedConditionalBranch(
3125: byte revertedOpcode, BranchLabel wideTarget) {
3126: BranchLabel intermediate = new BranchLabel(this );
3127: if (classFileOffset >= bCodeStream.length) {
3128: resizeByteArray();
3129: }
3130: position++;
3131: bCodeStream[classFileOffset++] = revertedOpcode;
3132: intermediate.branch();
3133: this .goto_w(wideTarget);
3134: intermediate.place();
3135: }
3136:
3137: public void getBaseTypeValue(int baseTypeID) {
3138: switch (baseTypeID) {
3139: case TypeIds.T_byte:
3140: // invokevirtual: byteValue()
3141: this .invoke(
3142: Opcodes.OPC_invokevirtual,
3143: 0, // argCount
3144: 1, // return type size
3145: ConstantPool.JavaLangByteConstantPoolName,
3146: ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
3147: ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
3148: break;
3149: case TypeIds.T_short:
3150: // invokevirtual: shortValue()
3151: this .invoke(
3152: Opcodes.OPC_invokevirtual,
3153: 0, // argCount
3154: 1, // return type size
3155: ConstantPool.JavaLangShortConstantPoolName,
3156: ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
3157: ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
3158: break;
3159: case TypeIds.T_char:
3160: // invokevirtual: charValue()
3161: this .invoke(
3162: Opcodes.OPC_invokevirtual,
3163: 0, // argCount
3164: 1, // return type size
3165: ConstantPool.JavaLangCharacterConstantPoolName,
3166: ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
3167: ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
3168: break;
3169: case TypeIds.T_int:
3170: // invokevirtual: intValue()
3171: this .invoke(
3172: Opcodes.OPC_invokevirtual,
3173: 0, // argCount
3174: 1, // return type size
3175: ConstantPool.JavaLangIntegerConstantPoolName,
3176: ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
3177: ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
3178: break;
3179: case TypeIds.T_long:
3180: // invokevirtual: longValue()
3181: this .invoke(
3182: Opcodes.OPC_invokevirtual,
3183: 0, // argCount
3184: 2, // return type size
3185: ConstantPool.JavaLangLongConstantPoolName,
3186: ConstantPool.LONGVALUE_LONG_METHOD_NAME,
3187: ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
3188: break;
3189: case TypeIds.T_float:
3190: // invokevirtual: floatValue()
3191: this .invoke(
3192: Opcodes.OPC_invokevirtual,
3193: 0, // argCount
3194: 1, // return type size
3195: ConstantPool.JavaLangFloatConstantPoolName,
3196: ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
3197: ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
3198: break;
3199: case TypeIds.T_double:
3200: // invokevirtual: doubleValue()
3201: this .invoke(
3202: Opcodes.OPC_invokevirtual,
3203: 0, // argCount
3204: 2, // return type size
3205: ConstantPool.JavaLangDoubleConstantPoolName,
3206: ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
3207: ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
3208: break;
3209: case TypeIds.T_boolean:
3210: // invokevirtual: booleanValue()
3211: this .invoke(
3212: Opcodes.OPC_invokevirtual,
3213: 0, // argCount
3214: 1, // return type size
3215: ConstantPool.JavaLangBooleanConstantPoolName,
3216: ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
3217: ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
3218: }
3219: }
3220:
3221: final public byte[] getContents() {
3222: byte[] contents;
3223: System.arraycopy(bCodeStream, 0, contents = new byte[position],
3224: 0, position);
3225: return contents;
3226: }
3227:
3228: public void getfield(FieldBinding fieldBinding) {
3229: if (DEBUG)
3230: System.out.println(position
3231: + "\t\tgetfield:" + fieldBinding); //$NON-NLS-1$
3232: int returnTypeSize = 1;
3233: if ((fieldBinding.type.id == TypeIds.T_double)
3234: || (fieldBinding.type.id == TypeIds.T_long)) {
3235: returnTypeSize = 2;
3236: }
3237: generateFieldAccess(Opcodes.OPC_getfield, returnTypeSize,
3238: fieldBinding.declaringClass, fieldBinding.name,
3239: fieldBinding.type);
3240: }
3241:
3242: protected int getPosition() {
3243: return this .position;
3244: }
3245:
3246: public void getstatic(FieldBinding fieldBinding) {
3247: if (DEBUG)
3248: System.out.println(position
3249: + "\t\tgetstatic:" + fieldBinding); //$NON-NLS-1$
3250: int returnTypeSize = 1;
3251: if ((fieldBinding.type.id == TypeIds.T_double)
3252: || (fieldBinding.type.id == TypeIds.T_long)) {
3253: returnTypeSize = 2;
3254: }
3255: generateFieldAccess(Opcodes.OPC_getstatic, returnTypeSize,
3256: fieldBinding.declaringClass, fieldBinding.name,
3257: fieldBinding.type);
3258: }
3259:
3260: public void getTYPE(int baseTypeID) {
3261: countLabels = 0;
3262: switch (baseTypeID) {
3263: case TypeIds.T_byte:
3264: // getstatic: java.lang.Byte.TYPE
3265: if (DEBUG)
3266: System.out.println(position
3267: + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$
3268: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3269: ConstantPool.JavaLangByteConstantPoolName,
3270: ConstantPool.TYPE,
3271: ConstantPool.JavaLangClassSignature);
3272: break;
3273: case TypeIds.T_short:
3274: // getstatic: java.lang.Short.TYPE
3275: if (DEBUG)
3276: System.out.println(position
3277: + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$
3278: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3279: ConstantPool.JavaLangShortConstantPoolName,
3280: ConstantPool.TYPE,
3281: ConstantPool.JavaLangClassSignature);
3282: break;
3283: case TypeIds.T_char:
3284: // getstatic: java.lang.Character.TYPE
3285: if (DEBUG)
3286: System.out.println(position
3287: + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$
3288: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3289: ConstantPool.JavaLangCharacterConstantPoolName,
3290: ConstantPool.TYPE,
3291: ConstantPool.JavaLangClassSignature);
3292: break;
3293: case TypeIds.T_int:
3294: // getstatic: java.lang.Integer.TYPE
3295: if (DEBUG)
3296: System.out.println(position
3297: + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$
3298: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3299: ConstantPool.JavaLangIntegerConstantPoolName,
3300: ConstantPool.TYPE,
3301: ConstantPool.JavaLangClassSignature);
3302: break;
3303: case TypeIds.T_long:
3304: // getstatic: java.lang.Long.TYPE
3305: if (DEBUG)
3306: System.out.println(position
3307: + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$
3308: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3309: ConstantPool.JavaLangLongConstantPoolName,
3310: ConstantPool.TYPE,
3311: ConstantPool.JavaLangClassSignature);
3312: break;
3313: case TypeIds.T_float:
3314: // getstatic: java.lang.Float.TYPE
3315: if (DEBUG)
3316: System.out.println(position
3317: + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$
3318: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3319: ConstantPool.JavaLangFloatConstantPoolName,
3320: ConstantPool.TYPE,
3321: ConstantPool.JavaLangClassSignature);
3322: break;
3323: case TypeIds.T_double:
3324: // getstatic: java.lang.Double.TYPE
3325: if (DEBUG)
3326: System.out.println(position
3327: + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$
3328: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3329: ConstantPool.JavaLangDoubleConstantPoolName,
3330: ConstantPool.TYPE,
3331: ConstantPool.JavaLangClassSignature);
3332: break;
3333: case TypeIds.T_boolean:
3334: // getstatic: java.lang.Boolean.TYPE
3335: if (DEBUG)
3336: System.out.println(position
3337: + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$
3338: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3339: ConstantPool.JavaLangBooleanConstantPoolName,
3340: ConstantPool.TYPE,
3341: ConstantPool.JavaLangClassSignature);
3342: break;
3343: case TypeIds.T_void:
3344: // getstatic: java.lang.Void.TYPE
3345: if (DEBUG)
3346: System.out.println(position
3347: + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$
3348: generateFieldAccess(Opcodes.OPC_getstatic, 1,
3349: ConstantPool.JavaLangVoidConstantPoolName,
3350: ConstantPool.TYPE,
3351: ConstantPool.JavaLangClassSignature);
3352: break;
3353: }
3354: }
3355:
3356: /**
3357: * We didn't call it goto, because there is a conflit with the goto keyword
3358: */
3359: public void goto_(BranchLabel label) {
3360: if (this .wideMode) {
3361: this .goto_w(label);
3362: return;
3363: }
3364: if (DEBUG)
3365: System.out.println(position + "\t\tgoto:" + label); //$NON-NLS-1$
3366: if (classFileOffset >= bCodeStream.length) {
3367: resizeByteArray();
3368: }
3369: boolean chained = this
3370: .inlineForwardReferencesFromLabelsTargeting(label,
3371: position);
3372: if (DEBUG && chained) {
3373: if (DEBUG) {
3374: if (this .lastAbruptCompletion == this .position) {
3375: System.out
3376: .println("\t\t\t\t<branch chaining - goto eliminated : " + this .position + "," + label + ">");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
3377: } else {
3378: System.out
3379: .println("\t\t\t\t<branch chaining - goto issued : " + this .position + "," + label + ">");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
3380: }
3381: }
3382: }
3383: /*
3384: Possible optimization for code such as:
3385: public Object foo() {
3386: boolean b = true;
3387: if (b) {
3388: if (b)
3389: return null;
3390: } else {
3391: if (b) {
3392: return null;
3393: }
3394: }
3395: return null;
3396: }
3397: The goto around the else block for the first if will
3398: be unreachable, because the thenClause of the second if
3399: returns. Also see 114894
3400: }*/
3401: if (chained && this .lastAbruptCompletion == this .position) {
3402: if (label.position != Label.POS_NOT_SET) { // ensure existing forward references are updated
3403: int[] forwardRefs = label.forwardReferences();
3404: for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
3405: this .writePosition(label, forwardRefs[i]);
3406: }
3407: this .countLabels = 0; // backward jump, no further chaining allowed
3408: }
3409: return;
3410: }
3411: position++;
3412: bCodeStream[classFileOffset++] = Opcodes.OPC_goto;
3413: label.branch();
3414: this .lastAbruptCompletion = this .position;
3415: }
3416:
3417: public void goto_w(BranchLabel label) {
3418: if (DEBUG)
3419: System.out.println(position + "\t\tgotow:" + label); //$NON-NLS-1$
3420: if (classFileOffset >= bCodeStream.length) {
3421: resizeByteArray();
3422: }
3423: position++;
3424: bCodeStream[classFileOffset++] = Opcodes.OPC_goto_w;
3425: label.branchWide();
3426: this .lastAbruptCompletion = this .position;
3427: }
3428:
3429: public void i2b() {
3430: if (DEBUG)
3431: System.out.println(position + "\t\ti2b"); //$NON-NLS-1$
3432: countLabels = 0;
3433: if (classFileOffset >= bCodeStream.length) {
3434: resizeByteArray();
3435: }
3436: position++;
3437: bCodeStream[classFileOffset++] = Opcodes.OPC_i2b;
3438: }
3439:
3440: public void i2c() {
3441: if (DEBUG)
3442: System.out.println(position + "\t\ti2c"); //$NON-NLS-1$
3443: countLabels = 0;
3444: if (classFileOffset >= bCodeStream.length) {
3445: resizeByteArray();
3446: }
3447: position++;
3448: bCodeStream[classFileOffset++] = Opcodes.OPC_i2c;
3449: }
3450:
3451: public void i2d() {
3452: if (DEBUG)
3453: System.out.println(position + "\t\ti2d"); //$NON-NLS-1$
3454: countLabels = 0;
3455: stackDepth++;
3456: if (stackDepth > stackMax)
3457: stackMax = stackDepth;
3458: if (classFileOffset >= bCodeStream.length) {
3459: resizeByteArray();
3460: }
3461: position++;
3462: bCodeStream[classFileOffset++] = Opcodes.OPC_i2d;
3463: }
3464:
3465: public void i2f() {
3466: if (DEBUG)
3467: System.out.println(position + "\t\ti2f"); //$NON-NLS-1$
3468: countLabels = 0;
3469: if (classFileOffset >= bCodeStream.length) {
3470: resizeByteArray();
3471: }
3472: position++;
3473: bCodeStream[classFileOffset++] = Opcodes.OPC_i2f;
3474: }
3475:
3476: public void i2l() {
3477: if (DEBUG)
3478: System.out.println(position + "\t\ti2l"); //$NON-NLS-1$
3479: countLabels = 0;
3480: stackDepth++;
3481: if (stackDepth > stackMax)
3482: stackMax = stackDepth;
3483: if (classFileOffset >= bCodeStream.length) {
3484: resizeByteArray();
3485: }
3486: position++;
3487: bCodeStream[classFileOffset++] = Opcodes.OPC_i2l;
3488: }
3489:
3490: public void i2s() {
3491: if (DEBUG)
3492: System.out.println(position + "\t\ti2s"); //$NON-NLS-1$
3493: countLabels = 0;
3494: if (classFileOffset >= bCodeStream.length) {
3495: resizeByteArray();
3496: }
3497: position++;
3498: bCodeStream[classFileOffset++] = Opcodes.OPC_i2s;
3499: }
3500:
3501: public void iadd() {
3502: if (DEBUG)
3503: System.out.println(position + "\t\tiadd"); //$NON-NLS-1$
3504: countLabels = 0;
3505: stackDepth--;
3506: if (classFileOffset >= bCodeStream.length) {
3507: resizeByteArray();
3508: }
3509: position++;
3510: bCodeStream[classFileOffset++] = Opcodes.OPC_iadd;
3511: }
3512:
3513: public void iaload() {
3514: if (DEBUG)
3515: System.out.println(position + "\t\tiaload"); //$NON-NLS-1$
3516: countLabels = 0;
3517: stackDepth--;
3518: if (classFileOffset >= bCodeStream.length) {
3519: resizeByteArray();
3520: }
3521: position++;
3522: bCodeStream[classFileOffset++] = Opcodes.OPC_iaload;
3523: }
3524:
3525: public void iand() {
3526: if (DEBUG)
3527: System.out.println(position + "\t\tiand"); //$NON-NLS-1$
3528: countLabels = 0;
3529: stackDepth--;
3530: if (classFileOffset >= bCodeStream.length) {
3531: resizeByteArray();
3532: }
3533: position++;
3534: bCodeStream[classFileOffset++] = Opcodes.OPC_iand;
3535: }
3536:
3537: public void iastore() {
3538: if (DEBUG)
3539: System.out.println(position + "\t\tiastore"); //$NON-NLS-1$
3540: countLabels = 0;
3541: stackDepth -= 3;
3542: if (classFileOffset >= bCodeStream.length) {
3543: resizeByteArray();
3544: }
3545: position++;
3546: bCodeStream[classFileOffset++] = Opcodes.OPC_iastore;
3547: }
3548:
3549: public void iconst_0() {
3550: if (DEBUG)
3551: System.out.println(position + "\t\ticonst_0"); //$NON-NLS-1$
3552: countLabels = 0;
3553: stackDepth++;
3554: if (stackDepth > stackMax)
3555: stackMax = stackDepth;
3556: if (classFileOffset >= bCodeStream.length) {
3557: resizeByteArray();
3558: }
3559: position++;
3560: bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_0;
3561: }
3562:
3563: public void iconst_1() {
3564: if (DEBUG)
3565: System.out.println(position + "\t\ticonst_1"); //$NON-NLS-1$
3566: countLabels = 0;
3567: stackDepth++;
3568: if (stackDepth > stackMax)
3569: stackMax = stackDepth;
3570: if (classFileOffset >= bCodeStream.length) {
3571: resizeByteArray();
3572: }
3573: position++;
3574: bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_1;
3575: }
3576:
3577: public void iconst_2() {
3578: if (DEBUG)
3579: System.out.println(position + "\t\ticonst_2"); //$NON-NLS-1$
3580: countLabels = 0;
3581: stackDepth++;
3582: if (stackDepth > stackMax)
3583: stackMax = stackDepth;
3584: if (classFileOffset >= bCodeStream.length) {
3585: resizeByteArray();
3586: }
3587: position++;
3588: bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_2;
3589: }
3590:
3591: public void iconst_3() {
3592: if (DEBUG)
3593: System.out.println(position + "\t\ticonst_3"); //$NON-NLS-1$
3594: countLabels = 0;
3595: stackDepth++;
3596: if (stackDepth > stackMax)
3597: stackMax = stackDepth;
3598: if (classFileOffset >= bCodeStream.length) {
3599: resizeByteArray();
3600: }
3601: position++;
3602: bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_3;
3603: }
3604:
3605: public void iconst_4() {
3606: if (DEBUG)
3607: System.out.println(position + "\t\ticonst_4"); //$NON-NLS-1$
3608: countLabels = 0;
3609: stackDepth++;
3610: if (stackDepth > stackMax)
3611: stackMax = stackDepth;
3612: if (classFileOffset >= bCodeStream.length) {
3613: resizeByteArray();
3614: }
3615: position++;
3616: bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_4;
3617: }
3618:
3619: public void iconst_5() {
3620: if (DEBUG)
3621: System.out.println(position + "\t\ticonst_5"); //$NON-NLS-1$
3622: countLabels = 0;
3623: stackDepth++;
3624: if (stackDepth > stackMax)
3625: stackMax = stackDepth;
3626: if (classFileOffset >= bCodeStream.length) {
3627: resizeByteArray();
3628: }
3629: position++;
3630: bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_5;
3631: }
3632:
3633: public void iconst_m1() {
3634: if (DEBUG)
3635: System.out.println(position + "\t\ticonst_m1"); //$NON-NLS-1$
3636: countLabels = 0;
3637: stackDepth++;
3638: if (stackDepth > stackMax)
3639: stackMax = stackDepth;
3640: if (classFileOffset >= bCodeStream.length) {
3641: resizeByteArray();
3642: }
3643: position++;
3644: bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_m1;
3645: }
3646:
3647: public void idiv() {
3648: if (DEBUG)
3649: System.out.println(position + "\t\tidiv"); //$NON-NLS-1$
3650: countLabels = 0;
3651: stackDepth--;
3652: if (classFileOffset >= bCodeStream.length) {
3653: resizeByteArray();
3654: }
3655: position++;
3656: bCodeStream[classFileOffset++] = Opcodes.OPC_idiv;
3657: }
3658:
3659: public void if_acmpeq(BranchLabel lbl) {
3660: if (DEBUG)
3661: System.out.println(position + "\t\tif_acmpeq:" + lbl); //$NON-NLS-1$
3662: countLabels = 0;
3663: stackDepth -= 2;
3664: if (this .wideMode) {
3665: generateWideRevertedConditionalBranch(
3666: Opcodes.OPC_if_acmpne, lbl);
3667: } else {
3668: if (classFileOffset >= bCodeStream.length) {
3669: resizeByteArray();
3670: }
3671: position++;
3672: bCodeStream[classFileOffset++] = Opcodes.OPC_if_acmpeq;
3673: lbl.branch();
3674: }
3675: }
3676:
3677: public void if_acmpne(BranchLabel lbl) {
3678: if (DEBUG)
3679: System.out.println(position + "\t\tif_acmpne:" + lbl); //$NON-NLS-1$
3680: countLabels = 0;
3681: stackDepth -= 2;
3682: if (this .wideMode) {
3683: generateWideRevertedConditionalBranch(
3684: Opcodes.OPC_if_acmpeq, lbl);
3685: } else {
3686: if (classFileOffset >= bCodeStream.length) {
3687: resizeByteArray();
3688: }
3689: position++;
3690: bCodeStream[classFileOffset++] = Opcodes.OPC_if_acmpne;
3691: lbl.branch();
3692: }
3693: }
3694:
3695: public void if_icmpeq(BranchLabel lbl) {
3696: if (DEBUG)
3697: System.out.println(position + "\t\tif_cmpeq:" + lbl); //$NON-NLS-1$
3698: countLabels = 0;
3699: stackDepth -= 2;
3700: if (this .wideMode) {
3701: generateWideRevertedConditionalBranch(
3702: Opcodes.OPC_if_icmpne, lbl);
3703: } else {
3704: if (classFileOffset >= bCodeStream.length) {
3705: resizeByteArray();
3706: }
3707: position++;
3708: bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpeq;
3709: lbl.branch();
3710: }
3711: }
3712:
3713: public void if_icmpge(BranchLabel lbl) {
3714: if (DEBUG)
3715: System.out.println(position + "\t\tif_icmpge:" + lbl); //$NON-NLS-1$
3716: countLabels = 0;
3717: stackDepth -= 2;
3718: if (this .wideMode) {
3719: generateWideRevertedConditionalBranch(
3720: Opcodes.OPC_if_icmplt, lbl);
3721: } else {
3722: if (classFileOffset >= bCodeStream.length) {
3723: resizeByteArray();
3724: }
3725: position++;
3726: bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpge;
3727: lbl.branch();
3728: }
3729: }
3730:
3731: public void if_icmpgt(BranchLabel lbl) {
3732: if (DEBUG)
3733: System.out.println(position + "\t\tif_icmpgt:" + lbl); //$NON-NLS-1$
3734: countLabels = 0;
3735: stackDepth -= 2;
3736: if (this .wideMode) {
3737: generateWideRevertedConditionalBranch(
3738: Opcodes.OPC_if_icmple, lbl);
3739: } else {
3740: if (classFileOffset >= bCodeStream.length) {
3741: resizeByteArray();
3742: }
3743: position++;
3744: bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpgt;
3745: lbl.branch();
3746: }
3747: }
3748:
3749: public void if_icmple(BranchLabel lbl) {
3750: if (DEBUG)
3751: System.out.println(position + "\t\tif_icmple:" + lbl); //$NON-NLS-1$
3752: countLabels = 0;
3753: stackDepth -= 2;
3754: if (this .wideMode) {
3755: generateWideRevertedConditionalBranch(
3756: Opcodes.OPC_if_icmpgt, lbl);
3757: } else {
3758: if (classFileOffset >= bCodeStream.length) {
3759: resizeByteArray();
3760: }
3761: position++;
3762: bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmple;
3763: lbl.branch();
3764: }
3765: }
3766:
3767: public void if_icmplt(BranchLabel lbl) {
3768: if (DEBUG)
3769: System.out.println(position + "\t\tif_icmplt:" + lbl); //$NON-NLS-1$
3770: countLabels = 0;
3771: stackDepth -= 2;
3772: if (this .wideMode) {
3773: generateWideRevertedConditionalBranch(
3774: Opcodes.OPC_if_icmpge, lbl);
3775: } else {
3776: if (classFileOffset >= bCodeStream.length) {
3777: resizeByteArray();
3778: }
3779: position++;
3780: bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmplt;
3781: lbl.branch();
3782: }
3783: }
3784:
3785: public void if_icmpne(BranchLabel lbl) {
3786: if (DEBUG)
3787: System.out.println(position + "\t\tif_icmpne:" + lbl); //$NON-NLS-1$
3788: countLabels = 0;
3789: stackDepth -= 2;
3790: if (this .wideMode) {
3791: generateWideRevertedConditionalBranch(
3792: Opcodes.OPC_if_icmpeq, lbl);
3793: } else {
3794: if (classFileOffset >= bCodeStream.length) {
3795: resizeByteArray();
3796: }
3797: position++;
3798: bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpne;
3799: lbl.branch();
3800: }
3801: }
3802:
3803: public void ifeq(BranchLabel lbl) {
3804: if (DEBUG)
3805: System.out.println(position + "\t\tifeq:" + lbl); //$NON-NLS-1$
3806: countLabels = 0;
3807: stackDepth--;
3808: if (this .wideMode) {
3809: generateWideRevertedConditionalBranch(Opcodes.OPC_ifne, lbl);
3810: } else {
3811: if (classFileOffset >= bCodeStream.length) {
3812: resizeByteArray();
3813: }
3814: position++;
3815: bCodeStream[classFileOffset++] = Opcodes.OPC_ifeq;
3816: lbl.branch();
3817: }
3818: }
3819:
3820: public void ifge(BranchLabel lbl) {
3821: if (DEBUG)
3822: System.out.println(position + "\t\tifge:" + lbl); //$NON-NLS-1$
3823: countLabels = 0;
3824: stackDepth--;
3825: if (this .wideMode) {
3826: generateWideRevertedConditionalBranch(Opcodes.OPC_iflt, lbl);
3827: } else {
3828: if (classFileOffset >= bCodeStream.length) {
3829: resizeByteArray();
3830: }
3831: position++;
3832: bCodeStream[classFileOffset++] = Opcodes.OPC_ifge;
3833: lbl.branch();
3834: }
3835: }
3836:
3837: public void ifgt(BranchLabel lbl) {
3838: if (DEBUG)
3839: System.out.println(position + "\t\tifgt:" + lbl); //$NON-NLS-1$
3840: countLabels = 0;
3841: stackDepth--;
3842: if (this .wideMode) {
3843: generateWideRevertedConditionalBranch(Opcodes.OPC_ifle, lbl);
3844: } else {
3845: if (classFileOffset >= bCodeStream.length) {
3846: resizeByteArray();
3847: }
3848: position++;
3849: bCodeStream[classFileOffset++] = Opcodes.OPC_ifgt;
3850: lbl.branch();
3851: }
3852: }
3853:
3854: public void ifle(BranchLabel lbl) {
3855: if (DEBUG)
3856: System.out.println(position + "\t\tifle:" + lbl); //$NON-NLS-1$
3857: countLabels = 0;
3858: stackDepth--;
3859: if (this .wideMode) {
3860: generateWideRevertedConditionalBranch(Opcodes.OPC_ifgt, lbl);
3861: } else {
3862: if (classFileOffset >= bCodeStream.length) {
3863: resizeByteArray();
3864: }
3865: position++;
3866: bCodeStream[classFileOffset++] = Opcodes.OPC_ifle;
3867: lbl.branch();
3868: }
3869: }
3870:
3871: public void iflt(BranchLabel lbl) {
3872: if (DEBUG)
3873: System.out.println(position + "\t\tiflt:" + lbl); //$NON-NLS-1$
3874: countLabels = 0;
3875: stackDepth--;
3876: if (this .wideMode) {
3877: generateWideRevertedConditionalBranch(Opcodes.OPC_ifge, lbl);
3878: } else {
3879: if (classFileOffset >= bCodeStream.length) {
3880: resizeByteArray();
3881: }
3882: position++;
3883: bCodeStream[classFileOffset++] = Opcodes.OPC_iflt;
3884: lbl.branch();
3885: }
3886: }
3887:
3888: public void ifne(BranchLabel lbl) {
3889: if (DEBUG)
3890: System.out.println(position + "\t\tifne:" + lbl); //$NON-NLS-1$
3891: countLabels = 0;
3892: stackDepth--;
3893: if (this .wideMode) {
3894: generateWideRevertedConditionalBranch(Opcodes.OPC_ifeq, lbl);
3895: } else {
3896: if (classFileOffset >= bCodeStream.length) {
3897: resizeByteArray();
3898: }
3899: position++;
3900: bCodeStream[classFileOffset++] = Opcodes.OPC_ifne;
3901: lbl.branch();
3902: }
3903: }
3904:
3905: public void ifnonnull(BranchLabel lbl) {
3906: if (DEBUG)
3907: System.out.println(position + "\t\tifnonnull:" + lbl); //$NON-NLS-1$
3908: countLabels = 0;
3909: stackDepth--;
3910: if (this .wideMode) {
3911: generateWideRevertedConditionalBranch(Opcodes.OPC_ifnull,
3912: lbl);
3913: } else {
3914: if (classFileOffset >= bCodeStream.length) {
3915: resizeByteArray();
3916: }
3917: position++;
3918: bCodeStream[classFileOffset++] = Opcodes.OPC_ifnonnull;
3919: lbl.branch();
3920: }
3921: }
3922:
3923: public void ifnull(BranchLabel lbl) {
3924: if (DEBUG)
3925: System.out.println(position + "\t\tifnull:" + lbl); //$NON-NLS-1$
3926: countLabels = 0;
3927: stackDepth--;
3928: if (this .wideMode) {
3929: generateWideRevertedConditionalBranch(
3930: Opcodes.OPC_ifnonnull, lbl);
3931: } else {
3932: if (classFileOffset >= bCodeStream.length) {
3933: resizeByteArray();
3934: }
3935: position++;
3936: bCodeStream[classFileOffset++] = Opcodes.OPC_ifnull;
3937: lbl.branch();
3938: }
3939: }
3940:
3941: final public void iinc(int index, int value) {
3942: if (DEBUG)
3943: System.out.println(position
3944: + "\t\tiinc:" + index + "," + value); //$NON-NLS-1$ //$NON-NLS-2$
3945: countLabels = 0;
3946: if ((index > 255) || (value < -128 || value > 127)) { // have to widen
3947: if (classFileOffset + 3 >= bCodeStream.length) {
3948: resizeByteArray();
3949: }
3950: position += 2;
3951: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
3952: bCodeStream[classFileOffset++] = Opcodes.OPC_iinc;
3953: writeUnsignedShort(index);
3954: writeSignedShort(value);
3955: } else {
3956: if (classFileOffset + 2 >= bCodeStream.length) {
3957: resizeByteArray();
3958: }
3959: position += 3;
3960: bCodeStream[classFileOffset++] = Opcodes.OPC_iinc;
3961: bCodeStream[classFileOffset++] = (byte) index;
3962: bCodeStream[classFileOffset++] = (byte) value;
3963: }
3964: }
3965:
3966: public void iload(int iArg) {
3967: if (DEBUG)
3968: System.out.println(position + "\t\tiload:" + iArg); //$NON-NLS-1$
3969: countLabels = 0;
3970: stackDepth++;
3971: if (maxLocals <= iArg) {
3972: maxLocals = iArg + 1;
3973: }
3974: if (stackDepth > stackMax)
3975: stackMax = stackDepth;
3976: if (iArg > 255) { // Widen
3977: if (classFileOffset + 3 >= bCodeStream.length) {
3978: resizeByteArray();
3979: }
3980: position += 2;
3981: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
3982: bCodeStream[classFileOffset++] = Opcodes.OPC_iload;
3983: writeUnsignedShort(iArg);
3984: } else {
3985: if (classFileOffset + 1 >= bCodeStream.length) {
3986: resizeByteArray();
3987: }
3988: position += 2;
3989: bCodeStream[classFileOffset++] = Opcodes.OPC_iload;
3990: bCodeStream[classFileOffset++] = (byte) iArg;
3991: }
3992: }
3993:
3994: public void iload_0() {
3995: if (DEBUG)
3996: System.out.println(position + "\t\tiload_0"); //$NON-NLS-1$
3997: countLabels = 0;
3998: stackDepth++;
3999: if (maxLocals <= 0) {
4000: maxLocals = 1;
4001: }
4002: if (stackDepth > stackMax)
4003: stackMax = stackDepth;
4004: if (classFileOffset >= bCodeStream.length) {
4005: resizeByteArray();
4006: }
4007: position++;
4008: bCodeStream[classFileOffset++] = Opcodes.OPC_iload_0;
4009: }
4010:
4011: public void iload_1() {
4012: if (DEBUG)
4013: System.out.println(position + "\t\tiload_1"); //$NON-NLS-1$
4014: countLabels = 0;
4015: stackDepth++;
4016: if (maxLocals <= 1) {
4017: maxLocals = 2;
4018: }
4019: if (stackDepth > stackMax)
4020: stackMax = stackDepth;
4021: if (classFileOffset >= bCodeStream.length) {
4022: resizeByteArray();
4023: }
4024: position++;
4025: bCodeStream[classFileOffset++] = Opcodes.OPC_iload_1;
4026: }
4027:
4028: public void iload_2() {
4029: if (DEBUG)
4030: System.out.println(position + "\t\tiload_2"); //$NON-NLS-1$
4031: countLabels = 0;
4032: stackDepth++;
4033: if (maxLocals <= 2) {
4034: maxLocals = 3;
4035: }
4036: if (stackDepth > stackMax)
4037: stackMax = stackDepth;
4038: if (classFileOffset >= bCodeStream.length) {
4039: resizeByteArray();
4040: }
4041: position++;
4042: bCodeStream[classFileOffset++] = Opcodes.OPC_iload_2;
4043: }
4044:
4045: public void iload_3() {
4046: if (DEBUG)
4047: System.out.println(position + "\t\tiload_3"); //$NON-NLS-1$
4048: countLabels = 0;
4049: stackDepth++;
4050: if (maxLocals <= 3) {
4051: maxLocals = 4;
4052: }
4053: if (stackDepth > stackMax)
4054: stackMax = stackDepth;
4055: if (classFileOffset >= bCodeStream.length) {
4056: resizeByteArray();
4057: }
4058: position++;
4059: bCodeStream[classFileOffset++] = Opcodes.OPC_iload_3;
4060: }
4061:
4062: public void imul() {
4063: if (DEBUG)
4064: System.out.println(position + "\t\timul"); //$NON-NLS-1$
4065: countLabels = 0;
4066: stackDepth--;
4067: if (classFileOffset >= bCodeStream.length) {
4068: resizeByteArray();
4069: }
4070: position++;
4071: bCodeStream[classFileOffset++] = Opcodes.OPC_imul;
4072: }
4073:
4074: public int indexOfSameLineEntrySincePC(int pc, int line) {
4075: for (int index = pc, max = pcToSourceMapSize; index < max; index += 2) {
4076: if (pcToSourceMap[index + 1] == line)
4077: return index;
4078: }
4079: return -1;
4080: }
4081:
4082: public void ineg() {
4083: if (DEBUG)
4084: System.out.println(position + "\t\tineg"); //$NON-NLS-1$
4085: countLabels = 0;
4086: if (classFileOffset >= bCodeStream.length) {
4087: resizeByteArray();
4088: }
4089: position++;
4090: bCodeStream[classFileOffset++] = Opcodes.OPC_ineg;
4091: }
4092:
4093: /*
4094: * Some placed labels might be branching to a goto bytecode which we can optimize better.
4095: */
4096: public boolean inlineForwardReferencesFromLabelsTargeting(
4097: BranchLabel targetLabel, int gotoLocation) {
4098: if (targetLabel.delegate != null)
4099: return false; // already inlined
4100: int chaining = L_UNKNOWN;
4101: for (int i = this .countLabels - 1; i >= 0; i--) {
4102: BranchLabel currentLabel = labels[i];
4103: if (currentLabel.position != gotoLocation)
4104: break;
4105: if (currentLabel == targetLabel) {
4106: chaining |= L_CANNOT_OPTIMIZE; // recursive
4107: continue;
4108: }
4109: if (currentLabel.isStandardLabel()) {
4110: if (currentLabel.delegate != null)
4111: continue; // ignore since already inlined
4112: targetLabel.becomeDelegateFor(currentLabel);
4113: chaining |= L_OPTIMIZABLE; // optimizable, providing no vetoing
4114: continue;
4115: }
4116: // case label
4117: chaining |= L_CANNOT_OPTIMIZE;
4118: }
4119: return (chaining & (L_OPTIMIZABLE | L_CANNOT_OPTIMIZE)) == L_OPTIMIZABLE; // check was some standards, and no case/recursive
4120: }
4121:
4122: public void init(ClassFile targetClassFile) {
4123: this .classFile = targetClassFile;
4124: this .constantPool = targetClassFile.constantPool;
4125: this .bCodeStream = targetClassFile.contents;
4126: this .classFileOffset = targetClassFile.contentsOffset;
4127: this .startingClassFileOffset = this .classFileOffset;
4128: pcToSourceMapSize = 0;
4129: lastEntryPC = 0;
4130: int length = visibleLocals.length;
4131: if (noVisibleLocals.length < length) {
4132: noVisibleLocals = new LocalVariableBinding[length];
4133: }
4134: System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
4135: visibleLocalsCount = 0;
4136:
4137: length = locals.length;
4138: if (noLocals.length < length) {
4139: noLocals = new LocalVariableBinding[length];
4140: }
4141: System.arraycopy(noLocals, 0, locals, 0, length);
4142: allLocalsCounter = 0;
4143:
4144: length = exceptionLabels.length;
4145: if (noExceptionHandlers.length < length) {
4146: noExceptionHandlers = new ExceptionLabel[length];
4147: }
4148: System.arraycopy(noExceptionHandlers, 0, exceptionLabels, 0,
4149: length);
4150: exceptionLabelsCounter = 0;
4151:
4152: length = labels.length;
4153: if (noLabels.length < length) {
4154: noLabels = new BranchLabel[length];
4155: }
4156: System.arraycopy(noLabels, 0, labels, 0, length);
4157: countLabels = 0;
4158: this .lastAbruptCompletion = -1;
4159:
4160: stackMax = 0;
4161: stackDepth = 0;
4162: maxLocals = 0;
4163: position = 0;
4164: }
4165:
4166: /**
4167: * @param methodBinding the given method binding to initialize the max locals
4168: */
4169: public void initializeMaxLocals(MethodBinding methodBinding) {
4170:
4171: if (methodBinding == null) {
4172: this .maxLocals = 0;
4173: return;
4174: }
4175:
4176: this .maxLocals = methodBinding.isStatic() ? 0 : 1;
4177:
4178: // take into account enum constructor synthetic name+ordinal
4179: if (methodBinding.isConstructor()
4180: && methodBinding.declaringClass.isEnum()) {
4181: this .maxLocals += 2; // String and int (enum constant name+ordinal)
4182: }
4183:
4184: // take into account the synthetic parameters
4185: if (methodBinding.isConstructor()
4186: && methodBinding.declaringClass.isNestedType()) {
4187: ReferenceBinding enclosingInstanceTypes[];
4188: if ((enclosingInstanceTypes = methodBinding.declaringClass
4189: .syntheticEnclosingInstanceTypes()) != null) {
4190: for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
4191: this .maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
4192: // LongBinding or DoubleBinding
4193: }
4194: }
4195: SyntheticArgumentBinding syntheticArguments[];
4196: if ((syntheticArguments = methodBinding.declaringClass
4197: .syntheticOuterLocalVariables()) != null) {
4198: for (int i = 0, max = syntheticArguments.length; i < max; i++) {
4199: TypeBinding argType;
4200: if (((argType = syntheticArguments[i].type) == TypeBinding.LONG)
4201: || (argType == TypeBinding.DOUBLE)) {
4202: this .maxLocals += 2;
4203: } else {
4204: this .maxLocals++;
4205: }
4206: }
4207: }
4208: }
4209: TypeBinding[] arguments;
4210: if ((arguments = methodBinding.parameters) != null) {
4211: for (int i = 0, max = arguments.length; i < max; i++) {
4212: TypeBinding argType;
4213: if (((argType = arguments[i]) == TypeBinding.LONG)
4214: || (argType == TypeBinding.DOUBLE)) {
4215: this .maxLocals += 2;
4216: } else {
4217: this .maxLocals++;
4218: }
4219: }
4220: }
4221: }
4222:
4223: /**
4224: * We didn't call it instanceof because there is a conflit with the
4225: * instanceof keyword
4226: */
4227: public void instance_of(TypeBinding typeBinding) {
4228: if (DEBUG)
4229: System.out.println(position
4230: + "\t\tinstance_of:" + typeBinding); //$NON-NLS-1$
4231: countLabels = 0;
4232: if (classFileOffset + 2 >= bCodeStream.length) {
4233: resizeByteArray();
4234: }
4235: position++;
4236: bCodeStream[classFileOffset++] = Opcodes.OPC_instanceof ;
4237: writeUnsignedShort(constantPool
4238: .literalIndexForType(typeBinding));
4239: }
4240:
4241: protected void invoke(int opcode, int argsSize, int returnTypeSize,
4242: char[] declaringClass, char[] selector, char[] signature) {
4243: countLabels = 0;
4244: int argCount = argsSize;
4245: switch (opcode) {
4246: case Opcodes.OPC_invokeinterface:
4247: if (classFileOffset + 4 >= bCodeStream.length) {
4248: resizeByteArray();
4249: }
4250: position += 3;
4251: bCodeStream[classFileOffset++] = Opcodes.OPC_invokeinterface;
4252: writeUnsignedShort(constantPool.literalIndexForMethod(
4253: declaringClass, selector, signature, true));
4254: argCount++;
4255: bCodeStream[classFileOffset++] = (byte) argCount;
4256: bCodeStream[classFileOffset++] = 0;
4257: break;
4258: case Opcodes.OPC_invokevirtual:
4259: case Opcodes.OPC_invokespecial:
4260: if (classFileOffset + 2 >= bCodeStream.length) {
4261: resizeByteArray();
4262: }
4263: position++;
4264: bCodeStream[classFileOffset++] = (byte) opcode;
4265: writeUnsignedShort(constantPool.literalIndexForMethod(
4266: declaringClass, selector, signature, false));
4267: argCount++;
4268: break;
4269: case Opcodes.OPC_invokestatic:
4270: if (classFileOffset + 2 >= bCodeStream.length) {
4271: resizeByteArray();
4272: }
4273: position++;
4274: bCodeStream[classFileOffset++] = Opcodes.OPC_invokestatic;
4275: writeUnsignedShort(constantPool.literalIndexForMethod(
4276: declaringClass, selector, signature, false));
4277: }
4278: stackDepth += returnTypeSize - argCount;
4279: if (stackDepth > stackMax) {
4280: stackMax = stackDepth;
4281: }
4282: }
4283:
4284: protected void invokeAccessibleObjectSetAccessible() {
4285: // invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V;
4286: this
4287: .invoke(
4288: Opcodes.OPC_invokevirtual,
4289: 1, // argCount
4290: 0, // return type size
4291: ConstantPool.JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME,
4292: ConstantPool.SETACCESSIBLE_NAME,
4293: ConstantPool.SETACCESSIBLE_SIGNATURE);
4294: }
4295:
4296: protected void invokeArrayNewInstance() {
4297: // invokestatic: java.lang.reflect.Array.newInstance(Ljava.lang.Class;int[])Ljava.lang.Object;
4298: this .invoke(
4299: Opcodes.OPC_invokestatic,
4300: 2, // argCount
4301: 1, // return type size
4302: ConstantPool.JAVALANGREFLECTARRAY_CONSTANTPOOLNAME,
4303: ConstantPool.NewInstance,
4304: ConstantPool.NewInstanceSignature);
4305: }
4306:
4307: public void invokeClassForName() {
4308: // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
4309: if (DEBUG)
4310: System.out
4311: .println(position
4312: + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$
4313: this .invoke(Opcodes.OPC_invokestatic,
4314: 1, // argCount
4315: 1, // return type size
4316: ConstantPool.JavaLangClassConstantPoolName,
4317: ConstantPool.ForName, ConstantPool.ForNameSignature);
4318: }
4319:
4320: protected void invokeClassGetDeclaredConstructor() {
4321: // invokevirtual: java.lang.Class getDeclaredConstructor([Ljava.lang.Class)Ljava.lang.reflect.Constructor;
4322: this .invoke(
4323: Opcodes.OPC_invokevirtual,
4324: 1, // argCount
4325: 1, // return type size
4326: ConstantPool.JavaLangClassConstantPoolName,
4327: ConstantPool.GETDECLAREDCONSTRUCTOR_NAME,
4328: ConstantPool.GETDECLAREDCONSTRUCTOR_SIGNATURE);
4329: }
4330:
4331: protected void invokeClassGetDeclaredField() {
4332: // invokevirtual: java.lang.Class.getDeclaredField(Ljava.lang.String)Ljava.lang.reflect.Field;
4333: this .invoke(
4334: Opcodes.OPC_invokevirtual,
4335: 1, // argCount
4336: 1, // return type size
4337: ConstantPool.JavaLangClassConstantPoolName,
4338: ConstantPool.GETDECLAREDFIELD_NAME,
4339: ConstantPool.GETDECLAREDFIELD_SIGNATURE);
4340: }
4341:
4342: protected void invokeClassGetDeclaredMethod() {
4343: // invokevirtual: java.lang.Class getDeclaredMethod(Ljava.lang.String, [Ljava.lang.Class)Ljava.lang.reflect.Method;
4344: this .invoke(
4345: Opcodes.OPC_invokevirtual,
4346: 2, // argCount
4347: 1, // return type size
4348: ConstantPool.JavaLangClassConstantPoolName,
4349: ConstantPool.GETDECLAREDMETHOD_NAME,
4350: ConstantPool.GETDECLAREDMETHOD_SIGNATURE);
4351: }
4352:
4353: public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
4354: // invokevirtual: <enumConstantPoolName>.ordinal()
4355: if (DEBUG)
4356: System.out
4357: .println(position
4358: + "\t\tinvokevirtual: " + new String(enumTypeConstantPoolName) + ".ordinal()"); //$NON-NLS-1$ //$NON-NLS-2$
4359: this .invoke(Opcodes.OPC_invokevirtual,
4360: 0, // argCount
4361: 1, // return type size
4362: enumTypeConstantPoolName, ConstantPool.Ordinal,
4363: ConstantPool.OrdinalSignature);
4364: }
4365:
4366: public void invokeinterface(MethodBinding methodBinding) {
4367: if (DEBUG)
4368: System.out.println(position
4369: + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$
4370: countLabels = 0;
4371: // initialized to 1 to take into account this immediately
4372: int argCount = 1;
4373: int id;
4374: if (classFileOffset + 4 >= bCodeStream.length) {
4375: resizeByteArray();
4376: }
4377: position += 3;
4378: bCodeStream[classFileOffset++] = Opcodes.OPC_invokeinterface;
4379: writeUnsignedShort(constantPool.literalIndexForMethod(
4380: methodBinding.constantPoolDeclaringClass(),
4381: methodBinding.selector, methodBinding
4382: .signature(classFile), true));
4383: for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
4384: if (((id = methodBinding.parameters[i].id) == TypeIds.T_double)
4385: || (id == TypeIds.T_long))
4386: argCount += 2;
4387: else
4388: argCount += 1;
4389: bCodeStream[classFileOffset++] = (byte) argCount;
4390: // Generate a 0 into the byte array. Like the array is already fill with 0, we just need to increment
4391: // the number of bytes.
4392: bCodeStream[classFileOffset++] = 0;
4393: if (((id = methodBinding.returnType.id) == TypeIds.T_double)
4394: || (id == TypeIds.T_long)) {
4395: stackDepth += (2 - argCount);
4396: } else {
4397: if (id == TypeIds.T_void) {
4398: stackDepth -= argCount;
4399: } else {
4400: stackDepth += (1 - argCount);
4401: }
4402: }
4403: if (stackDepth > stackMax) {
4404: stackMax = stackDepth;
4405: }
4406: }
4407:
4408: public void invokeJavaLangAssertionErrorConstructor(
4409: int typeBindingID) {
4410: // invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
4411: if (DEBUG)
4412: System.out
4413: .println(position
4414: + "\t\tinvokespecial: java.lang.AssertionError.<init>(typeBindingID)V"); //$NON-NLS-1$
4415: int argCount = 1;
4416: char[] signature = null;
4417: switch (typeBindingID) {
4418: case TypeIds.T_int:
4419: case TypeIds.T_byte:
4420: case TypeIds.T_short:
4421: signature = ConstantPool.IntConstrSignature;
4422: break;
4423: case TypeIds.T_long:
4424: signature = ConstantPool.LongConstrSignature;
4425: argCount = 2;
4426: break;
4427: case TypeIds.T_float:
4428: signature = ConstantPool.FloatConstrSignature;
4429: break;
4430: case TypeIds.T_double:
4431: signature = ConstantPool.DoubleConstrSignature;
4432: argCount = 2;
4433: break;
4434: case TypeIds.T_char:
4435: signature = ConstantPool.CharConstrSignature;
4436: break;
4437: case TypeIds.T_boolean:
4438: signature = ConstantPool.BooleanConstrSignature;
4439: break;
4440: case TypeIds.T_JavaLangObject:
4441: case TypeIds.T_JavaLangString:
4442: case TypeIds.T_null:
4443: signature = ConstantPool.ObjectConstrSignature;
4444: break;
4445: }
4446: this .invoke(Opcodes.OPC_invokespecial,
4447: argCount, // argCount
4448: 0, // return type size
4449: ConstantPool.JavaLangAssertionErrorConstantPoolName,
4450: ConstantPool.Init, signature);
4451: }
4452:
4453: public void invokeJavaLangAssertionErrorDefaultConstructor() {
4454: // invokespecial: java.lang.AssertionError.<init>()V
4455: if (DEBUG)
4456: System.out
4457: .println(position
4458: + "\t\tinvokespecial: java.lang.AssertionError.<init>()V"); //$NON-NLS-1$
4459: this .invoke(
4460: Opcodes.OPC_invokespecial,
4461: 0, // argCount
4462: 0, // return type size
4463: ConstantPool.JavaLangAssertionErrorConstantPoolName,
4464: ConstantPool.Init,
4465: ConstantPool.DefaultConstructorSignature);
4466: }
4467:
4468: public void invokeJavaLangClassDesiredAssertionStatus() {
4469: // invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
4470: if (DEBUG)
4471: System.out
4472: .println(position
4473: + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$
4474: this .invoke(
4475: Opcodes.OPC_invokevirtual,
4476: 0, // argCount
4477: 1, // return type size
4478: ConstantPool.JavaLangClassConstantPoolName,
4479: ConstantPool.DesiredAssertionStatus,
4480: ConstantPool.DesiredAssertionStatusSignature);
4481: }
4482:
4483: public void invokeJavaLangEnumvalueOf(ReferenceBinding binding) {
4484: // invokestatic: java.lang.Enum.valueOf(Class,String)
4485: if (DEBUG)
4486: System.out
4487: .println(position
4488: + "\t\tinvokestatic: java.lang.Enum.valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;"); //$NON-NLS-1$
4489: this .invoke(
4490: Opcodes.OPC_invokestatic,
4491: 2, // argCount
4492: 1, // return type size
4493: ConstantPool.JavaLangEnumConstantPoolName,
4494: ConstantPool.ValueOf,
4495: ConstantPool.ValueOfStringClassSignature);
4496: }
4497:
4498: public void invokeJavaLangEnumValues(TypeBinding enumBinding,
4499: ArrayBinding arrayBinding) {
4500: char[] signature = "()".toCharArray(); //$NON-NLS-1$
4501: signature = CharOperation.concat(signature, arrayBinding
4502: .constantPoolName());
4503: this .invoke(Opcodes.OPC_invokestatic, 0, 1, enumBinding
4504: .constantPoolName(), TypeConstants.VALUES, signature);
4505: }
4506:
4507: public void invokeJavaLangErrorConstructor() {
4508: // invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
4509: if (DEBUG)
4510: System.out
4511: .println(position
4512: + "\t\tinvokespecial: java.lang.Error<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
4513: this .invoke(
4514: Opcodes.OPC_invokespecial,
4515: 1, // argCount
4516: 0, // return type size
4517: ConstantPool.JavaLangErrorConstantPoolName,
4518: ConstantPool.Init,
4519: ConstantPool.StringConstructorSignature);
4520: }
4521:
4522: public void invokeJavaLangReflectConstructorNewInstance() {
4523: // invokevirtual: java.lang.reflect.Constructor.newInstance([Ljava.lang.Object;)Ljava.lang.Object;
4524: this
4525: .invoke(
4526: Opcodes.OPC_invokevirtual,
4527: 1, // argCount
4528: 1, // return type size
4529: ConstantPool.JavaLangReflectConstructorConstantPoolName,
4530: ConstantPool.NewInstance,
4531: ConstantPool.JavaLangReflectConstructorNewInstanceSignature);
4532: }
4533:
4534: protected void invokeJavaLangReflectFieldGetter(int typeID) {
4535: int returnTypeSize = 1;
4536: char[] signature = null;
4537: char[] selector = null;
4538: switch (typeID) {
4539: case TypeIds.T_int:
4540: selector = ConstantPool.GET_INT_METHOD_NAME;
4541: signature = ConstantPool.GET_INT_METHOD_SIGNATURE;
4542: break;
4543: case TypeIds.T_byte:
4544: selector = ConstantPool.GET_BYTE_METHOD_NAME;
4545: signature = ConstantPool.GET_BYTE_METHOD_SIGNATURE;
4546: break;
4547: case TypeIds.T_short:
4548: selector = ConstantPool.GET_SHORT_METHOD_NAME;
4549: signature = ConstantPool.GET_SHORT_METHOD_SIGNATURE;
4550: break;
4551: case TypeIds.T_long:
4552: selector = ConstantPool.GET_LONG_METHOD_NAME;
4553: signature = ConstantPool.GET_LONG_METHOD_SIGNATURE;
4554: returnTypeSize = 2;
4555: break;
4556: case TypeIds.T_float:
4557: selector = ConstantPool.GET_FLOAT_METHOD_NAME;
4558: signature = ConstantPool.GET_FLOAT_METHOD_SIGNATURE;
4559: break;
4560: case TypeIds.T_double:
4561: selector = ConstantPool.GET_DOUBLE_METHOD_NAME;
4562: signature = ConstantPool.GET_DOUBLE_METHOD_SIGNATURE;
4563: returnTypeSize = 2;
4564: break;
4565: case TypeIds.T_char:
4566: selector = ConstantPool.GET_CHAR_METHOD_NAME;
4567: signature = ConstantPool.GET_CHAR_METHOD_SIGNATURE;
4568: break;
4569: case TypeIds.T_boolean:
4570: selector = ConstantPool.GET_BOOLEAN_METHOD_NAME;
4571: signature = ConstantPool.GET_BOOLEAN_METHOD_SIGNATURE;
4572: break;
4573: default:
4574: selector = ConstantPool.GET_OBJECT_METHOD_NAME;
4575: signature = ConstantPool.GET_OBJECT_METHOD_SIGNATURE;
4576: break;
4577: }
4578: this .invoke(Opcodes.OPC_invokevirtual,
4579: 1, // argCount
4580: returnTypeSize, // return type size
4581: ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
4582: selector, signature);
4583: }
4584:
4585: protected void invokeJavaLangReflectFieldSetter(int typeID) {
4586: int argCount = 2;
4587: char[] signature = null;
4588: char[] selector = null;
4589: switch (typeID) {
4590: case TypeIds.T_int:
4591: selector = ConstantPool.SET_INT_METHOD_NAME;
4592: signature = ConstantPool.SET_INT_METHOD_SIGNATURE;
4593: break;
4594: case TypeIds.T_byte:
4595: selector = ConstantPool.SET_BYTE_METHOD_NAME;
4596: signature = ConstantPool.SET_BYTE_METHOD_SIGNATURE;
4597: break;
4598: case TypeIds.T_short:
4599: selector = ConstantPool.SET_SHORT_METHOD_NAME;
4600: signature = ConstantPool.SET_SHORT_METHOD_SIGNATURE;
4601: break;
4602: case TypeIds.T_long:
4603: selector = ConstantPool.SET_LONG_METHOD_NAME;
4604: signature = ConstantPool.SET_LONG_METHOD_SIGNATURE;
4605: argCount = 3;
4606: break;
4607: case TypeIds.T_float:
4608: selector = ConstantPool.SET_FLOAT_METHOD_NAME;
4609: signature = ConstantPool.SET_FLOAT_METHOD_SIGNATURE;
4610: break;
4611: case TypeIds.T_double:
4612: selector = ConstantPool.SET_DOUBLE_METHOD_NAME;
4613: signature = ConstantPool.SET_DOUBLE_METHOD_SIGNATURE;
4614: argCount = 3;
4615: break;
4616: case TypeIds.T_char:
4617: selector = ConstantPool.SET_CHAR_METHOD_NAME;
4618: signature = ConstantPool.SET_CHAR_METHOD_SIGNATURE;
4619: break;
4620: case TypeIds.T_boolean:
4621: selector = ConstantPool.SET_BOOLEAN_METHOD_NAME;
4622: signature = ConstantPool.SET_BOOLEAN_METHOD_SIGNATURE;
4623: break;
4624: default:
4625: selector = ConstantPool.SET_OBJECT_METHOD_NAME;
4626: signature = ConstantPool.SET_OBJECT_METHOD_SIGNATURE;
4627: break;
4628: }
4629: this .invoke(Opcodes.OPC_invokevirtual,
4630: argCount, // argCount
4631: 0, // return type size
4632: ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
4633: selector, signature);
4634: }
4635:
4636: public void invokeJavaLangReflectMethodInvoke() {
4637: // invokevirtual: java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;
4638: this .invoke(
4639: Opcodes.OPC_invokevirtual,
4640: 2, // argCount
4641: 1, // return type size
4642: ConstantPool.JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME,
4643: ConstantPool.INVOKE_METHOD_METHOD_NAME,
4644: ConstantPool.INVOKE_METHOD_METHOD_SIGNATURE);
4645: }
4646:
4647: public void invokeJavaUtilIteratorHasNext() {
4648: // invokeinterface java.util.Iterator.hasNext()Z
4649: if (DEBUG)
4650: System.out
4651: .println(position
4652: + "\t\tinvokeinterface: java.util.Iterator.hasNext()Z"); //$NON-NLS-1$
4653: this .invoke(Opcodes.OPC_invokeinterface,
4654: 0, // argCount
4655: 1, // return type size
4656: ConstantPool.JavaUtilIteratorConstantPoolName,
4657: ConstantPool.HasNext, ConstantPool.HasNextSignature);
4658: }
4659:
4660: public void invokeJavaUtilIteratorNext() {
4661: // invokeinterface java.util.Iterator.next()java.lang.Object
4662: if (DEBUG)
4663: System.out
4664: .println(position
4665: + "\t\tinvokeinterface: java.util.Iterator.next()java.lang.Object"); //$NON-NLS-1$
4666: this .invoke(Opcodes.OPC_invokeinterface,
4667: 0, // argCount
4668: 1, // return type size
4669: ConstantPool.JavaUtilIteratorConstantPoolName,
4670: ConstantPool.Next, ConstantPool.NextSignature);
4671: }
4672:
4673: public void invokeNoClassDefFoundErrorStringConstructor() {
4674: // invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
4675: if (DEBUG)
4676: System.out
4677: .println(position
4678: + "\t\tinvokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
4679: this
4680: .invoke(
4681: Opcodes.OPC_invokespecial,
4682: 1, // argCount
4683: 0, // return type size
4684: ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName,
4685: ConstantPool.Init,
4686: ConstantPool.StringConstructorSignature);
4687: }
4688:
4689: public void invokeObjectGetClass() {
4690: // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
4691: if (DEBUG)
4692: System.out
4693: .println(position
4694: + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$
4695: this .invoke(Opcodes.OPC_invokevirtual,
4696: 0, // argCount
4697: 1, // return type size
4698: ConstantPool.JavaLangObjectConstantPoolName,
4699: ConstantPool.GetClass, ConstantPool.GetClassSignature);
4700: }
4701:
4702: public void invokespecial(MethodBinding methodBinding) {
4703: if (DEBUG)
4704: System.out.println(position
4705: + "\t\tinvokespecial:" + methodBinding); //$NON-NLS-1$
4706: countLabels = 0;
4707: // initialized to 1 to take into account this immediately
4708: int argCount = 1;
4709: int id;
4710: if (classFileOffset + 2 >= bCodeStream.length) {
4711: resizeByteArray();
4712: }
4713: position++;
4714: bCodeStream[classFileOffset++] = Opcodes.OPC_invokespecial;
4715: writeUnsignedShort(constantPool.literalIndexForMethod(
4716: methodBinding.constantPoolDeclaringClass(),
4717: methodBinding.selector, methodBinding
4718: .signature(classFile), false));
4719: if (methodBinding.isConstructor()) {
4720: final ReferenceBinding declaringClass = methodBinding.declaringClass;
4721: if (declaringClass.isNestedType()) {
4722: // enclosing instances
4723: TypeBinding[] syntheticArgumentTypes = declaringClass
4724: .syntheticEnclosingInstanceTypes();
4725: if (syntheticArgumentTypes != null) {
4726: for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
4727: if (((id = syntheticArgumentTypes[i].id) == TypeIds.T_double)
4728: || (id == TypeIds.T_long)) {
4729: argCount += 2;
4730: } else {
4731: argCount++;
4732: }
4733: }
4734: }
4735: // outer local variables
4736: SyntheticArgumentBinding[] syntheticArguments = declaringClass
4737: .syntheticOuterLocalVariables();
4738: if (syntheticArguments != null) {
4739: for (int i = 0, max = syntheticArguments.length; i < max; i++) {
4740: if (((id = syntheticArguments[i].type.id) == TypeIds.T_double)
4741: || (id == TypeIds.T_long)) {
4742: argCount += 2;
4743: } else {
4744: argCount++;
4745: }
4746: }
4747: }
4748: }
4749: if (declaringClass.isEnum()) {
4750: // adding String and int
4751: argCount += 2;
4752: }
4753: }
4754: for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
4755: if (((id = methodBinding.parameters[i].id) == TypeIds.T_double)
4756: || (id == TypeIds.T_long))
4757: argCount += 2;
4758: else
4759: argCount++;
4760: if (((id = methodBinding.returnType.id) == TypeIds.T_double)
4761: || (id == TypeIds.T_long))
4762: stackDepth += (2 - argCount);
4763: else if (id == TypeIds.T_void)
4764: stackDepth -= argCount;
4765: else
4766: stackDepth += (1 - argCount);
4767: if (stackDepth > stackMax)
4768: stackMax = stackDepth;
4769: }
4770:
4771: public void invokestatic(MethodBinding methodBinding) {
4772: if (DEBUG)
4773: System.out.println(position
4774: + "\t\tinvokestatic:" + methodBinding); //$NON-NLS-1$
4775: // initialized to 0 to take into account that there is no this for
4776: // a static method
4777: countLabels = 0;
4778: int argCount = 0;
4779: int id;
4780: if (classFileOffset + 2 >= bCodeStream.length) {
4781: resizeByteArray();
4782: }
4783: position++;
4784: bCodeStream[classFileOffset++] = Opcodes.OPC_invokestatic;
4785: writeUnsignedShort(constantPool.literalIndexForMethod(
4786: methodBinding.constantPoolDeclaringClass(),
4787: methodBinding.selector, methodBinding
4788: .signature(classFile), false));
4789: for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
4790: if (((id = methodBinding.parameters[i].id) == TypeIds.T_double)
4791: || (id == TypeIds.T_long))
4792: argCount += 2;
4793: else
4794: argCount += 1;
4795: if (((id = methodBinding.returnType.id) == TypeIds.T_double)
4796: || (id == TypeIds.T_long))
4797: stackDepth += (2 - argCount);
4798: else if (id == TypeIds.T_void)
4799: stackDepth -= argCount;
4800: else
4801: stackDepth += (1 - argCount);
4802: if (stackDepth > stackMax)
4803: stackMax = stackDepth;
4804: }
4805:
4806: /**
4807: * The equivalent code performs a string conversion of the TOS
4808: * @param typeID <CODE>int</CODE>
4809: */
4810: public void invokeStringConcatenationAppendForType(int typeID) {
4811: if (DEBUG) {
4812: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4813: System.out
4814: .println(position
4815: + "\t\tinvokevirtual: java.lang.StringBuilder.append(...)"); //$NON-NLS-1$
4816: } else {
4817: System.out
4818: .println(position
4819: + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$
4820: }
4821: }
4822: int argCount = 1;
4823: int returnType = 1;
4824: char[] declaringClass = null;
4825: char[] selector = ConstantPool.Append;
4826: char[] signature = null;
4827: switch (typeID) {
4828: case TypeIds.T_int:
4829: case TypeIds.T_byte:
4830: case TypeIds.T_short:
4831: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4832: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4833: signature = ConstantPool.StringBuilderAppendIntSignature;
4834: } else {
4835: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4836: signature = ConstantPool.StringBufferAppendIntSignature;
4837: }
4838: break;
4839: case TypeIds.T_long:
4840: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4841: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4842: signature = ConstantPool.StringBuilderAppendLongSignature;
4843: } else {
4844: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4845: signature = ConstantPool.StringBufferAppendLongSignature;
4846: }
4847: argCount = 2;
4848: break;
4849: case TypeIds.T_float:
4850: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4851: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4852: signature = ConstantPool.StringBuilderAppendFloatSignature;
4853: } else {
4854: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4855: signature = ConstantPool.StringBufferAppendFloatSignature;
4856: }
4857: break;
4858: case TypeIds.T_double:
4859: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4860: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4861: signature = ConstantPool.StringBuilderAppendDoubleSignature;
4862: } else {
4863: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4864: signature = ConstantPool.StringBufferAppendDoubleSignature;
4865: }
4866: argCount = 2;
4867: break;
4868: case TypeIds.T_char:
4869: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4870: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4871: signature = ConstantPool.StringBuilderAppendCharSignature;
4872: } else {
4873: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4874: signature = ConstantPool.StringBufferAppendCharSignature;
4875: }
4876: break;
4877: case TypeIds.T_boolean:
4878: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4879: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4880: signature = ConstantPool.StringBuilderAppendBooleanSignature;
4881: } else {
4882: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4883: signature = ConstantPool.StringBufferAppendBooleanSignature;
4884: }
4885: break;
4886: case TypeIds.T_undefined:
4887: case TypeIds.T_JavaLangObject:
4888: case TypeIds.T_null:
4889: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4890: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4891: signature = ConstantPool.StringBuilderAppendObjectSignature;
4892: } else {
4893: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4894: signature = ConstantPool.StringBufferAppendObjectSignature;
4895: }
4896: break;
4897: case TypeIds.T_JavaLangString:
4898: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4899: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4900: signature = ConstantPool.StringBuilderAppendStringSignature;
4901: } else {
4902: declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4903: signature = ConstantPool.StringBufferAppendStringSignature;
4904: }
4905: break;
4906: }
4907: this .invoke(Opcodes.OPC_invokevirtual, argCount, // argCount
4908: returnType, // return type size
4909: declaringClass, selector, signature);
4910: }
4911:
4912: public void invokeStringConcatenationDefaultConstructor() {
4913: // invokespecial: java.lang.StringBuffer.<init>()V
4914: if (DEBUG) {
4915: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4916: System.out
4917: .println(position
4918: + "\t\tinvokespecial: java.lang.StringBuilder.<init>()V"); //$NON-NLS-1$
4919: } else {
4920: System.out
4921: .println(position
4922: + "\t\tinvokespecial: java.lang.StringBuffer.<init>()V"); //$NON-NLS-1$
4923: }
4924: }
4925: char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4926: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4927: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4928: }
4929: this .invoke(Opcodes.OPC_invokespecial,
4930: 0, // argCount
4931: 0, // return type size
4932: declaringClass, ConstantPool.Init,
4933: ConstantPool.DefaultConstructorSignature);
4934: }
4935:
4936: public void invokeStringConcatenationStringConstructor() {
4937: if (DEBUG) {
4938: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4939: System.out
4940: .println(position
4941: + "\t\tjava.lang.StringBuilder.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
4942: } else {
4943: System.out
4944: .println(position
4945: + "\t\tjava.lang.StringBuffer.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
4946: }
4947: }
4948: char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4949: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4950: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4951: }
4952: this .invoke(Opcodes.OPC_invokespecial,
4953: 1, // argCount
4954: 0, // return type size
4955: declaringClass, ConstantPool.Init,
4956: ConstantPool.StringConstructorSignature);
4957: }
4958:
4959: public void invokeStringConcatenationToString() {
4960: if (DEBUG) {
4961: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4962: System.out
4963: .println(position
4964: + "\t\tinvokevirtual: StringBuilder.toString()Ljava.lang.String;"); //$NON-NLS-1$
4965: } else {
4966: System.out
4967: .println(position
4968: + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$
4969: }
4970: }
4971: char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4972: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
4973: declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4974: }
4975: this .invoke(Opcodes.OPC_invokevirtual,
4976: 0, // argCount
4977: 1, // return type size
4978: declaringClass, ConstantPool.ToString,
4979: ConstantPool.ToStringSignature);
4980: }
4981:
4982: public void invokeStringIntern() {
4983: // invokevirtual: java.lang.String.intern()
4984: if (DEBUG)
4985: System.out.println(position
4986: + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$
4987: this .invoke(Opcodes.OPC_invokevirtual,
4988: 0, // argCount
4989: 1, // return type size
4990: ConstantPool.JavaLangStringConstantPoolName,
4991: ConstantPool.Intern, ConstantPool.InternSignature);
4992: }
4993:
4994: public void invokeStringValueOf(int typeID) {
4995: // invokestatic: java.lang.String.valueOf(argumentType)
4996: if (DEBUG)
4997: System.out
4998: .println(position
4999: + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$
5000: int argCount = 1;
5001: char[] signature = null;
5002: switch (typeID) {
5003: case TypeIds.T_int:
5004: case TypeIds.T_byte:
5005: case TypeIds.T_short:
5006: signature = ConstantPool.ValueOfIntSignature;
5007: break;
5008: case TypeIds.T_long:
5009: signature = ConstantPool.ValueOfLongSignature;
5010: argCount = 2;
5011: break;
5012: case TypeIds.T_float:
5013: signature = ConstantPool.ValueOfFloatSignature;
5014: break;
5015: case TypeIds.T_double:
5016: signature = ConstantPool.ValueOfDoubleSignature;
5017: argCount = 2;
5018: break;
5019: case TypeIds.T_char:
5020: signature = ConstantPool.ValueOfCharSignature;
5021: break;
5022: case TypeIds.T_boolean:
5023: signature = ConstantPool.ValueOfBooleanSignature;
5024: break;
5025: case TypeIds.T_JavaLangObject:
5026: case TypeIds.T_JavaLangString:
5027: case TypeIds.T_null:
5028: case TypeIds.T_undefined:
5029: signature = ConstantPool.ValueOfObjectSignature;
5030: break;
5031: }
5032: this .invoke(Opcodes.OPC_invokestatic,
5033: argCount, // argCount
5034: 1, // return type size
5035: ConstantPool.JavaLangStringConstantPoolName,
5036: ConstantPool.ValueOf, signature);
5037: }
5038:
5039: public void invokeSystemArraycopy() {
5040: // invokestatic #21 <Method java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>
5041: if (DEBUG)
5042: System.out
5043: .println(position
5044: + "\t\tinvokevirtual: java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V"); //$NON-NLS-1$
5045: this
5046: .invoke(
5047: Opcodes.OPC_invokestatic,
5048: 5, // argCount
5049: 0, // return type size
5050: ConstantPool.JavaLangSystemConstantPoolName,
5051: ConstantPool.ArrayCopy,
5052: ConstantPool.ArrayCopySignature);
5053: }
5054:
5055: public void invokeThrowableGetMessage() {
5056: // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
5057: if (DEBUG)
5058: System.out
5059: .println(position
5060: + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$
5061: this .invoke(
5062: Opcodes.OPC_invokevirtual,
5063: 0, // argCount
5064: 1, // return type size
5065: ConstantPool.JavaLangThrowableConstantPoolName,
5066: ConstantPool.GetMessage,
5067: ConstantPool.GetMessageSignature);
5068: }
5069:
5070: public void invokevirtual(MethodBinding methodBinding) {
5071: if (DEBUG)
5072: System.out.println(position
5073: + "\t\tinvokevirtual:" + methodBinding); //$NON-NLS-1$
5074: countLabels = 0;
5075: // initialized to 1 to take into account this immediately
5076: int argCount = 1;
5077: int id;
5078: if (classFileOffset + 2 >= bCodeStream.length) {
5079: resizeByteArray();
5080: }
5081: position++;
5082: bCodeStream[classFileOffset++] = Opcodes.OPC_invokevirtual;
5083: writeUnsignedShort(constantPool.literalIndexForMethod(
5084: methodBinding.constantPoolDeclaringClass(),
5085: methodBinding.selector, methodBinding
5086: .signature(classFile), false));
5087: for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
5088: if (((id = methodBinding.parameters[i].id) == TypeIds.T_double)
5089: || (id == TypeIds.T_long))
5090: argCount += 2;
5091: else
5092: argCount++;
5093: if (((id = methodBinding.returnType.id) == TypeIds.T_double)
5094: || (id == TypeIds.T_long))
5095: stackDepth += (2 - argCount);
5096: else if (id == TypeIds.T_void)
5097: stackDepth -= argCount;
5098: else
5099: stackDepth += (1 - argCount);
5100: if (stackDepth > stackMax)
5101: stackMax = stackDepth;
5102: }
5103:
5104: public void ior() {
5105: if (DEBUG)
5106: System.out.println(position + "\t\tior"); //$NON-NLS-1$
5107: countLabels = 0;
5108: stackDepth--;
5109: if (classFileOffset >= bCodeStream.length) {
5110: resizeByteArray();
5111: }
5112: position++;
5113: bCodeStream[classFileOffset++] = Opcodes.OPC_ior;
5114: }
5115:
5116: public void irem() {
5117: if (DEBUG)
5118: System.out.println(position + "\t\tirem"); //$NON-NLS-1$
5119: countLabels = 0;
5120: stackDepth--;
5121: if (classFileOffset >= bCodeStream.length) {
5122: resizeByteArray();
5123: }
5124: position++;
5125: bCodeStream[classFileOffset++] = Opcodes.OPC_irem;
5126: }
5127:
5128: public void ireturn() {
5129: if (DEBUG)
5130: System.out.println(position + "\t\tireturn"); //$NON-NLS-1$
5131: countLabels = 0;
5132: stackDepth--;
5133: // the stackDepth should be equal to 0
5134: if (classFileOffset >= bCodeStream.length) {
5135: resizeByteArray();
5136: }
5137: position++;
5138: bCodeStream[classFileOffset++] = Opcodes.OPC_ireturn;
5139: this .lastAbruptCompletion = this .position;
5140: }
5141:
5142: public boolean isDefinitelyAssigned(Scope scope,
5143: int initStateIndex, LocalVariableBinding local) {
5144: // Mirror of UnconditionalFlowInfo.isDefinitelyAssigned(..)
5145: if ((local.tagBits & TagBits.IsArgument) != 0) {
5146: return true;
5147: }
5148: if (initStateIndex == -1)
5149: return false;
5150: int localPosition = local.id + maxFieldCount;
5151: MethodScope methodScope = scope.methodScope();
5152: // id is zero-based
5153: if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
5154: return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 0; // use bits
5155: }
5156: // use extra vector
5157: long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
5158: if (extraInits == null)
5159: return false; // if vector not yet allocated, then not initialized
5160: int vectorIndex;
5161: if ((vectorIndex = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
5162: return false; // if not enough room in vector, then not initialized
5163: return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
5164: }
5165:
5166: public void ishl() {
5167: if (DEBUG)
5168: System.out.println(position + "\t\tishl"); //$NON-NLS-1$
5169: countLabels = 0;
5170: stackDepth--;
5171: if (classFileOffset >= bCodeStream.length) {
5172: resizeByteArray();
5173: }
5174: position++;
5175: bCodeStream[classFileOffset++] = Opcodes.OPC_ishl;
5176: }
5177:
5178: public void ishr() {
5179: if (DEBUG)
5180: System.out.println(position + "\t\tishr"); //$NON-NLS-1$
5181: countLabels = 0;
5182: stackDepth--;
5183: if (classFileOffset >= bCodeStream.length) {
5184: resizeByteArray();
5185: }
5186: position++;
5187: bCodeStream[classFileOffset++] = Opcodes.OPC_ishr;
5188: }
5189:
5190: public void istore(int iArg) {
5191: if (DEBUG)
5192: System.out.println(position + "\t\tistore:" + iArg); //$NON-NLS-1$
5193: countLabels = 0;
5194: stackDepth--;
5195: if (maxLocals <= iArg) {
5196: maxLocals = iArg + 1;
5197: }
5198: if (iArg > 255) { // Widen
5199: if (classFileOffset + 3 >= bCodeStream.length) {
5200: resizeByteArray();
5201: }
5202: position += 2;
5203: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
5204: bCodeStream[classFileOffset++] = Opcodes.OPC_istore;
5205: writeUnsignedShort(iArg);
5206: } else {
5207: if (classFileOffset + 1 >= bCodeStream.length) {
5208: resizeByteArray();
5209: }
5210: position += 2;
5211: bCodeStream[classFileOffset++] = Opcodes.OPC_istore;
5212: bCodeStream[classFileOffset++] = (byte) iArg;
5213: }
5214: }
5215:
5216: public void istore_0() {
5217: if (DEBUG)
5218: System.out.println(position + "\t\tistore_0"); //$NON-NLS-1$
5219: countLabels = 0;
5220: stackDepth--;
5221: if (maxLocals == 0) {
5222: maxLocals = 1;
5223: }
5224: if (classFileOffset >= bCodeStream.length) {
5225: resizeByteArray();
5226: }
5227: position++;
5228: bCodeStream[classFileOffset++] = Opcodes.OPC_istore_0;
5229: }
5230:
5231: public void istore_1() {
5232: if (DEBUG)
5233: System.out.println(position + "\t\tistore_1"); //$NON-NLS-1$
5234: countLabels = 0;
5235: stackDepth--;
5236: if (maxLocals <= 1) {
5237: maxLocals = 2;
5238: }
5239: if (classFileOffset >= bCodeStream.length) {
5240: resizeByteArray();
5241: }
5242: position++;
5243: bCodeStream[classFileOffset++] = Opcodes.OPC_istore_1;
5244: }
5245:
5246: public void istore_2() {
5247: if (DEBUG)
5248: System.out.println(position + "\t\tistore_2"); //$NON-NLS-1$
5249: countLabels = 0;
5250: stackDepth--;
5251: if (maxLocals <= 2) {
5252: maxLocals = 3;
5253: }
5254: if (classFileOffset >= bCodeStream.length) {
5255: resizeByteArray();
5256: }
5257: position++;
5258: bCodeStream[classFileOffset++] = Opcodes.OPC_istore_2;
5259: }
5260:
5261: public void istore_3() {
5262: if (DEBUG)
5263: System.out.println(position + "\t\tistore_3"); //$NON-NLS-1$
5264: countLabels = 0;
5265: stackDepth--;
5266: if (maxLocals <= 3) {
5267: maxLocals = 4;
5268: }
5269: if (classFileOffset >= bCodeStream.length) {
5270: resizeByteArray();
5271: }
5272: position++;
5273: bCodeStream[classFileOffset++] = Opcodes.OPC_istore_3;
5274: }
5275:
5276: public void isub() {
5277: if (DEBUG)
5278: System.out.println(position + "\t\tisub"); //$NON-NLS-1$
5279: countLabels = 0;
5280: stackDepth--;
5281: if (classFileOffset >= bCodeStream.length) {
5282: resizeByteArray();
5283: }
5284: position++;
5285: bCodeStream[classFileOffset++] = Opcodes.OPC_isub;
5286: }
5287:
5288: public void iushr() {
5289: if (DEBUG)
5290: System.out.println(position + "\t\tiushr"); //$NON-NLS-1$
5291: countLabels = 0;
5292: stackDepth--;
5293: if (classFileOffset >= bCodeStream.length) {
5294: resizeByteArray();
5295: }
5296: position++;
5297: bCodeStream[classFileOffset++] = Opcodes.OPC_iushr;
5298: }
5299:
5300: public void ixor() {
5301: if (DEBUG)
5302: System.out.println(position + "\t\tixor"); //$NON-NLS-1$
5303: countLabels = 0;
5304: stackDepth--;
5305: if (classFileOffset >= bCodeStream.length) {
5306: resizeByteArray();
5307: }
5308: position++;
5309: bCodeStream[classFileOffset++] = Opcodes.OPC_ixor;
5310: }
5311:
5312: final public void jsr(BranchLabel lbl) {
5313: if (this .wideMode) {
5314: this .jsr_w(lbl);
5315: return;
5316: }
5317: if (DEBUG)
5318: System.out.println(position + "\t\tjsr" + lbl); //$NON-NLS-1$
5319: countLabels = 0;
5320: if (classFileOffset >= bCodeStream.length) {
5321: resizeByteArray();
5322: }
5323: position++;
5324: bCodeStream[classFileOffset++] = Opcodes.OPC_jsr;
5325: lbl.branch();
5326: }
5327:
5328: final public void jsr_w(BranchLabel lbl) {
5329: if (DEBUG)
5330: System.out.println(position + "\t\tjsr_w" + lbl); //$NON-NLS-1$
5331: countLabels = 0;
5332: if (classFileOffset >= bCodeStream.length) {
5333: resizeByteArray();
5334: }
5335: position++;
5336: bCodeStream[classFileOffset++] = Opcodes.OPC_jsr_w;
5337: lbl.branchWide();
5338: }
5339:
5340: public void l2d() {
5341: if (DEBUG)
5342: System.out.println(position + "\t\tl2d"); //$NON-NLS-1$
5343: countLabels = 0;
5344: if (classFileOffset >= bCodeStream.length) {
5345: resizeByteArray();
5346: }
5347: position++;
5348: bCodeStream[classFileOffset++] = Opcodes.OPC_l2d;
5349: }
5350:
5351: public void l2f() {
5352: if (DEBUG)
5353: System.out.println(position + "\t\tl2f"); //$NON-NLS-1$
5354: countLabels = 0;
5355: stackDepth--;
5356: if (classFileOffset >= bCodeStream.length) {
5357: resizeByteArray();
5358: }
5359: position++;
5360: bCodeStream[classFileOffset++] = Opcodes.OPC_l2f;
5361: }
5362:
5363: public void l2i() {
5364: if (DEBUG)
5365: System.out.println(position + "\t\tl2i"); //$NON-NLS-1$
5366: countLabels = 0;
5367: stackDepth--;
5368: if (classFileOffset >= bCodeStream.length) {
5369: resizeByteArray();
5370: }
5371: position++;
5372: bCodeStream[classFileOffset++] = Opcodes.OPC_l2i;
5373: }
5374:
5375: public void ladd() {
5376: if (DEBUG)
5377: System.out.println(position + "\t\tladd"); //$NON-NLS-1$
5378: countLabels = 0;
5379: stackDepth -= 2;
5380: if (classFileOffset >= bCodeStream.length) {
5381: resizeByteArray();
5382: }
5383: position++;
5384: bCodeStream[classFileOffset++] = Opcodes.OPC_ladd;
5385: }
5386:
5387: public void laload() {
5388: if (DEBUG)
5389: System.out.println(position + "\t\tlaload"); //$NON-NLS-1$
5390: countLabels = 0;
5391: if (classFileOffset >= bCodeStream.length) {
5392: resizeByteArray();
5393: }
5394: position++;
5395: bCodeStream[classFileOffset++] = Opcodes.OPC_laload;
5396: }
5397:
5398: public void land() {
5399: if (DEBUG)
5400: System.out.println(position + "\t\tland"); //$NON-NLS-1$
5401: countLabels = 0;
5402: stackDepth -= 2;
5403: if (classFileOffset >= bCodeStream.length) {
5404: resizeByteArray();
5405: }
5406: position++;
5407: bCodeStream[classFileOffset++] = Opcodes.OPC_land;
5408: }
5409:
5410: public void lastore() {
5411: if (DEBUG)
5412: System.out.println(position + "\t\tlastore"); //$NON-NLS-1$
5413: countLabels = 0;
5414: stackDepth -= 4;
5415: if (classFileOffset >= bCodeStream.length) {
5416: resizeByteArray();
5417: }
5418: position++;
5419: bCodeStream[classFileOffset++] = Opcodes.OPC_lastore;
5420: }
5421:
5422: public void lcmp() {
5423: if (DEBUG)
5424: System.out.println(position + "\t\tlcmp"); //$NON-NLS-1$
5425: countLabels = 0;
5426: stackDepth -= 3;
5427: if (classFileOffset >= bCodeStream.length) {
5428: resizeByteArray();
5429: }
5430: position++;
5431: bCodeStream[classFileOffset++] = Opcodes.OPC_lcmp;
5432: }
5433:
5434: public void lconst_0() {
5435: if (DEBUG)
5436: System.out.println(position + "\t\tlconst_0"); //$NON-NLS-1$
5437: countLabels = 0;
5438: stackDepth += 2;
5439: if (stackDepth > stackMax)
5440: stackMax = stackDepth;
5441: if (classFileOffset >= bCodeStream.length) {
5442: resizeByteArray();
5443: }
5444: position++;
5445: bCodeStream[classFileOffset++] = Opcodes.OPC_lconst_0;
5446: }
5447:
5448: public void lconst_1() {
5449: if (DEBUG)
5450: System.out.println(position + "\t\tlconst_1"); //$NON-NLS-1$
5451: countLabels = 0;
5452: stackDepth += 2;
5453: if (stackDepth > stackMax)
5454: stackMax = stackDepth;
5455: if (classFileOffset >= bCodeStream.length) {
5456: resizeByteArray();
5457: }
5458: position++;
5459: bCodeStream[classFileOffset++] = Opcodes.OPC_lconst_1;
5460: }
5461:
5462: public void ldc(float constant) {
5463: countLabels = 0;
5464: int index = constantPool.literalIndex(constant);
5465: stackDepth++;
5466: if (stackDepth > stackMax)
5467: stackMax = stackDepth;
5468: if (index > 255) {
5469: if (DEBUG)
5470: System.out.println(position + "\t\tldc_w:" + constant); //$NON-NLS-1$
5471: // Generate a ldc_w
5472: if (classFileOffset + 2 >= bCodeStream.length) {
5473: resizeByteArray();
5474: }
5475: position++;
5476: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
5477: writeUnsignedShort(index);
5478: } else {
5479: if (DEBUG)
5480: System.out.println(position + "\t\tldc:" + constant); //$NON-NLS-1$
5481: // Generate a ldc
5482: if (classFileOffset + 1 >= bCodeStream.length) {
5483: resizeByteArray();
5484: }
5485: position += 2;
5486: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
5487: bCodeStream[classFileOffset++] = (byte) index;
5488: }
5489: }
5490:
5491: public void ldc(int constant) {
5492: countLabels = 0;
5493: int index = constantPool.literalIndex(constant);
5494: stackDepth++;
5495: if (stackDepth > stackMax)
5496: stackMax = stackDepth;
5497: if (index > 255) {
5498: if (DEBUG)
5499: System.out.println(position + "\t\tldc_w:" + constant); //$NON-NLS-1$
5500: // Generate a ldc_w
5501: if (classFileOffset + 2 >= bCodeStream.length) {
5502: resizeByteArray();
5503: }
5504: position++;
5505: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
5506: writeUnsignedShort(index);
5507: } else {
5508: if (DEBUG)
5509: System.out.println(position + "\t\tldc:" + constant); //$NON-NLS-1$
5510: // Generate a ldc
5511: if (classFileOffset + 1 >= bCodeStream.length) {
5512: resizeByteArray();
5513: }
5514: position += 2;
5515: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
5516: bCodeStream[classFileOffset++] = (byte) index;
5517: }
5518: }
5519:
5520: public void ldc(String constant) {
5521: countLabels = 0;
5522: int currentCodeStreamPosition = position;
5523: char[] constantChars = constant.toCharArray();
5524: int index = constantPool.literalIndexForLdc(constantChars);
5525: if (index > 0) {
5526: // the string already exists inside the constant pool
5527: // we reuse the same index
5528: this .ldcForIndex(index, constantChars);
5529: } else {
5530: // the string is too big to be utf8-encoded in one pass.
5531: // we have to split it into different pieces.
5532: // first we clean all side-effects due to the code above
5533: // this case is very rare, so we can afford to lose time to handle it
5534: position = currentCodeStreamPosition;
5535: int i = 0;
5536: int length = 0;
5537: int constantLength = constant.length();
5538: byte[] utf8encoding = new byte[Math.min(
5539: constantLength + 100, 65535)];
5540: int utf8encodingLength = 0;
5541: while ((length < 65532) && (i < constantLength)) {
5542: char current = constantChars[i];
5543: // we resize the byte array immediately if necessary
5544: if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
5545: System.arraycopy(utf8encoding, 0,
5546: utf8encoding = new byte[Math.min(
5547: utf8encodingLength + 100, 65535)],
5548: 0, length);
5549: }
5550: if ((current >= 0x0001) && (current <= 0x007F)) {
5551: // we only need one byte: ASCII table
5552: utf8encoding[length++] = (byte) current;
5553: } else {
5554: if (current > 0x07FF) {
5555: // we need 3 bytes
5556: utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
5557: utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
5558: utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
5559: } else {
5560: // we can be 0 or between 0x0080 and 0x07FF
5561: // In that case we only need 2 bytes
5562: utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
5563: utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
5564: }
5565: }
5566: i++;
5567: }
5568: // check if all the string is encoded (PR 1PR2DWJ)
5569: // the string is too big to be encoded in one pass
5570: newStringContatenation();
5571: dup();
5572: // write the first part
5573: char[] subChars = new char[i];
5574: System.arraycopy(constantChars, 0, subChars, 0, i);
5575: System.arraycopy(utf8encoding, 0,
5576: utf8encoding = new byte[length], 0, length);
5577: index = constantPool.literalIndex(subChars, utf8encoding);
5578: this .ldcForIndex(index, subChars);
5579: // write the remaining part
5580: invokeStringConcatenationStringConstructor();
5581: while (i < constantLength) {
5582: length = 0;
5583: utf8encoding = new byte[Math.min(constantLength - i
5584: + 100, 65535)];
5585: int startIndex = i;
5586: while ((length < 65532) && (i < constantLength)) {
5587: char current = constantChars[i];
5588: // we resize the byte array immediately if necessary
5589: if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
5590: System.arraycopy(utf8encoding, 0,
5591: utf8encoding = new byte[Math
5592: .min(utf8encodingLength + 100,
5593: 65535)], 0, length);
5594: }
5595: if ((current >= 0x0001) && (current <= 0x007F)) {
5596: // we only need one byte: ASCII table
5597: utf8encoding[length++] = (byte) current;
5598: } else {
5599: if (current > 0x07FF) {
5600: // we need 3 bytes
5601: utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
5602: utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
5603: utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
5604: } else {
5605: // we can be 0 or between 0x0080 and 0x07FF
5606: // In that case we only need 2 bytes
5607: utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
5608: utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
5609: }
5610: }
5611: i++;
5612: }
5613: // the next part is done
5614: int newCharLength = i - startIndex;
5615: subChars = new char[newCharLength];
5616: System.arraycopy(constantChars, startIndex, subChars,
5617: 0, newCharLength);
5618: System.arraycopy(utf8encoding, 0,
5619: utf8encoding = new byte[length], 0, length);
5620: index = constantPool.literalIndex(subChars,
5621: utf8encoding);
5622: this .ldcForIndex(index, subChars);
5623: // now on the stack it should be a StringBuffer and a string.
5624: invokeStringConcatenationAppendForType(TypeIds.T_JavaLangString);
5625: }
5626: invokeStringConcatenationToString();
5627: invokeStringIntern();
5628: }
5629: }
5630:
5631: public void ldc(TypeBinding typeBinding) {
5632: countLabels = 0;
5633: int index = constantPool.literalIndexForType(typeBinding);
5634: stackDepth++;
5635: if (stackDepth > stackMax)
5636: stackMax = stackDepth;
5637: if (index > 255) {
5638: if (DEBUG)
5639: System.out.println(position
5640: + "\t\tldc_w:" + typeBinding); //$NON-NLS-1$
5641: // Generate a ldc_w
5642: if (classFileOffset + 2 >= bCodeStream.length) {
5643: resizeByteArray();
5644: }
5645: position++;
5646: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
5647: writeUnsignedShort(index);
5648: } else {
5649: if (DEBUG)
5650: System.out.println(position + "\t\tldw:" + typeBinding); //$NON-NLS-1$
5651: // Generate a ldc
5652: if (classFileOffset + 1 >= bCodeStream.length) {
5653: resizeByteArray();
5654: }
5655: position += 2;
5656: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
5657: bCodeStream[classFileOffset++] = (byte) index;
5658: }
5659: }
5660:
5661: public void ldc2_w(double constant) {
5662: if (DEBUG)
5663: System.out.println(position + "\t\tldc2_w:" + constant); //$NON-NLS-1$
5664: countLabels = 0;
5665: int index = constantPool.literalIndex(constant);
5666: stackDepth += 2;
5667: if (stackDepth > stackMax)
5668: stackMax = stackDepth;
5669: // Generate a ldc2_w
5670: if (classFileOffset + 2 >= bCodeStream.length) {
5671: resizeByteArray();
5672: }
5673: position++;
5674: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc2_w;
5675: writeUnsignedShort(index);
5676: }
5677:
5678: public void ldc2_w(long constant) {
5679: if (DEBUG)
5680: System.out.println(position + "\t\tldc2_w:" + constant); //$NON-NLS-1$
5681: countLabels = 0;
5682: int index = constantPool.literalIndex(constant);
5683: stackDepth += 2;
5684: if (stackDepth > stackMax)
5685: stackMax = stackDepth;
5686: // Generate a ldc2_w
5687: if (classFileOffset + 2 >= bCodeStream.length) {
5688: resizeByteArray();
5689: }
5690: position++;
5691: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc2_w;
5692: writeUnsignedShort(index);
5693: }
5694:
5695: public void ldcForIndex(int index, char[] constant) {
5696: stackDepth++;
5697: if (stackDepth > stackMax) {
5698: stackMax = stackDepth;
5699: }
5700: if (index > 255) {
5701: // Generate a ldc_w
5702: if (DEBUG)
5703: System.out.println(position
5704: + "\t\tldc_w:" + new String(constant)); //$NON-NLS-1$
5705: if (classFileOffset + 2 >= bCodeStream.length) {
5706: resizeByteArray();
5707: }
5708: position++;
5709: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
5710: writeUnsignedShort(index);
5711: } else {
5712: // Generate a ldc
5713: if (DEBUG)
5714: System.out.println(position
5715: + "\t\tldc:" + new String(constant)); //$NON-NLS-1$
5716: if (classFileOffset + 1 >= bCodeStream.length) {
5717: resizeByteArray();
5718: }
5719: position += 2;
5720: bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
5721: bCodeStream[classFileOffset++] = (byte) index;
5722: }
5723: }
5724:
5725: public void ldiv() {
5726: if (DEBUG)
5727: System.out.println(position + "\t\tldiv"); //$NON-NLS-1$
5728: countLabels = 0;
5729: stackDepth -= 2;
5730: if (classFileOffset >= bCodeStream.length) {
5731: resizeByteArray();
5732: }
5733: position++;
5734: bCodeStream[classFileOffset++] = Opcodes.OPC_ldiv;
5735: }
5736:
5737: public void lload(int iArg) {
5738: if (DEBUG)
5739: System.out.println(position + "\t\tlload:" + iArg); //$NON-NLS-1$
5740: countLabels = 0;
5741: stackDepth += 2;
5742: if (maxLocals <= iArg + 1) {
5743: maxLocals = iArg + 2;
5744: }
5745: if (stackDepth > stackMax)
5746: stackMax = stackDepth;
5747: if (iArg > 255) { // Widen
5748: if (classFileOffset + 3 >= bCodeStream.length) {
5749: resizeByteArray();
5750: }
5751: position += 2;
5752: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
5753: bCodeStream[classFileOffset++] = Opcodes.OPC_lload;
5754: writeUnsignedShort(iArg);
5755: } else {
5756: if (classFileOffset + 1 >= bCodeStream.length) {
5757: resizeByteArray();
5758: }
5759: position += 2;
5760: bCodeStream[classFileOffset++] = Opcodes.OPC_lload;
5761: bCodeStream[classFileOffset++] = (byte) iArg;
5762: }
5763: }
5764:
5765: public void lload_0() {
5766: if (DEBUG)
5767: System.out.println(position + "\t\tlload_0"); //$NON-NLS-1$
5768: countLabels = 0;
5769: stackDepth += 2;
5770: if (maxLocals < 2) {
5771: maxLocals = 2;
5772: }
5773: if (stackDepth > stackMax)
5774: stackMax = stackDepth;
5775: if (classFileOffset >= bCodeStream.length) {
5776: resizeByteArray();
5777: }
5778: position++;
5779: bCodeStream[classFileOffset++] = Opcodes.OPC_lload_0;
5780: }
5781:
5782: public void lload_1() {
5783: if (DEBUG)
5784: System.out.println(position + "\t\tlload_1"); //$NON-NLS-1$
5785: countLabels = 0;
5786: stackDepth += 2;
5787: if (maxLocals < 3) {
5788: maxLocals = 3;
5789: }
5790: if (stackDepth > stackMax)
5791: stackMax = stackDepth;
5792: if (classFileOffset >= bCodeStream.length) {
5793: resizeByteArray();
5794: }
5795: position++;
5796: bCodeStream[classFileOffset++] = Opcodes.OPC_lload_1;
5797: }
5798:
5799: public void lload_2() {
5800: if (DEBUG)
5801: System.out.println(position + "\t\tlload_2"); //$NON-NLS-1$
5802: countLabels = 0;
5803: stackDepth += 2;
5804: if (maxLocals < 4) {
5805: maxLocals = 4;
5806: }
5807: if (stackDepth > stackMax)
5808: stackMax = stackDepth;
5809: if (classFileOffset >= bCodeStream.length) {
5810: resizeByteArray();
5811: }
5812: position++;
5813: bCodeStream[classFileOffset++] = Opcodes.OPC_lload_2;
5814: }
5815:
5816: public void lload_3() {
5817: if (DEBUG)
5818: System.out.println(position + "\t\tlload_3"); //$NON-NLS-1$
5819: countLabels = 0;
5820: stackDepth += 2;
5821: if (maxLocals < 5) {
5822: maxLocals = 5;
5823: }
5824: if (stackDepth > stackMax)
5825: stackMax = stackDepth;
5826: if (classFileOffset >= bCodeStream.length) {
5827: resizeByteArray();
5828: }
5829: position++;
5830: bCodeStream[classFileOffset++] = Opcodes.OPC_lload_3;
5831: }
5832:
5833: public void lmul() {
5834: if (DEBUG)
5835: System.out.println(position + "\t\tlmul"); //$NON-NLS-1$
5836: countLabels = 0;
5837: stackDepth -= 2;
5838: if (classFileOffset >= bCodeStream.length) {
5839: resizeByteArray();
5840: }
5841: position++;
5842: bCodeStream[classFileOffset++] = Opcodes.OPC_lmul;
5843: }
5844:
5845: public void lneg() {
5846: if (DEBUG)
5847: System.out.println(position + "\t\tlneg"); //$NON-NLS-1$
5848: countLabels = 0;
5849: if (classFileOffset >= bCodeStream.length) {
5850: resizeByteArray();
5851: }
5852: position++;
5853: bCodeStream[classFileOffset++] = Opcodes.OPC_lneg;
5854: }
5855:
5856: public final void load(LocalVariableBinding localBinding) {
5857: load(localBinding.type, localBinding.resolvedPosition);
5858: }
5859:
5860: public final void load(TypeBinding typeBinding, int resolvedPosition) {
5861: countLabels = 0;
5862: // Using dedicated int bytecode
5863: switch (typeBinding.id) {
5864: case TypeIds.T_int:
5865: case TypeIds.T_byte:
5866: case TypeIds.T_char:
5867: case TypeIds.T_boolean:
5868: case TypeIds.T_short:
5869: switch (resolvedPosition) {
5870: case 0:
5871: this .iload_0();
5872: break;
5873: case 1:
5874: this .iload_1();
5875: break;
5876: case 2:
5877: this .iload_2();
5878: break;
5879: case 3:
5880: this .iload_3();
5881: break;
5882: //case -1 :
5883: // internal failure: trying to load variable not supposed to be generated
5884: // break;
5885: default:
5886: this .iload(resolvedPosition);
5887: }
5888: break;
5889: case TypeIds.T_float:
5890: switch (resolvedPosition) {
5891: case 0:
5892: this .fload_0();
5893: break;
5894: case 1:
5895: this .fload_1();
5896: break;
5897: case 2:
5898: this .fload_2();
5899: break;
5900: case 3:
5901: this .fload_3();
5902: break;
5903: default:
5904: this .fload(resolvedPosition);
5905: }
5906: break;
5907: case TypeIds.T_long:
5908: switch (resolvedPosition) {
5909: case 0:
5910: this .lload_0();
5911: break;
5912: case 1:
5913: this .lload_1();
5914: break;
5915: case 2:
5916: this .lload_2();
5917: break;
5918: case 3:
5919: this .lload_3();
5920: break;
5921: default:
5922: this .lload(resolvedPosition);
5923: }
5924: break;
5925: case TypeIds.T_double:
5926: switch (resolvedPosition) {
5927: case 0:
5928: this .dload_0();
5929: break;
5930: case 1:
5931: this .dload_1();
5932: break;
5933: case 2:
5934: this .dload_2();
5935: break;
5936: case 3:
5937: this .dload_3();
5938: break;
5939: default:
5940: this .dload(resolvedPosition);
5941: }
5942: break;
5943: default:
5944: switch (resolvedPosition) {
5945: case 0:
5946: this .aload_0();
5947: break;
5948: case 1:
5949: this .aload_1();
5950: break;
5951: case 2:
5952: this .aload_2();
5953: break;
5954: case 3:
5955: this .aload_3();
5956: break;
5957: default:
5958: this .aload(resolvedPosition);
5959: }
5960: }
5961: }
5962:
5963: public void lookupswitch(CaseLabel defaultLabel, int[] keys,
5964: int[] sortedIndexes, CaseLabel[] casesLabel) {
5965: if (DEBUG)
5966: System.out.println(position + "\t\tlookupswitch"); //$NON-NLS-1$
5967: countLabels = 0;
5968: stackDepth--;
5969: int length = keys.length;
5970: int pos = position;
5971: defaultLabel.placeInstruction();
5972: for (int i = 0; i < length; i++) {
5973: casesLabel[i].placeInstruction();
5974: }
5975: if (classFileOffset >= bCodeStream.length) {
5976: resizeByteArray();
5977: }
5978: position++;
5979: bCodeStream[classFileOffset++] = Opcodes.OPC_lookupswitch;
5980: for (int i = (3 - (pos & 3)); i > 0; i--) { // faster than % 4
5981: if (classFileOffset >= bCodeStream.length) {
5982: resizeByteArray();
5983: }
5984: position++;
5985: bCodeStream[classFileOffset++] = 0;
5986: }
5987: defaultLabel.branch();
5988: writeSignedWord(length);
5989: for (int i = 0; i < length; i++) {
5990: writeSignedWord(keys[sortedIndexes[i]]);
5991: casesLabel[sortedIndexes[i]].branch();
5992: }
5993: }
5994:
5995: public void lor() {
5996: if (DEBUG)
5997: System.out.println(position + "\t\tlor"); //$NON-NLS-1$
5998: countLabels = 0;
5999: stackDepth -= 2;
6000: if (classFileOffset >= bCodeStream.length) {
6001: resizeByteArray();
6002: }
6003: position++;
6004: bCodeStream[classFileOffset++] = Opcodes.OPC_lor;
6005: }
6006:
6007: public void lrem() {
6008: if (DEBUG)
6009: System.out.println(position + "\t\tlrem"); //$NON-NLS-1$
6010: countLabels = 0;
6011: stackDepth -= 2;
6012: if (classFileOffset >= bCodeStream.length) {
6013: resizeByteArray();
6014: }
6015: position++;
6016: bCodeStream[classFileOffset++] = Opcodes.OPC_lrem;
6017: }
6018:
6019: public void lreturn() {
6020: if (DEBUG)
6021: System.out.println(position + "\t\tlreturn"); //$NON-NLS-1$
6022: countLabels = 0;
6023: stackDepth -= 2;
6024: // the stackDepth should be equal to 0
6025: if (classFileOffset >= bCodeStream.length) {
6026: resizeByteArray();
6027: }
6028: position++;
6029: bCodeStream[classFileOffset++] = Opcodes.OPC_lreturn;
6030: this .lastAbruptCompletion = this .position;
6031: }
6032:
6033: public void lshl() {
6034: if (DEBUG)
6035: System.out.println(position + "\t\tlshl"); //$NON-NLS-1$
6036: countLabels = 0;
6037: stackDepth--;
6038: if (classFileOffset >= bCodeStream.length) {
6039: resizeByteArray();
6040: }
6041: position++;
6042: bCodeStream[classFileOffset++] = Opcodes.OPC_lshl;
6043: }
6044:
6045: public void lshr() {
6046: if (DEBUG)
6047: System.out.println(position + "\t\tlshr"); //$NON-NLS-1$
6048: countLabels = 0;
6049: stackDepth--;
6050: if (classFileOffset >= bCodeStream.length) {
6051: resizeByteArray();
6052: }
6053: position++;
6054: bCodeStream[classFileOffset++] = Opcodes.OPC_lshr;
6055: }
6056:
6057: public void lstore(int iArg) {
6058: if (DEBUG)
6059: System.out.println(position + "\t\tlstore:" + iArg); //$NON-NLS-1$
6060: countLabels = 0;
6061: stackDepth -= 2;
6062: if (maxLocals <= iArg + 1) {
6063: maxLocals = iArg + 2;
6064: }
6065: if (iArg > 255) { // Widen
6066: if (classFileOffset + 3 >= bCodeStream.length) {
6067: resizeByteArray();
6068: }
6069: position += 2;
6070: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
6071: bCodeStream[classFileOffset++] = Opcodes.OPC_lstore;
6072: writeUnsignedShort(iArg);
6073: } else {
6074: if (classFileOffset + 1 >= bCodeStream.length) {
6075: resizeByteArray();
6076: }
6077: position += 2;
6078: bCodeStream[classFileOffset++] = Opcodes.OPC_lstore;
6079: bCodeStream[classFileOffset++] = (byte) iArg;
6080: }
6081: }
6082:
6083: public void lstore_0() {
6084: if (DEBUG)
6085: System.out.println(position + "\t\tlstore_0"); //$NON-NLS-1$
6086: countLabels = 0;
6087: stackDepth -= 2;
6088: if (maxLocals < 2) {
6089: maxLocals = 2;
6090: }
6091: if (classFileOffset >= bCodeStream.length) {
6092: resizeByteArray();
6093: }
6094: position++;
6095: bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_0;
6096: }
6097:
6098: public void lstore_1() {
6099: if (DEBUG)
6100: System.out.println(position + "\t\tlstore_1"); //$NON-NLS-1$
6101: countLabels = 0;
6102: stackDepth -= 2;
6103: if (maxLocals < 3) {
6104: maxLocals = 3;
6105: }
6106: if (classFileOffset >= bCodeStream.length) {
6107: resizeByteArray();
6108: }
6109: position++;
6110: bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_1;
6111: }
6112:
6113: public void lstore_2() {
6114: if (DEBUG)
6115: System.out.println(position + "\t\tlstore_2"); //$NON-NLS-1$
6116: countLabels = 0;
6117: stackDepth -= 2;
6118: if (maxLocals < 4) {
6119: maxLocals = 4;
6120: }
6121: if (classFileOffset >= bCodeStream.length) {
6122: resizeByteArray();
6123: }
6124: position++;
6125: bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_2;
6126: }
6127:
6128: public void lstore_3() {
6129: if (DEBUG)
6130: System.out.println(position + "\t\tlstore_3"); //$NON-NLS-1$
6131: countLabels = 0;
6132: stackDepth -= 2;
6133: if (maxLocals < 5) {
6134: maxLocals = 5;
6135: }
6136: if (classFileOffset >= bCodeStream.length) {
6137: resizeByteArray();
6138: }
6139: position++;
6140: bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_3;
6141: }
6142:
6143: public void lsub() {
6144: if (DEBUG)
6145: System.out.println(position + "\t\tlsub"); //$NON-NLS-1$
6146: countLabels = 0;
6147: stackDepth -= 2;
6148: if (classFileOffset >= bCodeStream.length) {
6149: resizeByteArray();
6150: }
6151: position++;
6152: bCodeStream[classFileOffset++] = Opcodes.OPC_lsub;
6153: }
6154:
6155: public void lushr() {
6156: if (DEBUG)
6157: System.out.println(position + "\t\tlushr"); //$NON-NLS-1$
6158: countLabels = 0;
6159: stackDepth--;
6160: if (classFileOffset >= bCodeStream.length) {
6161: resizeByteArray();
6162: }
6163: position++;
6164: bCodeStream[classFileOffset++] = Opcodes.OPC_lushr;
6165: }
6166:
6167: public void lxor() {
6168: if (DEBUG)
6169: System.out.println(position + "\t\tlxor"); //$NON-NLS-1$
6170: countLabels = 0;
6171: stackDepth -= 2;
6172: if (classFileOffset >= bCodeStream.length) {
6173: resizeByteArray();
6174: }
6175: position++;
6176: bCodeStream[classFileOffset++] = Opcodes.OPC_lxor;
6177: }
6178:
6179: public void monitorenter() {
6180: if (DEBUG)
6181: System.out.println(position + "\t\tmonitorenter"); //$NON-NLS-1$
6182: countLabels = 0;
6183: stackDepth--;
6184: if (classFileOffset >= bCodeStream.length) {
6185: resizeByteArray();
6186: }
6187: position++;
6188: bCodeStream[classFileOffset++] = Opcodes.OPC_monitorenter;
6189: }
6190:
6191: public void monitorexit() {
6192: if (DEBUG)
6193: System.out.println(position + "\t\tmonitorexit"); //$NON-NLS-1$
6194: countLabels = 0;
6195: stackDepth--;
6196: if (classFileOffset >= bCodeStream.length) {
6197: resizeByteArray();
6198: }
6199: position++;
6200: bCodeStream[classFileOffset++] = Opcodes.OPC_monitorexit;
6201: }
6202:
6203: public void multianewarray(TypeBinding typeBinding, int dimensions) {
6204: if (DEBUG)
6205: System.out
6206: .println(position
6207: + "\t\tmultinewarray:" + typeBinding + "," + dimensions); //$NON-NLS-1$ //$NON-NLS-2$
6208: countLabels = 0;
6209: stackDepth += (1 - dimensions);
6210: if (classFileOffset + 3 >= bCodeStream.length) {
6211: resizeByteArray();
6212: }
6213: position += 2;
6214: bCodeStream[classFileOffset++] = Opcodes.OPC_multianewarray;
6215: writeUnsignedShort(constantPool
6216: .literalIndexForType(typeBinding));
6217: bCodeStream[classFileOffset++] = (byte) dimensions;
6218: }
6219:
6220: // We didn't call it new, because there is a conflit with the new keyword
6221: public void new_(TypeBinding typeBinding) {
6222: if (DEBUG)
6223: System.out.println(position
6224: + "\t\tnew:" + typeBinding.debugName()); //$NON-NLS-1$
6225: countLabels = 0;
6226: stackDepth++;
6227: if (stackDepth > stackMax)
6228: stackMax = stackDepth;
6229: if (classFileOffset + 2 >= bCodeStream.length) {
6230: resizeByteArray();
6231: }
6232: position++;
6233: bCodeStream[classFileOffset++] = Opcodes.OPC_new;
6234: writeUnsignedShort(constantPool
6235: .literalIndexForType(typeBinding));
6236: }
6237:
6238: public void newarray(int array_Type) {
6239: if (DEBUG)
6240: System.out.println(position + "\t\tnewarray:" + array_Type); //$NON-NLS-1$
6241: countLabels = 0;
6242: if (classFileOffset + 1 >= bCodeStream.length) {
6243: resizeByteArray();
6244: }
6245: position += 2;
6246: bCodeStream[classFileOffset++] = Opcodes.OPC_newarray;
6247: bCodeStream[classFileOffset++] = (byte) array_Type;
6248: }
6249:
6250: public void newArray(ArrayBinding arrayBinding) {
6251: TypeBinding component = arrayBinding.elementsType();
6252: switch (component.id) {
6253: case TypeIds.T_int:
6254: this .newarray(ClassFileConstants.INT_ARRAY);
6255: break;
6256: case TypeIds.T_byte:
6257: this .newarray(ClassFileConstants.BYTE_ARRAY);
6258: break;
6259: case TypeIds.T_boolean:
6260: this .newarray(ClassFileConstants.BOOLEAN_ARRAY);
6261: break;
6262: case TypeIds.T_short:
6263: this .newarray(ClassFileConstants.SHORT_ARRAY);
6264: break;
6265: case TypeIds.T_char:
6266: this .newarray(ClassFileConstants.CHAR_ARRAY);
6267: break;
6268: case TypeIds.T_long:
6269: this .newarray(ClassFileConstants.LONG_ARRAY);
6270: break;
6271: case TypeIds.T_float:
6272: this .newarray(ClassFileConstants.FLOAT_ARRAY);
6273: break;
6274: case TypeIds.T_double:
6275: this .newarray(ClassFileConstants.DOUBLE_ARRAY);
6276: break;
6277: default:
6278: this .anewarray(component);
6279: }
6280: }
6281:
6282: public void newJavaLangAssertionError() {
6283: // new: java.lang.AssertionError
6284: if (DEBUG)
6285: System.out.println(position
6286: + "\t\tnew: java.lang.AssertionError"); //$NON-NLS-1$
6287: countLabels = 0;
6288: stackDepth++;
6289: if (stackDepth > stackMax)
6290: stackMax = stackDepth;
6291: if (classFileOffset + 2 >= bCodeStream.length) {
6292: resizeByteArray();
6293: }
6294: position++;
6295: bCodeStream[classFileOffset++] = Opcodes.OPC_new;
6296: writeUnsignedShort(constantPool
6297: .literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName));
6298: }
6299:
6300: public void newJavaLangError() {
6301: // new: java.lang.Error
6302: if (DEBUG)
6303: System.out.println(position + "\t\tnew: java.lang.Error"); //$NON-NLS-1$
6304: countLabels = 0;
6305: stackDepth++;
6306: if (stackDepth > stackMax)
6307: stackMax = stackDepth;
6308: if (classFileOffset + 2 >= bCodeStream.length) {
6309: resizeByteArray();
6310: }
6311: position++;
6312: bCodeStream[classFileOffset++] = Opcodes.OPC_new;
6313: writeUnsignedShort(constantPool
6314: .literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
6315: }
6316:
6317: public void newNoClassDefFoundError() {
6318: // new: java.lang.NoClassDefFoundError
6319: if (DEBUG)
6320: System.out.println(position
6321: + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$
6322: countLabels = 0;
6323: stackDepth++;
6324: if (stackDepth > stackMax)
6325: stackMax = stackDepth;
6326: if (classFileOffset + 2 >= bCodeStream.length) {
6327: resizeByteArray();
6328: }
6329: position++;
6330: bCodeStream[classFileOffset++] = Opcodes.OPC_new;
6331: writeUnsignedShort(constantPool
6332: .literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName));
6333: }
6334:
6335: public void newStringContatenation() {
6336: // new: java.lang.StringBuffer
6337: // new: java.lang.StringBuilder
6338: if (DEBUG) {
6339: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
6340: System.out.println(position
6341: + "\t\tnew: java.lang.StringBuilder"); //$NON-NLS-1$
6342: } else {
6343: System.out.println(position
6344: + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$
6345: }
6346: }
6347: countLabels = 0;
6348: stackDepth++;
6349: if (stackDepth > stackMax) {
6350: stackMax = stackDepth;
6351: }
6352: if (classFileOffset + 2 >= bCodeStream.length) {
6353: resizeByteArray();
6354: }
6355: position++;
6356: bCodeStream[classFileOffset++] = Opcodes.OPC_new;
6357: if (this .targetLevel >= ClassFileConstants.JDK1_5) {
6358: writeUnsignedShort(constantPool
6359: .literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName));
6360: } else {
6361: writeUnsignedShort(constantPool
6362: .literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName));
6363: }
6364: }
6365:
6366: public void newWrapperFor(int typeID) {
6367: countLabels = 0;
6368: stackDepth++;
6369: if (stackDepth > stackMax)
6370: stackMax = stackDepth;
6371: if (classFileOffset + 2 >= bCodeStream.length) {
6372: resizeByteArray();
6373: }
6374: position++;
6375: bCodeStream[classFileOffset++] = Opcodes.OPC_new;
6376: switch (typeID) {
6377: case TypeIds.T_int: // new: java.lang.Integer
6378: if (DEBUG)
6379: System.out.println(position
6380: + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$
6381: writeUnsignedShort(constantPool
6382: .literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
6383: break;
6384: case TypeIds.T_boolean: // new: java.lang.Boolean
6385: if (DEBUG)
6386: System.out.println(position
6387: + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$
6388: writeUnsignedShort(constantPool
6389: .literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
6390: break;
6391: case TypeIds.T_byte: // new: java.lang.Byte
6392: if (DEBUG)
6393: System.out
6394: .println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$
6395: writeUnsignedShort(constantPool
6396: .literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
6397: break;
6398: case TypeIds.T_char: // new: java.lang.Character
6399: if (DEBUG)
6400: System.out.println(position
6401: + "\t\tnew: java.lang.Character"); //$NON-NLS-1$
6402: writeUnsignedShort(constantPool
6403: .literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
6404: break;
6405: case TypeIds.T_float: // new: java.lang.Float
6406: if (DEBUG)
6407: System.out.println(position
6408: + "\t\tnew: java.lang.Float"); //$NON-NLS-1$
6409: writeUnsignedShort(constantPool
6410: .literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
6411: break;
6412: case TypeIds.T_double: // new: java.lang.Double
6413: if (DEBUG)
6414: System.out.println(position
6415: + "\t\tnew: java.lang.Double"); //$NON-NLS-1$
6416: writeUnsignedShort(constantPool
6417: .literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
6418: break;
6419: case TypeIds.T_short: // new: java.lang.Short
6420: if (DEBUG)
6421: System.out.println(position
6422: + "\t\tnew: java.lang.Short"); //$NON-NLS-1$
6423: writeUnsignedShort(constantPool
6424: .literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
6425: break;
6426: case TypeIds.T_long: // new: java.lang.Long
6427: if (DEBUG)
6428: System.out
6429: .println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$
6430: writeUnsignedShort(constantPool
6431: .literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
6432: break;
6433: case TypeIds.T_void: // new: java.lang.Void
6434: if (DEBUG)
6435: System.out
6436: .println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$
6437: writeUnsignedShort(constantPool
6438: .literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName));
6439: }
6440: }
6441:
6442: public void nop() {
6443: if (DEBUG)
6444: System.out.println(position + "\t\tnop"); //$NON-NLS-1$
6445: countLabels = 0;
6446: if (classFileOffset >= bCodeStream.length) {
6447: resizeByteArray();
6448: }
6449: position++;
6450: bCodeStream[classFileOffset++] = Opcodes.OPC_nop;
6451: }
6452:
6453: public void optimizeBranch(int oldPosition, BranchLabel lbl) {
6454: for (int i = 0; i < this .countLabels; i++) {
6455: BranchLabel label = this .labels[i];
6456: if (oldPosition == label.position) {
6457: label.position = position;
6458: if (label instanceof CaseLabel) {
6459: int offset = position
6460: - ((CaseLabel) label).instructionPosition;
6461: int[] forwardRefs = label.forwardReferences();
6462: for (int j = 0, length = label
6463: .forwardReferenceCount(); j < length; j++) {
6464: int forwardRef = forwardRefs[j];
6465: this .writeSignedWord(forwardRef, offset);
6466: }
6467: } else {
6468: int[] forwardRefs = label.forwardReferences();
6469: for (int j = 0, length = label
6470: .forwardReferenceCount(); j < length; j++) {
6471: final int forwardRef = forwardRefs[j];
6472: this .writePosition(lbl, forwardRef);
6473: }
6474: }
6475: }
6476: }
6477: }
6478:
6479: public void pop() {
6480: if (DEBUG)
6481: System.out.println(position + "\t\tpop"); //$NON-NLS-1$
6482: countLabels = 0;
6483: stackDepth--;
6484: if (classFileOffset >= bCodeStream.length) {
6485: resizeByteArray();
6486: }
6487: position++;
6488: bCodeStream[classFileOffset++] = Opcodes.OPC_pop;
6489: }
6490:
6491: public void pop2() {
6492: if (DEBUG)
6493: System.out.println(position + "\t\tpop2"); //$NON-NLS-1$
6494: countLabels = 0;
6495: stackDepth -= 2;
6496: if (classFileOffset >= bCodeStream.length) {
6497: resizeByteArray();
6498: }
6499: position++;
6500: bCodeStream[classFileOffset++] = Opcodes.OPC_pop2;
6501: }
6502:
6503: public void pushOnStack(TypeBinding binding) {
6504: if (++stackDepth > stackMax)
6505: stackMax = stackDepth;
6506: }
6507:
6508: public void pushExceptionOnStack(TypeBinding binding) {
6509: if (++stackDepth > stackMax)
6510: stackMax = stackDepth;
6511: }
6512:
6513: public void putfield(FieldBinding fieldBinding) {
6514: if (DEBUG)
6515: System.out.println(position
6516: + "\t\tputfield:" + fieldBinding); //$NON-NLS-1$
6517: int returnTypeSize = 1;
6518: if ((fieldBinding.type.id == TypeIds.T_double)
6519: || (fieldBinding.type.id == TypeIds.T_long)) {
6520: returnTypeSize = 2;
6521: }
6522: generateFieldAccess(Opcodes.OPC_putfield, returnTypeSize,
6523: fieldBinding.declaringClass, fieldBinding.name,
6524: fieldBinding.type);
6525: }
6526:
6527: public void putstatic(FieldBinding fieldBinding) {
6528: if (DEBUG)
6529: System.out.println(position
6530: + "\t\tputstatic:" + fieldBinding); //$NON-NLS-1$
6531: int returnTypeSize = 1;
6532: if ((fieldBinding.type.id == TypeIds.T_double)
6533: || (fieldBinding.type.id == TypeIds.T_long)) {
6534: returnTypeSize = 2;
6535: }
6536: generateFieldAccess(Opcodes.OPC_putstatic, returnTypeSize,
6537: fieldBinding.declaringClass, fieldBinding.name,
6538: fieldBinding.type);
6539: }
6540:
6541: public void record(LocalVariableBinding local) {
6542: if ((this .generateAttributes & (ClassFileConstants.ATTR_VARS
6543: | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) == 0)
6544: return;
6545: if (allLocalsCounter == locals.length) {
6546: // resize the collection
6547: System.arraycopy(locals, 0,
6548: locals = new LocalVariableBinding[allLocalsCounter
6549: + LOCALS_INCREMENT], 0, allLocalsCounter);
6550: }
6551: locals[allLocalsCounter++] = local;
6552: local.initializationPCs = new int[4];
6553: local.initializationCount = 0;
6554: }
6555:
6556: public void recordExpressionType(TypeBinding typeBinding) {
6557: // nothing to do
6558: }
6559:
6560: public void recordPositionsFrom(int startPC, int sourcePos) {
6561: this .recordPositionsFrom(startPC, sourcePos, false);
6562: }
6563:
6564: public void recordPositionsFrom(int startPC, int sourcePos,
6565: boolean widen) {
6566:
6567: /* Record positions in the table, only if nothing has
6568: * already been recorded. Since we output them on the way
6569: * up (children first for more specific info)
6570: * The pcToSourceMap table is always sorted.
6571: */
6572:
6573: if ((this .generateAttributes & ClassFileConstants.ATTR_LINES) == 0
6574: || sourcePos == 0 || (startPC == position && !widen))
6575: return;
6576:
6577: // Widening an existing entry that already has the same source positions
6578: if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
6579: // resize the array pcToSourceMap
6580: System.arraycopy(pcToSourceMap, 0,
6581: pcToSourceMap = new int[pcToSourceMapSize << 1], 0,
6582: pcToSourceMapSize);
6583: }
6584: // lastEntryPC represents the endPC of the lastEntry.
6585: if (pcToSourceMapSize > 0) {
6586: int lineNumber;
6587: int previousLineNumber = pcToSourceMap[pcToSourceMapSize - 1];
6588: if (this .lineNumberStart == this .lineNumberEnd) {
6589: // method on one line
6590: lineNumber = this .lineNumberStart;
6591: } else {
6592: // Check next line number if this is the one we are looking for
6593: int[] lineSeparatorPositions2 = this .lineSeparatorPositions;
6594: int length = lineSeparatorPositions2.length;
6595: if (previousLineNumber == 1) {
6596: if (sourcePos < lineSeparatorPositions2[0]) {
6597: lineNumber = 1;
6598: /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
6599: we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
6600: */
6601: if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
6602: int insertionIndex = insertionIndex(
6603: pcToSourceMap, pcToSourceMapSize,
6604: startPC);
6605: if (insertionIndex != -1) {
6606: // widen the existing entry
6607: // we have to figure out if we need to move the last entry at another location to keep a sorted table
6608: /* First we need to check if at the insertion position there is not an existing entry
6609: * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
6610: * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
6611: * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
6612: */
6613: if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == lineNumber))) {
6614: if ((pcToSourceMapSize > 4)
6615: && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
6616: System
6617: .arraycopy(
6618: pcToSourceMap,
6619: insertionIndex,
6620: pcToSourceMap,
6621: insertionIndex + 2,
6622: pcToSourceMapSize
6623: - 2
6624: - insertionIndex);
6625: pcToSourceMap[insertionIndex++] = startPC;
6626: pcToSourceMap[insertionIndex] = lineNumber;
6627: } else {
6628: pcToSourceMap[pcToSourceMapSize - 2] = startPC;
6629: }
6630: }
6631: }
6632: }
6633: lastEntryPC = position;
6634: return;
6635: } else if (length == 1
6636: || sourcePos < lineSeparatorPositions2[1]) {
6637: lineNumber = 2;
6638: if (startPC <= lastEntryPC) {
6639: // we forgot to add an entry.
6640: // search if an existing entry exists for startPC
6641: int insertionIndex = insertionIndex(
6642: pcToSourceMap, pcToSourceMapSize,
6643: startPC);
6644: if (insertionIndex != -1) {
6645: // there is no existing entry starting with startPC.
6646: int existingEntryIndex = indexOfSameLineEntrySincePC(
6647: startPC, lineNumber); // index for PC
6648: /* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
6649: in this case it is relevant to widen this entry instead of creating a new one.
6650: line1: this(a,
6651: b,
6652: c);
6653: with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
6654: aload0 bytecode. The first entry is the one for the argument a.
6655: But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
6656: So we widen the existing entry (if there is one) or we create a new entry with the startPC.
6657: */
6658: if (existingEntryIndex != -1) {
6659: // widen existing entry
6660: pcToSourceMap[existingEntryIndex] = startPC;
6661: } else if (insertionIndex < 1
6662: || pcToSourceMap[insertionIndex - 1] != lineNumber) {
6663: // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
6664: System.arraycopy(pcToSourceMap,
6665: insertionIndex,
6666: pcToSourceMap,
6667: insertionIndex + 2,
6668: pcToSourceMapSize
6669: - insertionIndex);
6670: pcToSourceMap[insertionIndex++] = startPC;
6671: pcToSourceMap[insertionIndex] = lineNumber;
6672: pcToSourceMapSize += 2;
6673: }
6674: } else if (position != lastEntryPC) { // no bytecode since last entry pc
6675: if (lastEntryPC == startPC
6676: || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
6677: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6678: } else {
6679: pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
6680: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6681: }
6682: } else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber
6683: && widen) {
6684: // see if we can widen the existing entry
6685: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6686: }
6687: } else {
6688: // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
6689: pcToSourceMap[pcToSourceMapSize++] = startPC;
6690: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6691: }
6692: lastEntryPC = position;
6693: return;
6694: } else {
6695: // since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
6696: lineNumber = Util.getLineNumber(sourcePos,
6697: lineSeparatorPositions,
6698: this .lineNumberStart - 1,
6699: this .lineNumberEnd - 1);
6700: }
6701: } else if (previousLineNumber < length) {
6702: if (lineSeparatorPositions2[previousLineNumber - 2] < sourcePos) {
6703: if (sourcePos < lineSeparatorPositions2[previousLineNumber - 1]) {
6704: lineNumber = previousLineNumber;
6705: /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
6706: we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
6707: */
6708: if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
6709: int insertionIndex = insertionIndex(
6710: pcToSourceMap,
6711: pcToSourceMapSize, startPC);
6712: if (insertionIndex != -1) {
6713: // widen the existing entry
6714: // we have to figure out if we need to move the last entry at another location to keep a sorted table
6715: /* First we need to check if at the insertion position there is not an existing entry
6716: * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
6717: * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
6718: * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
6719: */
6720: if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == lineNumber))) {
6721: if ((pcToSourceMapSize > 4)
6722: && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
6723: System
6724: .arraycopy(
6725: pcToSourceMap,
6726: insertionIndex,
6727: pcToSourceMap,
6728: insertionIndex + 2,
6729: pcToSourceMapSize
6730: - 2
6731: - insertionIndex);
6732: pcToSourceMap[insertionIndex++] = startPC;
6733: pcToSourceMap[insertionIndex] = lineNumber;
6734: } else {
6735: pcToSourceMap[pcToSourceMapSize - 2] = startPC;
6736: }
6737: }
6738: }
6739: }
6740: lastEntryPC = position;
6741: return;
6742: } else if (sourcePos < lineSeparatorPositions2[previousLineNumber]) {
6743: lineNumber = previousLineNumber + 1;
6744: if (startPC <= lastEntryPC) {
6745: // we forgot to add an entry.
6746: // search if an existing entry exists for startPC
6747: int insertionIndex = insertionIndex(
6748: pcToSourceMap,
6749: pcToSourceMapSize, startPC);
6750: if (insertionIndex != -1) {
6751: // there is no existing entry starting with startPC.
6752: int existingEntryIndex = indexOfSameLineEntrySincePC(
6753: startPC, lineNumber); // index for PC
6754: /* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
6755: in this case it is relevant to widen this entry instead of creating a new one.
6756: line1: this(a,
6757: b,
6758: c);
6759: with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
6760: aload0 bytecode. The first entry is the one for the argument a.
6761: But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
6762: So we widen the existing entry (if there is one) or we create a new entry with the startPC.
6763: */
6764: if (existingEntryIndex != -1) {
6765: // widen existing entry
6766: pcToSourceMap[existingEntryIndex] = startPC;
6767: } else if (insertionIndex < 1
6768: || pcToSourceMap[insertionIndex - 1] != lineNumber) {
6769: // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
6770: System
6771: .arraycopy(
6772: pcToSourceMap,
6773: insertionIndex,
6774: pcToSourceMap,
6775: insertionIndex + 2,
6776: pcToSourceMapSize
6777: - insertionIndex);
6778: pcToSourceMap[insertionIndex++] = startPC;
6779: pcToSourceMap[insertionIndex] = lineNumber;
6780: pcToSourceMapSize += 2;
6781: }
6782: } else if (position != lastEntryPC) { // no bytecode since last entry pc
6783: if (lastEntryPC == startPC
6784: || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
6785: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6786: } else {
6787: pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
6788: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6789: }
6790: } else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber
6791: && widen) {
6792: // see if we can widen the existing entry
6793: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6794: }
6795: } else {
6796: // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
6797: pcToSourceMap[pcToSourceMapSize++] = startPC;
6798: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6799: }
6800: lastEntryPC = position;
6801: return;
6802: } else {
6803: // since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
6804: lineNumber = Util.getLineNumber(sourcePos,
6805: lineSeparatorPositions,
6806: this .lineNumberStart - 1,
6807: this .lineNumberEnd - 1);
6808: }
6809: } else {
6810: // since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
6811: lineNumber = Util.getLineNumber(sourcePos,
6812: lineSeparatorPositions,
6813: this .lineNumberStart - 1,
6814: this .lineNumberEnd - 1);
6815: }
6816: } else if (lineSeparatorPositions2[length - 1] < sourcePos) {
6817: lineNumber = length + 1;
6818: if (startPC <= lastEntryPC) {
6819: // we forgot to add an entry.
6820: // search if an existing entry exists for startPC
6821: int insertionIndex = insertionIndex(
6822: pcToSourceMap, pcToSourceMapSize,
6823: startPC);
6824: if (insertionIndex != -1) {
6825: // there is no existing entry starting with startPC.
6826: int existingEntryIndex = indexOfSameLineEntrySincePC(
6827: startPC, lineNumber); // index for PC
6828: /* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
6829: in this case it is relevant to widen this entry instead of creating a new one.
6830: line1: this(a,
6831: b,
6832: c);
6833: with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
6834: aload0 bytecode. The first entry is the one for the argument a.
6835: But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
6836: So we widen the existing entry (if there is one) or we create a new entry with the startPC.
6837: */
6838: if (existingEntryIndex != -1) {
6839: // widen existing entry
6840: pcToSourceMap[existingEntryIndex] = startPC;
6841: } else if (insertionIndex < 1
6842: || pcToSourceMap[insertionIndex - 1] != lineNumber) {
6843: // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
6844: System.arraycopy(pcToSourceMap,
6845: insertionIndex, pcToSourceMap,
6846: insertionIndex + 2,
6847: pcToSourceMapSize
6848: - insertionIndex);
6849: pcToSourceMap[insertionIndex++] = startPC;
6850: pcToSourceMap[insertionIndex] = lineNumber;
6851: pcToSourceMapSize += 2;
6852: }
6853: } else if (position != lastEntryPC) { // no bytecode since last entry pc
6854: if (lastEntryPC == startPC
6855: || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
6856: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6857: } else {
6858: pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
6859: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6860: }
6861: } else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber
6862: && widen) {
6863: // see if we can widen the existing entry
6864: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6865: }
6866: } else {
6867: // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
6868: pcToSourceMap[pcToSourceMapSize++] = startPC;
6869: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6870: }
6871: lastEntryPC = position;
6872: return;
6873: } else {
6874: // since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
6875: lineNumber = Util.getLineNumber(sourcePos,
6876: lineSeparatorPositions,
6877: this .lineNumberStart - 1,
6878: this .lineNumberEnd - 1);
6879: }
6880: }
6881: // in this case there is already an entry in the table
6882: if (previousLineNumber != lineNumber) {
6883: if (startPC <= lastEntryPC) {
6884: // we forgot to add an entry.
6885: // search if an existing entry exists for startPC
6886: int insertionIndex = insertionIndex(pcToSourceMap,
6887: pcToSourceMapSize, startPC);
6888: if (insertionIndex != -1) {
6889: // there is no existing entry starting with startPC.
6890: int existingEntryIndex = indexOfSameLineEntrySincePC(
6891: startPC, lineNumber); // index for PC
6892: /* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
6893: in this case it is relevant to widen this entry instead of creating a new one.
6894: line1: this(a,
6895: b,
6896: c);
6897: with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
6898: aload0 bytecode. The first entry is the one for the argument a.
6899: But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
6900: So we widen the existing entry (if there is one) or we create a new entry with the startPC.
6901: */
6902: if (existingEntryIndex != -1) {
6903: // widen existing entry
6904: pcToSourceMap[existingEntryIndex] = startPC;
6905: } else if (insertionIndex < 1
6906: || pcToSourceMap[insertionIndex - 1] != lineNumber) {
6907: // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
6908: System.arraycopy(pcToSourceMap,
6909: insertionIndex, pcToSourceMap,
6910: insertionIndex + 2,
6911: pcToSourceMapSize - insertionIndex);
6912: pcToSourceMap[insertionIndex++] = startPC;
6913: pcToSourceMap[insertionIndex] = lineNumber;
6914: pcToSourceMapSize += 2;
6915: }
6916: } else if (position != lastEntryPC) { // no bytecode since last entry pc
6917: if (lastEntryPC == startPC
6918: || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
6919: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6920: } else {
6921: pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
6922: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6923: }
6924: } else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber
6925: && widen) {
6926: // see if we can widen the existing entry
6927: pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
6928: }
6929: } else {
6930: // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
6931: pcToSourceMap[pcToSourceMapSize++] = startPC;
6932: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6933: }
6934: } else {
6935: /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
6936: we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
6937: */
6938: if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
6939: int insertionIndex = insertionIndex(pcToSourceMap,
6940: pcToSourceMapSize, startPC);
6941: if (insertionIndex != -1) {
6942: // widen the existing entry
6943: // we have to figure out if we need to move the last entry at another location to keep a sorted table
6944: /* First we need to check if at the insertion position there is not an existing entry
6945: * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
6946: * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
6947: * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
6948: */
6949: if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == lineNumber))) {
6950: if ((pcToSourceMapSize > 4)
6951: && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
6952: System.arraycopy(pcToSourceMap,
6953: insertionIndex, pcToSourceMap,
6954: insertionIndex + 2,
6955: pcToSourceMapSize - 2
6956: - insertionIndex);
6957: pcToSourceMap[insertionIndex++] = startPC;
6958: pcToSourceMap[insertionIndex] = lineNumber;
6959: } else {
6960: pcToSourceMap[pcToSourceMapSize - 2] = startPC;
6961: }
6962: }
6963: }
6964: }
6965: }
6966: lastEntryPC = position;
6967: } else {
6968: int lineNumber = 0;
6969: if (this .lineNumberStart == this .lineNumberEnd) {
6970: // method on one line
6971: lineNumber = this .lineNumberStart;
6972: } else {
6973: // since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
6974: lineNumber = Util.getLineNumber(sourcePos,
6975: lineSeparatorPositions,
6976: this .lineNumberStart - 1,
6977: this .lineNumberEnd - 1);
6978: }
6979: // record the first entry
6980: pcToSourceMap[pcToSourceMapSize++] = startPC;
6981: pcToSourceMap[pcToSourceMapSize++] = lineNumber;
6982: lastEntryPC = position;
6983: }
6984: }
6985:
6986: /**
6987: * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
6988: */
6989: public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
6990: int length;
6991: if (exceptionLabelsCounter == (length = exceptionLabels.length)) {
6992: // resize the exception handlers table
6993: System.arraycopy(exceptionLabels, 0,
6994: exceptionLabels = new ExceptionLabel[length
6995: + LABELS_INCREMENT], 0, length);
6996: }
6997: // no need to resize. So just add the new exception label
6998: exceptionLabels[exceptionLabelsCounter++] = anExceptionLabel;
6999: }
7000:
7001: public void removeNotDefinitelyAssignedVariables(Scope scope,
7002: int initStateIndex) {
7003: // given some flow info, make sure we did not loose some variables initialization
7004: // if this happens, then we must update their pc entries to reflect it in debug attributes
7005: if ((this .generateAttributes & (ClassFileConstants.ATTR_VARS
7006: | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) == 0)
7007: return;
7008: for (int i = 0; i < visibleLocalsCount; i++) {
7009: LocalVariableBinding localBinding = visibleLocals[i];
7010: if (localBinding != null
7011: && !isDefinitelyAssigned(scope, initStateIndex,
7012: localBinding)
7013: && localBinding.initializationCount > 0) {
7014: localBinding.recordInitializationEndPC(position);
7015: }
7016: }
7017: }
7018:
7019: /**
7020: * Remove all entries in pcToSourceMap table that are beyond this.position
7021: */
7022: public void removeUnusedPcToSourceMapEntries() {
7023: if (this .pcToSourceMapSize != 0) {
7024: while (this .pcToSourceMapSize >= 2
7025: && this .pcToSourceMap[this .pcToSourceMapSize - 2] > this .position) {
7026: this .pcToSourceMapSize -= 2;
7027: }
7028: }
7029: }
7030:
7031: public void removeVariable(LocalVariableBinding localBinding) {
7032: if (localBinding == null)
7033: return;
7034: if (localBinding.initializationCount > 0) {
7035: localBinding.recordInitializationEndPC(position);
7036: }
7037: for (int i = visibleLocalsCount - 1; i >= 0; i--) {
7038: LocalVariableBinding visibleLocal = visibleLocals[i];
7039: if (visibleLocal == localBinding) {
7040: visibleLocals[i] = null; // this variable is no longer visible afterwards
7041: return;
7042: }
7043: }
7044: }
7045:
7046: /**
7047: * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
7048: * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
7049: */
7050: public void reset(AbstractMethodDeclaration referenceMethod,
7051: ClassFile targetClassFile) {
7052: init(targetClassFile);
7053: this .methodDeclaration = referenceMethod;
7054: int[] lineSeparatorPositions2 = this .lineSeparatorPositions;
7055: if (lineSeparatorPositions2 != null) {
7056: int length = lineSeparatorPositions2.length;
7057: int lineSeparatorPositionsEnd = length - 1;
7058: if (referenceMethod.isClinit()
7059: || referenceMethod.isConstructor()) {
7060: this .lineNumberStart = 1;
7061: this .lineNumberEnd = length == 0 ? 1 : length;
7062: } else {
7063: int start = Util.getLineNumber(
7064: referenceMethod.bodyStart,
7065: lineSeparatorPositions2, 0,
7066: lineSeparatorPositionsEnd);
7067: this .lineNumberStart = start;
7068: if (start > lineSeparatorPositionsEnd) {
7069: this .lineNumberEnd = start;
7070: } else {
7071: int end = Util.getLineNumber(
7072: referenceMethod.bodyEnd,
7073: lineSeparatorPositions2, start - 1,
7074: lineSeparatorPositionsEnd);
7075: if (end >= lineSeparatorPositionsEnd) {
7076: end = length;
7077: }
7078: this .lineNumberEnd = end == 0 ? 1 : end;
7079: }
7080: }
7081: }
7082: this .preserveUnusedLocals = referenceMethod.scope
7083: .compilerOptions().preserveAllLocalVariables;
7084: initializeMaxLocals(referenceMethod.binding);
7085: }
7086:
7087: public void reset(ClassFile givenClassFile) {
7088: this .targetLevel = givenClassFile.targetJDK;
7089: int produceAttributes = givenClassFile.produceAttributes;
7090: this .generateAttributes = produceAttributes;
7091: if ((produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
7092: this .lineSeparatorPositions = givenClassFile.referenceBinding.scope
7093: .referenceCompilationUnit().compilationResult
7094: .getLineSeparatorPositions();
7095: } else {
7096: this .lineSeparatorPositions = null;
7097: }
7098: }
7099:
7100: /**
7101: * @param targetClassFile The given classfile to reset the code stream
7102: */
7103: public void resetForProblemClinit(ClassFile targetClassFile) {
7104: init(targetClassFile);
7105: initializeMaxLocals(null);
7106: }
7107:
7108: private final void resizeByteArray() {
7109: int length = bCodeStream.length;
7110: int requiredSize = length + length;
7111: if (classFileOffset >= requiredSize) {
7112: // must be sure to grow enough
7113: requiredSize = classFileOffset + length;
7114: }
7115: System.arraycopy(bCodeStream, 0,
7116: bCodeStream = new byte[requiredSize], 0, length);
7117: }
7118:
7119: final public void ret(int index) {
7120: if (DEBUG)
7121: System.out.println(position + "\t\tret:" + index); //$NON-NLS-1$
7122: countLabels = 0;
7123: if (index > 255) { // Widen
7124: if (classFileOffset + 3 >= bCodeStream.length) {
7125: resizeByteArray();
7126: }
7127: position += 2;
7128: bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
7129: bCodeStream[classFileOffset++] = Opcodes.OPC_ret;
7130: writeUnsignedShort(index);
7131: } else { // Don't Widen
7132: if (classFileOffset + 1 >= bCodeStream.length) {
7133: resizeByteArray();
7134: }
7135: position += 2;
7136: bCodeStream[classFileOffset++] = Opcodes.OPC_ret;
7137: bCodeStream[classFileOffset++] = (byte) index;
7138: }
7139: }
7140:
7141: public void return_() {
7142: if (DEBUG)
7143: System.out.println(position + "\t\treturn"); //$NON-NLS-1$
7144: countLabels = 0;
7145: // the stackDepth should be equal to 0
7146: if (classFileOffset >= bCodeStream.length) {
7147: resizeByteArray();
7148: }
7149: position++;
7150: bCodeStream[classFileOffset++] = Opcodes.OPC_return;
7151: this .lastAbruptCompletion = this .position;
7152: }
7153:
7154: public void saload() {
7155: if (DEBUG)
7156: System.out.println(position + "\t\tsaload"); //$NON-NLS-1$
7157: countLabels = 0;
7158: stackDepth--;
7159: if (classFileOffset >= bCodeStream.length) {
7160: resizeByteArray();
7161: }
7162: position++;
7163: bCodeStream[classFileOffset++] = Opcodes.OPC_saload;
7164: }
7165:
7166: public void sastore() {
7167: if (DEBUG)
7168: System.out.println(position + "\t\tsastore"); //$NON-NLS-1$
7169: countLabels = 0;
7170: stackDepth -= 3;
7171: if (classFileOffset >= bCodeStream.length) {
7172: resizeByteArray();
7173: }
7174: position++;
7175: bCodeStream[classFileOffset++] = Opcodes.OPC_sastore;
7176: }
7177:
7178: /**
7179: * @param operatorConstant int
7180: * @param type_ID int
7181: */
7182: public void sendOperator(int operatorConstant, int type_ID) {
7183: switch (type_ID) {
7184: case TypeIds.T_int:
7185: case TypeIds.T_boolean:
7186: case TypeIds.T_char:
7187: case TypeIds.T_byte:
7188: case TypeIds.T_short:
7189: switch (operatorConstant) {
7190: case OperatorIds.PLUS:
7191: this .iadd();
7192: break;
7193: case OperatorIds.MINUS:
7194: this .isub();
7195: break;
7196: case OperatorIds.MULTIPLY:
7197: this .imul();
7198: break;
7199: case OperatorIds.DIVIDE:
7200: this .idiv();
7201: break;
7202: case OperatorIds.REMAINDER:
7203: this .irem();
7204: break;
7205: case OperatorIds.LEFT_SHIFT:
7206: this .ishl();
7207: break;
7208: case OperatorIds.RIGHT_SHIFT:
7209: this .ishr();
7210: break;
7211: case OperatorIds.UNSIGNED_RIGHT_SHIFT:
7212: this .iushr();
7213: break;
7214: case OperatorIds.AND:
7215: this .iand();
7216: break;
7217: case OperatorIds.OR:
7218: this .ior();
7219: break;
7220: case OperatorIds.XOR:
7221: this .ixor();
7222: break;
7223: }
7224: break;
7225: case TypeIds.T_long:
7226: switch (operatorConstant) {
7227: case OperatorIds.PLUS:
7228: this .ladd();
7229: break;
7230: case OperatorIds.MINUS:
7231: this .lsub();
7232: break;
7233: case OperatorIds.MULTIPLY:
7234: this .lmul();
7235: break;
7236: case OperatorIds.DIVIDE:
7237: this .ldiv();
7238: break;
7239: case OperatorIds.REMAINDER:
7240: this .lrem();
7241: break;
7242: case OperatorIds.LEFT_SHIFT:
7243: this .lshl();
7244: break;
7245: case OperatorIds.RIGHT_SHIFT:
7246: this .lshr();
7247: break;
7248: case OperatorIds.UNSIGNED_RIGHT_SHIFT:
7249: this .lushr();
7250: break;
7251: case OperatorIds.AND:
7252: this .land();
7253: break;
7254: case OperatorIds.OR:
7255: this .lor();
7256: break;
7257: case OperatorIds.XOR:
7258: this .lxor();
7259: break;
7260: }
7261: break;
7262: case TypeIds.T_float:
7263: switch (operatorConstant) {
7264: case OperatorIds.PLUS:
7265: this .fadd();
7266: break;
7267: case OperatorIds.MINUS:
7268: this .fsub();
7269: break;
7270: case OperatorIds.MULTIPLY:
7271: this .fmul();
7272: break;
7273: case OperatorIds.DIVIDE:
7274: this .fdiv();
7275: break;
7276: case OperatorIds.REMAINDER:
7277: this .frem();
7278: }
7279: break;
7280: case TypeIds.T_double:
7281: switch (operatorConstant) {
7282: case OperatorIds.PLUS:
7283: this .dadd();
7284: break;
7285: case OperatorIds.MINUS:
7286: this .dsub();
7287: break;
7288: case OperatorIds.MULTIPLY:
7289: this .dmul();
7290: break;
7291: case OperatorIds.DIVIDE:
7292: this .ddiv();
7293: break;
7294: case OperatorIds.REMAINDER:
7295: this .drem();
7296: }
7297: }
7298: }
7299:
7300: public void sipush(int s) {
7301: if (DEBUG)
7302: System.out.println(position + "\t\tsipush:" + s); //$NON-NLS-1$
7303: countLabels = 0;
7304: stackDepth++;
7305: if (stackDepth > stackMax)
7306: stackMax = stackDepth;
7307: if (classFileOffset >= bCodeStream.length) {
7308: resizeByteArray();
7309: }
7310: position++;
7311: bCodeStream[classFileOffset++] = Opcodes.OPC_sipush;
7312: writeSignedShort(s);
7313: }
7314:
7315: public void store(LocalVariableBinding localBinding,
7316: boolean valueRequired) {
7317: int localPosition = localBinding.resolvedPosition;
7318: // Using dedicated int bytecode
7319: switch (localBinding.type.id) {
7320: case TypeIds.T_int:
7321: case TypeIds.T_char:
7322: case TypeIds.T_byte:
7323: case TypeIds.T_short:
7324: case TypeIds.T_boolean:
7325: if (valueRequired)
7326: this .dup();
7327: switch (localPosition) {
7328: case 0:
7329: this .istore_0();
7330: break;
7331: case 1:
7332: this .istore_1();
7333: break;
7334: case 2:
7335: this .istore_2();
7336: break;
7337: case 3:
7338: this .istore_3();
7339: break;
7340: //case -1 :
7341: // internal failure: trying to store into variable not supposed to be generated
7342: // break;
7343: default:
7344: this .istore(localPosition);
7345: }
7346: break;
7347: case TypeIds.T_float:
7348: if (valueRequired)
7349: this .dup();
7350: switch (localPosition) {
7351: case 0:
7352: this .fstore_0();
7353: break;
7354: case 1:
7355: this .fstore_1();
7356: break;
7357: case 2:
7358: this .fstore_2();
7359: break;
7360: case 3:
7361: this .fstore_3();
7362: break;
7363: default:
7364: this .fstore(localPosition);
7365: }
7366: break;
7367: case TypeIds.T_double:
7368: if (valueRequired)
7369: this .dup2();
7370: switch (localPosition) {
7371: case 0:
7372: this .dstore_0();
7373: break;
7374: case 1:
7375: this .dstore_1();
7376: break;
7377: case 2:
7378: this .dstore_2();
7379: break;
7380: case 3:
7381: this .dstore_3();
7382: break;
7383: default:
7384: this .dstore(localPosition);
7385: }
7386: break;
7387: case TypeIds.T_long:
7388: if (valueRequired)
7389: this .dup2();
7390: switch (localPosition) {
7391: case 0:
7392: this .lstore_0();
7393: break;
7394: case 1:
7395: this .lstore_1();
7396: break;
7397: case 2:
7398: this .lstore_2();
7399: break;
7400: case 3:
7401: this .lstore_3();
7402: break;
7403: default:
7404: this .lstore(localPosition);
7405: }
7406: break;
7407: default:
7408: // Reference object
7409: if (valueRequired)
7410: this .dup();
7411: switch (localPosition) {
7412: case 0:
7413: this .astore_0();
7414: break;
7415: case 1:
7416: this .astore_1();
7417: break;
7418: case 2:
7419: this .astore_2();
7420: break;
7421: case 3:
7422: this .astore_3();
7423: break;
7424: default:
7425: this .astore(localPosition);
7426: }
7427: }
7428: }
7429:
7430: public void swap() {
7431: if (DEBUG)
7432: System.out.println(position + "\t\tswap"); //$NON-NLS-1$
7433: countLabels = 0;
7434: if (classFileOffset >= bCodeStream.length) {
7435: resizeByteArray();
7436: }
7437: position++;
7438: bCodeStream[classFileOffset++] = Opcodes.OPC_swap;
7439: }
7440:
7441: public void tableswitch(CaseLabel defaultLabel, int low, int high,
7442: int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
7443: if (DEBUG)
7444: System.out.println(position + "\t\ttableswitch"); //$NON-NLS-1$
7445: countLabels = 0;
7446: stackDepth--;
7447: int length = casesLabel.length;
7448: int pos = position;
7449: defaultLabel.placeInstruction();
7450: for (int i = 0; i < length; i++)
7451: casesLabel[i].placeInstruction();
7452: if (classFileOffset >= bCodeStream.length) {
7453: resizeByteArray();
7454: }
7455: position++;
7456: bCodeStream[classFileOffset++] = Opcodes.OPC_tableswitch;
7457: // padding
7458: for (int i = (3 - (pos & 3)); i > 0; i--) {
7459: if (classFileOffset >= bCodeStream.length) {
7460: resizeByteArray();
7461: }
7462: position++;
7463: bCodeStream[classFileOffset++] = 0;
7464: }
7465: defaultLabel.branch();
7466: writeSignedWord(low);
7467: writeSignedWord(high);
7468: int i = low, j = low;
7469: // the index j is used to know if the index i is one of the missing entries in case of an
7470: // optimized tableswitch
7471: while (true) {
7472: int index;
7473: int key = keys[index = sortedIndexes[j - low]];
7474: if (key == i) {
7475: casesLabel[index].branch();
7476: j++;
7477: if (i == high)
7478: break; // if high is maxint, then avoids wrapping to minint.
7479: } else {
7480: defaultLabel.branch();
7481: }
7482: i++;
7483: }
7484: }
7485:
7486: public void throwAnyException(
7487: LocalVariableBinding anyExceptionVariable) {
7488: this .load(anyExceptionVariable);
7489: this .athrow();
7490: }
7491:
7492: public String toString() {
7493: StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
7494: buffer.append(position);
7495: buffer.append(",\nstackDepth:"); //$NON-NLS-1$
7496: buffer.append(stackDepth);
7497: buffer.append(",\nmaxStack:"); //$NON-NLS-1$
7498: buffer.append(stackMax);
7499: buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
7500: buffer.append(maxLocals);
7501: buffer.append(")"); //$NON-NLS-1$
7502: return buffer.toString();
7503: }
7504:
7505: /**
7506: * Note: it will walk the locals table and extend the end range for all matching ones, no matter if
7507: * visible or not.
7508: * { int i = 0;
7509: * { int j = 1; }
7510: * } <== would process both 'i' and 'j'
7511: * Processing non-visible ones is mandated in some cases (include goto instruction after if-then block)
7512: */
7513: public void updateLastRecordedEndPC(Scope scope, int pos) {
7514:
7515: /* Tune positions in the table, this is due to some
7516: * extra bytecodes being
7517: * added to some user code (jumps). */
7518: /** OLD CODE
7519: if (!generateLineNumberAttributes)
7520: return;
7521: pcToSourceMap[pcToSourceMapSize - 1][1] = position;
7522: // need to update the initialization endPC in case of generation of local variable attributes.
7523: updateLocalVariablesAttribute(pos);
7524: */
7525:
7526: if ((this .generateAttributes & ClassFileConstants.ATTR_LINES) != 0) {
7527: this .lastEntryPC = pos;
7528: }
7529: // need to update the initialization endPC in case of generation of local variable attributes.
7530: if ((this .generateAttributes & (ClassFileConstants.ATTR_VARS
7531: | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) != 0) {
7532: for (int i = 0, max = this .locals.length; i < max; i++) {
7533: LocalVariableBinding local = this .locals[i];
7534: if (local != null && local.declaringScope == scope
7535: && local.initializationCount > 0) {
7536: if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
7537: local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = this .position;
7538: }
7539: }
7540: }
7541: }
7542: }
7543:
7544: protected void writePosition(BranchLabel label) {
7545: int offset = label.position - this .position + 1;
7546: if (Math.abs(offset) > 0x7FFF && !this .wideMode) {
7547: throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE, null);
7548: }
7549: this .writeSignedShort(offset);
7550: int[] forwardRefs = label.forwardReferences();
7551: for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
7552: this .writePosition(label, forwardRefs[i]);
7553: }
7554: }
7555:
7556: protected void writePosition(BranchLabel label, int forwardReference) {
7557: final int offset = label.position - forwardReference + 1;
7558: if (Math.abs(offset) > 0x7FFF && !this .wideMode) {
7559: throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE, null);
7560: }
7561: if (this .wideMode) {
7562: if ((label.tagBits & BranchLabel.WIDE) != 0) {
7563: this .writeSignedWord(forwardReference, offset);
7564: } else {
7565: this .writeSignedShort(forwardReference, offset);
7566: }
7567: } else {
7568: this .writeSignedShort(forwardReference, offset);
7569: }
7570: }
7571:
7572: /**
7573: * Write a signed 16 bits value into the byte array
7574: * @param value the signed short
7575: */
7576: private final void writeSignedShort(int value) {
7577: // we keep the resize in here because it is used outside the code stream
7578: if (classFileOffset + 1 >= bCodeStream.length) {
7579: resizeByteArray();
7580: }
7581: position += 2;
7582: bCodeStream[classFileOffset++] = (byte) (value >> 8);
7583: bCodeStream[classFileOffset++] = (byte) value;
7584: }
7585:
7586: private final void writeSignedShort(int pos, int value) {
7587: int currentOffset = startingClassFileOffset + pos;
7588: if (currentOffset + 1 >= bCodeStream.length) {
7589: resizeByteArray();
7590: }
7591: bCodeStream[currentOffset] = (byte) (value >> 8);
7592: bCodeStream[currentOffset + 1] = (byte) value;
7593: }
7594:
7595: protected final void writeSignedWord(int value) {
7596: // we keep the resize in here because it is used outside the code stream
7597: if (classFileOffset + 3 >= bCodeStream.length) {
7598: resizeByteArray();
7599: }
7600: position += 4;
7601: bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
7602: bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
7603: bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
7604: bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
7605: }
7606:
7607: protected void writeSignedWord(int pos, int value) {
7608: int currentOffset = startingClassFileOffset + pos;
7609: if (currentOffset + 3 >= bCodeStream.length) {
7610: resizeByteArray();
7611: }
7612: bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
7613: bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
7614: bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
7615: bCodeStream[currentOffset++] = (byte) (value & 0xFF);
7616: }
7617:
7618: /**
7619: * Write a unsigned 16 bits value into the byte array
7620: * @param value the unsigned short
7621: */
7622: private final void writeUnsignedShort(int value) {
7623: // no bound check since used only from within codestream where already checked
7624: position += 2;
7625: bCodeStream[classFileOffset++] = (byte) (value >>> 8);
7626: bCodeStream[classFileOffset++] = (byte) value;
7627: }
7628:
7629: protected void writeWidePosition(BranchLabel label) {
7630: int labelPos = label.position;
7631: int offset = labelPos - this .position + 1;
7632: this .writeSignedWord(offset);
7633: int[] forwardRefs = label.forwardReferences();
7634: for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
7635: int forward = forwardRefs[i];
7636: offset = labelPos - forward + 1;
7637: this.writeSignedWord(forward, offset);
7638: }
7639: }
7640: }
|