1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.codegen;
13 import org.eclipse.jdt.internal.compiler.*;
15 import org.eclipse.jdt.internal.compiler.impl.*;
16 import org.eclipse.jdt.internal.compiler.ast.*;
17 import org.eclipse.jdt.internal.compiler.classfmt.*;
18 import org.eclipse.jdt.internal.compiler.flow.*;
19 import org.eclipse.jdt.internal.compiler.lookup.*;
21 public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, BaseTypes, TypeConstants, TypeIds {
23 public static final boolean DEBUG = false;
25 // It will be responsible for the following items.
26 // -> Tracking Max Stack.
28 public int stackMax; // Use Ints to keep from using extra bc when adding
29 public int stackDepth; // Use Ints to keep from using extra bc when adding
31 public static final int LABELS_INCREMENT = 5;
32 public byte[] bCodeStream;
33 public int pcToSourceMapSize;
34 public int[] pcToSourceMap = new int[24];
35 public int lastEntryPC; // last entry recorded
36 public int[] lineSeparatorPositions;
37 public int position; // So when first set can be incremented
38 public int classFileOffset;
39 public int startingClassFileOffset; // I need to keep the starting point inside the byte array
40 public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
41 public ClassFile classFile; // The current classfile it is associated to.
42 // local variable attributes output
43 public static final int LOCALS_INCREMENT = 10;
44 public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
45 static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
46 public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
47 static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
48 int visibleLocalsCount;
49 public AbstractMethodDeclaration methodDeclaration;
50 public ExceptionLabel[] exceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
51 static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
52 public int exceptionHandlersNumber;
53 public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
54 public boolean generateLineNumberAttributes;
55 public boolean generateLocalVariableTableAttributes;
56 public boolean preserveUnusedLocals;
57 // store all the labels placed at the current position to be able to optimize
58 // a jump to the next bytecode.
59 public Label[] labels = new Label[LABELS_INCREMENT];
60 static Label[] noLabels = new Label[LABELS_INCREMENT];
61 public int countLabels;
62 public int allLocalsCounter;
63 public int maxFieldCount;
65 public boolean wideMode = false;
66 public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
68 public CodeStream(ClassFile classFile) {
69 generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0;
70 generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0;
71 if (generateLineNumberAttributes) {
72 lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions;
75 final public void aaload() {
76 if (DEBUG) System.out.println(position + "\t\taaload"); //$NON-NLS-1$
79 if (classFileOffset >= bCodeStream.length) {
83 bCodeStream[classFileOffset++] = OPC_aaload;
85 final public void aastore() {
86 if (DEBUG) System.out.println(position + "\t\taastore"); //$NON-NLS-1$
89 if (classFileOffset >= bCodeStream.length) {
93 bCodeStream[classFileOffset++] = OPC_aastore;
95 final public void aconst_null() {
96 if (DEBUG) System.out.println(position + "\t\taconst_null"); //$NON-NLS-1$
99 if (stackDepth > stackMax) {
100 stackMax = stackDepth;
102 if (classFileOffset >= bCodeStream.length) {
106 bCodeStream[classFileOffset++] = OPC_aconst_null;
108 public final void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
109 // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
110 if (!generateLocalVariableTableAttributes)
112 /* if (initStateIndex == lastInitStateIndexWhenAddingInits)
114 lastInitStateIndexWhenAddingInits = initStateIndex;
115 if (lastInitStateIndexWhenRemovingInits != initStateIndex){
116 lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index
117 // remove(1)-add(1)-remove(1) -> ignore second remove
118 // remove(1)-add(2)-remove(1) -> perform second remove
121 */ for (int i = 0; i < visibleLocalsCount; i++) {
122 LocalVariableBinding localBinding = visibleLocals[i];
123 if (localBinding != null) {
124 // Check if the local is definitely assigned
125 if ((initStateIndex != -1) && isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
126 if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
127 /* There are two cases:
128 * 1) there is no initialization interval opened ==> add an opened interval
129 * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
130 * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
132 * initializationPCs is a collection of pairs of int:
133 * first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
136 localBinding.recordInitializationStartPC(position);
142 public void addLabel(Label aLabel) {
143 if (countLabels == labels.length)
144 System.arraycopy(labels, 0, labels = new Label[countLabels + LABELS_INCREMENT], 0, countLabels);
145 labels[countLabels++] = aLabel;
147 public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
148 if (!generateLocalVariableTableAttributes)
151 if (visibleLocalsCount >= visibleLocals.length)
152 System.arraycopy(visibleLocals, 0, visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2], 0, visibleLocalsCount);
153 visibleLocals[visibleLocalsCount++] = localBinding;
155 final public void aload(int iArg) {
156 if (DEBUG) System.out.println(position + "\t\taload:"+iArg); //$NON-NLS-1$
159 if (stackDepth > stackMax)
160 stackMax = stackDepth;
161 if (maxLocals <= iArg) {
162 maxLocals = iArg + 1;
164 if (iArg > 255) { // Widen
165 if (classFileOffset + 3 >= bCodeStream.length) {
169 bCodeStream[classFileOffset++] = OPC_wide;
170 bCodeStream[classFileOffset++] = OPC_aload;
171 writeUnsignedShort(iArg);
173 // Don't need to use the wide bytecode
174 if (classFileOffset + 1 >= bCodeStream.length) {
178 bCodeStream[classFileOffset++] = OPC_aload;
179 bCodeStream[classFileOffset++] = (byte) iArg;
182 final public void aload_0() {
183 if (DEBUG) System.out.println(position + "\t\taload_0"); //$NON-NLS-1$
186 if (stackDepth > stackMax) {
187 stackMax = stackDepth;
189 if (maxLocals == 0) {
192 if (classFileOffset >= bCodeStream.length) {
196 bCodeStream[classFileOffset++] = OPC_aload_0;
198 final public void aload_1() {
199 if (DEBUG) System.out.println(position + "\t\taload_1"); //$NON-NLS-1$
202 if (stackDepth > stackMax)
203 stackMax = stackDepth;
204 if (maxLocals <= 1) {
207 if (classFileOffset >= bCodeStream.length) {
211 bCodeStream[classFileOffset++] = OPC_aload_1;
213 final public void aload_2() {
214 if (DEBUG) System.out.println(position + "\t\taload_2"); //$NON-NLS-1$
217 if (stackDepth > stackMax)
218 stackMax = stackDepth;
219 if (maxLocals <= 2) {
222 if (classFileOffset >= bCodeStream.length) {
226 bCodeStream[classFileOffset++] = OPC_aload_2;
228 final public void aload_3() {
229 if (DEBUG) System.out.println(position + "\t\taload_3"); //$NON-NLS-1$
232 if (stackDepth > stackMax)
233 stackMax = stackDepth;
234 if (maxLocals <= 3) {
237 if (classFileOffset >= bCodeStream.length) {
241 bCodeStream[classFileOffset++] = OPC_aload_3;
243 public final void anewarray(TypeBinding typeBinding) {
244 if (DEBUG) System.out.println(position + "\t\tanewarray: " + typeBinding); //$NON-NLS-1$
246 if (classFileOffset + 2 >= bCodeStream.length) {
250 bCodeStream[classFileOffset++] = OPC_anewarray;
251 writeUnsignedShort(constantPool.literalIndex(typeBinding));
253 final public void areturn() {
254 if (DEBUG) System.out.println(position + "\t\tareturn"); //$NON-NLS-1$
257 // the stackDepth should be equal to 0
258 if (classFileOffset >= bCodeStream.length) {
262 bCodeStream[classFileOffset++] = OPC_areturn;
264 public void arrayAt(int typeBindingID) {
265 switch (typeBindingID) {
292 public void arrayAtPut(int elementTypeID, boolean valueRequired) {
293 switch (elementTypeID) {
336 final public void arraylength() {
337 if (DEBUG) System.out.println(position + "\t\tarraylength"); //$NON-NLS-1$
339 if (classFileOffset >= bCodeStream.length) {
343 bCodeStream[classFileOffset++] = OPC_arraylength;
345 final public void astore(int iArg) {
346 if (DEBUG) System.out.println(position + "\t\tastore:"+iArg); //$NON-NLS-1$
349 if (maxLocals <= iArg) {
350 maxLocals = iArg + 1;
352 if (iArg > 255) { // Widen
353 if (classFileOffset + 3 >= bCodeStream.length) {
357 bCodeStream[classFileOffset++] = OPC_wide;
358 bCodeStream[classFileOffset++] = OPC_astore;
359 writeUnsignedShort(iArg);
361 if (classFileOffset + 1 >= bCodeStream.length) {
365 bCodeStream[classFileOffset++] = OPC_astore;
366 bCodeStream[classFileOffset++] = (byte) iArg;
369 final public void astore_0() {
370 if (DEBUG) System.out.println(position + "\t\tastore_0"); //$NON-NLS-1$
373 if (maxLocals == 0) {
376 if (classFileOffset >= bCodeStream.length) {
380 bCodeStream[classFileOffset++] = OPC_astore_0;
382 final public void astore_1() {
383 if (DEBUG) System.out.println(position + "\t\tastore_1"); //$NON-NLS-1$
386 if (maxLocals <= 1) {
389 if (classFileOffset >= bCodeStream.length) {
393 bCodeStream[classFileOffset++] = OPC_astore_1;
395 final public void astore_2() {
396 if (DEBUG) System.out.println(position + "\t\tastore_2"); //$NON-NLS-1$
399 if (maxLocals <= 2) {
402 if (classFileOffset >= bCodeStream.length) {
406 bCodeStream[classFileOffset++] = OPC_astore_2;
408 final public void astore_3() {
409 if (DEBUG) System.out.println(position + "\t\tastore_3"); //$NON-NLS-1$
412 if (maxLocals <= 3) {
415 if (classFileOffset >= bCodeStream.length) {
419 bCodeStream[classFileOffset++] = OPC_astore_3;
421 final public void athrow() {
422 if (DEBUG) System.out.println(position + "\t\tathrow"); //$NON-NLS-1$
425 if (classFileOffset >= bCodeStream.length) {
429 bCodeStream[classFileOffset++] = OPC_athrow;
431 final public void baload() {
432 if (DEBUG) System.out.println(position + "\t\tbaload"); //$NON-NLS-1$
435 if (classFileOffset >= bCodeStream.length) {
439 bCodeStream[classFileOffset++] = OPC_baload;
441 final public void bastore() {
442 if (DEBUG) System.out.println(position + "\t\tbastore"); //$NON-NLS-1$
445 if (classFileOffset >= bCodeStream.length) {
449 bCodeStream[classFileOffset++] = OPC_bastore;
451 final public void bipush(byte b) {
452 if (DEBUG) System.out.println(position + "\t\tbipush "+b); //$NON-NLS-1$
455 if (stackDepth > stackMax)
456 stackMax = stackDepth;
457 if (classFileOffset + 1 >= bCodeStream.length) {
461 bCodeStream[classFileOffset++] = OPC_bipush;
462 bCodeStream[classFileOffset++] = b;
464 final public void caload() {
465 if (DEBUG) System.out.println(position + "\t\tcaload"); //$NON-NLS-1$
468 if (classFileOffset >= bCodeStream.length) {
472 bCodeStream[classFileOffset++] = OPC_caload;
474 final public void castore() {
475 if (DEBUG) System.out.println(position + "\t\tcastore"); //$NON-NLS-1$
478 if (classFileOffset >= bCodeStream.length) {
482 bCodeStream[classFileOffset++] = OPC_castore;
484 public final void checkcast(TypeBinding typeBinding) {
485 if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding); //$NON-NLS-1$
487 if (classFileOffset + 2 >= bCodeStream.length) {
491 bCodeStream[classFileOffset++] = OPC_checkcast;
492 writeUnsignedShort(constantPool.literalIndex(typeBinding));
494 final public void d2f() {
495 if (DEBUG) System.out.println(position + "\t\td2f"); //$NON-NLS-1$
498 if (classFileOffset >= bCodeStream.length) {
502 bCodeStream[classFileOffset++] = OPC_d2f;
504 final public void d2i() {
505 if (DEBUG) System.out.println(position + "\t\td2i"); //$NON-NLS-1$
508 if (classFileOffset >= bCodeStream.length) {
512 bCodeStream[classFileOffset++] = OPC_d2i;
514 final public void d2l() {
515 if (DEBUG) System.out.println(position + "\t\td2l"); //$NON-NLS-1$
517 if (classFileOffset >= bCodeStream.length) {
521 bCodeStream[classFileOffset++] = OPC_d2l;
523 final public void dadd() {
524 if (DEBUG) System.out.println(position + "\t\tdadd"); //$NON-NLS-1$
527 if (classFileOffset >= bCodeStream.length) {
531 bCodeStream[classFileOffset++] = OPC_dadd;
533 final public void daload() {
534 if (DEBUG) System.out.println(position + "\t\tdaload"); //$NON-NLS-1$
536 if (classFileOffset >= bCodeStream.length) {
540 bCodeStream[classFileOffset++] = OPC_daload;
542 final public void dastore() {
543 if (DEBUG) System.out.println(position + "\t\tdastore"); //$NON-NLS-1$
546 if (classFileOffset >= bCodeStream.length) {
550 bCodeStream[classFileOffset++] = OPC_dastore;
552 final public void dcmpg() {
553 if (DEBUG) System.out.println(position + "\t\tdcmpg"); //$NON-NLS-1$
556 if (classFileOffset >= bCodeStream.length) {
560 bCodeStream[classFileOffset++] = OPC_dcmpg;
562 final public void dcmpl() {
563 if (DEBUG) System.out.println(position + "\t\tdcmpl"); //$NON-NLS-1$
566 if (classFileOffset >= bCodeStream.length) {
570 bCodeStream[classFileOffset++] = OPC_dcmpl;
572 final public void dconst_0() {
573 if (DEBUG) System.out.println(position + "\t\tdconst_0"); //$NON-NLS-1$
576 if (stackDepth > stackMax)
577 stackMax = stackDepth;
578 if (classFileOffset >= bCodeStream.length) {
582 bCodeStream[classFileOffset++] = OPC_dconst_0;
584 final public void dconst_1() {
585 if (DEBUG) System.out.println(position + "\t\tdconst_1"); //$NON-NLS-1$
588 if (stackDepth > stackMax)
589 stackMax = stackDepth;
590 if (classFileOffset >= bCodeStream.length) {
594 bCodeStream[classFileOffset++] = OPC_dconst_1;
596 final public void ddiv() {
597 if (DEBUG) System.out.println(position + "\t\tddiv"); //$NON-NLS-1$
600 if (classFileOffset >= bCodeStream.length) {
604 bCodeStream[classFileOffset++] = OPC_ddiv;
606 public void decrStackSize(int offset) {
607 stackDepth -= offset;
609 final public void dload(int iArg) {
610 if (DEBUG) System.out.println(position + "\t\tdload:"+iArg); //$NON-NLS-1$
613 if (stackDepth > stackMax)
614 stackMax = stackDepth;
615 if (maxLocals < iArg + 2) {
616 maxLocals = iArg + 2; // + 2 because it is a double
618 if (iArg > 255) { // Widen
619 if (classFileOffset + 3 >= bCodeStream.length) {
623 bCodeStream[classFileOffset++] = OPC_wide;
624 bCodeStream[classFileOffset++] = OPC_dload;
625 writeUnsignedShort(iArg);
627 // Don't need to use the wide bytecode
628 if (classFileOffset + 1 >= bCodeStream.length) {
632 bCodeStream[classFileOffset++] = OPC_dload;
633 bCodeStream[classFileOffset++] = (byte) iArg;
636 final public void dload_0() {
637 if (DEBUG) System.out.println(position + "\t\tdload_0"); //$NON-NLS-1$
640 if (stackDepth > stackMax)
641 stackMax = stackDepth;
645 if (classFileOffset >= bCodeStream.length) {
649 bCodeStream[classFileOffset++] = OPC_dload_0;
651 final public void dload_1() {
652 if (DEBUG) System.out.println(position + "\t\tdload_1"); //$NON-NLS-1$
655 if (stackDepth > stackMax)
656 stackMax = stackDepth;
660 if (classFileOffset >= bCodeStream.length) {
664 bCodeStream[classFileOffset++] = OPC_dload_1;
666 final public void dload_2() {
667 if (DEBUG) System.out.println(position + "\t\tdload_2"); //$NON-NLS-1$
670 if (stackDepth > stackMax)
671 stackMax = stackDepth;
675 if (classFileOffset >= bCodeStream.length) {
679 bCodeStream[classFileOffset++] = OPC_dload_2;
681 final public void dload_3() {
682 if (DEBUG) System.out.println(position + "\t\tdload_3"); //$NON-NLS-1$
685 if (stackDepth > stackMax)
686 stackMax = stackDepth;
690 if (classFileOffset >= bCodeStream.length) {
694 bCodeStream[classFileOffset++] = OPC_dload_3;
696 final public void dmul() {
697 if (DEBUG) System.out.println(position + "\t\tdmul"); //$NON-NLS-1$
700 if (classFileOffset >= bCodeStream.length) {
704 bCodeStream[classFileOffset++] = OPC_dmul;
706 final public void dneg() {
707 if (DEBUG) System.out.println(position + "\t\tdneg"); //$NON-NLS-1$
709 if (classFileOffset >= bCodeStream.length) {
713 bCodeStream[classFileOffset++] = OPC_dneg;
715 final public void drem() {
716 if (DEBUG) System.out.println(position + "\t\tdrem"); //$NON-NLS-1$
719 if (classFileOffset >= bCodeStream.length) {
723 bCodeStream[classFileOffset++] = OPC_drem;
725 final public void dreturn() {
726 if (DEBUG) System.out.println(position + "\t\tdreturn"); //$NON-NLS-1$
729 // the stackDepth should be equal to 0
730 if (classFileOffset >= bCodeStream.length) {
734 bCodeStream[classFileOffset++] = OPC_dreturn;
736 final public void dstore(int iArg) {
737 if (DEBUG) System.out.println(position + "\t\tdstore:"+iArg); //$NON-NLS-1$
740 if (maxLocals <= iArg + 1) {
741 maxLocals = iArg + 2;
743 if (iArg > 255) { // Widen
744 if (classFileOffset + 3 >= bCodeStream.length) {
748 bCodeStream[classFileOffset++] = OPC_wide;
749 bCodeStream[classFileOffset++] = OPC_dstore;
750 writeUnsignedShort(iArg);
752 if (classFileOffset + 1 >= bCodeStream.length) {
756 bCodeStream[classFileOffset++] = OPC_dstore;
757 bCodeStream[classFileOffset++] = (byte) iArg;
760 final public void dstore_0() {
761 if (DEBUG) System.out.println(position + "\t\tdstore_0"); //$NON-NLS-1$
767 if (classFileOffset >= bCodeStream.length) {
771 bCodeStream[classFileOffset++] = OPC_dstore_0;
773 final public void dstore_1() {
774 if (DEBUG) System.out.println(position + "\t\tdstore_1"); //$NON-NLS-1$
780 if (classFileOffset >= bCodeStream.length) {
784 bCodeStream[classFileOffset++] = OPC_dstore_1;
786 final public void dstore_2() {
787 if (DEBUG) System.out.println(position + "\t\tdstore_2"); //$NON-NLS-1$
793 if (classFileOffset >= bCodeStream.length) {
797 bCodeStream[classFileOffset++] = OPC_dstore_2;
799 final public void dstore_3() {
800 if (DEBUG) System.out.println(position + "\t\tdstore_3"); //$NON-NLS-1$
806 if (classFileOffset >= bCodeStream.length) {
810 bCodeStream[classFileOffset++] = OPC_dstore_3;
812 final public void dsub() {
813 if (DEBUG) System.out.println(position + "\t\tdsub"); //$NON-NLS-1$
816 if (classFileOffset >= bCodeStream.length) {
820 bCodeStream[classFileOffset++] = OPC_dsub;
822 final public void dup() {
823 if (DEBUG) System.out.println(position + "\t\tdup"); //$NON-NLS-1$
826 if (stackDepth > stackMax) {
827 stackMax = stackDepth;
829 if (classFileOffset >= bCodeStream.length) {
833 bCodeStream[classFileOffset++] = OPC_dup;
835 final public void dup_x1() {
836 if (DEBUG) System.out.println(position + "\t\tdup_x1"); //$NON-NLS-1$
839 if (stackDepth > stackMax)
840 stackMax = stackDepth;
841 if (classFileOffset >= bCodeStream.length) {
845 bCodeStream[classFileOffset++] = OPC_dup_x1;
847 final public void dup_x2() {
848 if (DEBUG) System.out.println(position + "\t\tdup_x2"); //$NON-NLS-1$
851 if (stackDepth > stackMax)
852 stackMax = stackDepth;
853 if (classFileOffset >= bCodeStream.length) {
857 bCodeStream[classFileOffset++] = OPC_dup_x2;
859 final public void dup2() {
860 if (DEBUG) System.out.println(position + "\t\tdup2"); //$NON-NLS-1$
863 if (stackDepth > stackMax)
864 stackMax = stackDepth;
865 if (classFileOffset >= bCodeStream.length) {
869 bCodeStream[classFileOffset++] = OPC_dup2;
871 final public void dup2_x1() {
872 if (DEBUG) System.out.println(position + "\t\tdup2_x1"); //$NON-NLS-1$
875 if (stackDepth > stackMax)
876 stackMax = stackDepth;
877 if (classFileOffset >= bCodeStream.length) {
881 bCodeStream[classFileOffset++] = OPC_dup2_x1;
883 final public void dup2_x2() {
884 if (DEBUG) System.out.println(position + "\t\tdup2_x2"); //$NON-NLS-1$
887 if (stackDepth > stackMax)
888 stackMax = stackDepth;
889 if (classFileOffset >= bCodeStream.length) {
893 bCodeStream[classFileOffset++] = OPC_dup2_x2;
895 public void exitUserScope(BlockScope blockScope) {
896 // mark all the scope's locals as loosing their definite assignment
898 if (!generateLocalVariableTableAttributes)
900 for (int i = 0; i < visibleLocalsCount; i++) {
901 LocalVariableBinding visibleLocal = visibleLocals[i];
902 if ((visibleLocal != null) && (visibleLocal.declaringScope == blockScope)) {
903 // there maybe some some preserved locals never initialized
904 if (visibleLocal.initializationCount > 0){
905 visibleLocals[i].recordInitializationEndPC(position);
907 visibleLocals[i] = null; // this variable is no longer visible afterwards
911 final public void f2d() {
912 if (DEBUG) System.out.println(position + "\t\tf2d"); //$NON-NLS-1$
915 if (stackDepth > stackMax)
916 stackMax = stackDepth;
917 if (classFileOffset >= bCodeStream.length) {
921 bCodeStream[classFileOffset++] = OPC_f2d;
923 final public void f2i() {
924 if (DEBUG) System.out.println(position + "\t\tf2i"); //$NON-NLS-1$
926 if (classFileOffset >= bCodeStream.length) {
930 bCodeStream[classFileOffset++] = OPC_f2i;
932 final public void f2l() {
933 if (DEBUG) System.out.println(position + "\t\tf2l"); //$NON-NLS-1$
936 if (stackDepth > stackMax)
937 stackMax = stackDepth;
938 if (classFileOffset >= bCodeStream.length) {
942 bCodeStream[classFileOffset++] = OPC_f2l;
944 final public void fadd() {
945 if (DEBUG) System.out.println(position + "\t\tfadd"); //$NON-NLS-1$
948 if (classFileOffset >= bCodeStream.length) {
952 bCodeStream[classFileOffset++] = OPC_fadd;
954 final public void faload() {
955 if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
958 if (classFileOffset >= bCodeStream.length) {
962 bCodeStream[classFileOffset++] = OPC_faload;
964 final public void fastore() {
965 if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
968 if (classFileOffset >= bCodeStream.length) {
972 bCodeStream[classFileOffset++] = OPC_fastore;
974 final public void fcmpg() {
975 if (DEBUG) System.out.println(position + "\t\tfcmpg"); //$NON-NLS-1$
978 if (classFileOffset >= bCodeStream.length) {
982 bCodeStream[classFileOffset++] = OPC_fcmpg;
984 final public void fcmpl() {
985 if (DEBUG) System.out.println(position + "\t\tfcmpl"); //$NON-NLS-1$
988 if (classFileOffset >= bCodeStream.length) {
992 bCodeStream[classFileOffset++] = OPC_fcmpl;
994 final public void fconst_0() {
995 if (DEBUG) System.out.println(position + "\t\tfconst_0"); //$NON-NLS-1$
998 if (stackDepth > stackMax)
999 stackMax = stackDepth;
1000 if (classFileOffset >= bCodeStream.length) {
1004 bCodeStream[classFileOffset++] = OPC_fconst_0;
1006 final public void fconst_1() {
1007 if (DEBUG) System.out.println(position + "\t\tfconst_1"); //$NON-NLS-1$
1010 if (stackDepth > stackMax)
1011 stackMax = stackDepth;
1012 if (classFileOffset >= bCodeStream.length) {
1016 bCodeStream[classFileOffset++] = OPC_fconst_1;
1018 final public void fconst_2() {
1019 if (DEBUG) System.out.println(position + "\t\tfconst_2"); //$NON-NLS-1$
1022 if (stackDepth > stackMax)
1023 stackMax = stackDepth;
1024 if (classFileOffset >= bCodeStream.length) {
1028 bCodeStream[classFileOffset++] = OPC_fconst_2;
1030 final public void fdiv() {
1031 if (DEBUG) System.out.println(position + "\t\tfdiv"); //$NON-NLS-1$
1034 if (classFileOffset >= bCodeStream.length) {
1038 bCodeStream[classFileOffset++] = OPC_fdiv;
1040 final public void fload(int iArg) {
1041 if (DEBUG) System.out.println(position + "\t\tfload:"+iArg); //$NON-NLS-1$
1044 if (maxLocals <= iArg) {
1045 maxLocals = iArg + 1;
1047 if (stackDepth > stackMax)
1048 stackMax = stackDepth;
1049 if (iArg > 255) { // Widen
1050 if (classFileOffset + 3 >= bCodeStream.length) {
1054 bCodeStream[classFileOffset++] = OPC_wide;
1055 bCodeStream[classFileOffset++] = OPC_fload;
1056 writeUnsignedShort(iArg);
1058 if (classFileOffset + 1 >= bCodeStream.length) {
1062 bCodeStream[classFileOffset++] = OPC_fload;
1063 bCodeStream[classFileOffset++] = (byte) iArg;
1066 final public void fload_0() {
1067 if (DEBUG) System.out.println(position + "\t\tfload_0"); //$NON-NLS-1$
1070 if (maxLocals == 0) {
1073 if (stackDepth > stackMax)
1074 stackMax = stackDepth;
1075 if (classFileOffset >= bCodeStream.length) {
1079 bCodeStream[classFileOffset++] = OPC_fload_0;
1081 final public void fload_1() {
1082 if (DEBUG) System.out.println(position + "\t\tfload_1"); //$NON-NLS-1$
1085 if (maxLocals <= 1) {
1088 if (stackDepth > stackMax)
1089 stackMax = stackDepth;
1090 if (classFileOffset >= bCodeStream.length) {
1094 bCodeStream[classFileOffset++] = OPC_fload_1;
1096 final public void fload_2() {
1097 if (DEBUG) System.out.println(position + "\t\tfload_2"); //$NON-NLS-1$
1100 if (maxLocals <= 2) {
1103 if (stackDepth > stackMax)
1104 stackMax = stackDepth;
1105 if (classFileOffset >= bCodeStream.length) {
1109 bCodeStream[classFileOffset++] = OPC_fload_2;
1111 final public void fload_3() {
1112 if (DEBUG) System.out.println(position + "\t\tfload_3"); //$NON-NLS-1$
1115 if (maxLocals <= 3) {
1118 if (stackDepth > stackMax)
1119 stackMax = stackDepth;
1120 if (classFileOffset >= bCodeStream.length) {
1124 bCodeStream[classFileOffset++] = OPC_fload_3;
1126 final public void fmul() {
1127 if (DEBUG) System.out.println(position + "\t\tfmul"); //$NON-NLS-1$
1130 if (classFileOffset >= bCodeStream.length) {
1134 bCodeStream[classFileOffset++] = OPC_fmul;
1136 final public void fneg() {
1137 if (DEBUG) System.out.println(position + "\t\tfneg"); //$NON-NLS-1$
1139 if (classFileOffset >= bCodeStream.length) {
1143 bCodeStream[classFileOffset++] = OPC_fneg;
1145 final public void frem() {
1146 if (DEBUG) System.out.println(position + "\t\tfrem"); //$NON-NLS-1$
1149 if (classFileOffset >= bCodeStream.length) {
1153 bCodeStream[classFileOffset++] = OPC_frem;
1155 final public void freturn() {
1156 if (DEBUG) System.out.println(position + "\t\tfreturn"); //$NON-NLS-1$
1159 // the stackDepth should be equal to 0
1160 if (classFileOffset >= bCodeStream.length) {
1164 bCodeStream[classFileOffset++] = OPC_freturn;
1166 final public void fstore(int iArg) {
1167 if (DEBUG) System.out.println(position + "\t\tfstore:"+iArg); //$NON-NLS-1$
1170 if (maxLocals <= iArg) {
1171 maxLocals = iArg + 1;
1173 if (iArg > 255) { // Widen
1174 if (classFileOffset + 3 >= bCodeStream.length) {
1178 bCodeStream[classFileOffset++] = OPC_wide;
1179 bCodeStream[classFileOffset++] = OPC_fstore;
1180 writeUnsignedShort(iArg);
1182 if (classFileOffset + 1 >= bCodeStream.length) {
1186 bCodeStream[classFileOffset++] = OPC_fstore;
1187 bCodeStream[classFileOffset++] = (byte) iArg;
1190 final public void fstore_0() {
1191 if (DEBUG) System.out.println(position + "\t\tfstore_0"); //$NON-NLS-1$
1194 if (maxLocals == 0) {
1197 if (classFileOffset >= bCodeStream.length) {
1201 bCodeStream[classFileOffset++] = OPC_fstore_0;
1203 final public void fstore_1() {
1204 if (DEBUG) System.out.println(position + "\t\tfstore_1"); //$NON-NLS-1$
1207 if (maxLocals <= 1) {
1210 if (classFileOffset >= bCodeStream.length) {
1214 bCodeStream[classFileOffset++] = OPC_fstore_1;
1216 final public void fstore_2() {
1217 if (DEBUG) System.out.println(position + "\t\tfstore_2"); //$NON-NLS-1$
1220 if (maxLocals <= 2) {
1223 if (classFileOffset >= bCodeStream.length) {
1227 bCodeStream[classFileOffset++] = OPC_fstore_2;
1229 final public void fstore_3() {
1230 if (DEBUG) System.out.println(position + "\t\tfstore_3"); //$NON-NLS-1$
1233 if (maxLocals <= 3) {
1236 if (classFileOffset >= bCodeStream.length) {
1240 bCodeStream[classFileOffset++] = OPC_fstore_3;
1242 final public void fsub() {
1243 if (DEBUG) System.out.println(position + "\t\tfsub"); //$NON-NLS-1$
1246 if (classFileOffset >= bCodeStream.length) {
1250 bCodeStream[classFileOffset++] = OPC_fsub;
1253 * Macro for building a class descriptor object
1255 public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
1257 ExceptionLabel anyExceptionHandler;
1259 if (accessedType.isBaseType() && accessedType != NullBinding) {
1260 this.getTYPE(accessedType.id);
1263 endLabel = new Label(this);
1265 if (syntheticFieldBinding != null) { // non interface case
1266 this.getstatic(syntheticFieldBinding);
1268 this.ifnonnull(endLabel);
1272 /* Macro for building a class descriptor object... using or not a field cache to store it into...
1273 this sequence is responsible for building the actual class descriptor.
1275 If the fieldCache is set, then it is supposed to be the body of a synthetic access method
1276 factoring the actual descriptor creation out of the invocation site (saving space).
1277 If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
1278 we have no way to get a hand on the field cache to do better. */
1281 // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
1283 anyExceptionHandler = new ExceptionLabel(this, BaseTypes.NullBinding /* represents ClassNotFoundException*/);
1284 this.ldc(accessedType == BaseTypes.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
1285 this.invokeClassForName();
1287 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
1288 if (accessedType == BaseTypes.NullBinding) {
1289 this.ldc("java.lang.Object"); //$NON-NLS-1$
1290 } else if (accessedType.isArrayType()) {
1291 this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
1293 // we make it an array type (to avoid class initialization)
1294 this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
1296 this.invokeClassForName();
1297 if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
1298 this.invokeJavaLangClassGetComponentType();
1301 /* We need to protect the runtime code from binary inconsistencies
1302 in case the accessedType is missing, the ClassNotFoundException has to be converted
1303 into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
1304 anyExceptionHandler.placeEnd();
1306 if (syntheticFieldBinding != null) { // non interface case
1308 this.putstatic(syntheticFieldBinding);
1310 this.goto_(endLabel);
1313 // Generate the body of the exception handler
1314 saveStackSize = stackDepth;
1316 /* ClassNotFoundException on stack -- the class literal could be doing more things
1317 on the stack, which means that the stack may not be empty at this point in the
1318 above code gen. So we save its state and restart it from 1. */
1320 anyExceptionHandler.place();
1322 // Transform the current exception, and repush and throw a
1323 // NoClassDefFoundError(ClassNotFound.getMessage())
1325 this.newNoClassDefFoundError();
1329 // Retrieve the message from the old exception
1330 this.invokeThrowableGetMessage();
1332 // Send the constructor taking a message string as an argument
1333 this.invokeNoClassDefFoundErrorStringConstructor();
1336 stackDepth = saveStackSize;
1339 * This method generates the code attribute bytecode
1341 final public void generateCodeAttributeForProblemMethod(String problemMessage) {
1344 ldc(problemMessage);
1345 invokeJavaLangErrorConstructor();
1348 public void generateConstant(Constant constant, int implicitConversionCode) {
1349 int targetTypeID = implicitConversionCode >> 4;
1350 switch (targetTypeID) {
1352 generateInlinedValue(constant.booleanValue());
1355 generateInlinedValue(constant.charValue());
1358 generateInlinedValue(constant.byteValue());
1361 generateInlinedValue(constant.shortValue());
1364 generateInlinedValue(constant.intValue());
1367 generateInlinedValue(constant.longValue());
1370 generateInlinedValue(constant.floatValue());
1373 generateInlinedValue(constant.doubleValue());
1375 default : //String or Object
1376 ldc(constant.stringValue());
1380 * @param implicitConversionCode int
1382 public void generateImplicitConversion(int implicitConversionCode) {
1383 switch (implicitConversionCode) {
1481 public void generateInlinedValue(byte inlinedValue) {
1482 switch (inlinedValue) {
1505 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1506 this.bipush(inlinedValue);
1511 public void generateInlinedValue(char inlinedValue) {
1512 switch (inlinedValue) {
1532 if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
1533 this.bipush((byte) inlinedValue);
1536 if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
1537 this.sipush(inlinedValue);
1540 this.ldc(inlinedValue);
1543 public void generateInlinedValue(double inlinedValue) {
1544 if (inlinedValue == 0.0) {
1545 if (Double.doubleToLongBits(inlinedValue) != 0L)
1546 this.ldc2_w(inlinedValue);
1551 if (inlinedValue == 1.0) {
1555 this.ldc2_w(inlinedValue);
1557 public void generateInlinedValue(float inlinedValue) {
1558 if (inlinedValue == 0.0f) {
1559 if (Float.floatToIntBits(inlinedValue) != 0)
1560 this.ldc(inlinedValue);
1565 if (inlinedValue == 1.0f) {
1569 if (inlinedValue == 2.0f) {
1573 this.ldc(inlinedValue);
1575 public void generateInlinedValue(int inlinedValue) {
1576 switch (inlinedValue) {
1599 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1600 this.bipush((byte) inlinedValue);
1603 if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
1604 this.sipush(inlinedValue);
1607 this.ldc(inlinedValue);
1610 public void generateInlinedValue(long inlinedValue) {
1611 if (inlinedValue == 0) {
1615 if (inlinedValue == 1) {
1619 this.ldc2_w(inlinedValue);
1621 public void generateInlinedValue(short inlinedValue) {
1622 switch (inlinedValue) {
1645 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1646 this.bipush((byte) inlinedValue);
1649 this.sipush(inlinedValue);
1652 public void generateInlinedValue(boolean inlinedValue) {
1658 public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
1659 if (mappingSequence == null) {
1660 if (target instanceof LocalVariableBinding) {
1661 scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
1663 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
1667 if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
1668 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
1670 } else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
1671 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
1675 if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
1678 } else if (mappingSequence[0] instanceof FieldBinding) {
1679 FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
1681 this.getfield(fieldBinding);
1683 load((LocalVariableBinding) mappingSequence[0]);
1685 for (int i = 1, length = mappingSequence.length; i < length; i++) {
1686 if (mappingSequence[i] instanceof FieldBinding) {
1687 FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
1688 this.getfield(fieldBinding);
1690 this.invokestatic((MethodBinding) mappingSequence[i]);
1696 * The equivalent code performs a string conversion:
1698 * @param blockScope the given blockScope
1699 * @param oper1 the first expression
1700 * @param oper2 the second expression
1702 public void generateStringAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
1704 if (oper1 == null) {
1705 /* Operand is already on the stack, and maybe nil:
1706 note type1 is always to java.lang.String here.*/
1707 this.newStringBuffer();
1710 // If argument is reference type, need to transform it
1711 // into a string (handles null case)
1712 this.invokeStringValueOf(T_Object);
1713 this.invokeStringBufferStringConstructor();
1716 oper1.generateOptimizedStringBufferCreation(blockScope, this, oper1.implicitConversion & 0xF);
1717 this.recordPositionsFrom(pc, oper1.sourceStart);
1720 oper2.generateOptimizedStringBuffer(blockScope, this, oper2.implicitConversion & 0xF);
1721 this.recordPositionsFrom(pc, oper2.sourceStart);
1722 this.invokeStringBufferToString();
1725 * Code responsible to generate the suitable code to supply values for the synthetic enclosing
1726 * instance arguments of a constructor invocation of a nested type.
1728 public void generateSyntheticEnclosingInstanceValues(
1729 BlockScope currentScope,
1730 ReferenceBinding targetType,
1731 Expression enclosingInstance,
1732 ASTNode invocationSite) {
1734 // supplying enclosing instance for the anonymous type's superclass
1735 ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? targetType.superclass() : targetType;
1736 boolean hasExtraEnclosingInstance = enclosingInstance != null;
1737 if (hasExtraEnclosingInstance
1738 && (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
1739 currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
1743 // perform some emulation work in case there is some and we are inside a local type only
1744 ReferenceBinding[] syntheticArgumentTypes;
1745 if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
1747 ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
1748 boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
1749 // deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
1750 boolean ignoreEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
1751 || (complyTo14 && ((invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess())));
1753 for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
1754 ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
1755 if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
1756 hasExtraEnclosingInstance = false;
1757 enclosingInstance.generateCode(currentScope, this, true);
1760 invokeObjectGetClass(); // will perform null check
1764 Object[] emulationPath = currentScope.getEmulationPath(
1766 false /*not only exact match (that is, allow compatible)*/,
1767 ignoreEnclosingArgInConstructorCall);
1768 this.generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
1771 if (hasExtraEnclosingInstance){
1772 currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
1778 * Code responsible to generate the suitable code to supply values for the synthetic outer local
1779 * variable arguments of a constructor invocation of a nested type.
1780 * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
1782 public void generateSyntheticOuterArgumentValues(BlockScope currentScope, ReferenceBinding targetType, ASTNode invocationSite) {
1784 // generate the synthetic outer arguments then
1785 SyntheticArgumentBinding syntheticArguments[];
1786 if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
1787 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
1788 LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
1789 VariableBinding[] emulationPath = currentScope.getEmulationPath(targetVariable);
1790 this.generateOuterAccess(emulationPath, invocationSite, targetVariable, currentScope);
1796 * @param accessBinding the access method binding to generate
1798 public void generateSyntheticBodyForConstructorAccess(SyntheticAccessMethodBinding accessBinding) {
1800 initializeMaxLocals(accessBinding);
1802 MethodBinding constructorBinding = accessBinding.targetMethod;
1803 TypeBinding[] parameters = constructorBinding.parameters;
1804 int length = parameters.length;
1805 int resolvedPosition = 1;
1807 if (constructorBinding.declaringClass.isNestedType()) {
1808 NestedTypeBinding nestedType = (NestedTypeBinding) constructorBinding.declaringClass;
1809 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
1810 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1812 load((type = syntheticArguments[i].type), resolvedPosition);
1813 if ((type == DoubleBinding) || (type == LongBinding))
1814 resolvedPosition += 2;
1819 for (int i = 0; i < length; i++) {
1820 load(parameters[i], resolvedPosition);
1821 if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
1822 resolvedPosition += 2;
1827 if (constructorBinding.declaringClass.isNestedType()) {
1828 NestedTypeBinding nestedType = (NestedTypeBinding) constructorBinding.declaringClass;
1829 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
1830 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1832 load((type = syntheticArguments[i].type), resolvedPosition);
1833 if ((type == DoubleBinding) || (type == LongBinding))
1834 resolvedPosition += 2;
1839 this.invokespecial(constructorBinding);
1842 public void generateSyntheticBodyForFieldReadAccess(SyntheticAccessMethodBinding accessBinding) {
1843 initializeMaxLocals(accessBinding);
1844 FieldBinding fieldBinding = accessBinding.targetReadField;
1846 if (fieldBinding.isStatic())
1847 this.getstatic(fieldBinding);
1850 this.getfield(fieldBinding);
1852 if ((type = fieldBinding.type).isBaseType()) {
1853 if (type == IntBinding)
1856 if (type == FloatBinding)
1859 if (type == LongBinding)
1862 if (type == DoubleBinding)
1869 public void generateSyntheticBodyForFieldWriteAccess(SyntheticAccessMethodBinding accessBinding) {
1870 initializeMaxLocals(accessBinding);
1871 FieldBinding fieldBinding = accessBinding.targetWriteField;
1872 if (fieldBinding.isStatic()) {
1873 load(fieldBinding.type, 0);
1874 this.putstatic(fieldBinding);
1877 load(fieldBinding.type, 1);
1878 this.putfield(fieldBinding);
1882 public void generateSyntheticBodyForMethodAccess(SyntheticAccessMethodBinding accessBinding) {
1884 initializeMaxLocals(accessBinding);
1885 MethodBinding methodBinding = accessBinding.targetMethod;
1886 TypeBinding[] parameters = methodBinding.parameters;
1887 int length = parameters.length;
1888 int resolvedPosition;
1889 if (methodBinding.isStatic())
1890 resolvedPosition = 0;
1893 resolvedPosition = 1;
1895 for (int i = 0; i < length; i++) {
1896 load(parameters[i], resolvedPosition);
1897 if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
1898 resolvedPosition += 2;
1903 if (methodBinding.isStatic())
1904 this.invokestatic(methodBinding);
1906 if (methodBinding.isConstructor()
1907 || methodBinding.isPrivate()
1908 // qualified super "X.super.foo()" targets methods from superclass
1909 || accessBinding.accessType == SyntheticAccessMethodBinding.SuperMethodAccess){
1910 this.invokespecial(methodBinding);
1912 if (methodBinding.declaringClass.isInterface()){
1913 this.invokeinterface(methodBinding);
1915 this.invokevirtual(methodBinding);
1919 if ((type = methodBinding.returnType).isBaseType())
1920 if (type == VoidBinding)
1923 if (type == IntBinding)
1926 if (type == FloatBinding)
1929 if (type == LongBinding)
1932 if (type == DoubleBinding)
1939 final public byte[] getContents() {
1941 System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
1944 final public void getfield(FieldBinding fieldBinding) {
1945 if (DEBUG) System.out.println(position + "\t\tgetfield:"+fieldBinding); //$NON-NLS-1$
1947 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
1948 if (++stackDepth > stackMax)
1949 stackMax = stackDepth;
1951 if (classFileOffset + 2 >= bCodeStream.length) {
1955 bCodeStream[classFileOffset++] = OPC_getfield;
1956 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
1958 final public void getstatic(FieldBinding fieldBinding) {
1959 if (DEBUG) System.out.println(position + "\t\tgetstatic:"+fieldBinding); //$NON-NLS-1$
1961 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long))
1965 if (stackDepth > stackMax)
1966 stackMax = stackDepth;
1967 if (classFileOffset + 2 >= bCodeStream.length) {
1971 bCodeStream[classFileOffset++] = OPC_getstatic;
1972 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
1974 public void getTYPE(int baseTypeID) {
1976 if (++stackDepth > stackMax)
1977 stackMax = stackDepth;
1978 if (classFileOffset + 2 >= bCodeStream.length) {
1982 bCodeStream[classFileOffset++] = OPC_getstatic;
1983 switch (baseTypeID) {
1985 // getstatic: java.lang.Byte.TYPE
1986 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$
1987 writeUnsignedShort(constantPool.literalIndexForJavaLangByteTYPE());
1990 // getstatic: java.lang.Short.TYPE
1991 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$
1992 writeUnsignedShort(constantPool.literalIndexForJavaLangShortTYPE());
1995 // getstatic: java.lang.Character.TYPE
1996 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$
1997 writeUnsignedShort(constantPool.literalIndexForJavaLangCharacterTYPE());
2000 // getstatic: java.lang.Integer.TYPE
2001 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$
2002 writeUnsignedShort(constantPool.literalIndexForJavaLangIntegerTYPE());
2005 // getstatic: java.lang.Long.TYPE
2006 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$
2007 writeUnsignedShort(constantPool.literalIndexForJavaLangLongTYPE());
2010 // getstatic: java.lang.Float.TYPE
2011 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$
2012 writeUnsignedShort(constantPool.literalIndexForJavaLangFloatTYPE());
2015 // getstatic: java.lang.Double.TYPE
2016 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$
2017 writeUnsignedShort(constantPool.literalIndexForJavaLangDoubleTYPE());
2020 // getstatic: java.lang.Boolean.TYPE
2021 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$
2022 writeUnsignedShort(constantPool.literalIndexForJavaLangBooleanTYPE());
2025 // getstatic: java.lang.Void.TYPE
2026 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$
2027 writeUnsignedShort(constantPool.literalIndexForJavaLangVoidTYPE());
2032 * We didn't call it goto, because there is a conflit with the goto keyword
2034 final public void goto_(Label label) {
2035 if (this.wideMode) {
2039 if (DEBUG) System.out.println(position + "\t\tgoto:"+label); //$NON-NLS-1$
2040 if (classFileOffset >= bCodeStream.length) {
2043 label.inlineForwardReferencesFromLabelsTargeting(position);
2045 Possible optimization for code such as:
2046 public Object foo() {
2058 The goto around the else block for the first if will
2059 be unreachable, because the thenClause of the second if
2061 See inlineForwardReferencesFromLabelsTargeting defined
2062 on the Label class for the remaining part of this
2064 if (!lbl.isBranchTarget(position)) {
2065 switch(bCodeStream[classFileOffset-1]) {
2072 bCodeStream[classFileOffset++] = OPC_goto;
2076 final public void goto_w(Label lbl) {
2077 if (DEBUG) System.out.println(position + "\t\tgotow:"+lbl); //$NON-NLS-1$
2078 if (classFileOffset >= bCodeStream.length) {
2082 bCodeStream[classFileOffset++] = OPC_goto_w;
2085 final public void i2b() {
2086 if (DEBUG) System.out.println(position + "\t\ti2b"); //$NON-NLS-1$
2088 if (classFileOffset >= bCodeStream.length) {
2092 bCodeStream[classFileOffset++] = OPC_i2b;
2094 final public void i2c() {
2095 if (DEBUG) System.out.println(position + "\t\ti2c"); //$NON-NLS-1$
2097 if (classFileOffset >= bCodeStream.length) {
2101 bCodeStream[classFileOffset++] = OPC_i2c;
2103 final public void i2d() {
2104 if (DEBUG) System.out.println(position + "\t\ti2d"); //$NON-NLS-1$
2107 if (stackDepth > stackMax)
2108 stackMax = stackDepth;
2109 if (classFileOffset >= bCodeStream.length) {
2113 bCodeStream[classFileOffset++] = OPC_i2d;
2115 final public void i2f() {
2116 if (DEBUG) System.out.println(position + "\t\ti2f"); //$NON-NLS-1$
2118 if (classFileOffset >= bCodeStream.length) {
2122 bCodeStream[classFileOffset++] = OPC_i2f;
2124 final public void i2l() {
2125 if (DEBUG) System.out.println(position + "\t\ti2l"); //$NON-NLS-1$
2128 if (stackDepth > stackMax)
2129 stackMax = stackDepth;
2130 if (classFileOffset >= bCodeStream.length) {
2134 bCodeStream[classFileOffset++] = OPC_i2l;
2136 final public void i2s() {
2137 if (DEBUG) System.out.println(position + "\t\ti2s"); //$NON-NLS-1$
2139 if (classFileOffset >= bCodeStream.length) {
2143 bCodeStream[classFileOffset++] = OPC_i2s;
2145 final public void iadd() {
2146 if (DEBUG) System.out.println(position + "\t\tiadd"); //$NON-NLS-1$
2149 if (classFileOffset >= bCodeStream.length) {
2153 bCodeStream[classFileOffset++] = OPC_iadd;
2155 final public void iaload() {
2156 if (DEBUG) System.out.println(position + "\t\tiaload"); //$NON-NLS-1$
2159 if (classFileOffset >= bCodeStream.length) {
2163 bCodeStream[classFileOffset++] = OPC_iaload;
2165 final public void iand() {
2166 if (DEBUG) System.out.println(position + "\t\tiand"); //$NON-NLS-1$
2169 if (classFileOffset >= bCodeStream.length) {
2173 bCodeStream[classFileOffset++] = OPC_iand;
2175 final public void iastore() {
2176 if (DEBUG) System.out.println(position + "\t\tiastore"); //$NON-NLS-1$
2179 if (classFileOffset >= bCodeStream.length) {
2183 bCodeStream[classFileOffset++] = OPC_iastore;
2185 final public void iconst_0() {
2186 if (DEBUG) System.out.println(position + "\t\ticonst_0"); //$NON-NLS-1$
2189 if (stackDepth > stackMax)
2190 stackMax = stackDepth;
2191 if (classFileOffset >= bCodeStream.length) {
2195 bCodeStream[classFileOffset++] = OPC_iconst_0;
2197 final public void iconst_1() {
2198 if (DEBUG) System.out.println(position + "\t\ticonst_1"); //$NON-NLS-1$
2201 if (stackDepth > stackMax)
2202 stackMax = stackDepth;
2203 if (classFileOffset >= bCodeStream.length) {
2207 bCodeStream[classFileOffset++] = OPC_iconst_1;
2209 final public void iconst_2() {
2210 if (DEBUG) System.out.println(position + "\t\ticonst_2"); //$NON-NLS-1$
2213 if (stackDepth > stackMax)
2214 stackMax = stackDepth;
2215 if (classFileOffset >= bCodeStream.length) {
2219 bCodeStream[classFileOffset++] = OPC_iconst_2;
2221 final public void iconst_3() {
2222 if (DEBUG) System.out.println(position + "\t\ticonst_3"); //$NON-NLS-1$
2225 if (stackDepth > stackMax)
2226 stackMax = stackDepth;
2227 if (classFileOffset >= bCodeStream.length) {
2231 bCodeStream[classFileOffset++] = OPC_iconst_3;
2233 final public void iconst_4() {
2234 if (DEBUG) System.out.println(position + "\t\ticonst_4"); //$NON-NLS-1$
2237 if (stackDepth > stackMax)
2238 stackMax = stackDepth;
2239 if (classFileOffset >= bCodeStream.length) {
2243 bCodeStream[classFileOffset++] = OPC_iconst_4;
2245 final public void iconst_5() {
2246 if (DEBUG) System.out.println(position + "\t\ticonst_5"); //$NON-NLS-1$
2249 if (stackDepth > stackMax)
2250 stackMax = stackDepth;
2251 if (classFileOffset >= bCodeStream.length) {
2255 bCodeStream[classFileOffset++] = OPC_iconst_5;
2257 final public void iconst_m1() {
2258 if (DEBUG) System.out.println(position + "\t\ticonst_m1"); //$NON-NLS-1$
2261 if (stackDepth > stackMax)
2262 stackMax = stackDepth;
2263 if (classFileOffset >= bCodeStream.length) {
2267 bCodeStream[classFileOffset++] = OPC_iconst_m1;
2269 final public void idiv() {
2270 if (DEBUG) System.out.println(position + "\t\tidiv"); //$NON-NLS-1$
2273 if (classFileOffset >= bCodeStream.length) {
2277 bCodeStream[classFileOffset++] = OPC_idiv;
2279 final public void if_acmpeq(Label lbl) {
2280 if (DEBUG) System.out.println(position + "\t\tif_acmpeq:"+lbl); //$NON-NLS-1$
2283 if (this.wideMode) {
2284 generateWideRevertedConditionalBranch(OPC_if_acmpne, lbl);
2286 if (classFileOffset >= bCodeStream.length) {
2290 bCodeStream[classFileOffset++] = OPC_if_acmpeq;
2294 final public void if_acmpne(Label lbl) {
2295 if (DEBUG) System.out.println(position + "\t\tif_acmpne:"+lbl); //$NON-NLS-1$
2298 if (this.wideMode) {
2299 generateWideRevertedConditionalBranch(OPC_if_acmpeq, lbl);
2301 if (classFileOffset >= bCodeStream.length) {
2305 bCodeStream[classFileOffset++] = OPC_if_acmpne;
2309 final public void if_icmpeq(Label lbl) {
2310 if (DEBUG) System.out.println(position + "\t\tif_cmpeq:"+lbl); //$NON-NLS-1$
2313 if (this.wideMode) {
2314 generateWideRevertedConditionalBranch(OPC_if_icmpne, lbl);
2316 if (classFileOffset >= bCodeStream.length) {
2320 bCodeStream[classFileOffset++] = OPC_if_icmpeq;
2324 final public void if_icmpge(Label lbl) {
2325 if (DEBUG) System.out.println(position + "\t\tif_iacmpge:"+lbl); //$NON-NLS-1$
2328 if (this.wideMode) {
2329 generateWideRevertedConditionalBranch(OPC_if_icmplt, lbl);
2331 if (classFileOffset >= bCodeStream.length) {
2335 bCodeStream[classFileOffset++] = OPC_if_icmpge;
2339 final public void if_icmpgt(Label lbl) {
2340 if (DEBUG) System.out.println(position + "\t\tif_iacmpgt:"+lbl); //$NON-NLS-1$
2343 if (this.wideMode) {
2344 generateWideRevertedConditionalBranch(OPC_if_icmple, lbl);
2346 if (classFileOffset >= bCodeStream.length) {
2350 bCodeStream[classFileOffset++] = OPC_if_icmpgt;
2354 final public void if_icmple(Label lbl) {
2355 if (DEBUG) System.out.println(position + "\t\tif_iacmple:"+lbl); //$NON-NLS-1$
2358 if (this.wideMode) {
2359 generateWideRevertedConditionalBranch(OPC_if_icmpgt, lbl);
2361 if (classFileOffset >= bCodeStream.length) {
2365 bCodeStream[classFileOffset++] = OPC_if_icmple;
2369 final public void if_icmplt(Label lbl) {
2370 if (DEBUG) System.out.println(position + "\t\tif_iacmplt:"+lbl); //$NON-NLS-1$
2373 if (this.wideMode) {
2374 generateWideRevertedConditionalBranch(OPC_if_icmpge, lbl);
2376 if (classFileOffset >= bCodeStream.length) {
2380 bCodeStream[classFileOffset++] = OPC_if_icmplt;
2384 final public void if_icmpne(Label lbl) {
2385 if (DEBUG) System.out.println(position + "\t\tif_iacmpne:"+lbl); //$NON-NLS-1$
2388 if (this.wideMode) {
2389 generateWideRevertedConditionalBranch(OPC_if_icmpeq, lbl);
2391 if (classFileOffset >= bCodeStream.length) {
2395 bCodeStream[classFileOffset++] = OPC_if_icmpne;
2399 final public void ifeq(Label lbl) {
2400 if (DEBUG) System.out.println(position + "\t\tifeq:"+lbl); //$NON-NLS-1$
2403 if (this.wideMode) {
2404 generateWideRevertedConditionalBranch(OPC_ifne, lbl);
2406 if (classFileOffset >= bCodeStream.length) {
2410 bCodeStream[classFileOffset++] = OPC_ifeq;
2414 final public void ifge(Label lbl) {
2415 if (DEBUG) System.out.println(position + "\t\tifge:"+lbl); //$NON-NLS-1$
2418 if (this.wideMode) {
2419 generateWideRevertedConditionalBranch(OPC_iflt, lbl);
2421 if (classFileOffset >= bCodeStream.length) {
2425 bCodeStream[classFileOffset++] = OPC_ifge;
2429 final public void ifgt(Label lbl) {
2430 if (DEBUG) System.out.println(position + "\t\tifgt:"+lbl); //$NON-NLS-1$
2433 if (this.wideMode) {
2434 generateWideRevertedConditionalBranch(OPC_ifle, lbl);
2436 if (classFileOffset >= bCodeStream.length) {
2440 bCodeStream[classFileOffset++] = OPC_ifgt;
2444 final public void ifle(Label lbl) {
2445 if (DEBUG) System.out.println(position + "\t\tifle:"+lbl); //$NON-NLS-1$
2448 if (this.wideMode) {
2449 generateWideRevertedConditionalBranch(OPC_ifgt, lbl);
2451 if (classFileOffset >= bCodeStream.length) {
2455 bCodeStream[classFileOffset++] = OPC_ifle;
2459 final public void iflt(Label lbl) {
2460 if (DEBUG) System.out.println(position + "\t\tiflt:"+lbl); //$NON-NLS-1$
2463 if (this.wideMode) {
2464 generateWideRevertedConditionalBranch(OPC_ifge, lbl);
2466 if (classFileOffset >= bCodeStream.length) {
2470 bCodeStream[classFileOffset++] = OPC_iflt;
2474 final public void ifne(Label lbl) {
2475 if (DEBUG) System.out.println(position + "\t\tifne:"+lbl); //$NON-NLS-1$
2478 if (this.wideMode) {
2479 generateWideRevertedConditionalBranch(OPC_ifeq, lbl);
2481 if (classFileOffset >= bCodeStream.length) {
2485 bCodeStream[classFileOffset++] = OPC_ifne;
2489 final public void ifnonnull(Label lbl) {
2490 if (DEBUG) System.out.println(position + "\t\tifnonnull:"+lbl); //$NON-NLS-1$
2493 if (this.wideMode) {
2494 generateWideRevertedConditionalBranch(OPC_ifnull, lbl);
2496 if (classFileOffset >= bCodeStream.length) {
2500 bCodeStream[classFileOffset++] = OPC_ifnonnull;
2504 final public void ifnull(Label lbl) {
2505 if (DEBUG) System.out.println(position + "\t\tifnull:"+lbl); //$NON-NLS-1$
2508 if (this.wideMode) {
2509 generateWideRevertedConditionalBranch(OPC_ifnonnull, lbl);
2511 if (classFileOffset >= bCodeStream.length) {
2515 bCodeStream[classFileOffset++] = OPC_ifnull;
2519 final public void iinc(int index, int value) {
2520 if (DEBUG) System.out.println(position + "\t\tiinc:"+index+","+value); //$NON-NLS-1$ //$NON-NLS-2$
2522 if ((index > 255) || (value < -128 || value > 127)) { // have to widen
2523 if (classFileOffset + 3 >= bCodeStream.length) {
2527 bCodeStream[classFileOffset++] = OPC_wide;
2528 bCodeStream[classFileOffset++] = OPC_iinc;
2529 writeUnsignedShort(index);
2530 writeSignedShort(value);
2532 if (classFileOffset + 2 >= bCodeStream.length) {
2536 bCodeStream[classFileOffset++] = OPC_iinc;
2537 bCodeStream[classFileOffset++] = (byte) index;
2538 bCodeStream[classFileOffset++] = (byte) value;
2541 final public void iload(int iArg) {
2542 if (DEBUG) System.out.println(position + "\t\tiload:"+iArg); //$NON-NLS-1$
2545 if (maxLocals <= iArg) {
2546 maxLocals = iArg + 1;
2548 if (stackDepth > stackMax)
2549 stackMax = stackDepth;
2550 if (iArg > 255) { // Widen
2551 if (classFileOffset + 3 >= bCodeStream.length) {
2555 bCodeStream[classFileOffset++] = OPC_wide;
2556 bCodeStream[classFileOffset++] = OPC_iload;
2557 writeUnsignedShort(iArg);
2559 if (classFileOffset + 1 >= bCodeStream.length) {
2563 bCodeStream[classFileOffset++] = OPC_iload;
2564 bCodeStream[classFileOffset++] = (byte) iArg;
2567 final public void iload_0() {
2568 if (DEBUG) System.out.println(position + "\t\tiload_0"); //$NON-NLS-1$
2571 if (maxLocals <= 0) {
2574 if (stackDepth > stackMax)
2575 stackMax = stackDepth;
2576 if (classFileOffset >= bCodeStream.length) {
2580 bCodeStream[classFileOffset++] = OPC_iload_0;
2582 final public void iload_1() {
2583 if (DEBUG) System.out.println(position + "\t\tiload_1"); //$NON-NLS-1$
2586 if (maxLocals <= 1) {
2589 if (stackDepth > stackMax)
2590 stackMax = stackDepth;
2591 if (classFileOffset >= bCodeStream.length) {
2595 bCodeStream[classFileOffset++] = OPC_iload_1;
2597 final public void iload_2() {
2598 if (DEBUG) System.out.println(position + "\t\tiload_2"); //$NON-NLS-1$
2601 if (maxLocals <= 2) {
2604 if (stackDepth > stackMax)
2605 stackMax = stackDepth;
2606 if (classFileOffset >= bCodeStream.length) {
2610 bCodeStream[classFileOffset++] = OPC_iload_2;
2612 final public void iload_3() {
2613 if (DEBUG) System.out.println(position + "\t\tiload_3"); //$NON-NLS-1$
2616 if (maxLocals <= 3) {
2619 if (stackDepth > stackMax)
2620 stackMax = stackDepth;
2621 if (classFileOffset >= bCodeStream.length) {
2625 bCodeStream[classFileOffset++] = OPC_iload_3;
2627 final public void imul() {
2628 if (DEBUG) System.out.println(position + "\t\timul"); //$NON-NLS-1$
2631 if (classFileOffset >= bCodeStream.length) {
2635 bCodeStream[classFileOffset++] = OPC_imul;
2637 public void incrementTemp(LocalVariableBinding localBinding, int value) {
2638 if (value == (short) value) {
2639 this.iinc(localBinding.resolvedPosition, value);
2645 store(localBinding, false);
2647 public void incrStackSize(int offset) {
2648 if ((stackDepth += offset) > stackMax)
2649 stackMax = stackDepth;
2651 public int indexOfSameLineEntrySincePC(int pc, int line) {
2652 for (int index = pc, max = pcToSourceMapSize; index < max; index+=2) {
2653 if (pcToSourceMap[index+1] == line)
2658 final public void ineg() {
2659 if (DEBUG) System.out.println(position + "\t\tineg"); //$NON-NLS-1$
2661 if (classFileOffset >= bCodeStream.length) {
2665 bCodeStream[classFileOffset++] = OPC_ineg;
2667 public void init(ClassFile targetClassFile) {
2668 this.classFile = targetClassFile;
2669 this.constantPool = targetClassFile.constantPool;
2670 this.bCodeStream = targetClassFile.contents;
2671 this.classFileOffset = targetClassFile.contentsOffset;
2672 this.startingClassFileOffset = this.classFileOffset;
2673 pcToSourceMapSize = 0;
2675 int length = visibleLocals.length;
2676 if (noVisibleLocals.length < length) {
2677 noVisibleLocals = new LocalVariableBinding[length];
2679 System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
2680 visibleLocalsCount = 0;
2682 length = locals.length;
2683 if (noLocals.length < length) {
2684 noLocals = new LocalVariableBinding[length];
2686 System.arraycopy(noLocals, 0, locals, 0, length);
2687 allLocalsCounter = 0;
2689 length = exceptionHandlers.length;
2690 if (noExceptionHandlers.length < length) {
2691 noExceptionHandlers = new ExceptionLabel[length];
2693 System.arraycopy(noExceptionHandlers, 0, exceptionHandlers, 0, length);
2694 exceptionHandlersNumber = 0;
2696 length = labels.length;
2697 if (noLabels.length < length) {
2698 noLabels = new Label[length];
2700 System.arraycopy(noLabels, 0, labels, 0, length);
2709 * @param methodBinding the given method binding to initialize the max locals
2711 public void initializeMaxLocals(MethodBinding methodBinding) {
2713 maxLocals = (methodBinding == null || methodBinding.isStatic()) ? 0 : 1;
2714 // take into account the synthetic parameters
2715 if (methodBinding != null) {
2716 if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
2717 ReferenceBinding enclosingInstanceTypes[];
2718 if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
2719 for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
2720 maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
2721 // LongBinding or DoubleBinding
2724 SyntheticArgumentBinding syntheticArguments[];
2725 if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
2726 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
2727 TypeBinding argType;
2728 if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) {
2736 TypeBinding[] arguments;
2737 if ((arguments = methodBinding.parameters) != null) {
2738 for (int i = 0, max = arguments.length; i < max; i++) {
2739 TypeBinding argType;
2740 if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) {
2750 * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
2751 * If there is an existing entry it returns -1 (no insertion required).
2752 * Otherwise it returns the index where the entry for the pc has to be inserted.
2753 * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
2755 * @param pcToSourceMap the given pcToSourceMap array
2756 * @param length the given length
2757 * @param pc the given pc
2760 public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
2766 // we search only on even indexes
2769 int currentPC = pcToSourceMap[m];
2770 if (pc < currentPC) {
2773 if (pc > currentPC) {
2779 if (pc < pcToSourceMap[m])
2784 * We didn't call it instanceof because there is a conflit with the
2785 * instanceof keyword
2787 final public void instance_of(TypeBinding typeBinding) {
2788 if (DEBUG) System.out.println(position + "\t\tinstance_of:"+typeBinding); //$NON-NLS-1$
2790 if (classFileOffset + 2 >= bCodeStream.length) {
2794 bCodeStream[classFileOffset++] = OPC_instanceof;
2795 writeUnsignedShort(constantPool.literalIndex(typeBinding));
2797 public void invokeClassForName() {
2798 // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
2799 if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$
2801 if (classFileOffset + 2 >= bCodeStream.length) {
2805 bCodeStream[classFileOffset++] = OPC_invokestatic;
2806 writeUnsignedShort(constantPool.literalIndexForJavaLangClassForName());
2809 public void invokeJavaLangClassDesiredAssertionStatus() {
2810 // invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
2811 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$
2814 if (classFileOffset + 2 >= bCodeStream.length) {
2818 bCodeStream[classFileOffset++] = OPC_invokevirtual;
2819 writeUnsignedShort(constantPool.literalIndexForJavaLangClassDesiredAssertionStatus());
2822 public void invokeJavaLangClassGetComponentType() {
2823 // invokevirtual: java.lang.Class.getComponentType()java.lang.Class;
2824 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.getComponentType()java.lang.Class;"); //$NON-NLS-1$
2826 if (classFileOffset + 2 >= bCodeStream.length) {
2830 bCodeStream[classFileOffset++] = OPC_invokevirtual;
2831 writeUnsignedShort(constantPool.literalIndexForJavaLangClassGetComponentType());
2834 final public void invokeinterface(MethodBinding methodBinding) {
2835 // initialized to 1 to take into account this immediately
2836 if (DEBUG) System.out.println(position + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$
2840 if (classFileOffset + 4 >= bCodeStream.length) {
2844 bCodeStream[classFileOffset++] = OPC_invokeinterface;
2845 writeUnsignedShort(constantPool.literalIndex(methodBinding));
2846 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
2847 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
2851 bCodeStream[classFileOffset++] = (byte) argCount;
2852 // Generate a 0 into the byte array. Like the array is already fill with 0, we just need to increment
2853 // the number of bytes.
2854 bCodeStream[classFileOffset++] = 0;
2855 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long)) {
2856 stackDepth += (2 - argCount);
2859 stackDepth -= argCount;
2861 stackDepth += (1 - argCount);
2864 if (stackDepth > stackMax) {
2865 stackMax = stackDepth;
2868 public void invokeJavaLangErrorConstructor() {
2869 // invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
2870 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.Error<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
2872 if (classFileOffset + 2 >= bCodeStream.length) {
2876 bCodeStream[classFileOffset++] = OPC_invokespecial;
2878 writeUnsignedShort(constantPool.literalIndexForJavaLangErrorConstructor());
2880 public void invokeNoClassDefFoundErrorStringConstructor() {
2881 // invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
2882 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
2884 if (classFileOffset + 2 >= bCodeStream.length) {
2888 bCodeStream[classFileOffset++] = OPC_invokespecial;
2890 writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundErrorStringConstructor());
2892 public void invokeObjectGetClass() {
2893 // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
2894 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$
2896 if (classFileOffset + 2 >= bCodeStream.length) {
2900 bCodeStream[classFileOffset++] = OPC_invokevirtual;
2901 writeUnsignedShort(constantPool.literalIndexForJavaLangObjectGetClass());
2904 final public void invokespecial(MethodBinding methodBinding) {
2905 if (DEBUG) System.out.println(position + "\t\tinvokespecial:"+methodBinding); //$NON-NLS-1$
2906 // initialized to 1 to take into account this immediately
2910 if (classFileOffset + 2 >= bCodeStream.length) {
2914 bCodeStream[classFileOffset++] = OPC_invokespecial;
2915 writeUnsignedShort(constantPool.literalIndex(methodBinding));
2916 if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
2917 // enclosing instances
2918 TypeBinding[] syntheticArgumentTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes();
2919 if (syntheticArgumentTypes != null) {
2920 for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
2921 if (((id = syntheticArgumentTypes[i].id) == T_double) || (id == T_long)) {
2928 // outer local variables
2929 SyntheticArgumentBinding[] syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables();
2930 if (syntheticArguments != null) {
2931 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
2932 if (((id = syntheticArguments[i].type.id) == T_double) || (id == T_long)) {
2940 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
2941 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
2945 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
2946 stackDepth += (2 - argCount);
2949 stackDepth -= argCount;
2951 stackDepth += (1 - argCount);
2952 if (stackDepth > stackMax)
2953 stackMax = stackDepth;
2955 final public void invokestatic(MethodBinding methodBinding) {
2956 if (DEBUG) System.out.println(position + "\t\tinvokestatic:"+methodBinding); //$NON-NLS-1$
2957 // initialized to 0 to take into account that there is no this for
2962 if (classFileOffset + 2 >= bCodeStream.length) {
2966 bCodeStream[classFileOffset++] = OPC_invokestatic;
2967 writeUnsignedShort(constantPool.literalIndex(methodBinding));
2968 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
2969 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
2973 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
2974 stackDepth += (2 - argCount);
2977 stackDepth -= argCount;
2979 stackDepth += (1 - argCount);
2980 if (stackDepth > stackMax)
2981 stackMax = stackDepth;
2984 * The equivalent code performs a string conversion of the TOS
2985 * @param typeID <CODE>int</CODE>
2987 public void invokeStringBufferAppendForType(int typeID) {
2988 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$
2991 if (typeID == T_null)
2992 usedTypeID = T_String;
2994 usedTypeID = typeID;
2996 if (classFileOffset + 2 >= bCodeStream.length) {
3000 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3001 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferAppend(typeID));
3002 if ((usedTypeID == T_long) || (usedTypeID == T_double))
3008 public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
3009 // invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
3010 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>(typeBindingID)V"); //$NON-NLS-1$
3012 if (classFileOffset + 2 >= bCodeStream.length) {
3016 bCodeStream[classFileOffset++] = OPC_invokespecial;
3017 writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionErrorConstructor(typeBindingID));
3021 public void invokeJavaLangAssertionErrorDefaultConstructor() {
3022 // invokespecial: java.lang.AssertionError.<init>()V
3023 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>()V"); //$NON-NLS-1$
3025 if (classFileOffset + 2 >= bCodeStream.length) {
3029 bCodeStream[classFileOffset++] = OPC_invokespecial;
3030 writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionErrorDefaultConstructor());
3034 public void invokeStringBufferDefaultConstructor() {
3035 // invokespecial: java.lang.StringBuffer.<init>()V
3036 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.<init>()V"); //$NON-NLS-1$
3038 if (classFileOffset + 2 >= bCodeStream.length) {
3042 bCodeStream[classFileOffset++] = OPC_invokespecial;
3043 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferDefaultConstructor());
3046 public void invokeStringBufferStringConstructor() {
3047 // invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
3048 if (DEBUG) System.out.println(position + "\t\tjava.lang.StringBuffer.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3050 if (classFileOffset + 2 >= bCodeStream.length) {
3054 bCodeStream[classFileOffset++] = OPC_invokespecial;
3055 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferConstructor());
3059 public void invokeStringBufferToString() {
3060 // invokevirtual: StringBuffer.toString()Ljava.lang.String;
3061 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$
3063 if (classFileOffset + 2 >= bCodeStream.length) {
3067 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3068 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferToString());
3070 public void invokeStringIntern() {
3071 // invokevirtual: java.lang.String.intern()
3072 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$
3074 if (classFileOffset + 2 >= bCodeStream.length) {
3078 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3079 writeUnsignedShort(constantPool.literalIndexForJavaLangStringIntern());
3081 public void invokeStringValueOf(int typeID) {
3082 // invokestatic: java.lang.String.valueOf(argumentType)
3083 if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$
3085 if (classFileOffset + 2 >= bCodeStream.length) {
3089 bCodeStream[classFileOffset++] = OPC_invokestatic;
3090 writeUnsignedShort(constantPool.literalIndexForJavaLangStringValueOf(typeID));
3092 public void invokeThrowableGetMessage() {
3093 // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
3094 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$
3096 if (classFileOffset + 2 >= bCodeStream.length) {
3100 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3101 writeUnsignedShort(constantPool.literalIndexForJavaLangThrowableGetMessage());
3103 final public void invokevirtual(MethodBinding methodBinding) {
3104 if (DEBUG) System.out.println(position + "\t\tinvokevirtual:"+methodBinding); //$NON-NLS-1$
3105 // initialized to 1 to take into account this immediately
3109 if (classFileOffset + 2 >= bCodeStream.length) {
3113 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3114 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3115 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3116 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3120 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3121 stackDepth += (2 - argCount);
3124 stackDepth -= argCount;
3126 stackDepth += (1 - argCount);
3127 if (stackDepth > stackMax)
3128 stackMax = stackDepth;
3130 final public void ior() {
3131 if (DEBUG) System.out.println(position + "\t\tior"); //$NON-NLS-1$
3134 if (classFileOffset >= bCodeStream.length) {
3138 bCodeStream[classFileOffset++] = OPC_ior;
3140 final public void irem() {
3141 if (DEBUG) System.out.println(position + "\t\tirem"); //$NON-NLS-1$
3144 if (classFileOffset >= bCodeStream.length) {
3148 bCodeStream[classFileOffset++] = OPC_irem;
3150 final public void ireturn() {
3151 if (DEBUG) System.out.println(position + "\t\tireturn"); //$NON-NLS-1$
3154 // the stackDepth should be equal to 0
3155 if (classFileOffset >= bCodeStream.length) {
3159 bCodeStream[classFileOffset++] = OPC_ireturn;
3161 public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
3162 // Dependant of UnconditionalFlowInfo.isDefinitelyAssigned(..)
3163 if (initStateIndex == -1)
3165 if (local.isArgument) {
3168 int localPosition = local.id + maxFieldCount;
3169 MethodScope methodScope = scope.methodScope();
3171 if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
3172 return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 0; // use bits
3175 long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
3176 if (extraInits == null)
3177 return false; // if vector not yet allocated, then not initialized
3179 if ((vectorIndex = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
3180 return false; // if not enough room in vector, then not initialized
3181 return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
3183 final public void ishl() {
3184 if (DEBUG) System.out.println(position + "\t\tishl"); //$NON-NLS-1$
3187 if (classFileOffset >= bCodeStream.length) {
3191 bCodeStream[classFileOffset++] = OPC_ishl;
3193 final public void ishr() {
3194 if (DEBUG) System.out.println(position + "\t\tishr"); //$NON-NLS-1$
3197 if (classFileOffset >= bCodeStream.length) {
3201 bCodeStream[classFileOffset++] = OPC_ishr;
3203 final public void istore(int iArg) {
3204 if (DEBUG) System.out.println(position + "\t\tistore:"+iArg); //$NON-NLS-1$
3207 if (maxLocals <= iArg) {
3208 maxLocals = iArg + 1;
3210 if (iArg > 255) { // Widen
3211 if (classFileOffset + 3 >= bCodeStream.length) {
3215 bCodeStream[classFileOffset++] = OPC_wide;
3216 bCodeStream[classFileOffset++] = OPC_istore;
3217 writeUnsignedShort(iArg);
3219 if (classFileOffset + 1 >= bCodeStream.length) {
3223 bCodeStream[classFileOffset++] = OPC_istore;
3224 bCodeStream[classFileOffset++] = (byte) iArg;
3227 final public void istore_0() {
3228 if (DEBUG) System.out.println(position + "\t\tistore_0"); //$NON-NLS-1$
3231 if (maxLocals == 0) {
3234 if (classFileOffset >= bCodeStream.length) {
3238 bCodeStream[classFileOffset++] = OPC_istore_0;
3240 final public void istore_1() {
3241 if (DEBUG) System.out.println(position + "\t\tistore_1"); //$NON-NLS-1$
3244 if (maxLocals <= 1) {
3247 if (classFileOffset >= bCodeStream.length) {
3251 bCodeStream[classFileOffset++] = OPC_istore_1;
3253 final public void istore_2() {
3254 if (DEBUG) System.out.println(position + "\t\tistore_2"); //$NON-NLS-1$
3257 if (maxLocals <= 2) {
3260 if (classFileOffset >= bCodeStream.length) {
3264 bCodeStream[classFileOffset++] = OPC_istore_2;
3266 final public void istore_3() {
3267 if (DEBUG) System.out.println(position + "\t\tistore_3"); //$NON-NLS-1$
3270 if (maxLocals <= 3) {
3273 if (classFileOffset >= bCodeStream.length) {
3277 bCodeStream[classFileOffset++] = OPC_istore_3;
3279 final public void isub() {
3280 if (DEBUG) System.out.println(position + "\t\tisub"); //$NON-NLS-1$
3283 if (classFileOffset >= bCodeStream.length) {
3287 bCodeStream[classFileOffset++] = OPC_isub;
3289 final public void iushr() {
3290 if (DEBUG) System.out.println(position + "\t\tiushr"); //$NON-NLS-1$
3293 if (classFileOffset >= bCodeStream.length) {
3297 bCodeStream[classFileOffset++] = OPC_iushr;
3299 final public void ixor() {
3300 if (DEBUG) System.out.println(position + "\t\tixor"); //$NON-NLS-1$
3303 if (classFileOffset >= bCodeStream.length) {
3307 bCodeStream[classFileOffset++] = OPC_ixor;
3309 final public void jsr(Label lbl) {
3310 if (this.wideMode) {
3314 if (DEBUG) System.out.println(position + "\t\tjsr"+lbl); //$NON-NLS-1$
3316 if (classFileOffset >= bCodeStream.length) {
3320 bCodeStream[classFileOffset++] = OPC_jsr;
3323 final public void jsr_w(Label lbl) {
3324 if (DEBUG) System.out.println(position + "\t\tjsr_w"+lbl); //$NON-NLS-1$
3326 if (classFileOffset >= bCodeStream.length) {
3330 bCodeStream[classFileOffset++] = OPC_jsr_w;
3333 final public void l2d() {
3334 if (DEBUG) System.out.println(position + "\t\tl2d"); //$NON-NLS-1$
3336 if (classFileOffset >= bCodeStream.length) {
3340 bCodeStream[classFileOffset++] = OPC_l2d;
3342 final public void l2f() {
3343 if (DEBUG) System.out.println(position + "\t\tl2f"); //$NON-NLS-1$
3346 if (classFileOffset >= bCodeStream.length) {
3350 bCodeStream[classFileOffset++] = OPC_l2f;
3352 final public void l2i() {
3353 if (DEBUG) System.out.println(position + "\t\tl2i"); //$NON-NLS-1$
3356 if (classFileOffset >= bCodeStream.length) {
3360 bCodeStream[classFileOffset++] = OPC_l2i;
3362 final public void ladd() {
3363 if (DEBUG) System.out.println(position + "\t\tladd"); //$NON-NLS-1$
3366 if (classFileOffset >= bCodeStream.length) {
3370 bCodeStream[classFileOffset++] = OPC_ladd;
3372 final public void laload() {
3373 if (DEBUG) System.out.println(position + "\t\tlaload"); //$NON-NLS-1$
3375 if (classFileOffset >= bCodeStream.length) {
3379 bCodeStream[classFileOffset++] = OPC_laload;
3381 final public void land() {
3382 if (DEBUG) System.out.println(position + "\t\tland"); //$NON-NLS-1$
3385 if (classFileOffset >= bCodeStream.length) {
3389 bCodeStream[classFileOffset++] = OPC_land;
3391 final public void lastore() {
3392 if (DEBUG) System.out.println(position + "\t\tlastore"); //$NON-NLS-1$
3395 if (classFileOffset >= bCodeStream.length) {
3399 bCodeStream[classFileOffset++] = OPC_lastore;
3401 final public void lcmp() {
3402 if (DEBUG) System.out.println(position + "\t\tlcmp"); //$NON-NLS-1$
3405 if (classFileOffset >= bCodeStream.length) {
3409 bCodeStream[classFileOffset++] = OPC_lcmp;
3411 final public void lconst_0() {
3412 if (DEBUG) System.out.println(position + "\t\tlconst_0"); //$NON-NLS-1$
3415 if (stackDepth > stackMax)
3416 stackMax = stackDepth;
3417 if (classFileOffset >= bCodeStream.length) {
3421 bCodeStream[classFileOffset++] = OPC_lconst_0;
3423 final public void lconst_1() {
3424 if (DEBUG) System.out.println(position + "\t\tlconst_1"); //$NON-NLS-1$
3427 if (stackDepth > stackMax)
3428 stackMax = stackDepth;
3429 if (classFileOffset >= bCodeStream.length) {
3433 bCodeStream[classFileOffset++] = OPC_lconst_1;
3435 final public void ldc(float constant) {
3436 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
3438 int index = constantPool.literalIndex(constant);
3440 if (stackDepth > stackMax)
3441 stackMax = stackDepth;
3444 if (classFileOffset + 2 >= bCodeStream.length) {
3448 bCodeStream[classFileOffset++] = OPC_ldc_w;
3449 writeUnsignedShort(index);
3452 if (classFileOffset + 1 >= bCodeStream.length) {
3456 bCodeStream[classFileOffset++] = OPC_ldc;
3457 bCodeStream[classFileOffset++] = (byte) index;
3460 final public void ldc(int constant) {
3461 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
3463 int index = constantPool.literalIndex(constant);
3465 if (stackDepth > stackMax)
3466 stackMax = stackDepth;
3469 if (classFileOffset + 2 >= bCodeStream.length) {
3473 bCodeStream[classFileOffset++] = OPC_ldc_w;
3474 writeUnsignedShort(index);
3477 if (classFileOffset + 1 >= bCodeStream.length) {
3481 bCodeStream[classFileOffset++] = OPC_ldc;
3482 bCodeStream[classFileOffset++] = (byte) index;
3485 final public void ldc(String constant) {
3486 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
3488 int currentConstantPoolIndex = constantPool.currentIndex;
3489 int currentConstantPoolOffset = constantPool.currentOffset;
3490 int currentCodeStreamPosition = position;
3491 int index = constantPool.literalIndexForLdc(constant.toCharArray());
3493 // the string already exists inside the constant pool
3494 // we reuse the same index
3496 if (stackDepth > stackMax)
3497 stackMax = stackDepth;
3500 if (classFileOffset + 2 >= bCodeStream.length) {
3504 bCodeStream[classFileOffset++] = OPC_ldc_w;
3505 writeUnsignedShort(index);
3508 if (classFileOffset + 1 >= bCodeStream.length) {
3512 bCodeStream[classFileOffset++] = OPC_ldc;
3513 bCodeStream[classFileOffset++] = (byte) index;
3516 // the string is too big to be utf8-encoded in one pass.
3517 // we have to split it into different pieces.
3518 // first we clean all side-effects due to the code above
3519 // this case is very rare, so we can afford to lose time to handle it
3520 char[] constantChars = constant.toCharArray();
3521 position = currentCodeStreamPosition;
3522 constantPool.currentIndex = currentConstantPoolIndex;
3523 constantPool.currentOffset = currentConstantPoolOffset;
3524 constantPool.stringCache.remove(constantChars);
3525 constantPool.UTF8Cache.remove(constantChars);
3528 int constantLength = constant.length();
3529 byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
3530 int utf8encodingLength = 0;
3531 while ((length < 65532) && (i < constantLength)) {
3532 char current = constantChars[i];
3533 // we resize the byte array immediately if necessary
3534 if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
3535 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
3537 if ((current >= 0x0001) && (current <= 0x007F)) {
3538 // we only need one byte: ASCII table
3539 utf8encoding[length++] = (byte) current;
3541 if (current > 0x07FF) {
3543 utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
3544 utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
3545 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3547 // we can be 0 or between 0x0080 and 0x07FF
3548 // In that case we only need 2 bytes
3549 utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
3550 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3555 // check if all the string is encoded (PR 1PR2DWJ)
3556 // the string is too big to be encoded in one pass
3559 // write the first part
3560 char[] subChars = new char[i];
3561 System.arraycopy(constantChars, 0, subChars, 0, i);
3562 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
3563 index = constantPool.literalIndex(subChars, utf8encoding);
3565 if (stackDepth > stackMax)
3566 stackMax = stackDepth;
3569 if (classFileOffset + 2 >= bCodeStream.length) {
3573 bCodeStream[classFileOffset++] = OPC_ldc_w;
3574 writeUnsignedShort(index);
3577 if (classFileOffset + 1 >= bCodeStream.length) {
3581 bCodeStream[classFileOffset++] = OPC_ldc;
3582 bCodeStream[classFileOffset++] = (byte) index;
3584 // write the remaining part
3585 invokeStringBufferStringConstructor();
3586 while (i < constantLength) {
3588 utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
3590 while ((length < 65532) && (i < constantLength)) {
3591 char current = constantChars[i];
3592 // we resize the byte array immediately if necessary
3593 if (constantLength + 2 > (utf8encodingLength = utf8encoding.length)) {
3594 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
3596 if ((current >= 0x0001) && (current <= 0x007F)) {
3597 // we only need one byte: ASCII table
3598 utf8encoding[length++] = (byte) current;
3600 if (current > 0x07FF) {
3602 utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
3603 utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
3604 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3606 // we can be 0 or between 0x0080 and 0x07FF
3607 // In that case we only need 2 bytes
3608 utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
3609 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3614 // the next part is done
3615 subChars = new char[i - startIndex];
3616 System.arraycopy(constantChars, startIndex, subChars, 0, i - startIndex);
3617 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
3618 index = constantPool.literalIndex(subChars, utf8encoding);
3620 if (stackDepth > stackMax)
3621 stackMax = stackDepth;
3624 if (classFileOffset + 2 >= bCodeStream.length) {
3628 bCodeStream[classFileOffset++] = OPC_ldc_w;
3629 writeUnsignedShort(index);
3632 if (classFileOffset + 1 >= bCodeStream.length) {
3636 bCodeStream[classFileOffset++] = OPC_ldc;
3637 bCodeStream[classFileOffset++] = (byte) index;
3639 // now on the stack it should be a StringBuffer and a string.
3640 invokeStringBufferAppendForType(T_String);
3642 invokeStringBufferToString();
3643 invokeStringIntern();
3646 final public void ldc2_w(double constant) {
3647 if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
3649 int index = constantPool.literalIndex(constant);
3651 if (stackDepth > stackMax)
3652 stackMax = stackDepth;
3653 // Generate a ldc2_w
3654 if (classFileOffset + 2 >= bCodeStream.length) {
3658 bCodeStream[classFileOffset++] = OPC_ldc2_w;
3659 writeUnsignedShort(index);
3661 final public void ldc2_w(long constant) {
3662 if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
3664 int index = constantPool.literalIndex(constant);
3666 if (stackDepth > stackMax)
3667 stackMax = stackDepth;
3668 // Generate a ldc2_w
3669 if (classFileOffset + 2 >= bCodeStream.length) {
3673 bCodeStream[classFileOffset++] = OPC_ldc2_w;
3674 writeUnsignedShort(index);
3676 final public void ldiv() {
3677 if (DEBUG) System.out.println(position + "\t\tldiv"); //$NON-NLS-1$
3680 if (classFileOffset >= bCodeStream.length) {
3684 bCodeStream[classFileOffset++] = OPC_ldiv;
3686 final public void lload(int iArg) {
3687 if (DEBUG) System.out.println(position + "\t\tlload:"+iArg); //$NON-NLS-1$
3690 if (maxLocals <= iArg + 1) {
3691 maxLocals = iArg + 2;
3693 if (stackDepth > stackMax)
3694 stackMax = stackDepth;
3695 if (iArg > 255) { // Widen
3696 if (classFileOffset + 3 >= bCodeStream.length) {
3700 bCodeStream[classFileOffset++] = OPC_wide;
3701 bCodeStream[classFileOffset++] = OPC_lload;
3702 writeUnsignedShort(iArg);
3704 if (classFileOffset + 1 >= bCodeStream.length) {
3708 bCodeStream[classFileOffset++] = OPC_lload;
3709 bCodeStream[classFileOffset++] = (byte) iArg;
3712 final public void lload_0() {
3713 if (DEBUG) System.out.println(position + "\t\tlload_0"); //$NON-NLS-1$
3716 if (maxLocals < 2) {
3719 if (stackDepth > stackMax)
3720 stackMax = stackDepth;
3721 if (classFileOffset >= bCodeStream.length) {
3725 bCodeStream[classFileOffset++] = OPC_lload_0;
3727 final public void lload_1() {
3728 if (DEBUG) System.out.println(position + "\t\tlload_1"); //$NON-NLS-1$
3731 if (maxLocals < 3) {
3734 if (stackDepth > stackMax)
3735 stackMax = stackDepth;
3736 if (classFileOffset >= bCodeStream.length) {
3740 bCodeStream[classFileOffset++] = OPC_lload_1;
3742 final public void lload_2() {
3743 if (DEBUG) System.out.println(position + "\t\tlload_2"); //$NON-NLS-1$
3746 if (maxLocals < 4) {
3749 if (stackDepth > stackMax)
3750 stackMax = stackDepth;
3751 if (classFileOffset >= bCodeStream.length) {
3755 bCodeStream[classFileOffset++] = OPC_lload_2;
3757 final public void lload_3() {
3758 if (DEBUG) System.out.println(position + "\t\tlload_3"); //$NON-NLS-1$
3761 if (maxLocals < 5) {
3764 if (stackDepth > stackMax)
3765 stackMax = stackDepth;
3766 if (classFileOffset >= bCodeStream.length) {
3770 bCodeStream[classFileOffset++] = OPC_lload_3;
3772 final public void lmul() {
3773 if (DEBUG) System.out.println(position + "\t\tlmul"); //$NON-NLS-1$
3776 if (classFileOffset >= bCodeStream.length) {
3780 bCodeStream[classFileOffset++] = OPC_lmul;
3782 final public void lneg() {
3783 if (DEBUG) System.out.println(position + "\t\tlneg"); //$NON-NLS-1$
3785 if (classFileOffset >= bCodeStream.length) {
3789 bCodeStream[classFileOffset++] = OPC_lneg;
3791 public final void load(LocalVariableBinding localBinding) {
3793 TypeBinding typeBinding = localBinding.type;
3794 int resolvedPosition = localBinding.resolvedPosition;
3795 // Using dedicated int bytecode
3796 if (typeBinding == IntBinding) {
3797 switch (resolvedPosition) {
3811 // internal failure: trying to load variable not supposed to be generated
3814 this.iload(resolvedPosition);
3818 // Using dedicated float bytecode
3819 if (typeBinding == FloatBinding) {
3820 switch (resolvedPosition) {
3834 this.fload(resolvedPosition);
3838 // Using dedicated long bytecode
3839 if (typeBinding == LongBinding) {
3840 switch (resolvedPosition) {
3854 this.lload(resolvedPosition);
3858 // Using dedicated double bytecode
3859 if (typeBinding == DoubleBinding) {
3860 switch (resolvedPosition) {
3874 this.dload(resolvedPosition);
3878 // boolean, byte, char and short are handled as int
3879 if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
3880 switch (resolvedPosition) {
3894 this.iload(resolvedPosition);
3900 switch (resolvedPosition) {
3914 this.aload(resolvedPosition);
3917 public final void load(TypeBinding typeBinding, int resolvedPosition) {
3919 // Using dedicated int bytecode
3920 if (typeBinding == IntBinding) {
3921 switch (resolvedPosition) {
3935 this.iload(resolvedPosition);
3939 // Using dedicated float bytecode
3940 if (typeBinding == FloatBinding) {
3941 switch (resolvedPosition) {
3955 this.fload(resolvedPosition);
3959 // Using dedicated long bytecode
3960 if (typeBinding == LongBinding) {
3961 switch (resolvedPosition) {
3975 this.lload(resolvedPosition);
3979 // Using dedicated double bytecode
3980 if (typeBinding == DoubleBinding) {
3981 switch (resolvedPosition) {
3995 this.dload(resolvedPosition);
3999 // boolean, byte, char and short are handled as int
4000 if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
4001 switch (resolvedPosition) {
4015 this.iload(resolvedPosition);
4021 switch (resolvedPosition) {
4035 this.aload(resolvedPosition);
4038 public final void loadInt(int resolvedPosition) {
4039 // Using dedicated int bytecode
4040 switch (resolvedPosition) {
4054 this.iload(resolvedPosition);
4057 public final void loadObject(int resolvedPosition) {
4058 switch (resolvedPosition) {
4072 this.aload(resolvedPosition);
4075 final public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
4076 if (DEBUG) System.out.println(position + "\t\tlookupswitch"); //$NON-NLS-1$
4079 int length = keys.length;
4081 defaultLabel.placeInstruction();
4082 for (int i = 0; i < length; i++) {
4083 casesLabel[i].placeInstruction();
4085 if (classFileOffset >= bCodeStream.length) {
4089 bCodeStream[classFileOffset++] = OPC_lookupswitch;
4090 for (int i = (3 - (pos % 4)); i > 0; i--) {
4091 if (classFileOffset >= bCodeStream.length) {
4095 bCodeStream[classFileOffset++] = 0;
4097 defaultLabel.branch();
4098 writeSignedWord(length);
4099 for (int i = 0; i < length; i++) {
4100 writeSignedWord(keys[sortedIndexes[i]]);
4101 casesLabel[sortedIndexes[i]].branch();
4104 final public void lor() {
4105 if (DEBUG) System.out.println(position + "\t\tlor"); //$NON-NLS-1$
4108 if (classFileOffset >= bCodeStream.length) {
4112 bCodeStream[classFileOffset++] = OPC_lor;
4114 final public void lrem() {
4115 if (DEBUG) System.out.println(position + "\t\tlrem"); //$NON-NLS-1$
4118 if (classFileOffset >= bCodeStream.length) {
4122 bCodeStream[classFileOffset++] = OPC_lrem;
4124 final public void lreturn() {
4125 if (DEBUG) System.out.println(position + "\t\tlreturn"); //$NON-NLS-1$
4128 // the stackDepth should be equal to 0
4129 if (classFileOffset >= bCodeStream.length) {
4133 bCodeStream[classFileOffset++] = OPC_lreturn;
4135 final public void lshl() {
4136 if (DEBUG) System.out.println(position + "\t\tlshl"); //$NON-NLS-1$
4139 if (classFileOffset >= bCodeStream.length) {
4143 bCodeStream[classFileOffset++] = OPC_lshl;
4145 final public void lshr() {
4146 if (DEBUG) System.out.println(position + "\t\tlshr"); //$NON-NLS-1$
4149 if (classFileOffset >= bCodeStream.length) {
4153 bCodeStream[classFileOffset++] = OPC_lshr;
4155 final public void lstore(int iArg) {
4156 if (DEBUG) System.out.println(position + "\t\tlstore:"+iArg); //$NON-NLS-1$
4159 if (maxLocals <= iArg + 1) {
4160 maxLocals = iArg + 2;
4162 if (iArg > 255) { // Widen
4163 if (classFileOffset + 3 >= bCodeStream.length) {
4167 bCodeStream[classFileOffset++] = OPC_wide;
4168 bCodeStream[classFileOffset++] = OPC_lstore;
4169 writeUnsignedShort(iArg);
4171 if (classFileOffset + 1 >= bCodeStream.length) {
4175 bCodeStream[classFileOffset++] = OPC_lstore;
4176 bCodeStream[classFileOffset++] = (byte) iArg;
4179 final public void lstore_0() {
4180 if (DEBUG) System.out.println(position + "\t\tlstore_0"); //$NON-NLS-1$
4183 if (maxLocals < 2) {
4186 if (classFileOffset >= bCodeStream.length) {
4190 bCodeStream[classFileOffset++] = OPC_lstore_0;
4192 final public void lstore_1() {
4193 if (DEBUG) System.out.println(position + "\t\tlstore_1"); //$NON-NLS-1$
4196 if (maxLocals < 3) {
4199 if (classFileOffset >= bCodeStream.length) {
4203 bCodeStream[classFileOffset++] = OPC_lstore_1;
4205 final public void lstore_2() {
4206 if (DEBUG) System.out.println(position + "\t\tlstore_2"); //$NON-NLS-1$
4209 if (maxLocals < 4) {
4212 if (classFileOffset >= bCodeStream.length) {
4216 bCodeStream[classFileOffset++] = OPC_lstore_2;
4218 final public void lstore_3() {
4219 if (DEBUG) System.out.println(position + "\t\tlstore_3"); //$NON-NLS-1$
4222 if (maxLocals < 5) {
4225 if (classFileOffset >= bCodeStream.length) {
4229 bCodeStream[classFileOffset++] = OPC_lstore_3;
4231 final public void lsub() {
4232 if (DEBUG) System.out.println(position + "\t\tlsub"); //$NON-NLS-1$
4235 if (classFileOffset >= bCodeStream.length) {
4239 bCodeStream[classFileOffset++] = OPC_lsub;
4241 final public void lushr() {
4242 if (DEBUG) System.out.println(position + "\t\tlushr"); //$NON-NLS-1$
4245 if (classFileOffset >= bCodeStream.length) {
4249 bCodeStream[classFileOffset++] = OPC_lushr;
4251 final public void lxor() {
4252 if (DEBUG) System.out.println(position + "\t\tlxor"); //$NON-NLS-1$
4255 if (classFileOffset >= bCodeStream.length) {
4259 bCodeStream[classFileOffset++] = OPC_lxor;
4261 final public void monitorenter() {
4262 if (DEBUG) System.out.println(position + "\t\tmonitorenter"); //$NON-NLS-1$
4265 if (classFileOffset >= bCodeStream.length) {
4269 bCodeStream[classFileOffset++] = OPC_monitorenter;
4271 final public void monitorexit() {
4272 if (DEBUG) System.out.println(position + "\t\tmonitorexit"); //$NON-NLS-1$
4275 if (classFileOffset >= bCodeStream.length) {
4279 bCodeStream[classFileOffset++] = OPC_monitorexit;
4281 final public void multianewarray(TypeBinding typeBinding, int dimensions) {
4282 if (DEBUG) System.out.println(position + "\t\tmultinewarray:"+typeBinding+","+dimensions); //$NON-NLS-1$ //$NON-NLS-2$
4284 stackDepth += (1 - dimensions);
4285 if (classFileOffset + 3 >= bCodeStream.length) {
4289 bCodeStream[classFileOffset++] = OPC_multianewarray;
4290 writeUnsignedShort(constantPool.literalIndex(typeBinding));
4291 bCodeStream[classFileOffset++] = (byte) dimensions;
4294 * We didn't call it new, because there is a conflit with the new keyword
4296 final public void new_(TypeBinding typeBinding) {
4297 if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding); //$NON-NLS-1$
4300 if (stackDepth > stackMax)
4301 stackMax = stackDepth;
4302 if (classFileOffset + 2 >= bCodeStream.length) {
4306 bCodeStream[classFileOffset++] = OPC_new;
4307 writeUnsignedShort(constantPool.literalIndex(typeBinding));
4309 final public void newarray(int array_Type) {
4310 if (DEBUG) System.out.println(position + "\t\tnewarray:"+array_Type); //$NON-NLS-1$
4312 if (classFileOffset + 1 >= bCodeStream.length) {
4316 bCodeStream[classFileOffset++] = OPC_newarray;
4317 bCodeStream[classFileOffset++] = (byte) array_Type;
4319 public void newArray(Scope scope, ArrayBinding arrayBinding) {
4320 TypeBinding component = arrayBinding.elementsType(scope);
4321 switch (component.id) {
4347 this.anewarray(component);
4350 public void newJavaLangError() {
4351 // new: java.lang.Error
4352 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Error"); //$NON-NLS-1$
4355 if (stackDepth > stackMax)
4356 stackMax = stackDepth;
4357 if (classFileOffset + 2 >= bCodeStream.length) {
4361 bCodeStream[classFileOffset++] = OPC_new;
4362 writeUnsignedShort(constantPool.literalIndexForJavaLangError());
4365 public void newJavaLangAssertionError() {
4366 // new: java.lang.AssertionError
4367 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.AssertionError"); //$NON-NLS-1$
4370 if (stackDepth > stackMax)
4371 stackMax = stackDepth;
4372 if (classFileOffset + 2 >= bCodeStream.length) {
4376 bCodeStream[classFileOffset++] = OPC_new;
4377 writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionError());
4380 public void newNoClassDefFoundError() {
4381 // new: java.lang.NoClassDefFoundError
4382 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$
4385 if (stackDepth > stackMax)
4386 stackMax = stackDepth;
4387 if (classFileOffset + 2 >= bCodeStream.length) {
4391 bCodeStream[classFileOffset++] = OPC_new;
4392 writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundError());
4394 public void newStringBuffer() {
4395 // new: java.lang.StringBuffer
4396 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$
4399 if (stackDepth > stackMax)
4400 stackMax = stackDepth;
4401 if (classFileOffset + 2 >= bCodeStream.length) {
4405 bCodeStream[classFileOffset++] = OPC_new;
4406 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBuffer());
4408 public void newWrapperFor(int typeID) {
4411 if (stackDepth > stackMax)
4412 stackMax = stackDepth;
4413 if (classFileOffset + 2 >= bCodeStream.length) {
4417 bCodeStream[classFileOffset++] = OPC_new;
4419 case T_int : // new: java.lang.Integer
4420 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$
4421 writeUnsignedShort(constantPool.literalIndexForJavaLangInteger());
4423 case T_boolean : // new: java.lang.Boolean
4424 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$
4425 writeUnsignedShort(constantPool.literalIndexForJavaLangBoolean());
4427 case T_byte : // new: java.lang.Byte
4428 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$
4429 writeUnsignedShort(constantPool.literalIndexForJavaLangByte());
4431 case T_char : // new: java.lang.Character
4432 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Character"); //$NON-NLS-1$
4433 writeUnsignedShort(constantPool.literalIndexForJavaLangCharacter());
4435 case T_float : // new: java.lang.Float
4436 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Float"); //$NON-NLS-1$
4437 writeUnsignedShort(constantPool.literalIndexForJavaLangFloat());
4439 case T_double : // new: java.lang.Double
4440 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Double"); //$NON-NLS-1$
4441 writeUnsignedShort(constantPool.literalIndexForJavaLangDouble());
4443 case T_short : // new: java.lang.Short
4444 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Short"); //$NON-NLS-1$
4445 writeUnsignedShort(constantPool.literalIndexForJavaLangShort());
4447 case T_long : // new: java.lang.Long
4448 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$
4449 writeUnsignedShort(constantPool.literalIndexForJavaLangLong());
4451 case T_void : // new: java.lang.Void
4452 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$
4453 writeUnsignedShort(constantPool.literalIndexForJavaLangVoid());
4456 final public void nop() {
4457 if (DEBUG) System.out.println(position + "\t\tnop"); //$NON-NLS-1$
4459 if (classFileOffset >= bCodeStream.length) {
4463 bCodeStream[classFileOffset++] = OPC_nop;
4465 final public void pop() {
4466 if (DEBUG) System.out.println(position + "\t\tpop"); //$NON-NLS-1$
4469 if (classFileOffset >= bCodeStream.length) {
4473 bCodeStream[classFileOffset++] = OPC_pop;
4475 final public void pop2() {
4476 if (DEBUG) System.out.println(position + "\t\tpop2"); //$NON-NLS-1$
4479 if (classFileOffset >= bCodeStream.length) {
4483 bCodeStream[classFileOffset++] = OPC_pop2;
4485 final public void putfield(FieldBinding fieldBinding) {
4486 if (DEBUG) System.out.println(position + "\t\tputfield:"+fieldBinding); //$NON-NLS-1$
4489 if (((id = fieldBinding.type.id) == T_double) || (id == T_long))
4493 if (stackDepth > stackMax)
4494 stackMax = stackDepth;
4495 if (classFileOffset + 2 >= bCodeStream.length) {
4499 bCodeStream[classFileOffset++] = OPC_putfield;
4500 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
4502 final public void putstatic(FieldBinding fieldBinding) {
4503 if (DEBUG) System.out.println(position + "\t\tputstatic:"+fieldBinding); //$NON-NLS-1$
4506 if (((id = fieldBinding.type.id) == T_double) || (id == T_long))
4510 if (stackDepth > stackMax)
4511 stackMax = stackDepth;
4512 if (classFileOffset + 2 >= bCodeStream.length) {
4516 bCodeStream[classFileOffset++] = OPC_putstatic;
4517 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
4519 public void record(LocalVariableBinding local) {
4520 if (!generateLocalVariableTableAttributes)
4522 if (allLocalsCounter == locals.length) {
4523 // resize the collection
4524 System.arraycopy(locals, 0, locals = new LocalVariableBinding[allLocalsCounter + LOCALS_INCREMENT], 0, allLocalsCounter);
4526 locals[allLocalsCounter++] = local;
4527 local.initializationPCs = new int[4];
4528 local.initializationCount = 0;
4530 public void recordPositionsFrom(int startPC, int sourcePos) {
4532 /* Record positions in the table, only if nothing has
4533 * already been recorded. Since we output them on the way
4534 * up (children first for more specific info)
4535 * The pcToSourceMap table is always sorted.
4538 if (!generateLineNumberAttributes)
4543 // no code generated for this node. e.g. field without any initialization
4544 if (position == startPC)
4547 // Widening an existing entry that already has the same source positions
4548 if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
4549 // resize the array pcToSourceMap
4550 System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
4552 int newLine = ClassFile.searchLineNumber(lineSeparatorPositions, sourcePos);
4553 // lastEntryPC represents the endPC of the lastEntry.
4554 if (pcToSourceMapSize > 0) {
4555 // in this case there is already an entry in the table
4556 if (pcToSourceMap[pcToSourceMapSize - 1] != newLine) {
4557 if (startPC < lastEntryPC) {
4558 // we forgot to add an entry.
4559 // search if an existing entry exists for startPC
4560 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
4561 if (insertionIndex != -1) {
4562 // there is no existing entry starting with startPC.
4563 int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, newLine); // index for PC
4564 /* the existingEntryIndex corresponds to en entry with the same line and a PC >= startPC.
4565 in this case it is relevant to widen this entry instead of creating a new one.
4569 with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
4570 aload0 bytecode. The first entry is the one for the argument a.
4571 But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
4572 So we widen the existing entry (if there is one) or we create a new entry with the startPC.
4574 if (existingEntryIndex != -1) {
4575 // widen existing entry
4576 pcToSourceMap[existingEntryIndex] = startPC;
4578 // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
4579 System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
4580 pcToSourceMap[insertionIndex++] = startPC;
4581 pcToSourceMap[insertionIndex] = newLine;
4582 pcToSourceMapSize += 2;
4585 if (position != lastEntryPC) { // no bytecode since last entry pc
4586 pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
4587 pcToSourceMap[pcToSourceMapSize++] = newLine;
4590 // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
4591 pcToSourceMap[pcToSourceMapSize++] = startPC;
4592 pcToSourceMap[pcToSourceMapSize++] = newLine;
4595 /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
4596 we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
4598 if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
4599 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
4600 if (insertionIndex != -1) {
4601 // widen the existing entry
4602 // we have to figure out if we need to move the last entry at another location to keep a sorted table
4603 /* First we need to check if at the insertion position there is not an existing entry
4604 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
4605 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
4606 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
4608 if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == newLine))) {
4609 if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
4610 System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
4611 pcToSourceMap[insertionIndex++] = startPC;
4612 pcToSourceMap[insertionIndex] = newLine;
4614 pcToSourceMap[pcToSourceMapSize - 2] = startPC;
4620 lastEntryPC = position;
4622 // record the first entry
4623 pcToSourceMap[pcToSourceMapSize++] = startPC;
4624 pcToSourceMap[pcToSourceMapSize++] = newLine;
4625 lastEntryPC = position;
4629 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
4631 public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
4633 if (exceptionHandlersNumber >= (length = exceptionHandlers.length)) {
4634 // resize the exception handlers table
4635 System.arraycopy(exceptionHandlers, 0, exceptionHandlers = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
4637 // no need to resize. So just add the new exception label
4638 exceptionHandlers[exceptionHandlersNumber++] = anExceptionLabel;
4640 public final void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
4641 // given some flow info, make sure we did not loose some variables initialization
4642 // if this happens, then we must update their pc entries to reflect it in debug attributes
4643 if (!generateLocalVariableTableAttributes)
4645 /* if (initStateIndex == lastInitStateIndexWhenRemovingInits)
4648 lastInitStateIndexWhenRemovingInits = initStateIndex;
4649 if (lastInitStateIndexWhenAddingInits != initStateIndex){
4650 lastInitStateIndexWhenAddingInits = -2;// reinitialize add index
4651 // add(1)-remove(1)-add(1) -> ignore second add
4652 // add(1)-remove(2)-add(1) -> perform second add
4654 for (int i = 0; i < visibleLocalsCount; i++) {
4655 LocalVariableBinding localBinding = visibleLocals[i];
4656 if (localBinding != null) {
4657 if (initStateIndex == -1 || !isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
4658 if (localBinding.initializationCount > 0) {
4659 localBinding.recordInitializationEndPC(position);
4666 * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
4667 * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
4669 public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
4670 init(targetClassFile);
4671 this.methodDeclaration = referenceMethod;
4672 preserveUnusedLocals = referenceMethod.scope.problemReporter().options.preserveAllLocalVariables;
4673 initializeMaxLocals(referenceMethod.binding);
4676 * @param targetClassFile The given classfile to reset the code stream
4678 public void resetForProblemClinit(ClassFile targetClassFile) {
4679 init(targetClassFile);
4682 private final void resizeByteArray() {
4683 int length = bCodeStream.length;
4684 int requiredSize = length + length;
4685 if (classFileOffset > requiredSize) {
4686 // must be sure to grow by enough
4687 requiredSize = classFileOffset + length;
4689 System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length);
4691 final public void ret(int index) {
4692 if (DEBUG) System.out.println(position + "\t\tret:"+index); //$NON-NLS-1$
4694 if (index > 255) { // Widen
4695 if (classFileOffset + 3 >= bCodeStream.length) {
4699 bCodeStream[classFileOffset++] = OPC_wide;
4700 bCodeStream[classFileOffset++] = OPC_ret;
4701 writeUnsignedShort(index);
4702 } else { // Don't Widen
4703 if (classFileOffset + 1 >= bCodeStream.length) {
4707 bCodeStream[classFileOffset++] = OPC_ret;
4708 bCodeStream[classFileOffset++] = (byte) index;
4711 final public void return_() {
4712 if (DEBUG) System.out.println(position + "\t\treturn"); //$NON-NLS-1$
4714 // the stackDepth should be equal to 0
4715 if (classFileOffset >= bCodeStream.length) {
4719 bCodeStream[classFileOffset++] = OPC_return;
4721 final public void saload() {
4722 if (DEBUG) System.out.println(position + "\t\tsaload"); //$NON-NLS-1$
4725 if (classFileOffset >= bCodeStream.length) {
4729 bCodeStream[classFileOffset++] = OPC_saload;
4731 final public void sastore() {
4732 if (DEBUG) System.out.println(position + "\t\tsastore"); //$NON-NLS-1$
4735 if (classFileOffset >= bCodeStream.length) {
4739 bCodeStream[classFileOffset++] = OPC_sastore;
4742 * @param operatorConstant int
4743 * @param type_ID int
4745 public void sendOperator(int operatorConstant, int type_ID) {
4752 switch (operatorConstant) {
4774 case UNSIGNED_RIGHT_SHIFT :
4789 switch (operatorConstant) {
4811 case UNSIGNED_RIGHT_SHIFT :
4826 switch (operatorConstant) {
4844 switch (operatorConstant) {
4862 final public void sipush(int s) {
4863 if (DEBUG) System.out.println(position + "\t\tsipush:"+s); //$NON-NLS-1$
4866 if (stackDepth > stackMax)
4867 stackMax = stackDepth;
4868 if (classFileOffset >= bCodeStream.length) {
4872 bCodeStream[classFileOffset++] = OPC_sipush;
4873 writeSignedShort(s);
4875 public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
4880 /* Arbitrarily establishing partition element as the midpoint of
4883 mid = tab[ (lo0 + hi0) / 2];
4884 // loop through the array until indices cross
4886 /* find the first element that is greater than or equal to
4887 * the partition element starting from the left Index.
4889 while ((lo < hi0) && (tab[lo] < mid))
4891 /* find an element that is smaller than or equal to
4892 * the partition element starting from the right Index.
4894 while ((hi > lo0) && (tab[hi] > mid))
4896 // if the indexes have not crossed, swap
4898 swap(tab, lo, hi, result);
4903 /* If the right index has not reached the left side of array
4904 * must now sort the left partition.
4907 sort(tab, lo0, hi, result);
4908 /* If the left index has not reached the right side of array
4909 * must now sort the right partition.
4912 sort(tab, lo, hi0, result);
4916 public final void store(LocalVariableBinding localBinding, boolean valueRequired) {
4917 int localPosition = localBinding.resolvedPosition;
4918 // Using dedicated int bytecode
4919 switch(localBinding.type.id) {
4920 case TypeIds.T_int :
4921 case TypeIds.T_char :
4922 case TypeIds.T_byte :
4923 case TypeIds.T_short :
4924 case TypeIds.T_boolean :
4927 switch (localPosition) {
4941 // internal failure: trying to store into variable not supposed to be generated
4944 this.istore(localPosition);
4947 case TypeIds.T_float :
4950 switch (localPosition) {
4964 this.fstore(localPosition);
4967 case TypeIds.T_double :
4970 switch (localPosition) {
4984 this.dstore(localPosition);
4987 case TypeIds.T_long :
4990 switch (localPosition) {
5004 this.lstore(localPosition);
5011 switch (localPosition) {
5025 this.astore(localPosition);
5029 public final void store(TypeBinding type, int localPosition) {
5030 // Using dedicated int bytecode
5031 if ((type == IntBinding) || (type == CharBinding) || (type == ByteBinding) || (type == ShortBinding) || (type == BooleanBinding)) {
5032 switch (localPosition) {
5046 this.istore(localPosition);
5050 // Using dedicated float bytecode
5051 if (type == FloatBinding) {
5052 switch (localPosition) {
5066 this.fstore(localPosition);
5070 // Using dedicated long bytecode
5071 if (type == LongBinding) {
5072 switch (localPosition) {
5086 this.lstore(localPosition);
5090 // Using dedicated double bytecode
5091 if (type == DoubleBinding) {
5092 switch (localPosition) {
5106 this.dstore(localPosition);
5111 switch (localPosition) {
5125 this.astore(localPosition);
5128 public final void storeInt(int localPosition) {
5129 switch (localPosition) {
5143 this.istore(localPosition);
5146 public final void storeObject(int localPosition) {
5147 switch (localPosition) {
5161 this.astore(localPosition);
5164 final public void swap() {
5165 if (DEBUG) System.out.println(position + "\t\tswap"); //$NON-NLS-1$
5167 if (classFileOffset >= bCodeStream.length) {
5171 bCodeStream[classFileOffset++] = OPC_swap;
5173 private static final void swap(int a[], int i, int j, int result[]) {
5179 result[j] = result[i];
5182 final public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
5183 if (DEBUG) System.out.println(position + "\t\ttableswitch"); //$NON-NLS-1$
5186 int length = casesLabel.length;
5188 defaultLabel.placeInstruction();
5189 for (int i = 0; i < length; i++)
5190 casesLabel[i].placeInstruction();
5191 if (classFileOffset >= bCodeStream.length) {
5195 bCodeStream[classFileOffset++] = OPC_tableswitch;
5196 for (int i = (3 - (pos % 4)); i > 0; i--) {
5197 if (classFileOffset >= bCodeStream.length) {
5201 bCodeStream[classFileOffset++] = 0;
5203 defaultLabel.branch();
5204 writeSignedWord(low);
5205 writeSignedWord(high);
5206 int i = low, j = low;
5207 // the index j is used to know if the index i is one of the missing entries in case of an
5208 // optimized tableswitch
5211 int key = keys[index = sortedIndexes[j - low]];
5213 casesLabel[index].branch();
5215 if (i == high) break; // if high is maxint, then avoids wrapping to minint.
5217 defaultLabel.branch();
5222 public String toString() {
5223 StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
5224 buffer.append(position);
5225 buffer.append(",\nstackDepth:"); //$NON-NLS-1$
5226 buffer.append(stackDepth);
5227 buffer.append(",\nmaxStack:"); //$NON-NLS-1$
5228 buffer.append(stackMax);
5229 buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
5230 buffer.append(maxLocals);
5231 buffer.append(")"); //$NON-NLS-1$
5232 return buffer.toString();
5234 public void updateLastRecordedEndPC(int pos) {
5236 /* Tune positions in the table, this is due to some
5237 * extra bytecodes being
5238 * added to some user code (jumps). */
5240 if (!generateLineNumberAttributes)
5242 pcToSourceMap[pcToSourceMapSize - 1][1] = position;
5243 // need to update the initialization endPC in case of generation of local variable attributes.
5244 updateLocalVariablesAttribute(pos);
5247 if (!generateLineNumberAttributes)
5249 this.lastEntryPC = pos;
5250 // need to update the initialization endPC in case of generation of local variable attributes.
5251 updateLocalVariablesAttribute(pos);
5253 public void updateLocalVariablesAttribute(int pos) {
5254 // need to update the initialization endPC in case of generation of local variable attributes.
5255 if (generateLocalVariableTableAttributes) {
5256 for (int i = 0, max = locals.length; i < max; i++) {
5257 LocalVariableBinding local = locals[i];
5258 if ((local != null) && (local.initializationCount > 0)) {
5259 if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
5260 local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position;
5267 * Write a signed 16 bits value into the byte array
5268 * @param value the signed short
5270 public final void writeSignedShort(int value) {
5271 // we keep the resize in here because it is used outside the code stream
5272 if (classFileOffset + 1 >= bCodeStream.length) {
5276 bCodeStream[classFileOffset++] = (byte) (value >> 8);
5277 bCodeStream[classFileOffset++] = (byte) value;
5279 public final void writeSignedShort(int pos, int value) {
5280 int currentOffset = startingClassFileOffset + pos;
5281 if (currentOffset + 1 >= bCodeStream.length) {
5284 bCodeStream[currentOffset] = (byte) (value >> 8);
5285 bCodeStream[currentOffset + 1] = (byte) value;
5287 public final void writeSignedWord(int value) {
5288 // we keep the resize in here because it is used outside the code stream
5289 if (classFileOffset + 3 >= bCodeStream.length) {
5293 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
5294 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
5295 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
5296 bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
5298 public final void writeSignedWord(int pos, int value) {
5299 int currentOffset = startingClassFileOffset + pos;
5300 if (currentOffset + 4 >= bCodeStream.length) {
5303 bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
5304 bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
5305 bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
5306 bCodeStream[currentOffset++] = (byte) (value & 0xFF);
5309 * Write a unsigned 16 bits value into the byte array
5310 * @param value the unsigned short
5312 protected final void writeUnsignedShort(int value) {
5314 bCodeStream[classFileOffset++] = (byte) (value >>> 8);
5315 bCodeStream[classFileOffset++] = (byte) value;
5318 * Wide conditional branch compare, improved by swapping comparison opcode
5325 public void generateWideRevertedConditionalBranch(byte revertedOpcode, Label wideTarget) {
5326 Label intermediate = new Label(this);
5327 if (classFileOffset >= bCodeStream.length) {
5331 bCodeStream[classFileOffset++] = revertedOpcode;
5332 intermediate.branch();
5333 this.goto_w(wideTarget);
5334 intermediate.place();