1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.codegen;
13 import net.sourceforge.phpdt.internal.compiler.ClassFile;
14 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
15 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
16 import net.sourceforge.phpdt.internal.compiler.ast.AstNode;
17 import net.sourceforge.phpdt.internal.compiler.ast.Expression;
18 import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds;
19 import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
20 import net.sourceforge.phpdt.internal.compiler.flow.UnconditionalFlowInfo;
21 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
22 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
23 import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
24 import net.sourceforge.phpdt.internal.compiler.lookup.BaseTypes;
25 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
26 import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding;
27 import net.sourceforge.phpdt.internal.compiler.lookup.LocalVariableBinding;
28 import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
29 import net.sourceforge.phpdt.internal.compiler.lookup.MethodScope;
30 import net.sourceforge.phpdt.internal.compiler.lookup.NestedTypeBinding;
31 import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding;
32 import net.sourceforge.phpdt.internal.compiler.lookup.Scope;
33 import net.sourceforge.phpdt.internal.compiler.lookup.SyntheticAccessMethodBinding;
34 import net.sourceforge.phpdt.internal.compiler.lookup.SyntheticArgumentBinding;
35 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
36 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
37 import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds;
38 import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding;
40 public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, BaseTypes, TypeConstants, TypeIds {
41 // It will be responsible for the following items.
43 // -> Tracking Max Stack.
45 public int stackMax; // Use Ints to keep from using extra bc when adding
46 public int stackDepth; // Use Ints to keep from using extra bc when adding
48 public static final int max = 100; // Maximum size of the code array
49 public static final int growFactor = 400;
50 public static final int LABELS_INCREMENT = 5;
51 public byte[] bCodeStream;
52 public int pcToSourceMapSize;
53 public int[] pcToSourceMap = new int[24];
54 public int lastEntryPC; // last entry recorded
55 public int[] lineSeparatorPositions;
56 public int position; // So when first set can be incremented
57 public int classFileOffset;
58 public int startingClassFileOffset; // I need to keep the starting point inside the byte array
59 public ConstantPool constantPool;
60 // The constant pool used to generate bytecodes that need to store information into the constant pool
61 public ClassFile classFile; // The current classfile it is associated to.
62 // local variable attributes output
63 public static final int LOCALS_INCREMENT = 10;
64 public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
65 static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
66 public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
67 static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
68 int visibleLocalsCount;
69 public AbstractMethodDeclaration methodDeclaration;
70 public ExceptionLabel[] exceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
71 static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
72 public int exceptionHandlersNumber;
73 public static FieldBinding[] ImplicitThis = new FieldBinding[] {
75 public boolean generateLineNumberAttributes;
76 public boolean generateLocalVariableTableAttributes;
77 public boolean preserveUnusedLocals;
78 // store all the labels placed at the current position to be able to optimize
79 // a jump to the next bytecode.
80 public Label[] labels = new Label[LABELS_INCREMENT];
81 static Label[] noLabels = new Label[LABELS_INCREMENT];
82 public int countLabels;
83 public int allLocalsCounter;
84 public int maxFieldCount;
86 public boolean wideMode = false;
87 public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[]) null, 0, 0, 0);
89 public CodeStream(ClassFile classFile) {
90 generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0;
91 generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0;
92 if (generateLineNumberAttributes) {
93 lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions;
96 final public void aaload() {
101 bCodeStream[classFileOffset++] = OPC_aaload;
102 } catch (IndexOutOfBoundsException e) {
103 resizeByteArray(OPC_aaload);
106 final public void aastore() {
111 bCodeStream[classFileOffset++] = OPC_aastore;
112 } catch (IndexOutOfBoundsException e) {
113 resizeByteArray(OPC_aastore);
116 final public void aconst_null() {
119 if (stackDepth > stackMax)
120 stackMax = stackDepth;
123 bCodeStream[classFileOffset++] = OPC_aconst_null;
124 } catch (IndexOutOfBoundsException e) {
125 resizeByteArray(OPC_aconst_null);
128 public final void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
129 // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
130 if (!generateLocalVariableTableAttributes)
132 /* if (initStateIndex == lastInitStateIndexWhenAddingInits)
134 lastInitStateIndexWhenAddingInits = initStateIndex;
135 if (lastInitStateIndexWhenRemovingInits != initStateIndex){
136 lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index
137 // remove(1)-add(1)-remove(1) -> ignore second remove
138 // remove(1)-add(2)-remove(1) -> perform second remove
142 for (int i = 0; i < visibleLocalsCount; i++) {
143 LocalVariableBinding localBinding = visibleLocals[i];
144 if (localBinding != null) {
145 // Check if the local is definitely assigned
146 if ((initStateIndex != -1) && isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
147 if ((localBinding.initializationCount == 0)
148 || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
149 /* There are two cases:
150 * 1) there is no initialization interval opened ==> add an opened interval
151 * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
152 * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
154 * initializationPCs is a collection of pairs of int:
155 * first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
158 localBinding.recordInitializationStartPC(position);
164 public void addLabel(Label aLabel) {
165 if (countLabels == labels.length)
166 System.arraycopy(labels, 0, (labels = new Label[countLabels + LABELS_INCREMENT]), 0, countLabels);
167 labels[countLabels++] = aLabel;
169 public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
170 if (!generateLocalVariableTableAttributes)
173 if (visibleLocalsCount >= visibleLocals.length) {
174 System.arraycopy(visibleLocals, 0, (visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2]), 0, visibleLocalsCount);
176 visibleLocals[visibleLocalsCount++] = localBinding;
178 final public void aload(int iArg) {
181 if (stackDepth > stackMax)
182 stackMax = stackDepth;
183 if (maxLocals <= iArg) {
184 maxLocals = iArg + 1;
186 if (iArg > 255) { // Widen
189 bCodeStream[classFileOffset++] = OPC_wide;
190 } catch (IndexOutOfBoundsException e) {
191 resizeByteArray(OPC_wide);
195 bCodeStream[classFileOffset++] = OPC_aload;
196 } catch (IndexOutOfBoundsException e) {
197 resizeByteArray(OPC_aload);
199 writeUnsignedShort(iArg);
201 // Don't need to use the wide bytecode
204 bCodeStream[classFileOffset++] = OPC_aload;
205 } catch (IndexOutOfBoundsException e) {
206 resizeByteArray(OPC_aload);
210 bCodeStream[classFileOffset++] = (byte) (iArg);
211 } catch (IndexOutOfBoundsException e) {
212 resizeByteArray((byte) iArg);
216 final public void aload_0() {
219 if (stackDepth > stackMax)
220 stackMax = stackDepth;
221 if (maxLocals == 0) {
226 bCodeStream[classFileOffset++] = OPC_aload_0;
227 } catch (IndexOutOfBoundsException e) {
228 resizeByteArray(OPC_aload_0);
231 final public void aload_1() {
234 if (stackDepth > stackMax)
235 stackMax = stackDepth;
236 if (maxLocals <= 1) {
241 bCodeStream[classFileOffset++] = OPC_aload_1;
242 } catch (IndexOutOfBoundsException e) {
243 resizeByteArray(OPC_aload_1);
246 final public void aload_2() {
249 if (stackDepth > stackMax)
250 stackMax = stackDepth;
251 if (maxLocals <= 2) {
256 bCodeStream[classFileOffset++] = OPC_aload_2;
257 } catch (IndexOutOfBoundsException e) {
258 resizeByteArray(OPC_aload_2);
261 final public void aload_3() {
264 if (stackDepth > stackMax)
265 stackMax = stackDepth;
266 if (maxLocals <= 3) {
271 bCodeStream[classFileOffset++] = OPC_aload_3;
272 } catch (IndexOutOfBoundsException e) {
273 resizeByteArray(OPC_aload_3);
276 public final void anewarray(TypeBinding typeBinding) {
280 bCodeStream[classFileOffset++] = OPC_anewarray;
281 } catch (IndexOutOfBoundsException e) {
282 resizeByteArray(OPC_anewarray);
284 writeUnsignedShort(constantPool.literalIndex(typeBinding));
286 public void anewarrayJavaLangClass() {
287 // anewarray: java.lang.Class
291 bCodeStream[classFileOffset++] = OPC_anewarray;
292 } catch (IndexOutOfBoundsException e) {
293 resizeByteArray(OPC_anewarray);
295 writeUnsignedShort(constantPool.literalIndexForJavaLangClass());
297 public void anewarrayJavaLangObject() {
298 // anewarray: java.lang.Object
302 bCodeStream[classFileOffset++] = OPC_anewarray;
303 } catch (IndexOutOfBoundsException e) {
304 resizeByteArray(OPC_anewarray);
306 writeUnsignedShort(constantPool.literalIndexForJavaLangObject());
308 final public void areturn() {
311 // the stackDepth should be equal to 0
314 bCodeStream[classFileOffset++] = OPC_areturn;
315 } catch (IndexOutOfBoundsException e) {
316 resizeByteArray(OPC_areturn);
319 public void arrayAt(int typeBindingID) {
320 switch (typeBindingID) {
347 public void arrayAtPut(int elementTypeID, boolean valueRequired) {
348 switch (elementTypeID) {
391 final public void arraylength() {
395 bCodeStream[classFileOffset++] = OPC_arraylength;
396 } catch (IndexOutOfBoundsException e) {
397 resizeByteArray(OPC_arraylength);
400 final public void astore(int iArg) {
403 if (maxLocals <= iArg) {
404 maxLocals = iArg + 1;
406 if (iArg > 255) { // Widen
409 bCodeStream[classFileOffset++] = OPC_wide;
410 } catch (IndexOutOfBoundsException e) {
411 resizeByteArray(OPC_wide);
415 bCodeStream[classFileOffset++] = OPC_astore;
416 } catch (IndexOutOfBoundsException e) {
417 resizeByteArray(OPC_astore);
419 writeUnsignedShort(iArg);
423 bCodeStream[classFileOffset++] = OPC_astore;
424 } catch (IndexOutOfBoundsException e) {
425 resizeByteArray(OPC_astore);
429 bCodeStream[classFileOffset++] = (byte) iArg;
430 } catch (IndexOutOfBoundsException e) {
431 resizeByteArray((byte) iArg);
435 final public void astore_0() {
438 if (maxLocals == 0) {
443 bCodeStream[classFileOffset++] = OPC_astore_0;
444 } catch (IndexOutOfBoundsException e) {
445 resizeByteArray(OPC_astore_0);
448 final public void astore_1() {
451 if (maxLocals <= 1) {
456 bCodeStream[classFileOffset++] = OPC_astore_1;
457 } catch (IndexOutOfBoundsException e) {
458 resizeByteArray(OPC_astore_1);
461 final public void astore_2() {
464 if (maxLocals <= 2) {
469 bCodeStream[classFileOffset++] = OPC_astore_2;
470 } catch (IndexOutOfBoundsException e) {
471 resizeByteArray(OPC_astore_2);
474 final public void astore_3() {
477 if (maxLocals <= 3) {
482 bCodeStream[classFileOffset++] = OPC_astore_3;
483 } catch (IndexOutOfBoundsException e) {
484 resizeByteArray(OPC_astore_3);
487 final public void athrow() {
492 bCodeStream[classFileOffset++] = OPC_athrow;
493 } catch (IndexOutOfBoundsException e) {
494 resizeByteArray(OPC_athrow);
497 final public void baload() {
502 bCodeStream[classFileOffset++] = OPC_baload;
503 } catch (IndexOutOfBoundsException e) {
504 resizeByteArray(OPC_baload);
507 final public void bastore() {
512 bCodeStream[classFileOffset++] = OPC_bastore;
513 } catch (IndexOutOfBoundsException e) {
514 resizeByteArray(OPC_bastore);
517 final public void bipush(byte b) {
520 if (stackDepth > stackMax)
521 stackMax = stackDepth;
524 bCodeStream[classFileOffset++] = OPC_bipush;
525 } catch (IndexOutOfBoundsException e) {
526 resizeByteArray(OPC_bipush);
530 final public void caload() {
535 bCodeStream[classFileOffset++] = OPC_caload;
536 } catch (IndexOutOfBoundsException e) {
537 resizeByteArray(OPC_caload);
540 final public void castore() {
545 bCodeStream[classFileOffset++] = OPC_castore;
546 } catch (IndexOutOfBoundsException e) {
547 resizeByteArray(OPC_castore);
550 public final void checkcast(TypeBinding typeBinding) {
554 bCodeStream[classFileOffset++] = OPC_checkcast;
555 } catch (IndexOutOfBoundsException e) {
556 resizeByteArray(OPC_checkcast);
558 writeUnsignedShort(constantPool.literalIndex(typeBinding));
560 public final void checkcastJavaLangError() {
564 bCodeStream[classFileOffset++] = OPC_checkcast;
565 } catch (IndexOutOfBoundsException e) {
566 resizeByteArray(OPC_checkcast);
568 writeUnsignedShort(constantPool.literalIndexForJavaLangError());
570 final public void d2f() {
575 bCodeStream[classFileOffset++] = OPC_d2f;
576 } catch (IndexOutOfBoundsException e) {
577 resizeByteArray(OPC_d2f);
580 final public void d2i() {
585 bCodeStream[classFileOffset++] = OPC_d2i;
586 } catch (IndexOutOfBoundsException e) {
587 resizeByteArray(OPC_d2i);
590 final public void d2l() {
594 bCodeStream[classFileOffset++] = OPC_d2l;
595 } catch (IndexOutOfBoundsException e) {
596 resizeByteArray(OPC_d2l);
599 final public void dadd() {
604 bCodeStream[classFileOffset++] = OPC_dadd;
605 } catch (IndexOutOfBoundsException e) {
606 resizeByteArray(OPC_dadd);
609 final public void daload() {
613 bCodeStream[classFileOffset++] = OPC_daload;
614 } catch (IndexOutOfBoundsException e) {
615 resizeByteArray(OPC_daload);
618 final public void dastore() {
623 bCodeStream[classFileOffset++] = OPC_dastore;
624 } catch (IndexOutOfBoundsException e) {
625 resizeByteArray(OPC_dastore);
628 final public void dcmpg() {
633 bCodeStream[classFileOffset++] = OPC_dcmpg;
634 } catch (IndexOutOfBoundsException e) {
635 resizeByteArray(OPC_dcmpg);
638 final public void dcmpl() {
643 bCodeStream[classFileOffset++] = OPC_dcmpl;
644 } catch (IndexOutOfBoundsException e) {
645 resizeByteArray(OPC_dcmpl);
648 final public void dconst_0() {
651 if (stackDepth > stackMax)
652 stackMax = stackDepth;
655 bCodeStream[classFileOffset++] = OPC_dconst_0;
656 } catch (IndexOutOfBoundsException e) {
657 resizeByteArray(OPC_dconst_0);
660 final public void dconst_1() {
663 if (stackDepth > stackMax)
664 stackMax = stackDepth;
667 bCodeStream[classFileOffset++] = OPC_dconst_1;
668 } catch (IndexOutOfBoundsException e) {
669 resizeByteArray(OPC_dconst_1);
672 final public void ddiv() {
677 bCodeStream[classFileOffset++] = OPC_ddiv;
678 } catch (IndexOutOfBoundsException e) {
679 resizeByteArray(OPC_ddiv);
682 public void decrStackSize(int offset) {
683 stackDepth -= offset;
685 final public void dload(int iArg) {
688 if (stackDepth > stackMax)
689 stackMax = stackDepth;
690 if (maxLocals < iArg + 2) {
691 maxLocals = iArg + 2; // + 2 because it is a double
693 if (iArg > 255) { // Widen
696 bCodeStream[classFileOffset++] = OPC_wide;
697 } catch (IndexOutOfBoundsException e) {
698 resizeByteArray(OPC_wide);
702 bCodeStream[classFileOffset++] = OPC_dload;
703 } catch (IndexOutOfBoundsException e) {
704 resizeByteArray(OPC_dload);
706 writeUnsignedShort(iArg);
708 // Don't need to use the wide bytecode
711 bCodeStream[classFileOffset++] = OPC_dload;
712 } catch (IndexOutOfBoundsException e) {
713 resizeByteArray(OPC_dload);
717 bCodeStream[classFileOffset++] = (byte) iArg;
718 } catch (IndexOutOfBoundsException e) {
719 resizeByteArray((byte) iArg);
723 final public void dload_0() {
726 if (stackDepth > stackMax)
727 stackMax = stackDepth;
733 bCodeStream[classFileOffset++] = OPC_dload_0;
734 } catch (IndexOutOfBoundsException e) {
735 resizeByteArray(OPC_dload_0);
738 final public void dload_1() {
741 if (stackDepth > stackMax)
742 stackMax = stackDepth;
748 bCodeStream[classFileOffset++] = OPC_dload_1;
749 } catch (IndexOutOfBoundsException e) {
750 resizeByteArray(OPC_dload_1);
753 final public void dload_2() {
756 if (stackDepth > stackMax)
757 stackMax = stackDepth;
763 bCodeStream[classFileOffset++] = OPC_dload_2;
764 } catch (IndexOutOfBoundsException e) {
765 resizeByteArray(OPC_dload_2);
768 final public void dload_3() {
771 if (stackDepth > stackMax)
772 stackMax = stackDepth;
778 bCodeStream[classFileOffset++] = OPC_dload_3;
779 } catch (IndexOutOfBoundsException e) {
780 resizeByteArray(OPC_dload_3);
783 final public void dmul() {
788 bCodeStream[classFileOffset++] = OPC_dmul;
789 } catch (IndexOutOfBoundsException e) {
790 resizeByteArray(OPC_dmul);
793 final public void dneg() {
797 bCodeStream[classFileOffset++] = OPC_dneg;
798 } catch (IndexOutOfBoundsException e) {
799 resizeByteArray(OPC_dneg);
802 final public void drem() {
807 bCodeStream[classFileOffset++] = OPC_drem;
808 } catch (IndexOutOfBoundsException e) {
809 resizeByteArray(OPC_drem);
812 final public void dreturn() {
815 // the stackDepth should be equal to 0
818 bCodeStream[classFileOffset++] = OPC_dreturn;
819 } catch (IndexOutOfBoundsException e) {
820 resizeByteArray(OPC_dreturn);
823 final public void dstore(int iArg) {
826 if (maxLocals <= iArg + 1) {
827 maxLocals = iArg + 2;
829 if (iArg > 255) { // Widen
832 bCodeStream[classFileOffset++] = OPC_wide;
833 } catch (IndexOutOfBoundsException e) {
834 resizeByteArray(OPC_wide);
838 bCodeStream[classFileOffset++] = OPC_dstore;
839 } catch (IndexOutOfBoundsException e) {
840 resizeByteArray(OPC_dstore);
842 writeUnsignedShort(iArg);
846 bCodeStream[classFileOffset++] = OPC_dstore;
847 } catch (IndexOutOfBoundsException e) {
848 resizeByteArray(OPC_dstore);
852 bCodeStream[classFileOffset++] = (byte) iArg;
853 } catch (IndexOutOfBoundsException e) {
854 resizeByteArray((byte) iArg);
858 final public void dstore_0() {
866 bCodeStream[classFileOffset++] = OPC_dstore_0;
867 } catch (IndexOutOfBoundsException e) {
868 resizeByteArray(OPC_dstore_0);
871 final public void dstore_1() {
879 bCodeStream[classFileOffset++] = OPC_dstore_1;
880 } catch (IndexOutOfBoundsException e) {
881 resizeByteArray(OPC_dstore_1);
884 final public void dstore_2() {
892 bCodeStream[classFileOffset++] = OPC_dstore_2;
893 } catch (IndexOutOfBoundsException e) {
894 resizeByteArray(OPC_dstore_2);
897 final public void dstore_3() {
905 bCodeStream[classFileOffset++] = OPC_dstore_3;
906 } catch (IndexOutOfBoundsException e) {
907 resizeByteArray(OPC_dstore_3);
910 final public void dsub() {
915 bCodeStream[classFileOffset++] = OPC_dsub;
916 } catch (IndexOutOfBoundsException e) {
917 resizeByteArray(OPC_dsub);
920 final public void dup() {
923 if (stackDepth > stackMax)
924 stackMax = stackDepth;
927 bCodeStream[classFileOffset++] = OPC_dup;
928 } catch (IndexOutOfBoundsException e) {
929 resizeByteArray(OPC_dup);
932 final public void dup_x1() {
935 if (stackDepth > stackMax)
936 stackMax = stackDepth;
939 bCodeStream[classFileOffset++] = OPC_dup_x1;
940 } catch (IndexOutOfBoundsException e) {
941 resizeByteArray(OPC_dup_x1);
944 final public void dup_x2() {
947 if (stackDepth > stackMax)
948 stackMax = stackDepth;
951 bCodeStream[classFileOffset++] = OPC_dup_x2;
952 } catch (IndexOutOfBoundsException e) {
953 resizeByteArray(OPC_dup_x2);
956 final public void dup2() {
959 if (stackDepth > stackMax)
960 stackMax = stackDepth;
963 bCodeStream[classFileOffset++] = OPC_dup2;
964 } catch (IndexOutOfBoundsException e) {
965 resizeByteArray(OPC_dup2);
968 final public void dup2_x1() {
971 if (stackDepth > stackMax)
972 stackMax = stackDepth;
975 bCodeStream[classFileOffset++] = OPC_dup2_x1;
976 } catch (IndexOutOfBoundsException e) {
977 resizeByteArray(OPC_dup2_x1);
980 final public void dup2_x2() {
983 if (stackDepth > stackMax)
984 stackMax = stackDepth;
987 bCodeStream[classFileOffset++] = OPC_dup2_x2;
988 } catch (IndexOutOfBoundsException e) {
989 resizeByteArray(OPC_dup2_x2);
992 public void exitUserScope(BlockScope blockScope) {
993 // mark all the scope's locals as loosing their definite assignment
995 if (!generateLocalVariableTableAttributes)
997 for (int i = 0; i < visibleLocalsCount; i++) {
998 LocalVariableBinding visibleLocal = visibleLocals[i];
999 if ((visibleLocal != null) && (visibleLocal.declaringScope == blockScope)) {
1000 // there maybe some some preserved locals never initialized
1001 if (visibleLocal.initializationCount > 0) {
1002 visibleLocals[i].recordInitializationEndPC(position);
1004 visibleLocals[i] = null; // this variable is no longer visible afterwards
1008 final public void f2d() {
1011 if (stackDepth > stackMax)
1012 stackMax = stackDepth;
1015 bCodeStream[classFileOffset++] = OPC_f2d;
1016 } catch (IndexOutOfBoundsException e) {
1017 resizeByteArray(OPC_f2d);
1020 final public void f2i() {
1024 bCodeStream[classFileOffset++] = OPC_f2i;
1025 } catch (IndexOutOfBoundsException e) {
1026 resizeByteArray(OPC_f2i);
1029 final public void f2l() {
1032 if (stackDepth > stackMax)
1033 stackMax = stackDepth;
1036 bCodeStream[classFileOffset++] = OPC_f2l;
1037 } catch (IndexOutOfBoundsException e) {
1038 resizeByteArray(OPC_f2l);
1041 final public void fadd() {
1046 bCodeStream[classFileOffset++] = OPC_fadd;
1047 } catch (IndexOutOfBoundsException e) {
1048 resizeByteArray(OPC_fadd);
1051 final public void faload() {
1056 bCodeStream[classFileOffset++] = OPC_faload;
1057 } catch (IndexOutOfBoundsException e) {
1058 resizeByteArray(OPC_faload);
1061 final public void fastore() {
1066 bCodeStream[classFileOffset++] = OPC_fastore;
1067 } catch (IndexOutOfBoundsException e) {
1068 resizeByteArray(OPC_fastore);
1071 final public void fcmpg() {
1076 bCodeStream[classFileOffset++] = OPC_fcmpg;
1077 } catch (IndexOutOfBoundsException e) {
1078 resizeByteArray(OPC_fcmpg);
1081 final public void fcmpl() {
1086 bCodeStream[classFileOffset++] = OPC_fcmpl;
1087 } catch (IndexOutOfBoundsException e) {
1088 resizeByteArray(OPC_fcmpl);
1091 final public void fconst_0() {
1094 if (stackDepth > stackMax)
1095 stackMax = stackDepth;
1098 bCodeStream[classFileOffset++] = OPC_fconst_0;
1099 } catch (IndexOutOfBoundsException e) {
1100 resizeByteArray(OPC_fconst_0);
1103 final public void fconst_1() {
1106 if (stackDepth > stackMax)
1107 stackMax = stackDepth;
1110 bCodeStream[classFileOffset++] = OPC_fconst_1;
1111 } catch (IndexOutOfBoundsException e) {
1112 resizeByteArray(OPC_fconst_1);
1115 final public void fconst_2() {
1118 if (stackDepth > stackMax)
1119 stackMax = stackDepth;
1122 bCodeStream[classFileOffset++] = OPC_fconst_2;
1123 } catch (IndexOutOfBoundsException e) {
1124 resizeByteArray(OPC_fconst_2);
1127 final public void fdiv() {
1132 bCodeStream[classFileOffset++] = OPC_fdiv;
1133 } catch (IndexOutOfBoundsException e) {
1134 resizeByteArray(OPC_fdiv);
1137 final public void fload(int iArg) {
1140 if (maxLocals <= iArg) {
1141 maxLocals = iArg + 1;
1143 if (stackDepth > stackMax)
1144 stackMax = stackDepth;
1145 if (iArg > 255) { // Widen
1148 bCodeStream[classFileOffset++] = OPC_wide;
1149 } catch (IndexOutOfBoundsException e) {
1150 resizeByteArray(OPC_wide);
1154 bCodeStream[classFileOffset++] = OPC_fload;
1155 } catch (IndexOutOfBoundsException e) {
1156 resizeByteArray(OPC_fload);
1158 writeUnsignedShort(iArg);
1162 bCodeStream[classFileOffset++] = OPC_fload;
1163 } catch (IndexOutOfBoundsException e) {
1164 resizeByteArray(OPC_fload);
1168 bCodeStream[classFileOffset++] = (byte) iArg;
1169 } catch (IndexOutOfBoundsException e) {
1170 resizeByteArray((byte) iArg);
1174 final public void fload_0() {
1177 if (maxLocals == 0) {
1180 if (stackDepth > stackMax)
1181 stackMax = stackDepth;
1184 bCodeStream[classFileOffset++] = OPC_fload_0;
1185 } catch (IndexOutOfBoundsException e) {
1186 resizeByteArray(OPC_fload_0);
1189 final public void fload_1() {
1192 if (maxLocals <= 1) {
1195 if (stackDepth > stackMax)
1196 stackMax = stackDepth;
1199 bCodeStream[classFileOffset++] = OPC_fload_1;
1200 } catch (IndexOutOfBoundsException e) {
1201 resizeByteArray(OPC_fload_1);
1204 final public void fload_2() {
1207 if (maxLocals <= 2) {
1210 if (stackDepth > stackMax)
1211 stackMax = stackDepth;
1214 bCodeStream[classFileOffset++] = OPC_fload_2;
1215 } catch (IndexOutOfBoundsException e) {
1216 resizeByteArray(OPC_fload_2);
1219 final public void fload_3() {
1222 if (maxLocals <= 3) {
1225 if (stackDepth > stackMax)
1226 stackMax = stackDepth;
1229 bCodeStream[classFileOffset++] = OPC_fload_3;
1230 } catch (IndexOutOfBoundsException e) {
1231 resizeByteArray(OPC_fload_3);
1234 final public void fmul() {
1239 bCodeStream[classFileOffset++] = OPC_fmul;
1240 } catch (IndexOutOfBoundsException e) {
1241 resizeByteArray(OPC_fmul);
1244 final public void fneg() {
1248 bCodeStream[classFileOffset++] = OPC_fneg;
1249 } catch (IndexOutOfBoundsException e) {
1250 resizeByteArray(OPC_fneg);
1253 final public void frem() {
1258 bCodeStream[classFileOffset++] = OPC_frem;
1259 } catch (IndexOutOfBoundsException e) {
1260 resizeByteArray(OPC_frem);
1263 final public void freturn() {
1266 // the stackDepth should be equal to 0
1269 bCodeStream[classFileOffset++] = OPC_freturn;
1270 } catch (IndexOutOfBoundsException e) {
1271 resizeByteArray(OPC_freturn);
1274 final public void fstore(int iArg) {
1277 if (maxLocals <= iArg) {
1278 maxLocals = iArg + 1;
1280 if (iArg > 255) { // Widen
1283 bCodeStream[classFileOffset++] = OPC_wide;
1284 } catch (IndexOutOfBoundsException e) {
1285 resizeByteArray(OPC_wide);
1289 bCodeStream[classFileOffset++] = OPC_fstore;
1290 } catch (IndexOutOfBoundsException e) {
1291 resizeByteArray(OPC_fstore);
1293 writeUnsignedShort(iArg);
1297 bCodeStream[classFileOffset++] = OPC_fstore;
1298 } catch (IndexOutOfBoundsException e) {
1299 resizeByteArray(OPC_fstore);
1303 bCodeStream[classFileOffset++] = (byte) iArg;
1304 } catch (IndexOutOfBoundsException e) {
1305 resizeByteArray((byte) iArg);
1309 final public void fstore_0() {
1312 if (maxLocals == 0) {
1317 bCodeStream[classFileOffset++] = OPC_fstore_0;
1318 } catch (IndexOutOfBoundsException e) {
1319 resizeByteArray(OPC_fstore_0);
1322 final public void fstore_1() {
1325 if (maxLocals <= 1) {
1330 bCodeStream[classFileOffset++] = OPC_fstore_1;
1331 } catch (IndexOutOfBoundsException e) {
1332 resizeByteArray(OPC_fstore_1);
1335 final public void fstore_2() {
1338 if (maxLocals <= 2) {
1343 bCodeStream[classFileOffset++] = OPC_fstore_2;
1344 } catch (IndexOutOfBoundsException e) {
1345 resizeByteArray(OPC_fstore_2);
1348 final public void fstore_3() {
1351 if (maxLocals <= 3) {
1356 bCodeStream[classFileOffset++] = OPC_fstore_3;
1357 } catch (IndexOutOfBoundsException e) {
1358 resizeByteArray(OPC_fstore_3);
1361 final public void fsub() {
1366 bCodeStream[classFileOffset++] = OPC_fsub;
1367 } catch (IndexOutOfBoundsException e) {
1368 resizeByteArray(OPC_fsub);
1372 * Macro for building a class descriptor object
1374 public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
1376 ExceptionLabel anyExceptionHandler;
1378 if (accessedType.isBaseType() && accessedType != NullBinding) {
1379 this.getTYPE(accessedType.id);
1382 endLabel = new Label(this);
1384 if (syntheticFieldBinding != null) { // non interface case
1385 this.getstatic(syntheticFieldBinding);
1387 this.ifnonnull(endLabel);
1391 /* Macro for building a class descriptor object... using or not a field cache to store it into...
1392 this sequence is responsible for building the actual class descriptor.
1394 If the fieldCache is set, then it is supposed to be the body of a synthetic access method
1395 factoring the actual descriptor creation out of the invocation site (saving space).
1396 If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
1397 we have no way to get a hand on the field cache to do better. */
1399 // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
1401 anyExceptionHandler = new ExceptionLabel(this, TypeBinding.NullBinding /* represents ClassNotFoundException*/
1403 this.ldc(accessedType == TypeBinding.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
1404 this.invokeClassForName();
1406 /* We need to protect the runtime code from binary inconsistencies
1407 in case the accessedType is missing, the ClassNotFoundException has to be converted
1408 into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
1409 anyExceptionHandler.placeEnd();
1411 if (syntheticFieldBinding != null) { // non interface case
1413 this.putstatic(syntheticFieldBinding);
1415 this.goto_(endLabel);
1417 // Generate the body of the exception handler
1418 saveStackSize = stackDepth;
1420 /* ClassNotFoundException on stack -- the class literal could be doing more things
1421 on the stack, which means that the stack may not be empty at this point in the
1422 above code gen. So we save its state and restart it from 1. */
1424 anyExceptionHandler.place();
1426 // Transform the current exception, and repush and throw a
1427 // NoClassDefFoundError(ClassNotFound.getMessage())
1429 this.newNoClassDefFoundError();
1433 // Retrieve the message from the old exception
1434 this.invokeThrowableGetMessage();
1436 // Send the constructor taking a message string as an argument
1437 this.invokeNoClassDefFoundErrorStringConstructor();
1440 stackDepth = saveStackSize;
1443 * This method returns the exception handler to be able to generate the exception handler
1446 final public int[] generateCodeAttributeForProblemMethod(String errorName, String problemMessage) {
1450 * throw ((Error) (Class.forName(errorName).getConstructor(new Class[] {Class.forName("java.lang.String")})).newInstance(new Object[] {problemMessage}));
1451 * } catch (Exception e) {
1452 * throw (NullPointerException) null;
1455 int endPC, handlerPC;
1457 invokeClassForName();
1459 anewarrayJavaLangClass();
1462 ldc("java.lang.String"); //$NON-NLS-1$
1463 invokeClassForName();
1465 invokeConstructorGetConstructor();
1467 anewarrayJavaLangObject();
1470 ldc(problemMessage);
1472 invokeObjectNewInstance();
1473 checkcastJavaLangError();
1475 endPC = handlerPC = position;
1480 return new int[] { 0, endPC, handlerPC };
1482 public void generateConstant(Constant constant, int implicitConversionCode) {
1483 int targetTypeID = implicitConversionCode >> 4;
1484 switch (targetTypeID) {
1486 generateInlinedValue(constant.booleanValue());
1489 generateInlinedValue(constant.charValue());
1492 generateInlinedValue(constant.byteValue());
1495 generateInlinedValue(constant.shortValue());
1498 generateInlinedValue(constant.intValue());
1501 generateInlinedValue(constant.longValue());
1504 generateInlinedValue(constant.floatValue());
1507 generateInlinedValue(constant.doubleValue());
1510 this.ldc(constant.stringValue());
1512 default : //reference object (constant can be from T_null or T_String)
1513 if (constant.typeID() == T_String)
1514 ldc(constant.stringValue());
1520 * @param implicitConversionCode int
1522 public void generateImplicitConversion(int implicitConversionCode) {
1523 switch (implicitConversionCode) {
1621 public void generateInlinedValue(byte inlinedValue) {
1622 switch (inlinedValue) {
1645 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1646 this.bipush((byte) inlinedValue);
1651 public void generateInlinedValue(char inlinedValue) {
1652 switch (inlinedValue) {
1672 if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
1673 this.bipush((byte) inlinedValue);
1676 if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
1677 this.sipush(inlinedValue);
1680 this.ldc(inlinedValue);
1683 public void generateInlinedValue(double inlinedValue) {
1684 if (inlinedValue == 0.0) {
1685 if (Double.doubleToLongBits(inlinedValue) != 0L)
1686 this.ldc2_w(inlinedValue);
1691 if (inlinedValue == 1.0) {
1695 this.ldc2_w(inlinedValue);
1697 public void generateInlinedValue(float inlinedValue) {
1698 if (inlinedValue == 0.0f) {
1699 if (Float.floatToIntBits(inlinedValue) != 0)
1700 this.ldc(inlinedValue);
1705 if (inlinedValue == 1.0f) {
1709 if (inlinedValue == 2.0f) {
1713 this.ldc(inlinedValue);
1715 public void generateInlinedValue(int inlinedValue) {
1716 switch (inlinedValue) {
1739 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1740 this.bipush((byte) inlinedValue);
1743 if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
1744 this.sipush(inlinedValue);
1747 this.ldc(inlinedValue);
1750 public void generateInlinedValue(long inlinedValue) {
1751 if (inlinedValue == 0) {
1755 if (inlinedValue == 1) {
1759 this.ldc2_w(inlinedValue);
1761 public void generateInlinedValue(short inlinedValue) {
1762 switch (inlinedValue) {
1785 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1786 this.bipush((byte) inlinedValue);
1789 this.sipush(inlinedValue);
1792 public void generateInlinedValue(boolean inlinedValue) {
1798 public void generateOuterAccess(Object[] mappingSequence, AstNode invocationSite, Scope scope) {
1799 if (mappingSequence == null)
1801 if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
1802 if (scope.methodScope().isConstructorCall) {
1803 scope.problemReporter().errorThisSuperInStatic(invocationSite);
1808 if (mappingSequence[0] instanceof FieldBinding) {
1809 FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
1810 if (scope.methodScope().isConstructorCall) {
1811 scope.problemReporter().errorThisSuperInStatic(invocationSite);
1814 this.getfield(fieldBinding);
1816 load((LocalVariableBinding) mappingSequence[0]);
1818 for (int i = 1, length = mappingSequence.length; i < length; i++) {
1819 if (mappingSequence[i] instanceof FieldBinding) {
1820 FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
1821 this.getfield(fieldBinding);
1823 this.invokestatic((MethodBinding) mappingSequence[i]);
1828 * The equivalent code performs a string conversion:
1830 * @param oper1 org.eclipse.jdt.internal.compiler.lookup.BlockScope
1831 * @param oper1 org.eclipse.jdt.internal.compiler.ast.Expression
1832 * @param oper2 org.eclipse.jdt.internal.compiler.ast.Expression
1834 public void generateStringAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
1836 if (oper1 == null) {
1837 /* Operand is already on the stack, and maybe nil:
1838 note type1 is always to java.lang.String here.*/
1839 this.newStringBuffer();
1842 // If argument is reference type, need to transform it
1843 // into a string (handles null case)
1844 this.invokeStringValueOf(T_Object);
1845 this.invokeStringBufferStringConstructor();
1848 oper1.generateOptimizedStringBufferCreation(blockScope, this, oper1.implicitConversion & 0xF);
1849 this.recordPositionsFrom(pc, oper1.sourceStart);
1852 oper2.generateOptimizedStringBuffer(blockScope, this, oper2.implicitConversion & 0xF);
1853 this.recordPositionsFrom(pc, oper2.sourceStart);
1854 this.invokeStringBufferToString();
1857 * Code responsible to generate the suitable code to supply values for the synthetic arguments of
1858 * a constructor invocation of a nested type.
1860 public void generateSyntheticArgumentValues(
1861 BlockScope currentScope,
1862 ReferenceBinding targetType,
1863 Expression enclosingInstance,
1864 AstNode invocationSite) {
1866 // perform some emulation work in case there is some and we are inside a local type only
1867 ReferenceBinding[] syntheticArgumentTypes;
1869 // generate the enclosing instance first
1870 if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
1872 ReferenceBinding targetEnclosingType =
1873 targetType.isAnonymousType()
1874 ? targetType.superclass().enclosingType() // supplying enclosing instance for the anonymous type's superclass
1875 : targetType.enclosingType();
1877 for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
1878 ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
1879 if (enclosingInstance != null && i == 0) {
1880 if (syntheticArgType != targetEnclosingType) {
1881 currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, targetType);
1883 //if (currentScope.environment().options.complianceLevel >= CompilerOptions.JDK1_4){
1884 enclosingInstance.generateCode(currentScope, this, true);
1885 if (syntheticArgType == targetEnclosingType) {
1888 this.invokeObjectGetClass(); // causes null check for all explicit enclosing instances
1891 // enclosingInstance.generateCode(currentScope, this, syntheticArgType == targetEnclosingType);
1894 Object[] emulationPath = currentScope.getCompatibleEmulationPath(syntheticArgType);
1895 if (emulationPath == null) {
1896 currentScope.problemReporter().missingEnclosingInstanceSpecification(syntheticArgType, invocationSite);
1898 this.generateOuterAccess(emulationPath, invocationSite, currentScope);
1902 } else { // we may still have an enclosing instance to consider
1903 if (enclosingInstance != null) {
1904 currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, targetType);
1905 //if (currentScope.environment().options.complianceLevel >= CompilerOptions.JDK1_4){
1906 enclosingInstance.generateCode(currentScope, this, true);
1907 this.invokeObjectGetClass(); // causes null check for all explicit enclosing instances
1910 // enclosingInstance.generateCode(currentScope, this, false); // do not want the value
1914 // generate the synthetic outer arguments then
1915 SyntheticArgumentBinding syntheticArguments[];
1916 if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
1917 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
1918 VariableBinding[] emulationPath = currentScope.getEmulationPath(syntheticArguments[i].actualOuterLocalVariable);
1919 if (emulationPath == null) {
1920 // could not emulate a path to a given outer local variable (internal error)
1921 currentScope.problemReporter().needImplementation();
1923 this.generateOuterAccess(emulationPath, invocationSite, currentScope);
1929 * @param parameters org.eclipse.jdt.internal.compiler.lookup.TypeBinding[]
1930 * @param constructorBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
1932 public void generateSyntheticBodyForConstructorAccess(SyntheticAccessMethodBinding accessBinding) {
1934 initializeMaxLocals(accessBinding);
1936 MethodBinding constructorBinding = accessBinding.targetMethod;
1937 TypeBinding[] parameters = constructorBinding.parameters;
1938 int length = parameters.length;
1939 int resolvedPosition = 1;
1941 if (constructorBinding.declaringClass.isNestedType()) {
1942 NestedTypeBinding nestedType = (NestedTypeBinding) constructorBinding.declaringClass;
1943 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
1944 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1946 load((type = syntheticArguments[i].type), resolvedPosition);
1947 if ((type == DoubleBinding) || (type == LongBinding))
1948 resolvedPosition += 2;
1952 syntheticArguments = nestedType.syntheticOuterLocalVariables();
1953 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1955 load((type = syntheticArguments[i].type), resolvedPosition);
1956 if ((type == DoubleBinding) || (type == LongBinding))
1957 resolvedPosition += 2;
1962 for (int i = 0; i < length; i++) {
1963 load(parameters[i], resolvedPosition);
1964 if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
1965 resolvedPosition += 2;
1969 this.invokespecial(constructorBinding);
1972 public void generateSyntheticBodyForFieldReadAccess(SyntheticAccessMethodBinding accessBinding) {
1973 initializeMaxLocals(accessBinding);
1974 FieldBinding fieldBinding = accessBinding.targetReadField;
1976 if (fieldBinding.isStatic())
1977 this.getstatic(fieldBinding);
1980 this.getfield(fieldBinding);
1982 if ((type = fieldBinding.type).isBaseType()) {
1983 if (type == IntBinding)
1985 else if (type == FloatBinding)
1987 else if (type == LongBinding)
1989 else if (type == DoubleBinding)
1996 public void generateSyntheticBodyForFieldWriteAccess(SyntheticAccessMethodBinding accessBinding) {
1997 initializeMaxLocals(accessBinding);
1998 FieldBinding fieldBinding = accessBinding.targetWriteField;
1999 if (fieldBinding.isStatic()) {
2000 load(fieldBinding.type, 0);
2001 this.putstatic(fieldBinding);
2004 load(fieldBinding.type, 1);
2005 this.putfield(fieldBinding);
2009 public void generateSyntheticBodyForMethodAccess(SyntheticAccessMethodBinding accessBinding) {
2011 initializeMaxLocals(accessBinding);
2012 MethodBinding methodBinding = accessBinding.targetMethod;
2013 TypeBinding[] parameters = methodBinding.parameters;
2014 int length = parameters.length;
2015 int resolvedPosition;
2016 if (methodBinding.isStatic())
2017 resolvedPosition = 0;
2020 resolvedPosition = 1;
2022 for (int i = 0; i < length; i++) {
2023 load(parameters[i], resolvedPosition);
2024 if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
2025 resolvedPosition += 2;
2030 if (methodBinding.isStatic())
2031 this.invokestatic(methodBinding);
2033 if (methodBinding.isConstructor()
2034 || methodBinding.isPrivate() // qualified super "X.super.foo()" targets methods from superclass
2035 || (methodBinding.declaringClass != methodDeclaration.binding.declaringClass)) {
2036 this.invokespecial(methodBinding);
2038 if (methodBinding.declaringClass.isInterface()) {
2039 this.invokeinterface(methodBinding);
2041 this.invokevirtual(methodBinding);
2045 if ((type = methodBinding.returnType).isBaseType())
2046 if (type == VoidBinding)
2048 else if (type == IntBinding)
2050 else if (type == FloatBinding)
2052 else if (type == LongBinding)
2054 else if (type == DoubleBinding)
2061 final public byte[] getContents() {
2063 System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
2066 final public void getfield(FieldBinding fieldBinding) {
2068 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
2069 if (++stackDepth > stackMax)
2070 stackMax = stackDepth;
2074 bCodeStream[classFileOffset++] = OPC_getfield;
2075 } catch (IndexOutOfBoundsException e) {
2076 resizeByteArray(OPC_getfield);
2078 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
2080 final public void getstatic(FieldBinding fieldBinding) {
2082 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long))
2086 if (stackDepth > stackMax)
2087 stackMax = stackDepth;
2090 bCodeStream[classFileOffset++] = OPC_getstatic;
2091 } catch (IndexOutOfBoundsException e) {
2092 resizeByteArray(OPC_getstatic);
2094 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
2096 public void getSystemOut() {
2098 if (++stackDepth > stackMax)
2099 stackMax = stackDepth;
2102 bCodeStream[classFileOffset++] = OPC_getstatic;
2103 } catch (IndexOutOfBoundsException e) {
2104 resizeByteArray(OPC_getstatic);
2106 writeUnsignedShort(constantPool.literalIndexForJavaLangSystemOut());
2108 public void getTYPE(int baseTypeID) {
2110 if (++stackDepth > stackMax)
2111 stackMax = stackDepth;
2114 bCodeStream[classFileOffset++] = OPC_getstatic;
2115 } catch (IndexOutOfBoundsException e) {
2116 resizeByteArray(OPC_getstatic);
2118 switch (baseTypeID) {
2119 // getstatic: java.lang.Byte.TYPE
2121 writeUnsignedShort(constantPool.literalIndexForJavaLangByteTYPE());
2123 // getstatic: java.lang.Short.TYPE
2125 writeUnsignedShort(constantPool.literalIndexForJavaLangShortTYPE());
2127 // getstatic: java.lang.Character.TYPE
2129 writeUnsignedShort(constantPool.literalIndexForJavaLangCharacterTYPE());
2131 // getstatic: java.lang.Integer.TYPE
2133 writeUnsignedShort(constantPool.literalIndexForJavaLangIntegerTYPE());
2135 // getstatic: java.lang.Long.TYPE
2137 writeUnsignedShort(constantPool.literalIndexForJavaLangLongTYPE());
2139 // getstatic: java.lang.Float.TYPE
2141 writeUnsignedShort(constantPool.literalIndexForJavaLangFloatTYPE());
2143 // getstatic: java.lang.Double.TYPE
2145 writeUnsignedShort(constantPool.literalIndexForJavaLangDoubleTYPE());
2147 // getstatic: java.lang.Boolean.TYPE
2149 writeUnsignedShort(constantPool.literalIndexForJavaLangBooleanTYPE());
2151 // getstatic: java.lang.Void.TYPE
2153 writeUnsignedShort(constantPool.literalIndexForJavaLangVoidTYPE());
2158 * We didn't call it goto, because there is a conflit with the goto keyword
2160 final public void goto_(Label lbl) {
2161 if (this.wideMode) {
2166 lbl.inlineForwardReferencesFromLabelsTargeting(position);
2168 Possible optimization for code such as:
2169 public Object foo() {
2181 The goto around the else block for the first if will
2182 be unreachable, because the thenClause of the second if
2184 See inlineForwardReferencesFromLabelsTargeting defined
2185 on the Label class for the remaining part of this
2187 if (!lbl.isBranchTarget(position)) {
2188 switch(bCodeStream[classFileOffset-1]) {
2195 bCodeStream[classFileOffset++] = OPC_goto;
2196 } catch (IndexOutOfBoundsException e) {
2197 resizeByteArray(OPC_goto);
2203 * We didn't call it goto, because there is a conflit with the goto keyword
2205 final public void internal_goto_(Label lbl) {
2207 lbl.inlineForwardReferencesFromLabelsTargeting(position);
2209 Possible optimization for code such as:
2210 public Object foo() {
2222 The goto around the else block for the first if will
2223 be unreachable, because the thenClause of the second if
2225 See inlineForwardReferencesFromLabelsTargeting defined
2226 on the Label class for the remaining part of this
2228 if (!lbl.isBranchTarget(position)) {
2229 switch(bCodeStream[classFileOffset-1]) {
2236 bCodeStream[classFileOffset++] = OPC_goto;
2237 } catch (IndexOutOfBoundsException e) {
2238 resizeByteArray(OPC_goto);
2242 final public void goto_w(Label lbl) {
2245 bCodeStream[classFileOffset++] = OPC_goto_w;
2246 } catch (IndexOutOfBoundsException e) {
2247 resizeByteArray(OPC_goto_w);
2251 final public void i2b() {
2255 bCodeStream[classFileOffset++] = OPC_i2b;
2256 } catch (IndexOutOfBoundsException e) {
2257 resizeByteArray(OPC_i2b);
2260 final public void i2c() {
2264 bCodeStream[classFileOffset++] = OPC_i2c;
2265 } catch (IndexOutOfBoundsException e) {
2266 resizeByteArray(OPC_i2c);
2269 final public void i2d() {
2272 if (stackDepth > stackMax)
2273 stackMax = stackDepth;
2276 bCodeStream[classFileOffset++] = OPC_i2d;
2277 } catch (IndexOutOfBoundsException e) {
2278 resizeByteArray(OPC_i2d);
2281 final public void i2f() {
2285 bCodeStream[classFileOffset++] = OPC_i2f;
2286 } catch (IndexOutOfBoundsException e) {
2287 resizeByteArray(OPC_i2f);
2290 final public void i2l() {
2293 if (stackDepth > stackMax)
2294 stackMax = stackDepth;
2297 bCodeStream[classFileOffset++] = OPC_i2l;
2298 } catch (IndexOutOfBoundsException e) {
2299 resizeByteArray(OPC_i2l);
2302 final public void i2s() {
2306 bCodeStream[classFileOffset++] = OPC_i2s;
2307 } catch (IndexOutOfBoundsException e) {
2308 resizeByteArray(OPC_i2s);
2311 final public void iadd() {
2316 bCodeStream[classFileOffset++] = OPC_iadd;
2317 } catch (IndexOutOfBoundsException e) {
2318 resizeByteArray(OPC_iadd);
2321 final public void iaload() {
2326 bCodeStream[classFileOffset++] = OPC_iaload;
2327 } catch (IndexOutOfBoundsException e) {
2328 resizeByteArray(OPC_iaload);
2331 final public void iand() {
2336 bCodeStream[classFileOffset++] = OPC_iand;
2337 } catch (IndexOutOfBoundsException e) {
2338 resizeByteArray(OPC_iand);
2341 final public void iastore() {
2346 bCodeStream[classFileOffset++] = OPC_iastore;
2347 } catch (IndexOutOfBoundsException e) {
2348 resizeByteArray(OPC_iastore);
2351 final public void iconst_0() {
2354 if (stackDepth > stackMax)
2355 stackMax = stackDepth;
2358 bCodeStream[classFileOffset++] = OPC_iconst_0;
2359 } catch (IndexOutOfBoundsException e) {
2360 resizeByteArray(OPC_iconst_0);
2363 final public void iconst_1() {
2366 if (stackDepth > stackMax)
2367 stackMax = stackDepth;
2370 bCodeStream[classFileOffset++] = OPC_iconst_1;
2371 } catch (IndexOutOfBoundsException e) {
2372 resizeByteArray(OPC_iconst_1);
2375 final public void iconst_2() {
2378 if (stackDepth > stackMax)
2379 stackMax = stackDepth;
2382 bCodeStream[classFileOffset++] = OPC_iconst_2;
2383 } catch (IndexOutOfBoundsException e) {
2384 resizeByteArray(OPC_iconst_2);
2387 final public void iconst_3() {
2390 if (stackDepth > stackMax)
2391 stackMax = stackDepth;
2394 bCodeStream[classFileOffset++] = OPC_iconst_3;
2395 } catch (IndexOutOfBoundsException e) {
2396 resizeByteArray(OPC_iconst_3);
2399 final public void iconst_4() {
2402 if (stackDepth > stackMax)
2403 stackMax = stackDepth;
2406 bCodeStream[classFileOffset++] = OPC_iconst_4;
2407 } catch (IndexOutOfBoundsException e) {
2408 resizeByteArray(OPC_iconst_4);
2411 final public void iconst_5() {
2414 if (stackDepth > stackMax)
2415 stackMax = stackDepth;
2418 bCodeStream[classFileOffset++] = OPC_iconst_5;
2419 } catch (IndexOutOfBoundsException e) {
2420 resizeByteArray(OPC_iconst_5);
2423 final public void iconst_m1() {
2426 if (stackDepth > stackMax)
2427 stackMax = stackDepth;
2430 bCodeStream[classFileOffset++] = OPC_iconst_m1;
2431 } catch (IndexOutOfBoundsException e) {
2432 resizeByteArray(OPC_iconst_m1);
2435 final public void idiv() {
2440 bCodeStream[classFileOffset++] = OPC_idiv;
2441 } catch (IndexOutOfBoundsException e) {
2442 resizeByteArray(OPC_idiv);
2445 final public void if_acmpeq(Label lbl) {
2448 if (this.wideMode) {
2449 generateWideConditionalBranch(OPC_if_acmpeq, lbl);
2453 bCodeStream[classFileOffset++] = OPC_if_acmpeq;
2454 } catch (IndexOutOfBoundsException e) {
2455 resizeByteArray(OPC_if_acmpeq);
2460 final public void if_acmpne(Label lbl) {
2463 if (this.wideMode) {
2464 generateWideConditionalBranch(OPC_if_acmpne, lbl);
2468 bCodeStream[classFileOffset++] = OPC_if_acmpne;
2469 } catch (IndexOutOfBoundsException e) {
2470 resizeByteArray(OPC_if_acmpne);
2475 final public void if_icmpeq(Label lbl) {
2478 if (this.wideMode) {
2479 generateWideConditionalBranch(OPC_if_icmpeq, lbl);
2483 bCodeStream[classFileOffset++] = OPC_if_icmpeq;
2484 } catch (IndexOutOfBoundsException e) {
2485 resizeByteArray(OPC_if_icmpeq);
2490 final public void if_icmpge(Label lbl) {
2493 if (this.wideMode) {
2494 generateWideConditionalBranch(OPC_if_icmpge, lbl);
2498 bCodeStream[classFileOffset++] = OPC_if_icmpge;
2499 } catch (IndexOutOfBoundsException e) {
2500 resizeByteArray(OPC_if_icmpge);
2505 final public void if_icmpgt(Label lbl) {
2508 if (this.wideMode) {
2509 generateWideConditionalBranch(OPC_if_icmpgt, lbl);
2513 bCodeStream[classFileOffset++] = OPC_if_icmpgt;
2514 } catch (IndexOutOfBoundsException e) {
2515 resizeByteArray(OPC_if_icmpgt);
2520 final public void if_icmple(Label lbl) {
2523 if (this.wideMode) {
2524 generateWideConditionalBranch(OPC_if_icmple, lbl);
2528 bCodeStream[classFileOffset++] = OPC_if_icmple;
2529 } catch (IndexOutOfBoundsException e) {
2530 resizeByteArray(OPC_if_icmple);
2535 final public void if_icmplt(Label lbl) {
2538 if (this.wideMode) {
2539 generateWideConditionalBranch(OPC_if_icmplt, lbl);
2543 bCodeStream[classFileOffset++] = OPC_if_icmplt;
2544 } catch (IndexOutOfBoundsException e) {
2545 resizeByteArray(OPC_if_icmplt);
2550 final public void if_icmpne(Label lbl) {
2553 if (this.wideMode) {
2554 generateWideConditionalBranch(OPC_if_icmpne, lbl);
2558 bCodeStream[classFileOffset++] = OPC_if_icmpne;
2559 } catch (IndexOutOfBoundsException e) {
2560 resizeByteArray(OPC_if_icmpne);
2565 final public void ifeq(Label lbl) {
2568 if (this.wideMode) {
2569 generateWideConditionalBranch(OPC_ifeq, lbl);
2573 bCodeStream[classFileOffset++] = OPC_ifeq;
2574 } catch (IndexOutOfBoundsException e) {
2575 resizeByteArray(OPC_ifeq);
2580 final public void ifge(Label lbl) {
2583 if (this.wideMode) {
2584 generateWideConditionalBranch(OPC_ifge, lbl);
2588 bCodeStream[classFileOffset++] = OPC_ifge;
2589 } catch (IndexOutOfBoundsException e) {
2590 resizeByteArray(OPC_ifge);
2595 final public void ifgt(Label lbl) {
2598 if (this.wideMode) {
2599 generateWideConditionalBranch(OPC_ifgt, lbl);
2603 bCodeStream[classFileOffset++] = OPC_ifgt;
2604 } catch (IndexOutOfBoundsException e) {
2605 resizeByteArray(OPC_ifgt);
2610 final public void ifle(Label lbl) {
2613 if (this.wideMode) {
2614 generateWideConditionalBranch(OPC_ifle, lbl);
2618 bCodeStream[classFileOffset++] = OPC_ifle;
2619 } catch (IndexOutOfBoundsException e) {
2620 resizeByteArray(OPC_ifle);
2625 final public void iflt(Label lbl) {
2628 if (this.wideMode) {
2629 generateWideConditionalBranch(OPC_iflt, lbl);
2633 bCodeStream[classFileOffset++] = OPC_iflt;
2634 } catch (IndexOutOfBoundsException e) {
2635 resizeByteArray(OPC_iflt);
2640 final public void ifne(Label lbl) {
2643 if (this.wideMode) {
2644 generateWideConditionalBranch(OPC_ifne, lbl);
2648 bCodeStream[classFileOffset++] = OPC_ifne;
2649 } catch (IndexOutOfBoundsException e) {
2650 resizeByteArray(OPC_ifne);
2655 final public void ifnonnull(Label lbl) {
2658 if (this.wideMode) {
2659 generateWideConditionalBranch(OPC_ifnonnull, lbl);
2663 bCodeStream[classFileOffset++] = OPC_ifnonnull;
2664 } catch (IndexOutOfBoundsException e) {
2665 resizeByteArray(OPC_ifnonnull);
2670 final public void ifnull(Label lbl) {
2673 if (this.wideMode) {
2674 generateWideConditionalBranch(OPC_ifnull, lbl);
2678 bCodeStream[classFileOffset++] = OPC_ifnull;
2679 } catch (IndexOutOfBoundsException e) {
2680 resizeByteArray(OPC_ifnull);
2685 final public void iinc(int index, int value) {
2687 if ((index > 255) || (value < -128 || value > 127)) { // have to widen
2690 bCodeStream[classFileOffset++] = OPC_wide;
2691 } catch (IndexOutOfBoundsException e) {
2692 resizeByteArray(OPC_wide);
2696 bCodeStream[classFileOffset++] = OPC_iinc;
2697 } catch (IndexOutOfBoundsException e) {
2698 resizeByteArray(OPC_iinc);
2700 writeUnsignedShort(index);
2701 writeSignedShort(value);
2705 bCodeStream[classFileOffset++] = OPC_iinc;
2706 } catch (IndexOutOfBoundsException e) {
2707 resizeByteArray(OPC_iinc);
2709 writeUnsignedByte(index);
2710 writeSignedByte(value);
2713 final public void iload(int iArg) {
2716 if (maxLocals <= iArg) {
2717 maxLocals = iArg + 1;
2719 if (stackDepth > stackMax)
2720 stackMax = stackDepth;
2721 if (iArg > 255) { // Widen
2724 bCodeStream[classFileOffset++] = OPC_wide;
2725 } catch (IndexOutOfBoundsException e) {
2726 resizeByteArray(OPC_wide);
2730 bCodeStream[classFileOffset++] = OPC_iload;
2731 } catch (IndexOutOfBoundsException e) {
2732 resizeByteArray(OPC_iload);
2734 writeUnsignedShort(iArg);
2738 bCodeStream[classFileOffset++] = OPC_iload;
2739 } catch (IndexOutOfBoundsException e) {
2740 resizeByteArray(OPC_iload);
2744 bCodeStream[classFileOffset++] = (byte) iArg;
2745 } catch (IndexOutOfBoundsException e) {
2746 resizeByteArray((byte) iArg);
2750 final public void iload_0() {
2753 if (maxLocals <= 0) {
2756 if (stackDepth > stackMax)
2757 stackMax = stackDepth;
2760 bCodeStream[classFileOffset++] = OPC_iload_0;
2761 } catch (IndexOutOfBoundsException e) {
2762 resizeByteArray(OPC_iload_0);
2765 final public void iload_1() {
2768 if (maxLocals <= 1) {
2771 if (stackDepth > stackMax)
2772 stackMax = stackDepth;
2775 bCodeStream[classFileOffset++] = OPC_iload_1;
2776 } catch (IndexOutOfBoundsException e) {
2777 resizeByteArray(OPC_iload_1);
2780 final public void iload_2() {
2783 if (maxLocals <= 2) {
2786 if (stackDepth > stackMax)
2787 stackMax = stackDepth;
2790 bCodeStream[classFileOffset++] = OPC_iload_2;
2791 } catch (IndexOutOfBoundsException e) {
2792 resizeByteArray(OPC_iload_2);
2795 final public void iload_3() {
2798 if (maxLocals <= 3) {
2801 if (stackDepth > stackMax)
2802 stackMax = stackDepth;
2805 bCodeStream[classFileOffset++] = OPC_iload_3;
2806 } catch (IndexOutOfBoundsException e) {
2807 resizeByteArray(OPC_iload_3);
2810 final public void imul() {
2815 bCodeStream[classFileOffset++] = OPC_imul;
2816 } catch (IndexOutOfBoundsException e) {
2817 resizeByteArray(OPC_imul);
2820 public void incrementTemp(LocalVariableBinding localBinding, int value) {
2821 if (value == (short) value) {
2822 this.iinc(localBinding.resolvedPosition, value);
2828 store(localBinding, false);
2830 public void incrStackSize(int offset) {
2831 if ((stackDepth += offset) > stackMax)
2832 stackMax = stackDepth;
2834 public int indexOfSameLineEntrySincePC(int pc, int line) {
2835 for (int index = pc, max = pcToSourceMapSize; index < max; index += 2) {
2836 if (pcToSourceMap[index + 1] == line)
2841 final public void ineg() {
2845 bCodeStream[classFileOffset++] = OPC_ineg;
2846 } catch (IndexOutOfBoundsException e) {
2847 resizeByteArray(OPC_ineg);
2850 public void init(ClassFile classFile) {
2851 this.classFile = classFile;
2852 this.constantPool = classFile.constantPool;
2853 this.bCodeStream = classFile.contents;
2854 this.classFileOffset = classFile.contentsOffset;
2855 this.startingClassFileOffset = this.classFileOffset;
2856 pcToSourceMapSize = 0;
2858 int length = visibleLocals.length;
2859 if (noVisibleLocals.length < length) {
2860 noVisibleLocals = new LocalVariableBinding[length];
2862 System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
2863 visibleLocalsCount = 0;
2865 length = locals.length;
2866 if (noLocals.length < length) {
2867 noLocals = new LocalVariableBinding[length];
2869 System.arraycopy(noLocals, 0, locals, 0, length);
2870 allLocalsCounter = 0;
2872 length = exceptionHandlers.length;
2873 if (noExceptionHandlers.length < length) {
2874 noExceptionHandlers = new ExceptionLabel[length];
2876 System.arraycopy(noExceptionHandlers, 0, exceptionHandlers, 0, length);
2877 exceptionHandlersNumber = 0;
2879 length = labels.length;
2880 if (noLabels.length < length) {
2881 noLabels = new Label[length];
2883 System.arraycopy(noLabels, 0, labels, 0, length);
2892 * @param methodDeclaration org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
2893 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
2895 public void initializeMaxLocals(MethodBinding methodBinding) {
2897 maxLocals = (methodBinding == null || methodBinding.isStatic()) ? 0 : 1;
2898 // take into account the synthetic parameters
2899 if (methodBinding != null) {
2900 if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
2901 ReferenceBinding enclosingInstanceTypes[];
2902 if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
2903 for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
2904 maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
2905 // LongBinding or DoubleBinding
2908 SyntheticArgumentBinding syntheticArguments[];
2909 if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
2910 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
2911 TypeBinding argType;
2912 if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) {
2920 TypeBinding[] arguments;
2921 if ((arguments = methodBinding.parameters) != null) {
2922 for (int i = 0, max = arguments.length; i < max; i++) {
2923 TypeBinding argType;
2924 if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) {
2934 * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
2935 * If there is an existing entry it returns -1 (no insertion required).
2936 * Otherwise it returns the index where the entry for the pc has to be inserted.
2937 * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
2942 public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
2948 // we search only on even indexes
2951 int currentPC = pcToSourceMap[m];
2952 if (pc < currentPC) {
2954 } else if (pc > currentPC) {
2960 if (pc < pcToSourceMap[m])
2965 * We didn't call it instanceof because there is a conflit with the
2966 * instanceof keyword
2968 final public void instance_of(TypeBinding typeBinding) {
2972 bCodeStream[classFileOffset++] = OPC_instanceof;
2973 } catch (IndexOutOfBoundsException e) {
2974 resizeByteArray(OPC_instanceof);
2976 writeUnsignedShort(constantPool.literalIndex(typeBinding));
2978 public void invokeClassForName() {
2979 // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
2983 bCodeStream[classFileOffset++] = OPC_invokestatic;
2984 } catch (IndexOutOfBoundsException e) {
2985 resizeByteArray(OPC_invokestatic);
2987 writeUnsignedShort(constantPool.literalIndexForJavaLangClassForName());
2990 public void invokeJavaLangClassDesiredAssertionStatus() {
2991 // invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
2996 bCodeStream[classFileOffset++] = OPC_invokevirtual;
2997 } catch (IndexOutOfBoundsException e) {
2998 resizeByteArray(OPC_invokevirtual);
3000 writeUnsignedShort(constantPool.literalIndexForJavaLangClassDesiredAssertionStatus());
3003 public void invokeConstructorGetConstructor() {
3004 // invokevirtual: java.lang.Class.getConstructor(java.lang.Class[])Ljava.lang.reflect.Constructor;
3009 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3010 } catch (IndexOutOfBoundsException e) {
3011 resizeByteArray(OPC_invokevirtual);
3013 writeUnsignedShort(constantPool.literalIndexForJavaLangClassGetConstructor());
3015 final public void invokeinterface(MethodBinding methodBinding) {
3016 // initialized to 1 to take into account this immediately
3022 bCodeStream[classFileOffset++] = OPC_invokeinterface;
3023 } catch (IndexOutOfBoundsException e) {
3024 resizeByteArray(OPC_invokeinterface);
3026 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3027 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3028 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3032 writeUnsignedByte(argCount);
3033 // Generate a 0 into the byte array. Like the array is already fill with 0, we just need to increment
3034 // the number of bytes.
3037 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3038 stackDepth += (2 - argCount);
3039 else if (id == T_void)
3040 stackDepth -= argCount;
3042 stackDepth += (1 - argCount);
3043 if (stackDepth > stackMax)
3044 stackMax = stackDepth;
3046 public void invokeJavaLangErrorConstructor() {
3047 // invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
3051 bCodeStream[classFileOffset++] = OPC_invokespecial;
3052 } catch (IndexOutOfBoundsException e) {
3053 resizeByteArray(OPC_invokespecial);
3056 writeUnsignedShort(constantPool.literalIndexForJavaLangErrorConstructor());
3058 public void invokeNoClassDefFoundErrorStringConstructor() {
3059 // invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
3063 bCodeStream[classFileOffset++] = OPC_invokespecial;
3064 } catch (IndexOutOfBoundsException e) {
3065 resizeByteArray(OPC_invokespecial);
3067 writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundErrorStringConstructor());
3070 public void invokeObjectNewInstance() {
3071 // invokevirtual: java.lang.reflect.Constructor.newInstance(java.lang.Object[])Ljava.lang.Object;
3076 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3077 } catch (IndexOutOfBoundsException e) {
3078 resizeByteArray(OPC_invokevirtual);
3080 writeUnsignedShort(constantPool.literalIndexForJavaLangReflectConstructorNewInstance());
3083 public void invokeObjectGetClass() {
3084 // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
3088 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3089 } catch (IndexOutOfBoundsException e) {
3090 resizeByteArray(OPC_invokevirtual);
3092 writeUnsignedShort(constantPool.literalIndexForJavaLangObjectGetClass());
3095 final public void invokespecial(MethodBinding methodBinding) {
3096 // initialized to 1 to take into account this immediately
3102 bCodeStream[classFileOffset++] = OPC_invokespecial;
3103 } catch (IndexOutOfBoundsException e) {
3104 resizeByteArray(OPC_invokespecial);
3106 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3107 if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
3108 // enclosing instances
3109 TypeBinding[] syntheticArgumentTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes();
3110 if (syntheticArgumentTypes != null) {
3111 for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
3112 if (((id = syntheticArgumentTypes[i].id) == T_double) || (id == T_long)) {
3119 // outer local variables
3120 SyntheticArgumentBinding[] syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables();
3121 if (syntheticArguments != null) {
3122 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
3123 if (((id = syntheticArguments[i].type.id) == T_double) || (id == T_long)) {
3131 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3132 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3136 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3137 stackDepth += (2 - argCount);
3138 else if (id == T_void)
3139 stackDepth -= argCount;
3141 stackDepth += (1 - argCount);
3142 if (stackDepth > stackMax)
3143 stackMax = stackDepth;
3145 final public void invokestatic(MethodBinding methodBinding) {
3146 // initialized to 0 to take into account that there is no this for
3153 bCodeStream[classFileOffset++] = OPC_invokestatic;
3154 } catch (IndexOutOfBoundsException e) {
3155 resizeByteArray(OPC_invokestatic);
3157 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3158 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3159 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3163 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3164 stackDepth += (2 - argCount);
3165 else if (id == T_void)
3166 stackDepth -= argCount;
3168 stackDepth += (1 - argCount);
3169 if (stackDepth > stackMax)
3170 stackMax = stackDepth;
3173 * The equivalent code performs a string conversion of the TOS
3174 * @param typeID <CODE>int</CODE>
3176 public void invokeStringBufferAppendForType(int typeID) {
3179 if (typeID == T_null)
3180 usedTypeID = T_String;
3182 usedTypeID = typeID;
3186 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3187 } catch (IndexOutOfBoundsException e) {
3188 resizeByteArray(OPC_invokevirtual);
3190 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferAppend(typeID));
3191 if ((usedTypeID == T_long) || (usedTypeID == T_double))
3197 public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
3198 // invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
3202 bCodeStream[classFileOffset++] = OPC_invokespecial;
3203 } catch (IndexOutOfBoundsException e) {
3204 resizeByteArray(OPC_invokespecial);
3206 writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionErrorConstructor(typeBindingID));
3210 public void invokeJavaLangAssertionErrorDefaultConstructor() {
3211 // invokespecial: java.lang.AssertionError.<init>()V
3215 bCodeStream[classFileOffset++] = OPC_invokespecial;
3216 } catch (IndexOutOfBoundsException e) {
3217 resizeByteArray(OPC_invokespecial);
3219 writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionErrorDefaultConstructor());
3223 public void invokeStringBufferDefaultConstructor() {
3224 // invokespecial: java.lang.StringBuffer.<init>()V
3228 bCodeStream[classFileOffset++] = OPC_invokespecial;
3229 } catch (IndexOutOfBoundsException e) {
3230 resizeByteArray(OPC_invokespecial);
3232 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferDefaultConstructor());
3235 public void invokeStringBufferStringConstructor() {
3236 // invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
3240 bCodeStream[classFileOffset++] = OPC_invokespecial;
3241 } catch (IndexOutOfBoundsException e) {
3242 resizeByteArray(OPC_invokespecial);
3244 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferConstructor());
3248 public void invokeStringBufferToString() {
3249 // invokevirtual: StringBuffer.toString()Ljava.lang.String;
3253 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3254 } catch (IndexOutOfBoundsException e) {
3255 resizeByteArray(OPC_invokevirtual);
3257 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferToString());
3259 public void invokeStringIntern() {
3260 // invokevirtual: java.lang.String.intern()
3264 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3265 } catch (IndexOutOfBoundsException e) {
3266 resizeByteArray(OPC_invokevirtual);
3268 writeUnsignedShort(constantPool.literalIndexForJavaLangStringIntern());
3270 public void invokeStringValueOf(int typeID) {
3271 // invokestatic: java.lang.String.valueOf(argumentType)
3275 bCodeStream[classFileOffset++] = OPC_invokestatic;
3276 } catch (IndexOutOfBoundsException e) {
3277 resizeByteArray(OPC_invokestatic);
3279 writeUnsignedShort(constantPool.literalIndexForJavaLangStringValueOf(typeID));
3281 public void invokeSystemExit() {
3282 // invokestatic: java.lang.System.exit(I)
3286 bCodeStream[classFileOffset++] = OPC_invokestatic;
3287 } catch (IndexOutOfBoundsException e) {
3288 resizeByteArray(OPC_invokestatic);
3290 writeUnsignedShort(constantPool.literalIndexForJavaLangSystemExitInt());
3291 stackDepth--; // int argument
3293 public void invokeThrowableGetMessage() {
3294 // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
3298 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3299 } catch (IndexOutOfBoundsException e) {
3300 resizeByteArray(OPC_invokevirtual);
3302 writeUnsignedShort(constantPool.literalIndexForJavaLangThrowableGetMessage());
3304 final public void invokevirtual(MethodBinding methodBinding) {
3305 // initialized to 1 to take into account this immediately
3311 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3312 } catch (IndexOutOfBoundsException e) {
3313 resizeByteArray(OPC_invokevirtual);
3315 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3316 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3317 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3321 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3322 stackDepth += (2 - argCount);
3323 else if (id == T_void)
3324 stackDepth -= argCount;
3326 stackDepth += (1 - argCount);
3327 if (stackDepth > stackMax)
3328 stackMax = stackDepth;
3330 final public void ior() {
3335 bCodeStream[classFileOffset++] = OPC_ior;
3336 } catch (IndexOutOfBoundsException e) {
3337 resizeByteArray(OPC_ior);
3340 final public void irem() {
3345 bCodeStream[classFileOffset++] = OPC_irem;
3346 } catch (IndexOutOfBoundsException e) {
3347 resizeByteArray(OPC_irem);
3350 final public void ireturn() {
3353 // the stackDepth should be equal to 0
3356 bCodeStream[classFileOffset++] = OPC_ireturn;
3357 } catch (IndexOutOfBoundsException e) {
3358 resizeByteArray(OPC_ireturn);
3361 public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
3362 // Dependant of UnconditionalFlowInfo.isDefinitelyAssigned(..)
3363 if (initStateIndex == -1)
3365 if (local.isArgument) {
3368 int position = local.id + maxFieldCount;
3369 MethodScope methodScope = scope.methodScope();
3371 if (position < UnconditionalFlowInfo.BitCacheSize) {
3372 return (methodScope.definiteInits[initStateIndex] & (1L << position)) != 0; // use bits
3375 long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
3376 if (extraInits == null)
3377 return false; // if vector not yet allocated, then not initialized
3379 if ((vectorIndex = (position / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
3380 return false; // if not enough room in vector, then not initialized
3381 return ((extraInits[vectorIndex]) & (1L << (position % UnconditionalFlowInfo.BitCacheSize))) != 0;
3383 final public void ishl() {
3388 bCodeStream[classFileOffset++] = OPC_ishl;
3389 } catch (IndexOutOfBoundsException e) {
3390 resizeByteArray(OPC_ishl);
3393 final public void ishr() {
3398 bCodeStream[classFileOffset++] = OPC_ishr;
3399 } catch (IndexOutOfBoundsException e) {
3400 resizeByteArray(OPC_ishr);
3403 final public void istore(int iArg) {
3406 if (maxLocals <= iArg) {
3407 maxLocals = iArg + 1;
3409 if (iArg > 255) { // Widen
3412 bCodeStream[classFileOffset++] = OPC_wide;
3413 } catch (IndexOutOfBoundsException e) {
3414 resizeByteArray(OPC_wide);
3418 bCodeStream[classFileOffset++] = OPC_istore;
3419 } catch (IndexOutOfBoundsException e) {
3420 resizeByteArray(OPC_istore);
3422 writeUnsignedShort(iArg);
3426 bCodeStream[classFileOffset++] = OPC_istore;
3427 } catch (IndexOutOfBoundsException e) {
3428 resizeByteArray(OPC_istore);
3432 bCodeStream[classFileOffset++] = (byte) iArg;
3433 } catch (IndexOutOfBoundsException e) {
3434 resizeByteArray((byte) iArg);
3438 final public void istore_0() {
3441 if (maxLocals == 0) {
3446 bCodeStream[classFileOffset++] = OPC_istore_0;
3447 } catch (IndexOutOfBoundsException e) {
3448 resizeByteArray(OPC_istore_0);
3451 final public void istore_1() {
3454 if (maxLocals <= 1) {
3459 bCodeStream[classFileOffset++] = OPC_istore_1;
3460 } catch (IndexOutOfBoundsException e) {
3461 resizeByteArray(OPC_istore_1);
3464 final public void istore_2() {
3467 if (maxLocals <= 2) {
3472 bCodeStream[classFileOffset++] = OPC_istore_2;
3473 } catch (IndexOutOfBoundsException e) {
3474 resizeByteArray(OPC_istore_2);
3477 final public void istore_3() {
3480 if (maxLocals <= 3) {
3485 bCodeStream[classFileOffset++] = OPC_istore_3;
3486 } catch (IndexOutOfBoundsException e) {
3487 resizeByteArray(OPC_istore_3);
3490 final public void isub() {
3495 bCodeStream[classFileOffset++] = OPC_isub;
3496 } catch (IndexOutOfBoundsException e) {
3497 resizeByteArray(OPC_isub);
3500 final public void iushr() {
3505 bCodeStream[classFileOffset++] = OPC_iushr;
3506 } catch (IndexOutOfBoundsException e) {
3507 resizeByteArray(OPC_iushr);
3510 final public void ixor() {
3515 bCodeStream[classFileOffset++] = OPC_ixor;
3516 } catch (IndexOutOfBoundsException e) {
3517 resizeByteArray(OPC_ixor);
3520 final public void jsr(Label lbl) {
3524 bCodeStream[classFileOffset++] = OPC_jsr;
3525 } catch (IndexOutOfBoundsException e) {
3526 resizeByteArray(OPC_jsr);
3530 final public void jsr_w(Label lbl) {
3534 bCodeStream[classFileOffset++] = OPC_jsr_w;
3535 } catch (IndexOutOfBoundsException e) {
3536 resizeByteArray(OPC_jsr_w);
3540 final public void l2d() {
3544 bCodeStream[classFileOffset++] = OPC_l2d;
3545 } catch (IndexOutOfBoundsException e) {
3546 resizeByteArray(OPC_l2d);
3549 final public void l2f() {
3554 bCodeStream[classFileOffset++] = OPC_l2f;
3555 } catch (IndexOutOfBoundsException e) {
3556 resizeByteArray(OPC_l2f);
3559 final public void l2i() {
3564 bCodeStream[classFileOffset++] = OPC_l2i;
3565 } catch (IndexOutOfBoundsException e) {
3566 resizeByteArray(OPC_l2i);
3569 final public void ladd() {
3574 bCodeStream[classFileOffset++] = OPC_ladd;
3575 } catch (IndexOutOfBoundsException e) {
3576 resizeByteArray(OPC_ladd);
3579 final public void laload() {
3583 bCodeStream[classFileOffset++] = OPC_laload;
3584 } catch (IndexOutOfBoundsException e) {
3585 resizeByteArray(OPC_laload);
3588 final public void land() {
3593 bCodeStream[classFileOffset++] = OPC_land;
3594 } catch (IndexOutOfBoundsException e) {
3595 resizeByteArray(OPC_land);
3598 final public void lastore() {
3603 bCodeStream[classFileOffset++] = OPC_lastore;
3604 } catch (IndexOutOfBoundsException e) {
3605 resizeByteArray(OPC_lastore);
3608 final public void lcmp() {
3613 bCodeStream[classFileOffset++] = OPC_lcmp;
3614 } catch (IndexOutOfBoundsException e) {
3615 resizeByteArray(OPC_lcmp);
3618 final public void lconst_0() {
3621 if (stackDepth > stackMax)
3622 stackMax = stackDepth;
3625 bCodeStream[classFileOffset++] = OPC_lconst_0;
3626 } catch (IndexOutOfBoundsException e) {
3627 resizeByteArray(OPC_lconst_0);
3630 final public void lconst_1() {
3633 if (stackDepth > stackMax)
3634 stackMax = stackDepth;
3637 bCodeStream[classFileOffset++] = OPC_lconst_1;
3638 } catch (IndexOutOfBoundsException e) {
3639 resizeByteArray(OPC_lconst_1);
3642 final public void ldc(float constant) {
3644 int index = constantPool.literalIndex(constant);
3646 if (stackDepth > stackMax)
3647 stackMax = stackDepth;
3652 bCodeStream[classFileOffset++] = OPC_ldc_w;
3653 } catch (IndexOutOfBoundsException e) {
3654 resizeByteArray(OPC_ldc_w);
3656 writeUnsignedShort(index);
3661 bCodeStream[classFileOffset++] = OPC_ldc;
3662 } catch (IndexOutOfBoundsException e) {
3663 resizeByteArray(OPC_ldc);
3665 writeUnsignedByte(index);
3668 final public void ldc(int constant) {
3670 int index = constantPool.literalIndex(constant);
3672 if (stackDepth > stackMax)
3673 stackMax = stackDepth;
3678 bCodeStream[classFileOffset++] = OPC_ldc_w;
3679 } catch (IndexOutOfBoundsException e) {
3680 resizeByteArray(OPC_ldc_w);
3682 writeUnsignedShort(index);
3687 bCodeStream[classFileOffset++] = OPC_ldc;
3688 } catch (IndexOutOfBoundsException e) {
3689 resizeByteArray(OPC_ldc);
3691 writeUnsignedByte(index);
3694 final public void ldc(String constant) {
3696 int currentConstantPoolIndex = constantPool.currentIndex;
3697 int currentConstantPoolOffset = constantPool.currentOffset;
3698 int currentCodeStreamPosition = position;
3699 int index = constantPool.literalIndexForLdc(constant.toCharArray());
3701 // the string already exists inside the constant pool
3702 // we reuse the same index
3704 if (stackDepth > stackMax)
3705 stackMax = stackDepth;
3710 bCodeStream[classFileOffset++] = OPC_ldc_w;
3711 } catch (IndexOutOfBoundsException e) {
3712 resizeByteArray(OPC_ldc_w);
3714 writeUnsignedShort(index);
3719 bCodeStream[classFileOffset++] = OPC_ldc;
3720 } catch (IndexOutOfBoundsException e) {
3721 resizeByteArray(OPC_ldc);
3723 writeUnsignedByte(index);
3726 // the string is too big to be utf8-encoded in one pass.
3727 // we have to split it into different pieces.
3728 // first we clean all side-effects due to the code above
3729 // this case is very rare, so we can afford to lose time to handle it
3730 char[] constantChars = constant.toCharArray();
3731 position = currentCodeStreamPosition;
3732 constantPool.currentIndex = currentConstantPoolIndex;
3733 constantPool.currentOffset = currentConstantPoolOffset;
3734 constantPool.stringCache.remove(constantChars);
3735 constantPool.UTF8Cache.remove(constantChars);
3738 int constantLength = constant.length();
3739 byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
3740 int utf8encodingLength = 0;
3741 while ((length < 65532) && (i < constantLength)) {
3742 char current = constantChars[i];
3743 // we resize the byte array immediately if necessary
3744 if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
3745 System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)]), 0, length);
3747 if ((current >= 0x0001) && (current <= 0x007F)) {
3748 // we only need one byte: ASCII table
3749 utf8encoding[length++] = (byte) current;
3751 if (current > 0x07FF) {
3753 utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
3754 utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
3755 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3757 // we can be 0 or between 0x0080 and 0x07FF
3758 // In that case we only need 2 bytes
3759 utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
3760 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3765 // check if all the string is encoded (PR 1PR2DWJ)
3766 // the string is too big to be encoded in one pass
3769 // write the first part
3770 char[] subChars = new char[i];
3771 System.arraycopy(constantChars, 0, subChars, 0, i);
3772 System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[length]), 0, length);
3773 index = constantPool.literalIndex(subChars, utf8encoding);
3775 if (stackDepth > stackMax)
3776 stackMax = stackDepth;
3781 bCodeStream[classFileOffset++] = OPC_ldc_w;
3782 } catch (IndexOutOfBoundsException e) {
3783 resizeByteArray(OPC_ldc_w);
3785 writeUnsignedShort(index);
3790 bCodeStream[classFileOffset++] = OPC_ldc;
3791 } catch (IndexOutOfBoundsException e) {
3792 resizeByteArray(OPC_ldc);
3794 writeUnsignedByte(index);
3796 // write the remaining part
3797 invokeStringBufferStringConstructor();
3798 while (i < constantLength) {
3800 utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
3802 while ((length < 65532) && (i < constantLength)) {
3803 char current = constantChars[i];
3804 // we resize the byte array immediately if necessary
3805 if (constantLength + 2 > (utf8encodingLength = utf8encoding.length)) {
3806 System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)]), 0, length);
3808 if ((current >= 0x0001) && (current <= 0x007F)) {
3809 // we only need one byte: ASCII table
3810 utf8encoding[length++] = (byte) current;
3812 if (current > 0x07FF) {
3814 utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
3815 utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
3816 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3818 // we can be 0 or between 0x0080 and 0x07FF
3819 // In that case we only need 2 bytes
3820 utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
3821 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
3826 // the next part is done
3827 subChars = new char[i - startIndex];
3828 System.arraycopy(constantChars, startIndex, subChars, 0, i - startIndex);
3829 System.arraycopy(utf8encoding, 0, (utf8encoding = new byte[length]), 0, length);
3830 index = constantPool.literalIndex(subChars, utf8encoding);
3832 if (stackDepth > stackMax)
3833 stackMax = stackDepth;
3838 bCodeStream[classFileOffset++] = OPC_ldc_w;
3839 } catch (IndexOutOfBoundsException e) {
3840 resizeByteArray(OPC_ldc_w);
3842 writeUnsignedShort(index);
3847 bCodeStream[classFileOffset++] = OPC_ldc;
3848 } catch (IndexOutOfBoundsException e) {
3849 resizeByteArray(OPC_ldc);
3851 writeUnsignedByte(index);
3853 // now on the stack it should be a StringBuffer and a string.
3854 invokeStringBufferAppendForType(T_String);
3856 invokeStringBufferToString();
3857 invokeStringIntern();
3860 final public void ldc2_w(double constant) {
3862 int index = constantPool.literalIndex(constant);
3864 if (stackDepth > stackMax)
3865 stackMax = stackDepth;
3866 // Generate a ldc2_w
3869 bCodeStream[classFileOffset++] = OPC_ldc2_w;
3870 } catch (IndexOutOfBoundsException e) {
3871 resizeByteArray(OPC_ldc2_w);
3873 writeUnsignedShort(index);
3875 final public void ldc2_w(long constant) {
3877 int index = constantPool.literalIndex(constant);
3879 if (stackDepth > stackMax)
3880 stackMax = stackDepth;
3881 // Generate a ldc2_w
3884 bCodeStream[classFileOffset++] = OPC_ldc2_w;
3885 } catch (IndexOutOfBoundsException e) {
3886 resizeByteArray(OPC_ldc2_w);
3888 writeUnsignedShort(index);
3890 final public void ldiv() {
3895 bCodeStream[classFileOffset++] = OPC_ldiv;
3896 } catch (IndexOutOfBoundsException e) {
3897 resizeByteArray(OPC_ldiv);
3900 final public void lload(int iArg) {
3903 if (maxLocals <= iArg + 1) {
3904 maxLocals = iArg + 2;
3906 if (stackDepth > stackMax)
3907 stackMax = stackDepth;
3908 if (iArg > 255) { // Widen
3911 bCodeStream[classFileOffset++] = OPC_wide;
3912 } catch (IndexOutOfBoundsException e) {
3913 resizeByteArray(OPC_wide);
3917 bCodeStream[classFileOffset++] = OPC_lload;
3918 } catch (IndexOutOfBoundsException e) {
3919 resizeByteArray(OPC_lload);
3921 writeUnsignedShort(iArg);
3925 bCodeStream[classFileOffset++] = OPC_lload;
3926 } catch (IndexOutOfBoundsException e) {
3927 resizeByteArray(OPC_lload);
3931 bCodeStream[classFileOffset++] = (byte) iArg;
3932 } catch (IndexOutOfBoundsException e) {
3933 resizeByteArray((byte) iArg);
3937 final public void lload_0() {
3940 if (maxLocals < 2) {
3943 if (stackDepth > stackMax)
3944 stackMax = stackDepth;
3947 bCodeStream[classFileOffset++] = OPC_lload_0;
3948 } catch (IndexOutOfBoundsException e) {
3949 resizeByteArray(OPC_lload_0);
3952 final public void lload_1() {
3955 if (maxLocals < 3) {
3958 if (stackDepth > stackMax)
3959 stackMax = stackDepth;
3962 bCodeStream[classFileOffset++] = OPC_lload_1;
3963 } catch (IndexOutOfBoundsException e) {
3964 resizeByteArray(OPC_lload_1);
3967 final public void lload_2() {
3970 if (maxLocals < 4) {
3973 if (stackDepth > stackMax)
3974 stackMax = stackDepth;
3977 bCodeStream[classFileOffset++] = OPC_lload_2;
3978 } catch (IndexOutOfBoundsException e) {
3979 resizeByteArray(OPC_lload_2);
3982 final public void lload_3() {
3985 if (maxLocals < 5) {
3988 if (stackDepth > stackMax)
3989 stackMax = stackDepth;
3992 bCodeStream[classFileOffset++] = OPC_lload_3;
3993 } catch (IndexOutOfBoundsException e) {
3994 resizeByteArray(OPC_lload_3);
3997 final public void lmul() {
4002 bCodeStream[classFileOffset++] = OPC_lmul;
4003 } catch (IndexOutOfBoundsException e) {
4004 resizeByteArray(OPC_lmul);
4007 final public void lneg() {
4011 bCodeStream[classFileOffset++] = OPC_lneg;
4012 } catch (IndexOutOfBoundsException e) {
4013 resizeByteArray(OPC_lneg);
4016 public final void load(LocalVariableBinding localBinding) {
4018 TypeBinding typeBinding = localBinding.type;
4019 int resolvedPosition = localBinding.resolvedPosition;
4020 // Using dedicated int bytecode
4021 if (typeBinding == IntBinding) {
4022 switch (resolvedPosition) {
4036 this.iload(resolvedPosition);
4040 // Using dedicated float bytecode
4041 if (typeBinding == FloatBinding) {
4042 switch (resolvedPosition) {
4056 this.fload(resolvedPosition);
4060 // Using dedicated long bytecode
4061 if (typeBinding == LongBinding) {
4062 switch (resolvedPosition) {
4076 this.lload(resolvedPosition);
4080 // Using dedicated double bytecode
4081 if (typeBinding == DoubleBinding) {
4082 switch (resolvedPosition) {
4096 this.dload(resolvedPosition);
4100 // boolean, byte, char and short are handled as int
4101 if ((typeBinding == ByteBinding)
4102 || (typeBinding == CharBinding)
4103 || (typeBinding == BooleanBinding)
4104 || (typeBinding == ShortBinding)) {
4105 switch (resolvedPosition) {
4119 this.iload(resolvedPosition);
4125 switch (resolvedPosition) {
4139 this.aload(resolvedPosition);
4142 public final void load(TypeBinding typeBinding, int resolvedPosition) {
4144 // Using dedicated int bytecode
4145 if (typeBinding == IntBinding) {
4146 switch (resolvedPosition) {
4160 this.iload(resolvedPosition);
4164 // Using dedicated float bytecode
4165 if (typeBinding == FloatBinding) {
4166 switch (resolvedPosition) {
4180 this.fload(resolvedPosition);
4184 // Using dedicated long bytecode
4185 if (typeBinding == LongBinding) {
4186 switch (resolvedPosition) {
4200 this.lload(resolvedPosition);
4204 // Using dedicated double bytecode
4205 if (typeBinding == DoubleBinding) {
4206 switch (resolvedPosition) {
4220 this.dload(resolvedPosition);
4224 // boolean, byte, char and short are handled as int
4225 if ((typeBinding == ByteBinding)
4226 || (typeBinding == CharBinding)
4227 || (typeBinding == BooleanBinding)
4228 || (typeBinding == ShortBinding)) {
4229 switch (resolvedPosition) {
4243 this.iload(resolvedPosition);
4249 switch (resolvedPosition) {
4263 this.aload(resolvedPosition);
4266 public final void loadInt(int resolvedPosition) {
4267 // Using dedicated int bytecode
4268 switch (resolvedPosition) {
4282 this.iload(resolvedPosition);
4285 public final void loadObject(int resolvedPosition) {
4286 switch (resolvedPosition) {
4300 this.aload(resolvedPosition);
4303 final public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
4306 int length = keys.length;
4308 defaultLabel.placeInstruction();
4309 for (int i = 0; i < length; i++) {
4310 casesLabel[i].placeInstruction();
4314 bCodeStream[classFileOffset++] = OPC_lookupswitch;
4315 } catch (IndexOutOfBoundsException e) {
4316 resizeByteArray(OPC_lookupswitch);
4318 for (int i = (3 - (pos % 4)); i > 0; i--) {
4319 position++; // Padding
4322 defaultLabel.branch();
4323 writeSignedWord(length);
4324 for (int i = 0; i < length; i++) {
4325 writeSignedWord(keys[sortedIndexes[i]]);
4326 casesLabel[sortedIndexes[i]].branch();
4329 final public void lor() {
4334 bCodeStream[classFileOffset++] = OPC_lor;
4335 } catch (IndexOutOfBoundsException e) {
4336 resizeByteArray(OPC_lor);
4339 final public void lrem() {
4344 bCodeStream[classFileOffset++] = OPC_lrem;
4345 } catch (IndexOutOfBoundsException e) {
4346 resizeByteArray(OPC_lrem);
4349 final public void lreturn() {
4352 // the stackDepth should be equal to 0
4355 bCodeStream[classFileOffset++] = OPC_lreturn;
4356 } catch (IndexOutOfBoundsException e) {
4357 resizeByteArray(OPC_lreturn);
4360 final public void lshl() {
4365 bCodeStream[classFileOffset++] = OPC_lshl;
4366 } catch (IndexOutOfBoundsException e) {
4367 resizeByteArray(OPC_lshl);
4370 final public void lshr() {
4375 bCodeStream[classFileOffset++] = OPC_lshr;
4376 } catch (IndexOutOfBoundsException e) {
4377 resizeByteArray(OPC_lshr);
4380 final public void lstore(int iArg) {
4383 if (maxLocals <= iArg + 1) {
4384 maxLocals = iArg + 2;
4386 if (iArg > 255) { // Widen
4389 bCodeStream[classFileOffset++] = OPC_wide;
4390 } catch (IndexOutOfBoundsException e) {
4391 resizeByteArray(OPC_wide);
4395 bCodeStream[classFileOffset++] = OPC_lstore;
4396 } catch (IndexOutOfBoundsException e) {
4397 resizeByteArray(OPC_lstore);
4399 writeUnsignedShort(iArg);
4403 bCodeStream[classFileOffset++] = OPC_lstore;
4404 } catch (IndexOutOfBoundsException e) {
4405 resizeByteArray(OPC_lstore);
4409 bCodeStream[classFileOffset++] = (byte) iArg;
4410 } catch (IndexOutOfBoundsException e) {
4411 resizeByteArray((byte) iArg);
4415 final public void lstore_0() {
4418 if (maxLocals < 2) {
4423 bCodeStream[classFileOffset++] = OPC_lstore_0;
4424 } catch (IndexOutOfBoundsException e) {
4425 resizeByteArray(OPC_lstore_0);
4428 final public void lstore_1() {
4431 if (maxLocals < 3) {
4436 bCodeStream[classFileOffset++] = OPC_lstore_1;
4437 } catch (IndexOutOfBoundsException e) {
4438 resizeByteArray(OPC_lstore_1);
4441 final public void lstore_2() {
4444 if (maxLocals < 4) {
4449 bCodeStream[classFileOffset++] = OPC_lstore_2;
4450 } catch (IndexOutOfBoundsException e) {
4451 resizeByteArray(OPC_lstore_2);
4454 final public void lstore_3() {
4457 if (maxLocals < 5) {
4462 bCodeStream[classFileOffset++] = OPC_lstore_3;
4463 } catch (IndexOutOfBoundsException e) {
4464 resizeByteArray(OPC_lstore_3);
4467 final public void lsub() {
4472 bCodeStream[classFileOffset++] = OPC_lsub;
4473 } catch (IndexOutOfBoundsException e) {
4474 resizeByteArray(OPC_lsub);
4477 final public void lushr() {
4482 bCodeStream[classFileOffset++] = OPC_lushr;
4483 } catch (IndexOutOfBoundsException e) {
4484 resizeByteArray(OPC_lushr);
4487 final public void lxor() {
4492 bCodeStream[classFileOffset++] = OPC_lxor;
4493 } catch (IndexOutOfBoundsException e) {
4494 resizeByteArray(OPC_lxor);
4497 final public void monitorenter() {
4502 bCodeStream[classFileOffset++] = OPC_monitorenter;
4503 } catch (IndexOutOfBoundsException e) {
4504 resizeByteArray(OPC_monitorenter);
4507 final public void monitorexit() {
4512 bCodeStream[classFileOffset++] = OPC_monitorexit;
4513 } catch (IndexOutOfBoundsException e) {
4514 resizeByteArray(OPC_monitorexit);
4517 final public void multianewarray(TypeBinding typeBinding, int dimensions) {
4519 stackDepth += (1 - dimensions);
4522 bCodeStream[classFileOffset++] = OPC_multianewarray;
4523 } catch (IndexOutOfBoundsException e) {
4524 resizeByteArray(OPC_multianewarray);
4526 writeUnsignedShort(constantPool.literalIndex(typeBinding));
4527 writeUnsignedByte(dimensions);
4529 public static void needImplementation() {
4532 * We didn't call it new, because there is a conflit with the new keyword
4534 final public void new_(TypeBinding typeBinding) {
4537 if (stackDepth > stackMax)
4538 stackMax = stackDepth;
4541 bCodeStream[classFileOffset++] = OPC_new;
4542 } catch (IndexOutOfBoundsException e) {
4543 resizeByteArray(OPC_new);
4545 writeUnsignedShort(constantPool.literalIndex(typeBinding));
4547 final public void newarray(int array_Type) {
4551 bCodeStream[classFileOffset++] = OPC_newarray;
4552 } catch (IndexOutOfBoundsException e) {
4553 resizeByteArray(OPC_newarray);
4555 writeUnsignedByte(array_Type);
4557 public void newArray(Scope scope, ArrayBinding arrayBinding) {
4558 TypeBinding component = arrayBinding.elementsType(scope);
4559 switch (component.id) {
4585 this.anewarray(component);
4588 public void newJavaLangError() {
4589 // new: java.lang.Error
4592 if (stackDepth > stackMax)
4593 stackMax = stackDepth;
4596 bCodeStream[classFileOffset++] = OPC_new;
4597 } catch (IndexOutOfBoundsException e) {
4598 resizeByteArray(OPC_new);
4600 writeUnsignedShort(constantPool.literalIndexForJavaLangError());
4603 public void newJavaLangAssertionError() {
4604 // new: java.lang.AssertionError
4607 if (stackDepth > stackMax)
4608 stackMax = stackDepth;
4611 bCodeStream[classFileOffset++] = OPC_new;
4612 } catch (IndexOutOfBoundsException e) {
4613 resizeByteArray(OPC_new);
4615 writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionError());
4618 public void newNoClassDefFoundError() { // new: java.lang.NoClassDefFoundError
4621 if (stackDepth > stackMax)
4622 stackMax = stackDepth;
4625 bCodeStream[classFileOffset++] = OPC_new;
4626 } catch (IndexOutOfBoundsException e) {
4627 resizeByteArray(OPC_new);
4629 writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundError());
4631 public void newStringBuffer() { // new: java.lang.StringBuffer
4634 if (stackDepth > stackMax)
4635 stackMax = stackDepth;
4638 bCodeStream[classFileOffset++] = OPC_new;
4639 } catch (IndexOutOfBoundsException e) {
4640 resizeByteArray(OPC_new);
4642 writeUnsignedShort(constantPool.literalIndexForJavaLangStringBuffer());
4644 public void newWrapperFor(int typeID) {
4647 if (stackDepth > stackMax)
4648 stackMax = stackDepth;
4651 bCodeStream[classFileOffset++] = OPC_new;
4652 } catch (IndexOutOfBoundsException e) {
4653 resizeByteArray(OPC_new);
4656 case T_int : // new: java.lang.Integer
4657 writeUnsignedShort(constantPool.literalIndexForJavaLangInteger());
4659 case T_boolean : // new: java.lang.Boolean
4660 writeUnsignedShort(constantPool.literalIndexForJavaLangBoolean());
4662 case T_byte : // new: java.lang.Byte
4663 writeUnsignedShort(constantPool.literalIndexForJavaLangByte());
4665 case T_char : // new: java.lang.Character
4666 writeUnsignedShort(constantPool.literalIndexForJavaLangCharacter());
4668 case T_float : // new: java.lang.Float
4669 writeUnsignedShort(constantPool.literalIndexForJavaLangFloat());
4671 case T_double : // new: java.lang.Double
4672 writeUnsignedShort(constantPool.literalIndexForJavaLangDouble());
4674 case T_short : // new: java.lang.Short
4675 writeUnsignedShort(constantPool.literalIndexForJavaLangShort());
4677 case T_long : // new: java.lang.Long
4678 writeUnsignedShort(constantPool.literalIndexForJavaLangLong());
4680 case T_void : // new: java.lang.Void
4681 writeUnsignedShort(constantPool.literalIndexForJavaLangVoid());
4684 final public void nop() {
4688 bCodeStream[classFileOffset++] = OPC_nop;
4689 } catch (IndexOutOfBoundsException e) {
4690 resizeByteArray(OPC_nop);
4693 final public void pop() {
4698 bCodeStream[classFileOffset++] = OPC_pop;
4699 } catch (IndexOutOfBoundsException e) {
4700 resizeByteArray(OPC_pop);
4703 final public void pop2() {
4708 bCodeStream[classFileOffset++] = OPC_pop2;
4709 } catch (IndexOutOfBoundsException e) {
4710 resizeByteArray(OPC_pop2);
4713 final public void putfield(FieldBinding fieldBinding) {
4716 if (((id = fieldBinding.type.id) == T_double) || (id == T_long))
4720 if (stackDepth > stackMax)
4721 stackMax = stackDepth;
4724 bCodeStream[classFileOffset++] = OPC_putfield;
4725 } catch (IndexOutOfBoundsException e) {
4726 resizeByteArray(OPC_putfield);
4728 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
4730 final public void putstatic(FieldBinding fieldBinding) {
4733 if (((id = fieldBinding.type.id) == T_double) || (id == T_long))
4737 if (stackDepth > stackMax)
4738 stackMax = stackDepth;
4741 bCodeStream[classFileOffset++] = OPC_putstatic;
4742 } catch (IndexOutOfBoundsException e) {
4743 resizeByteArray(OPC_putstatic);
4745 writeUnsignedShort(constantPool.literalIndex(fieldBinding));
4747 public void record(LocalVariableBinding local) {
4748 if (!generateLocalVariableTableAttributes)
4750 if (allLocalsCounter == locals.length) {
4751 // resize the collection
4752 System.arraycopy(locals, 0, (locals = new LocalVariableBinding[allLocalsCounter + LOCALS_INCREMENT]), 0, allLocalsCounter);
4754 locals[allLocalsCounter++] = local;
4755 local.initializationPCs = new int[4];
4756 local.initializationCount = 0;
4758 public void recordPositionsFrom(int startPC, int sourcePos) {
4760 /* Record positions in the table, only if nothing has
4761 * already been recorded. Since we output them on the way
4762 * up (children first for more specific info)
4763 * The pcToSourceMap table is always sorted.
4766 if (!generateLineNumberAttributes)
4771 // no code generated for this node. e.g. field without any initialization
4772 if (position == startPC)
4775 // Widening an existing entry that already has the same source positions
4776 if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
4777 // resize the array pcToSourceMap
4778 System.arraycopy(pcToSourceMap, 0, (pcToSourceMap = new int[pcToSourceMapSize << 1]), 0, pcToSourceMapSize);
4780 int newLine = ClassFile.searchLineNumber(lineSeparatorPositions, sourcePos);
4781 // lastEntryPC represents the endPC of the lastEntry.
4782 if (pcToSourceMapSize > 0) {
4783 // in this case there is already an entry in the table
4784 if (pcToSourceMap[pcToSourceMapSize - 1] != newLine) {
4785 if (startPC < lastEntryPC) {
4786 // we forgot to add an entry.
4787 // search if an existing entry exists for startPC
4788 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
4789 if (insertionIndex != -1) {
4790 // there is no existing entry starting with startPC.
4791 int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, newLine); // index for PC
4792 /* the existingEntryIndex corresponds to en entry with the same line and a PC >= startPC.
4793 in this case it is relevant to widen this entry instead of creating a new one.
4797 with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
4798 aload0 bytecode. The first entry is the one for the argument a.
4799 But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
4800 So we widen the existing entry (if there is one) or we create a new entry with the startPC.
4802 if (existingEntryIndex != -1) {
4803 // widen existing entry
4804 pcToSourceMap[existingEntryIndex] = startPC;
4806 // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
4812 pcToSourceMapSize - insertionIndex);
4813 pcToSourceMap[insertionIndex++] = startPC;
4814 pcToSourceMap[insertionIndex] = newLine;
4815 pcToSourceMapSize += 2;
4818 if (position != lastEntryPC) { // no bytecode since last entry pc
4819 pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
4820 pcToSourceMap[pcToSourceMapSize++] = newLine;
4823 // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
4824 pcToSourceMap[pcToSourceMapSize++] = startPC;
4825 pcToSourceMap[pcToSourceMapSize++] = newLine;
4828 /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
4829 we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
4831 if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
4832 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
4833 if (insertionIndex != -1) {
4834 // widen the existing entry
4835 // we have to figure out if we need to move the last entry at another location to keep a sorted table
4836 if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
4842 pcToSourceMapSize - 2 - insertionIndex);
4843 pcToSourceMap[insertionIndex++] = startPC;
4844 pcToSourceMap[insertionIndex] = newLine;
4846 pcToSourceMap[pcToSourceMapSize - 2] = startPC;
4851 lastEntryPC = position;
4853 // record the first entry
4854 pcToSourceMap[pcToSourceMapSize++] = startPC;
4855 pcToSourceMap[pcToSourceMapSize++] = newLine;
4856 lastEntryPC = position;
4860 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
4862 public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
4864 if (exceptionHandlersNumber >= (length = exceptionHandlers.length)) {
4865 // resize the exception handlers table
4866 System.arraycopy(exceptionHandlers, 0, exceptionHandlers = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
4868 // no need to resize. So just add the new exception label
4869 exceptionHandlers[exceptionHandlersNumber++] = anExceptionLabel;
4871 public final void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
4872 // given some flow info, make sure we did not loose some variables initialization
4873 // if this happens, then we must update their pc entries to reflect it in debug attributes
4874 if (!generateLocalVariableTableAttributes)
4876 /* if (initStateIndex == lastInitStateIndexWhenRemovingInits)
4879 lastInitStateIndexWhenRemovingInits = initStateIndex;
4880 if (lastInitStateIndexWhenAddingInits != initStateIndex){
4881 lastInitStateIndexWhenAddingInits = -2;// reinitialize add index
4882 // add(1)-remove(1)-add(1) -> ignore second add
4883 // add(1)-remove(2)-add(1) -> perform second add
4885 for (int i = 0; i < visibleLocalsCount; i++) {
4886 LocalVariableBinding localBinding = visibleLocals[i];
4887 if (localBinding != null) {
4888 if (initStateIndex == -1 || !isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
4889 if (localBinding.initializationCount > 0) {
4890 localBinding.recordInitializationEndPC(position);
4897 * @param methodDeclaration org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
4898 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
4900 public void reset(AbstractMethodDeclaration methodDeclaration, ClassFile classFile) {
4902 this.methodDeclaration = methodDeclaration;
4903 preserveUnusedLocals = methodDeclaration.scope.problemReporter().options.preserveAllLocalVariables;
4904 initializeMaxLocals(methodDeclaration.binding);
4907 * @param methodDeclaration org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
4908 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
4910 public void resetForProblemClinit(ClassFile classFile) {
4914 protected final void resizeByteArray() {
4915 int actualLength = bCodeStream.length;
4916 int requiredSize = actualLength + growFactor;
4917 if (classFileOffset > requiredSize) {
4918 requiredSize = classFileOffset + growFactor;
4920 System.arraycopy(bCodeStream, 0, (bCodeStream = new byte[requiredSize]), 0, actualLength);
4923 * This method is used to resize the internal byte array in
4924 * case of a ArrayOutOfBoundsException when adding the value b.
4925 * Resize and add the new byte b inside the array.
4928 protected final void resizeByteArray(byte b) {
4930 bCodeStream[classFileOffset - 1] = b;
4932 final public void ret(int index) {
4934 if (index > 255) { // Widen
4937 bCodeStream[classFileOffset++] = OPC_wide;
4938 } catch (IndexOutOfBoundsException e) {
4939 resizeByteArray(OPC_wide);
4943 bCodeStream[classFileOffset++] = OPC_ret;
4944 } catch (IndexOutOfBoundsException e) {
4945 resizeByteArray(OPC_ret);
4947 writeUnsignedShort(index);
4948 } else { // Don't Widen
4951 bCodeStream[classFileOffset++] = OPC_ret;
4952 } catch (IndexOutOfBoundsException e) {
4953 resizeByteArray(OPC_ret);
4957 bCodeStream[classFileOffset++] = (byte) index;
4958 } catch (IndexOutOfBoundsException e) {
4959 resizeByteArray((byte) index);
4963 final public void return_() {
4965 // the stackDepth should be equal to 0
4968 bCodeStream[classFileOffset++] = OPC_return;
4969 } catch (IndexOutOfBoundsException e) {
4970 resizeByteArray(OPC_return);
4973 final public void saload() {
4978 bCodeStream[classFileOffset++] = OPC_saload;
4979 } catch (IndexOutOfBoundsException e) {
4980 resizeByteArray(OPC_saload);
4983 final public void sastore() {
4988 bCodeStream[classFileOffset++] = OPC_sastore;
4989 } catch (IndexOutOfBoundsException e) {
4990 resizeByteArray(OPC_sastore);
4994 * @param operatorConstant int
4995 * @param type_ID int
4997 public void sendOperator(int operatorConstant, int type_ID) {
5004 switch (operatorConstant) {
5026 case UNSIGNED_RIGHT_SHIFT :
5041 switch (operatorConstant) {
5063 case UNSIGNED_RIGHT_SHIFT :
5078 switch (operatorConstant) {
5096 switch (operatorConstant) {
5114 final public void sipush(int s) {
5117 if (stackDepth > stackMax)
5118 stackMax = stackDepth;
5121 bCodeStream[classFileOffset++] = OPC_sipush;
5122 } catch (IndexOutOfBoundsException e) {
5123 resizeByteArray(OPC_sipush);
5125 writeSignedShort(s);
5127 public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
5132 /* Arbitrarily establishing partition element as the midpoint of
5135 mid = tab[(lo0 + hi0) / 2];
5136 // loop through the array until indices cross
5138 /* find the first element that is greater than or equal to
5139 * the partition element starting from the left Index.
5141 while ((lo < hi0) && (tab[lo] < mid))
5143 /* find an element that is smaller than or equal to
5144 * the partition element starting from the right Index.
5146 while ((hi > lo0) && (tab[hi] > mid))
5148 // if the indexes have not crossed, swap
5150 swap(tab, lo, hi, result);
5155 /* If the right index has not reached the left side of array
5156 * must now sort the left partition.
5159 sort(tab, lo0, hi, result);
5160 /* If the left index has not reached the right side of array
5161 * must now sort the right partition.
5164 sort(tab, lo, hi0, result);
5167 public final void store(LocalVariableBinding localBinding, boolean valueRequired) {
5168 TypeBinding type = localBinding.type;
5169 int position = localBinding.resolvedPosition;
5170 // Using dedicated int bytecode
5171 if ((type == IntBinding)
5172 || (type == CharBinding)
5173 || (type == ByteBinding)
5174 || (type == ShortBinding)
5175 || (type == BooleanBinding)) {
5192 this.istore(position);
5196 // Using dedicated float bytecode
5197 if (type == FloatBinding) {
5214 this.fstore(position);
5218 // Using dedicated long bytecode
5219 if (type == LongBinding) {
5236 this.lstore(position);
5240 // Using dedicated double bytecode
5241 if (type == DoubleBinding) {
5258 this.dstore(position);
5279 this.astore(position);
5282 public final void store(TypeBinding type, int position) {
5283 // Using dedicated int bytecode
5284 if ((type == IntBinding)
5285 || (type == CharBinding)
5286 || (type == ByteBinding)
5287 || (type == ShortBinding)
5288 || (type == BooleanBinding)) {
5303 this.istore(position);
5307 // Using dedicated float bytecode
5308 if (type == FloatBinding) {
5323 this.fstore(position);
5327 // Using dedicated long bytecode
5328 if (type == LongBinding) {
5343 this.lstore(position);
5347 // Using dedicated double bytecode
5348 if (type == DoubleBinding) {
5363 this.dstore(position);
5382 this.astore(position);
5385 public final void storeInt(int position) {
5400 this.istore(position);
5403 public final void storeObject(int position) {
5418 this.astore(position);
5421 final public void swap() {
5425 bCodeStream[classFileOffset++] = OPC_swap;
5426 } catch (IndexOutOfBoundsException e) {
5427 resizeByteArray(OPC_swap);
5430 private static final void swap(int a[], int i, int j, int result[]) {
5436 result[j] = result[i];
5439 final public void tableswitch(
5440 CaseLabel defaultLabel,
5444 int[] sortedIndexes,
5445 CaseLabel[] casesLabel) {
5448 int length = casesLabel.length;
5450 defaultLabel.placeInstruction();
5451 for (int i = 0; i < length; i++)
5452 casesLabel[i].placeInstruction();
5455 bCodeStream[classFileOffset++] = OPC_tableswitch;
5456 } catch (IndexOutOfBoundsException e) {
5457 resizeByteArray(OPC_tableswitch);
5459 for (int i = (3 - (pos % 4)); i > 0; i--) {
5460 position++; // Padding
5463 defaultLabel.branch();
5464 writeSignedWord(low);
5465 writeSignedWord(high);
5466 int i = low, j = low;
5467 // the index j is used to know if the index i is one of the missing entries in case of an
5468 // optimized tableswitch
5471 int key = keys[index = sortedIndexes[j - low]];
5473 casesLabel[index].branch();
5476 break; // if high is maxint, then avoids wrapping to minint.
5478 defaultLabel.branch();
5483 public String toString() {
5484 StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
5485 buffer.append(position);
5486 buffer.append(",\nstackDepth:"); //$NON-NLS-1$
5487 buffer.append(stackDepth);
5488 buffer.append(",\nmaxStack:"); //$NON-NLS-1$
5489 buffer.append(stackMax);
5490 buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
5491 buffer.append(maxLocals);
5492 buffer.append(")"); //$NON-NLS-1$
5493 return buffer.toString();
5495 public void updateLastRecordedEndPC(int pos) {
5497 /* Tune positions in the table, this is due to some
5498 * extra bytecodes being
5499 * added to some user code (jumps). */
5501 if (!generateLineNumberAttributes)
5503 pcToSourceMap[pcToSourceMapSize - 1][1] = position;
5504 // need to update the initialization endPC in case of generation of local variable attributes.
5505 updateLocalVariablesAttribute(pos);
5508 if (!generateLineNumberAttributes)
5510 // need to update the initialization endPC in case of generation of local variable attributes.
5511 updateLocalVariablesAttribute(pos);
5513 public void updateLocalVariablesAttribute(int pos) {
5514 // need to update the initialization endPC in case of generation of local variable attributes.
5515 if (generateLocalVariableTableAttributes) {
5516 for (int i = 0, max = locals.length; i < max; i++) {
5517 LocalVariableBinding local = locals[i];
5518 if ((local != null) && (local.initializationCount > 0)) {
5519 if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
5520 local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position;
5526 final public void wide() {
5530 bCodeStream[classFileOffset++] = OPC_wide;
5531 } catch (IndexOutOfBoundsException e) {
5532 resizeByteArray(OPC_wide);
5535 public final void writeByte(byte b) {
5538 bCodeStream[classFileOffset++] = b;
5539 } catch (IndexOutOfBoundsException e) {
5543 public final void writeByteAtPos(int pos, byte b) {
5545 bCodeStream[pos] = b;
5546 } catch (IndexOutOfBoundsException ex) {
5548 bCodeStream[pos] = b;
5552 * Write a unsigned 8 bits value into the byte array
5553 * @param b the signed byte
5555 public final void writeSignedByte(int b) {
5558 bCodeStream[classFileOffset++] = (byte) b;
5559 } catch (IndexOutOfBoundsException e) {
5560 resizeByteArray((byte) b);
5564 * Write a signed 16 bits value into the byte array
5565 * @param b the signed short
5567 public final void writeSignedShort(int b) {
5570 bCodeStream[classFileOffset++] = (byte) (b >> 8);
5571 } catch (IndexOutOfBoundsException e) {
5572 resizeByteArray((byte) (b >> 8));
5576 bCodeStream[classFileOffset++] = (byte) b;
5577 } catch (IndexOutOfBoundsException e) {
5578 resizeByteArray((byte) b);
5581 public final void writeSignedShort(int pos, int b) {
5582 int currentOffset = startingClassFileOffset + pos;
5584 bCodeStream[currentOffset] = (byte) (b >> 8);
5585 } catch (IndexOutOfBoundsException e) {
5587 bCodeStream[currentOffset] = (byte) (b >> 8);
5590 bCodeStream[currentOffset + 1] = (byte) b;
5591 } catch (IndexOutOfBoundsException e) {
5593 bCodeStream[currentOffset + 1] = (byte) b;
5596 public final void writeSignedWord(int value) {
5599 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
5600 } catch (IndexOutOfBoundsException e) {
5601 resizeByteArray((byte) ((value & 0xFF000000) >> 24));
5605 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
5606 } catch (IndexOutOfBoundsException e) {
5607 resizeByteArray((byte) ((value & 0xFF0000) >> 16));
5611 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
5612 } catch (IndexOutOfBoundsException e) {
5613 resizeByteArray((byte) ((value & 0xFF00) >> 8));
5617 bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
5618 } catch (IndexOutOfBoundsException e) {
5619 resizeByteArray((byte) (value & 0xFF));
5622 public final void writeSignedWord(int pos, int value) {
5623 int currentOffset = startingClassFileOffset + pos;
5625 bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
5626 } catch (IndexOutOfBoundsException e) {
5628 bCodeStream[currentOffset - 1] = (byte) ((value & 0xFF000000) >> 24);
5631 bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
5632 } catch (IndexOutOfBoundsException e) {
5634 bCodeStream[currentOffset - 1] = (byte) ((value & 0xFF0000) >> 16);
5637 bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
5638 } catch (IndexOutOfBoundsException e) {
5640 bCodeStream[currentOffset - 1] = (byte) ((value & 0xFF00) >> 8);
5643 bCodeStream[currentOffset++] = (byte) (value & 0xFF);
5644 } catch (IndexOutOfBoundsException e) {
5646 bCodeStream[currentOffset - 1] = (byte) (value & 0xFF);
5650 * Write a unsigned 8 bits value into the byte array
5651 * @param b the unsigned byte
5653 public final void writeUnsignedByte(int b) {
5656 bCodeStream[classFileOffset++] = (byte) b;
5657 } catch (IndexOutOfBoundsException e) {
5658 resizeByteArray((byte) b);
5662 * Write a unsigned 16 bits value into the byte array
5663 * @param b the unsigned short
5665 public final void writeUnsignedShort(int b) {
5668 bCodeStream[classFileOffset++] = (byte) (b >>> 8);
5669 } catch (IndexOutOfBoundsException e) {
5670 resizeByteArray((byte) (b >>> 8));
5674 bCodeStream[classFileOffset++] = (byte) b;
5675 } catch (IndexOutOfBoundsException e) {
5676 resizeByteArray((byte) b);
5680 * Write a unsigned 32 bits value into the byte array
5681 * @param value the unsigned word
5683 public final void writeUnsignedWord(int value) {
5686 bCodeStream[classFileOffset++] = (byte) (value >>> 24);
5687 } catch (IndexOutOfBoundsException e) {
5688 resizeByteArray((byte) (value >>> 24));
5692 bCodeStream[classFileOffset++] = (byte) (value >>> 16);
5693 } catch (IndexOutOfBoundsException e) {
5694 resizeByteArray((byte) (value >>> 16));
5698 bCodeStream[classFileOffset++] = (byte) (value >>> 8);
5699 } catch (IndexOutOfBoundsException e) {
5700 resizeByteArray((byte) (value >>> 8));
5704 bCodeStream[classFileOffset++] = (byte) value;
5705 } catch (IndexOutOfBoundsException e) {
5706 resizeByteArray((byte) value);
5710 public void generateWideConditionalBranch(byte opcode, Label lbl) {
5711 /* we handle the goto_w problem inside an if.... with some macro expansion
5712 * at the bytecode level
5718 * l1 gotow <l3> // l3 is a wide target
5721 Label l1 = new Label(this);
5724 bCodeStream[classFileOffset++] = opcode;
5725 } catch (IndexOutOfBoundsException e) {
5726 resizeByteArray(opcode);
5729 Label l2 = new Label(this);
5730 this.internal_goto_(l2);