1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.codegen;
13 import org.eclipse.jdt.internal.compiler.*;
15 import org.eclipse.jdt.internal.compiler.impl.*;
16 import org.eclipse.jdt.internal.compiler.ast.*;
17 import org.eclipse.jdt.internal.compiler.classfmt.*;
18 import org.eclipse.jdt.internal.compiler.flow.*;
19 import org.eclipse.jdt.internal.compiler.lookup.*;
21 public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, BaseTypes, TypeConstants, TypeIds {
23 public static final boolean DEBUG = false;
25 // It will be responsible for the following items.
26 // -> Tracking Max Stack.
28 public int stackMax; // Use Ints to keep from using extra bc when adding
29 public int stackDepth; // Use Ints to keep from using extra bc when adding
31 public static final int LABELS_INCREMENT = 5;
32 public byte[] bCodeStream;
33 public int pcToSourceMapSize;
34 public int[] pcToSourceMap = new int[24];
35 public int lastEntryPC; // last entry recorded
36 public int[] lineSeparatorPositions;
37 public int position; // So when first set can be incremented
38 public int classFileOffset;
39 public int startingClassFileOffset; // I need to keep the starting point inside the byte array
40 public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
41 public ClassFile classFile; // The current classfile it is associated to.
42 // local variable attributes output
43 public static final int LOCALS_INCREMENT = 10;
44 public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
45 static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
46 public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
47 static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
48 int visibleLocalsCount;
49 public AbstractMethodDeclaration methodDeclaration;
50 public ExceptionLabel[] exceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
51 static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
52 public int exceptionHandlersIndex;
53 public int exceptionHandlersCounter;
55 public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
56 public boolean generateLineNumberAttributes;
57 public boolean generateLocalVariableTableAttributes;
58 public boolean preserveUnusedLocals;
59 // store all the labels placed at the current position to be able to optimize
60 // a jump to the next bytecode.
61 public Label[] labels = new Label[LABELS_INCREMENT];
62 static Label[] noLabels = new Label[LABELS_INCREMENT];
63 public int countLabels;
64 public int allLocalsCounter;
65 public int maxFieldCount;
67 public boolean wideMode = false;
68 public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
70 // target level to manage different code generation between different target levels
71 private long targetLevel;
73 public CodeStream(ClassFile classFile, long targetLevel) {
74 this.targetLevel = targetLevel;
75 this.generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0;
76 this.generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0;
77 if (this.generateLineNumberAttributes) {
78 this.lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions;
81 final public void aaload() {
82 if (DEBUG) System.out.println(position + "\t\taaload"); //$NON-NLS-1$
85 if (classFileOffset >= bCodeStream.length) {
89 bCodeStream[classFileOffset++] = OPC_aaload;
91 final public void aastore() {
92 if (DEBUG) System.out.println(position + "\t\taastore"); //$NON-NLS-1$
95 if (classFileOffset >= bCodeStream.length) {
99 bCodeStream[classFileOffset++] = OPC_aastore;
101 final public void aconst_null() {
102 if (DEBUG) System.out.println(position + "\t\taconst_null"); //$NON-NLS-1$
105 if (stackDepth > stackMax) {
106 stackMax = stackDepth;
108 if (classFileOffset >= bCodeStream.length) {
112 bCodeStream[classFileOffset++] = OPC_aconst_null;
114 public final void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
115 // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
116 if (!generateLocalVariableTableAttributes)
118 /* if (initStateIndex == lastInitStateIndexWhenAddingInits)
120 lastInitStateIndexWhenAddingInits = initStateIndex;
121 if (lastInitStateIndexWhenRemovingInits != initStateIndex){
122 lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index
123 // remove(1)-add(1)-remove(1) -> ignore second remove
124 // remove(1)-add(2)-remove(1) -> perform second remove
127 */ for (int i = 0; i < visibleLocalsCount; i++) {
128 LocalVariableBinding localBinding = visibleLocals[i];
129 if (localBinding != null) {
130 // Check if the local is definitely assigned
131 if ((initStateIndex != -1) && isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
132 if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
133 /* There are two cases:
134 * 1) there is no initialization interval opened ==> add an opened interval
135 * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
136 * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
138 * initializationPCs is a collection of pairs of int:
139 * first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
142 localBinding.recordInitializationStartPC(position);
148 public void addLabel(Label aLabel) {
149 if (countLabels == labels.length)
150 System.arraycopy(labels, 0, labels = new Label[countLabels + LABELS_INCREMENT], 0, countLabels);
151 labels[countLabels++] = aLabel;
153 public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
154 if (!generateLocalVariableTableAttributes)
157 if (visibleLocalsCount >= visibleLocals.length)
158 System.arraycopy(visibleLocals, 0, visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2], 0, visibleLocalsCount);
159 visibleLocals[visibleLocalsCount++] = localBinding;
161 final public void aload(int iArg) {
162 if (DEBUG) System.out.println(position + "\t\taload:"+iArg); //$NON-NLS-1$
165 if (stackDepth > stackMax)
166 stackMax = stackDepth;
167 if (maxLocals <= iArg) {
168 maxLocals = iArg + 1;
170 if (iArg > 255) { // Widen
171 if (classFileOffset + 3 >= bCodeStream.length) {
175 bCodeStream[classFileOffset++] = OPC_wide;
176 bCodeStream[classFileOffset++] = OPC_aload;
177 writeUnsignedShort(iArg);
179 // Don't need to use the wide bytecode
180 if (classFileOffset + 1 >= bCodeStream.length) {
184 bCodeStream[classFileOffset++] = OPC_aload;
185 bCodeStream[classFileOffset++] = (byte) iArg;
188 final public void aload_0() {
189 if (DEBUG) System.out.println(position + "\t\taload_0"); //$NON-NLS-1$
192 if (stackDepth > stackMax) {
193 stackMax = stackDepth;
195 if (maxLocals == 0) {
198 if (classFileOffset >= bCodeStream.length) {
202 bCodeStream[classFileOffset++] = OPC_aload_0;
204 final public void aload_1() {
205 if (DEBUG) System.out.println(position + "\t\taload_1"); //$NON-NLS-1$
208 if (stackDepth > stackMax)
209 stackMax = stackDepth;
210 if (maxLocals <= 1) {
213 if (classFileOffset >= bCodeStream.length) {
217 bCodeStream[classFileOffset++] = OPC_aload_1;
219 final public void aload_2() {
220 if (DEBUG) System.out.println(position + "\t\taload_2"); //$NON-NLS-1$
223 if (stackDepth > stackMax)
224 stackMax = stackDepth;
225 if (maxLocals <= 2) {
228 if (classFileOffset >= bCodeStream.length) {
232 bCodeStream[classFileOffset++] = OPC_aload_2;
234 final public void aload_3() {
235 if (DEBUG) System.out.println(position + "\t\taload_3"); //$NON-NLS-1$
238 if (stackDepth > stackMax)
239 stackMax = stackDepth;
240 if (maxLocals <= 3) {
243 if (classFileOffset >= bCodeStream.length) {
247 bCodeStream[classFileOffset++] = OPC_aload_3;
249 public final void anewarray(TypeBinding typeBinding) {
250 if (DEBUG) System.out.println(position + "\t\tanewarray: " + typeBinding); //$NON-NLS-1$
252 if (classFileOffset + 2 >= bCodeStream.length) {
256 bCodeStream[classFileOffset++] = OPC_anewarray;
257 writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
259 final public void areturn() {
260 if (DEBUG) System.out.println(position + "\t\tareturn"); //$NON-NLS-1$
263 // the stackDepth should be equal to 0
264 if (classFileOffset >= bCodeStream.length) {
268 bCodeStream[classFileOffset++] = OPC_areturn;
270 public void arrayAt(int typeBindingID) {
271 switch (typeBindingID) {
298 public void arrayAtPut(int elementTypeID, boolean valueRequired) {
299 switch (elementTypeID) {
342 final public void arraylength() {
343 if (DEBUG) System.out.println(position + "\t\tarraylength"); //$NON-NLS-1$
345 if (classFileOffset >= bCodeStream.length) {
349 bCodeStream[classFileOffset++] = OPC_arraylength;
351 final public void astore(int iArg) {
352 if (DEBUG) System.out.println(position + "\t\tastore:"+iArg); //$NON-NLS-1$
355 if (maxLocals <= iArg) {
356 maxLocals = iArg + 1;
358 if (iArg > 255) { // Widen
359 if (classFileOffset + 3 >= bCodeStream.length) {
363 bCodeStream[classFileOffset++] = OPC_wide;
364 bCodeStream[classFileOffset++] = OPC_astore;
365 writeUnsignedShort(iArg);
367 if (classFileOffset + 1 >= bCodeStream.length) {
371 bCodeStream[classFileOffset++] = OPC_astore;
372 bCodeStream[classFileOffset++] = (byte) iArg;
375 final public void astore_0() {
376 if (DEBUG) System.out.println(position + "\t\tastore_0"); //$NON-NLS-1$
379 if (maxLocals == 0) {
382 if (classFileOffset >= bCodeStream.length) {
386 bCodeStream[classFileOffset++] = OPC_astore_0;
388 final public void astore_1() {
389 if (DEBUG) System.out.println(position + "\t\tastore_1"); //$NON-NLS-1$
392 if (maxLocals <= 1) {
395 if (classFileOffset >= bCodeStream.length) {
399 bCodeStream[classFileOffset++] = OPC_astore_1;
401 final public void astore_2() {
402 if (DEBUG) System.out.println(position + "\t\tastore_2"); //$NON-NLS-1$
405 if (maxLocals <= 2) {
408 if (classFileOffset >= bCodeStream.length) {
412 bCodeStream[classFileOffset++] = OPC_astore_2;
414 final public void astore_3() {
415 if (DEBUG) System.out.println(position + "\t\tastore_3"); //$NON-NLS-1$
418 if (maxLocals <= 3) {
421 if (classFileOffset >= bCodeStream.length) {
425 bCodeStream[classFileOffset++] = OPC_astore_3;
427 final public void athrow() {
428 if (DEBUG) System.out.println(position + "\t\tathrow"); //$NON-NLS-1$
431 if (classFileOffset >= bCodeStream.length) {
435 bCodeStream[classFileOffset++] = OPC_athrow;
437 final public void baload() {
438 if (DEBUG) System.out.println(position + "\t\tbaload"); //$NON-NLS-1$
441 if (classFileOffset >= bCodeStream.length) {
445 bCodeStream[classFileOffset++] = OPC_baload;
447 final public void bastore() {
448 if (DEBUG) System.out.println(position + "\t\tbastore"); //$NON-NLS-1$
451 if (classFileOffset >= bCodeStream.length) {
455 bCodeStream[classFileOffset++] = OPC_bastore;
457 final public void bipush(byte b) {
458 if (DEBUG) System.out.println(position + "\t\tbipush "+b); //$NON-NLS-1$
461 if (stackDepth > stackMax)
462 stackMax = stackDepth;
463 if (classFileOffset + 1 >= bCodeStream.length) {
467 bCodeStream[classFileOffset++] = OPC_bipush;
468 bCodeStream[classFileOffset++] = b;
470 final public void caload() {
471 if (DEBUG) System.out.println(position + "\t\tcaload"); //$NON-NLS-1$
474 if (classFileOffset >= bCodeStream.length) {
478 bCodeStream[classFileOffset++] = OPC_caload;
480 final public void castore() {
481 if (DEBUG) System.out.println(position + "\t\tcastore"); //$NON-NLS-1$
484 if (classFileOffset >= bCodeStream.length) {
488 bCodeStream[classFileOffset++] = OPC_castore;
490 public final void checkcast(TypeBinding typeBinding) {
491 if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding.debugName()); //$NON-NLS-1$
493 if (classFileOffset + 2 >= bCodeStream.length) {
497 bCodeStream[classFileOffset++] = OPC_checkcast;
498 writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
500 final public void d2f() {
501 if (DEBUG) System.out.println(position + "\t\td2f"); //$NON-NLS-1$
504 if (classFileOffset >= bCodeStream.length) {
508 bCodeStream[classFileOffset++] = OPC_d2f;
510 final public void d2i() {
511 if (DEBUG) System.out.println(position + "\t\td2i"); //$NON-NLS-1$
514 if (classFileOffset >= bCodeStream.length) {
518 bCodeStream[classFileOffset++] = OPC_d2i;
520 final public void d2l() {
521 if (DEBUG) System.out.println(position + "\t\td2l"); //$NON-NLS-1$
523 if (classFileOffset >= bCodeStream.length) {
527 bCodeStream[classFileOffset++] = OPC_d2l;
529 final public void dadd() {
530 if (DEBUG) System.out.println(position + "\t\tdadd"); //$NON-NLS-1$
533 if (classFileOffset >= bCodeStream.length) {
537 bCodeStream[classFileOffset++] = OPC_dadd;
539 final public void daload() {
540 if (DEBUG) System.out.println(position + "\t\tdaload"); //$NON-NLS-1$
542 if (classFileOffset >= bCodeStream.length) {
546 bCodeStream[classFileOffset++] = OPC_daload;
548 final public void dastore() {
549 if (DEBUG) System.out.println(position + "\t\tdastore"); //$NON-NLS-1$
552 if (classFileOffset >= bCodeStream.length) {
556 bCodeStream[classFileOffset++] = OPC_dastore;
558 final public void dcmpg() {
559 if (DEBUG) System.out.println(position + "\t\tdcmpg"); //$NON-NLS-1$
562 if (classFileOffset >= bCodeStream.length) {
566 bCodeStream[classFileOffset++] = OPC_dcmpg;
568 final public void dcmpl() {
569 if (DEBUG) System.out.println(position + "\t\tdcmpl"); //$NON-NLS-1$
572 if (classFileOffset >= bCodeStream.length) {
576 bCodeStream[classFileOffset++] = OPC_dcmpl;
578 final public void dconst_0() {
579 if (DEBUG) System.out.println(position + "\t\tdconst_0"); //$NON-NLS-1$
582 if (stackDepth > stackMax)
583 stackMax = stackDepth;
584 if (classFileOffset >= bCodeStream.length) {
588 bCodeStream[classFileOffset++] = OPC_dconst_0;
590 final public void dconst_1() {
591 if (DEBUG) System.out.println(position + "\t\tdconst_1"); //$NON-NLS-1$
594 if (stackDepth > stackMax)
595 stackMax = stackDepth;
596 if (classFileOffset >= bCodeStream.length) {
600 bCodeStream[classFileOffset++] = OPC_dconst_1;
602 final public void ddiv() {
603 if (DEBUG) System.out.println(position + "\t\tddiv"); //$NON-NLS-1$
606 if (classFileOffset >= bCodeStream.length) {
610 bCodeStream[classFileOffset++] = OPC_ddiv;
612 public void decrStackSize(int offset) {
613 stackDepth -= offset;
615 final public void dload(int iArg) {
616 if (DEBUG) System.out.println(position + "\t\tdload:"+iArg); //$NON-NLS-1$
619 if (stackDepth > stackMax)
620 stackMax = stackDepth;
621 if (maxLocals < iArg + 2) {
622 maxLocals = iArg + 2; // + 2 because it is a double
624 if (iArg > 255) { // Widen
625 if (classFileOffset + 3 >= bCodeStream.length) {
629 bCodeStream[classFileOffset++] = OPC_wide;
630 bCodeStream[classFileOffset++] = OPC_dload;
631 writeUnsignedShort(iArg);
633 // Don't need to use the wide bytecode
634 if (classFileOffset + 1 >= bCodeStream.length) {
638 bCodeStream[classFileOffset++] = OPC_dload;
639 bCodeStream[classFileOffset++] = (byte) iArg;
642 final public void dload_0() {
643 if (DEBUG) System.out.println(position + "\t\tdload_0"); //$NON-NLS-1$
646 if (stackDepth > stackMax)
647 stackMax = stackDepth;
651 if (classFileOffset >= bCodeStream.length) {
655 bCodeStream[classFileOffset++] = OPC_dload_0;
657 final public void dload_1() {
658 if (DEBUG) System.out.println(position + "\t\tdload_1"); //$NON-NLS-1$
661 if (stackDepth > stackMax)
662 stackMax = stackDepth;
666 if (classFileOffset >= bCodeStream.length) {
670 bCodeStream[classFileOffset++] = OPC_dload_1;
672 final public void dload_2() {
673 if (DEBUG) System.out.println(position + "\t\tdload_2"); //$NON-NLS-1$
676 if (stackDepth > stackMax)
677 stackMax = stackDepth;
681 if (classFileOffset >= bCodeStream.length) {
685 bCodeStream[classFileOffset++] = OPC_dload_2;
687 final public void dload_3() {
688 if (DEBUG) System.out.println(position + "\t\tdload_3"); //$NON-NLS-1$
691 if (stackDepth > stackMax)
692 stackMax = stackDepth;
696 if (classFileOffset >= bCodeStream.length) {
700 bCodeStream[classFileOffset++] = OPC_dload_3;
702 final public void dmul() {
703 if (DEBUG) System.out.println(position + "\t\tdmul"); //$NON-NLS-1$
706 if (classFileOffset >= bCodeStream.length) {
710 bCodeStream[classFileOffset++] = OPC_dmul;
712 final public void dneg() {
713 if (DEBUG) System.out.println(position + "\t\tdneg"); //$NON-NLS-1$
715 if (classFileOffset >= bCodeStream.length) {
719 bCodeStream[classFileOffset++] = OPC_dneg;
721 final public void drem() {
722 if (DEBUG) System.out.println(position + "\t\tdrem"); //$NON-NLS-1$
725 if (classFileOffset >= bCodeStream.length) {
729 bCodeStream[classFileOffset++] = OPC_drem;
731 final public void dreturn() {
732 if (DEBUG) System.out.println(position + "\t\tdreturn"); //$NON-NLS-1$
735 // the stackDepth should be equal to 0
736 if (classFileOffset >= bCodeStream.length) {
740 bCodeStream[classFileOffset++] = OPC_dreturn;
742 final public void dstore(int iArg) {
743 if (DEBUG) System.out.println(position + "\t\tdstore:"+iArg); //$NON-NLS-1$
746 if (maxLocals <= iArg + 1) {
747 maxLocals = iArg + 2;
749 if (iArg > 255) { // Widen
750 if (classFileOffset + 3 >= bCodeStream.length) {
754 bCodeStream[classFileOffset++] = OPC_wide;
755 bCodeStream[classFileOffset++] = OPC_dstore;
756 writeUnsignedShort(iArg);
758 if (classFileOffset + 1 >= bCodeStream.length) {
762 bCodeStream[classFileOffset++] = OPC_dstore;
763 bCodeStream[classFileOffset++] = (byte) iArg;
766 final public void dstore_0() {
767 if (DEBUG) System.out.println(position + "\t\tdstore_0"); //$NON-NLS-1$
773 if (classFileOffset >= bCodeStream.length) {
777 bCodeStream[classFileOffset++] = OPC_dstore_0;
779 final public void dstore_1() {
780 if (DEBUG) System.out.println(position + "\t\tdstore_1"); //$NON-NLS-1$
786 if (classFileOffset >= bCodeStream.length) {
790 bCodeStream[classFileOffset++] = OPC_dstore_1;
792 final public void dstore_2() {
793 if (DEBUG) System.out.println(position + "\t\tdstore_2"); //$NON-NLS-1$
799 if (classFileOffset >= bCodeStream.length) {
803 bCodeStream[classFileOffset++] = OPC_dstore_2;
805 final public void dstore_3() {
806 if (DEBUG) System.out.println(position + "\t\tdstore_3"); //$NON-NLS-1$
812 if (classFileOffset >= bCodeStream.length) {
816 bCodeStream[classFileOffset++] = OPC_dstore_3;
818 final public void dsub() {
819 if (DEBUG) System.out.println(position + "\t\tdsub"); //$NON-NLS-1$
822 if (classFileOffset >= bCodeStream.length) {
826 bCodeStream[classFileOffset++] = OPC_dsub;
828 final public void dup() {
829 if (DEBUG) System.out.println(position + "\t\tdup"); //$NON-NLS-1$
832 if (stackDepth > stackMax) {
833 stackMax = stackDepth;
835 if (classFileOffset >= bCodeStream.length) {
839 bCodeStream[classFileOffset++] = OPC_dup;
841 final public void dup_x1() {
842 if (DEBUG) System.out.println(position + "\t\tdup_x1"); //$NON-NLS-1$
845 if (stackDepth > stackMax)
846 stackMax = stackDepth;
847 if (classFileOffset >= bCodeStream.length) {
851 bCodeStream[classFileOffset++] = OPC_dup_x1;
853 final public void dup_x2() {
854 if (DEBUG) System.out.println(position + "\t\tdup_x2"); //$NON-NLS-1$
857 if (stackDepth > stackMax)
858 stackMax = stackDepth;
859 if (classFileOffset >= bCodeStream.length) {
863 bCodeStream[classFileOffset++] = OPC_dup_x2;
865 final public void dup2() {
866 if (DEBUG) System.out.println(position + "\t\tdup2"); //$NON-NLS-1$
869 if (stackDepth > stackMax)
870 stackMax = stackDepth;
871 if (classFileOffset >= bCodeStream.length) {
875 bCodeStream[classFileOffset++] = OPC_dup2;
877 final public void dup2_x1() {
878 if (DEBUG) System.out.println(position + "\t\tdup2_x1"); //$NON-NLS-1$
881 if (stackDepth > stackMax)
882 stackMax = stackDepth;
883 if (classFileOffset >= bCodeStream.length) {
887 bCodeStream[classFileOffset++] = OPC_dup2_x1;
889 final public void dup2_x2() {
890 if (DEBUG) System.out.println(position + "\t\tdup2_x2"); //$NON-NLS-1$
893 if (stackDepth > stackMax)
894 stackMax = stackDepth;
895 if (classFileOffset >= bCodeStream.length) {
899 bCodeStream[classFileOffset++] = OPC_dup2_x2;
901 public void exitUserScope(BlockScope blockScope) {
902 // mark all the scope's locals as loosing their definite assignment
904 if (!generateLocalVariableTableAttributes)
906 for (int i = 0; i < visibleLocalsCount; i++) {
907 LocalVariableBinding visibleLocal = visibleLocals[i];
908 if ((visibleLocal != null) && (visibleLocal.declaringScope == blockScope)) {
909 // there maybe some some preserved locals never initialized
910 if (visibleLocal.initializationCount > 0){
911 visibleLocals[i].recordInitializationEndPC(position);
913 visibleLocals[i] = null; // this variable is no longer visible afterwards
917 final public void f2d() {
918 if (DEBUG) System.out.println(position + "\t\tf2d"); //$NON-NLS-1$
921 if (stackDepth > stackMax)
922 stackMax = stackDepth;
923 if (classFileOffset >= bCodeStream.length) {
927 bCodeStream[classFileOffset++] = OPC_f2d;
929 final public void f2i() {
930 if (DEBUG) System.out.println(position + "\t\tf2i"); //$NON-NLS-1$
932 if (classFileOffset >= bCodeStream.length) {
936 bCodeStream[classFileOffset++] = OPC_f2i;
938 final public void f2l() {
939 if (DEBUG) System.out.println(position + "\t\tf2l"); //$NON-NLS-1$
942 if (stackDepth > stackMax)
943 stackMax = stackDepth;
944 if (classFileOffset >= bCodeStream.length) {
948 bCodeStream[classFileOffset++] = OPC_f2l;
950 final public void fadd() {
951 if (DEBUG) System.out.println(position + "\t\tfadd"); //$NON-NLS-1$
954 if (classFileOffset >= bCodeStream.length) {
958 bCodeStream[classFileOffset++] = OPC_fadd;
960 final public void faload() {
961 if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
964 if (classFileOffset >= bCodeStream.length) {
968 bCodeStream[classFileOffset++] = OPC_faload;
970 final public void fastore() {
971 if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
974 if (classFileOffset >= bCodeStream.length) {
978 bCodeStream[classFileOffset++] = OPC_fastore;
980 final public void fcmpg() {
981 if (DEBUG) System.out.println(position + "\t\tfcmpg"); //$NON-NLS-1$
984 if (classFileOffset >= bCodeStream.length) {
988 bCodeStream[classFileOffset++] = OPC_fcmpg;
990 final public void fcmpl() {
991 if (DEBUG) System.out.println(position + "\t\tfcmpl"); //$NON-NLS-1$
994 if (classFileOffset >= bCodeStream.length) {
998 bCodeStream[classFileOffset++] = OPC_fcmpl;
1000 final public void fconst_0() {
1001 if (DEBUG) System.out.println(position + "\t\tfconst_0"); //$NON-NLS-1$
1004 if (stackDepth > stackMax)
1005 stackMax = stackDepth;
1006 if (classFileOffset >= bCodeStream.length) {
1010 bCodeStream[classFileOffset++] = OPC_fconst_0;
1012 final public void fconst_1() {
1013 if (DEBUG) System.out.println(position + "\t\tfconst_1"); //$NON-NLS-1$
1016 if (stackDepth > stackMax)
1017 stackMax = stackDepth;
1018 if (classFileOffset >= bCodeStream.length) {
1022 bCodeStream[classFileOffset++] = OPC_fconst_1;
1024 final public void fconst_2() {
1025 if (DEBUG) System.out.println(position + "\t\tfconst_2"); //$NON-NLS-1$
1028 if (stackDepth > stackMax)
1029 stackMax = stackDepth;
1030 if (classFileOffset >= bCodeStream.length) {
1034 bCodeStream[classFileOffset++] = OPC_fconst_2;
1036 final public void fdiv() {
1037 if (DEBUG) System.out.println(position + "\t\tfdiv"); //$NON-NLS-1$
1040 if (classFileOffset >= bCodeStream.length) {
1044 bCodeStream[classFileOffset++] = OPC_fdiv;
1046 final public void fload(int iArg) {
1047 if (DEBUG) System.out.println(position + "\t\tfload:"+iArg); //$NON-NLS-1$
1050 if (maxLocals <= iArg) {
1051 maxLocals = iArg + 1;
1053 if (stackDepth > stackMax)
1054 stackMax = stackDepth;
1055 if (iArg > 255) { // Widen
1056 if (classFileOffset + 3 >= bCodeStream.length) {
1060 bCodeStream[classFileOffset++] = OPC_wide;
1061 bCodeStream[classFileOffset++] = OPC_fload;
1062 writeUnsignedShort(iArg);
1064 if (classFileOffset + 1 >= bCodeStream.length) {
1068 bCodeStream[classFileOffset++] = OPC_fload;
1069 bCodeStream[classFileOffset++] = (byte) iArg;
1072 final public void fload_0() {
1073 if (DEBUG) System.out.println(position + "\t\tfload_0"); //$NON-NLS-1$
1076 if (maxLocals == 0) {
1079 if (stackDepth > stackMax)
1080 stackMax = stackDepth;
1081 if (classFileOffset >= bCodeStream.length) {
1085 bCodeStream[classFileOffset++] = OPC_fload_0;
1087 final public void fload_1() {
1088 if (DEBUG) System.out.println(position + "\t\tfload_1"); //$NON-NLS-1$
1091 if (maxLocals <= 1) {
1094 if (stackDepth > stackMax)
1095 stackMax = stackDepth;
1096 if (classFileOffset >= bCodeStream.length) {
1100 bCodeStream[classFileOffset++] = OPC_fload_1;
1102 final public void fload_2() {
1103 if (DEBUG) System.out.println(position + "\t\tfload_2"); //$NON-NLS-1$
1106 if (maxLocals <= 2) {
1109 if (stackDepth > stackMax)
1110 stackMax = stackDepth;
1111 if (classFileOffset >= bCodeStream.length) {
1115 bCodeStream[classFileOffset++] = OPC_fload_2;
1117 final public void fload_3() {
1118 if (DEBUG) System.out.println(position + "\t\tfload_3"); //$NON-NLS-1$
1121 if (maxLocals <= 3) {
1124 if (stackDepth > stackMax)
1125 stackMax = stackDepth;
1126 if (classFileOffset >= bCodeStream.length) {
1130 bCodeStream[classFileOffset++] = OPC_fload_3;
1132 final public void fmul() {
1133 if (DEBUG) System.out.println(position + "\t\tfmul"); //$NON-NLS-1$
1136 if (classFileOffset >= bCodeStream.length) {
1140 bCodeStream[classFileOffset++] = OPC_fmul;
1142 final public void fneg() {
1143 if (DEBUG) System.out.println(position + "\t\tfneg"); //$NON-NLS-1$
1145 if (classFileOffset >= bCodeStream.length) {
1149 bCodeStream[classFileOffset++] = OPC_fneg;
1151 final public void frem() {
1152 if (DEBUG) System.out.println(position + "\t\tfrem"); //$NON-NLS-1$
1155 if (classFileOffset >= bCodeStream.length) {
1159 bCodeStream[classFileOffset++] = OPC_frem;
1161 final public void freturn() {
1162 if (DEBUG) System.out.println(position + "\t\tfreturn"); //$NON-NLS-1$
1165 // the stackDepth should be equal to 0
1166 if (classFileOffset >= bCodeStream.length) {
1170 bCodeStream[classFileOffset++] = OPC_freturn;
1172 final public void fstore(int iArg) {
1173 if (DEBUG) System.out.println(position + "\t\tfstore:"+iArg); //$NON-NLS-1$
1176 if (maxLocals <= iArg) {
1177 maxLocals = iArg + 1;
1179 if (iArg > 255) { // Widen
1180 if (classFileOffset + 3 >= bCodeStream.length) {
1184 bCodeStream[classFileOffset++] = OPC_wide;
1185 bCodeStream[classFileOffset++] = OPC_fstore;
1186 writeUnsignedShort(iArg);
1188 if (classFileOffset + 1 >= bCodeStream.length) {
1192 bCodeStream[classFileOffset++] = OPC_fstore;
1193 bCodeStream[classFileOffset++] = (byte) iArg;
1196 final public void fstore_0() {
1197 if (DEBUG) System.out.println(position + "\t\tfstore_0"); //$NON-NLS-1$
1200 if (maxLocals == 0) {
1203 if (classFileOffset >= bCodeStream.length) {
1207 bCodeStream[classFileOffset++] = OPC_fstore_0;
1209 final public void fstore_1() {
1210 if (DEBUG) System.out.println(position + "\t\tfstore_1"); //$NON-NLS-1$
1213 if (maxLocals <= 1) {
1216 if (classFileOffset >= bCodeStream.length) {
1220 bCodeStream[classFileOffset++] = OPC_fstore_1;
1222 final public void fstore_2() {
1223 if (DEBUG) System.out.println(position + "\t\tfstore_2"); //$NON-NLS-1$
1226 if (maxLocals <= 2) {
1229 if (classFileOffset >= bCodeStream.length) {
1233 bCodeStream[classFileOffset++] = OPC_fstore_2;
1235 final public void fstore_3() {
1236 if (DEBUG) System.out.println(position + "\t\tfstore_3"); //$NON-NLS-1$
1239 if (maxLocals <= 3) {
1242 if (classFileOffset >= bCodeStream.length) {
1246 bCodeStream[classFileOffset++] = OPC_fstore_3;
1248 final public void fsub() {
1249 if (DEBUG) System.out.println(position + "\t\tfsub"); //$NON-NLS-1$
1252 if (classFileOffset >= bCodeStream.length) {
1256 bCodeStream[classFileOffset++] = OPC_fsub;
1259 * Macro for building a class descriptor object
1261 public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
1263 ExceptionLabel anyExceptionHandler;
1265 if (accessedType.isBaseType() && accessedType != NullBinding) {
1266 this.getTYPE(accessedType.id);
1270 if (this.targetLevel >= ClassFileConstants.JDK1_5) {
1271 // generation using the new ldc_w bytecode
1272 this.ldc(accessedType);
1274 endLabel = new Label(this);
1275 if (syntheticFieldBinding != null) { // non interface case
1276 this.getstatic(syntheticFieldBinding);
1278 this.ifnonnull(endLabel);
1282 /* Macro for building a class descriptor object... using or not a field cache to store it into...
1283 this sequence is responsible for building the actual class descriptor.
1285 If the fieldCache is set, then it is supposed to be the body of a synthetic access method
1286 factoring the actual descriptor creation out of the invocation site (saving space).
1287 If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
1288 we have no way to get a hand on the field cache to do better. */
1291 // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
1293 anyExceptionHandler = new ExceptionLabel(this, BaseTypes.NullBinding /* represents ClassNotFoundException*/);
1294 this.ldc(accessedType == BaseTypes.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
1295 this.invokeClassForName();
1297 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
1298 if (accessedType == BaseTypes.NullBinding) {
1299 this.ldc("java.lang.Object"); //$NON-NLS-1$
1300 } else if (accessedType.isArrayType()) {
1301 this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
1303 // we make it an array type (to avoid class initialization)
1304 this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
1306 this.invokeClassForName();
1307 if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
1308 this.invokeJavaLangClassGetComponentType();
1311 /* We need to protect the runtime code from binary inconsistencies
1312 in case the accessedType is missing, the ClassNotFoundException has to be converted
1313 into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
1314 anyExceptionHandler.placeEnd();
1316 if (syntheticFieldBinding != null) { // non interface case
1318 this.putstatic(syntheticFieldBinding);
1320 this.goto_(endLabel);
1323 // Generate the body of the exception handler
1324 saveStackSize = stackDepth;
1326 /* ClassNotFoundException on stack -- the class literal could be doing more things
1327 on the stack, which means that the stack may not be empty at this point in the
1328 above code gen. So we save its state and restart it from 1. */
1330 anyExceptionHandler.place();
1332 // Transform the current exception, and repush and throw a
1333 // NoClassDefFoundError(ClassNotFound.getMessage())
1335 this.newNoClassDefFoundError();
1339 // Retrieve the message from the old exception
1340 this.invokeThrowableGetMessage();
1342 // Send the constructor taking a message string as an argument
1343 this.invokeNoClassDefFoundErrorStringConstructor();
1345 stackDepth = saveStackSize;
1350 * This method generates the code attribute bytecode
1352 final public void generateCodeAttributeForProblemMethod(String problemMessage) {
1355 ldc(problemMessage);
1356 invokeJavaLangErrorConstructor();
1359 public void generateConstant(Constant constant, int implicitConversionCode) {
1360 int targetTypeID = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
1361 if (targetTypeID != 0) {
1362 switch (targetTypeID) {
1364 generateInlinedValue(constant.booleanValue());
1367 generateInlinedValue(constant.charValue());
1370 generateInlinedValue(constant.byteValue());
1373 generateInlinedValue(constant.shortValue());
1376 generateInlinedValue(constant.intValue());
1379 generateInlinedValue(constant.longValue());
1382 generateInlinedValue(constant.floatValue());
1385 generateInlinedValue(constant.doubleValue());
1387 case T_JavaLangString :
1388 ldc(constant.stringValue());
1391 ldc(constant.stringValue());
1393 if ((implicitConversionCode & BOXING) != 0) {
1395 generateBoxingConversion(targetTypeID);
1400 * Generates the sequence of instructions which will perform the conversion of the expression
1401 * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
1402 * @param implicitConversionCode int
1404 public void generateImplicitConversion(int implicitConversionCode) {
1405 if ((implicitConversionCode & UNBOXING) != 0) {
1406 final int typeId = implicitConversionCode & COMPILE_TYPE_MASK;
1407 generateUnboxingConversion(typeId);
1408 // unboxing can further involve base type conversions
1410 switch (implicitConversionCode & IMPLICIT_CONVERSION_MASK) {
1507 if ((implicitConversionCode & BOXING) != 0) {
1508 // need to unbox/box the constant
1509 final int typeId = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
1510 generateBoxingConversion(typeId);
1513 public void generateInlinedValue(byte inlinedValue) {
1514 switch (inlinedValue) {
1537 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1538 this.bipush(inlinedValue);
1543 public void generateInlinedValue(char inlinedValue) {
1544 switch (inlinedValue) {
1564 if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
1565 this.bipush((byte) inlinedValue);
1568 if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
1569 this.sipush(inlinedValue);
1572 this.ldc(inlinedValue);
1575 public void generateInlinedValue(double inlinedValue) {
1576 if (inlinedValue == 0.0) {
1577 if (Double.doubleToLongBits(inlinedValue) != 0L)
1578 this.ldc2_w(inlinedValue);
1583 if (inlinedValue == 1.0) {
1587 this.ldc2_w(inlinedValue);
1589 public void generateInlinedValue(float inlinedValue) {
1590 if (inlinedValue == 0.0f) {
1591 if (Float.floatToIntBits(inlinedValue) != 0)
1592 this.ldc(inlinedValue);
1597 if (inlinedValue == 1.0f) {
1601 if (inlinedValue == 2.0f) {
1605 this.ldc(inlinedValue);
1607 public void generateInlinedValue(int inlinedValue) {
1608 switch (inlinedValue) {
1631 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1632 this.bipush((byte) inlinedValue);
1635 if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
1636 this.sipush(inlinedValue);
1639 this.ldc(inlinedValue);
1642 public void generateInlinedValue(long inlinedValue) {
1643 if (inlinedValue == 0) {
1647 if (inlinedValue == 1) {
1651 this.ldc2_w(inlinedValue);
1653 public void generateInlinedValue(short inlinedValue) {
1654 switch (inlinedValue) {
1677 if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1678 this.bipush((byte) inlinedValue);
1681 this.sipush(inlinedValue);
1684 public void generateInlinedValue(boolean inlinedValue) {
1690 public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
1691 if (mappingSequence == null) {
1692 if (target instanceof LocalVariableBinding) {
1693 scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
1695 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
1699 if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
1700 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
1702 } else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
1703 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
1707 if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
1710 } else if (mappingSequence[0] instanceof FieldBinding) {
1711 FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
1713 this.getfield(fieldBinding);
1715 load((LocalVariableBinding) mappingSequence[0]);
1717 for (int i = 1, length = mappingSequence.length; i < length; i++) {
1718 if (mappingSequence[i] instanceof FieldBinding) {
1719 FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
1720 this.getfield(fieldBinding);
1722 this.invokestatic((MethodBinding) mappingSequence[i]);
1728 * The equivalent code performs a string conversion:
1730 * @param blockScope the given blockScope
1731 * @param oper1 the first expression
1732 * @param oper2 the second expression
1734 public void generateStringConcatenationAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
1736 if (oper1 == null) {
1737 /* Operand is already on the stack, and maybe nil:
1738 note type1 is always to java.lang.String here.*/
1739 this.newStringContatenation();
1742 // If argument is reference type, need to transform it
1743 // into a string (handles null case)
1744 this.invokeStringValueOf(T_JavaLangObject);
1745 this.invokeStringConcatenationStringConstructor();
1748 oper1.generateOptimizedStringConcatenationCreation(blockScope, this, oper1.implicitConversion & COMPILE_TYPE_MASK);
1749 this.recordPositionsFrom(pc, oper1.sourceStart);
1752 oper2.generateOptimizedStringConcatenation(blockScope, this, oper2.implicitConversion & COMPILE_TYPE_MASK);
1753 this.recordPositionsFrom(pc, oper2.sourceStart);
1754 this.invokeStringConcatenationToString();
1757 * Code responsible to generate the suitable code to supply values for the synthetic enclosing
1758 * instance arguments of a constructor invocation of a nested type.
1760 public void generateSyntheticEnclosingInstanceValues(
1761 BlockScope currentScope,
1762 ReferenceBinding targetType,
1763 Expression enclosingInstance,
1764 ASTNode invocationSite) {
1766 // supplying enclosing instance for the anonymous type's superclass
1767 ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? targetType.superclass() : targetType;
1768 boolean hasExtraEnclosingInstance = enclosingInstance != null;
1769 if (hasExtraEnclosingInstance
1770 && (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
1771 currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
1775 // perform some emulation work in case there is some and we are inside a local type only
1776 ReferenceBinding[] syntheticArgumentTypes;
1777 if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
1779 ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
1780 boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
1781 // deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
1782 boolean ignoreEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
1783 || (complyTo14 && ((invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess())));
1785 for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
1786 ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
1787 if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
1788 hasExtraEnclosingInstance = false;
1789 enclosingInstance.generateCode(currentScope, this, true);
1792 invokeObjectGetClass(); // will perform null check
1796 Object[] emulationPath = currentScope.getEmulationPath(
1798 false /*not only exact match (that is, allow compatible)*/,
1799 ignoreEnclosingArgInConstructorCall);
1800 this.generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
1803 if (hasExtraEnclosingInstance){
1804 currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
1810 * Code responsible to generate the suitable code to supply values for the synthetic outer local
1811 * variable arguments of a constructor invocation of a nested type.
1812 * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
1814 public void generateSyntheticOuterArgumentValues(BlockScope currentScope, ReferenceBinding targetType, ASTNode invocationSite) {
1816 // generate the synthetic outer arguments then
1817 SyntheticArgumentBinding syntheticArguments[];
1818 if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
1819 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
1820 LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
1821 VariableBinding[] emulationPath = currentScope.getEmulationPath(targetVariable);
1822 this.generateOuterAccess(emulationPath, invocationSite, targetVariable, currentScope);
1828 * @param accessBinding the access method binding to generate
1830 public void generateSyntheticBodyForConstructorAccess(SyntheticMethodBinding accessBinding) {
1832 initializeMaxLocals(accessBinding);
1834 MethodBinding constructorBinding = accessBinding.targetMethod;
1835 TypeBinding[] parameters = constructorBinding.parameters;
1836 int length = parameters.length;
1837 int resolvedPosition = 1;
1839 // special name&ordinal argument generation for enum constructors
1840 TypeBinding declaringClass = constructorBinding.declaringClass;
1841 if (declaringClass.erasure().id == T_JavaLangEnum || declaringClass.isEnum()) {
1842 this.aload_1(); // pass along name param as name arg
1843 this.iload_2(); // pass along ordinal param as ordinal arg
1845 if (declaringClass.isNestedType()) {
1846 NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
1847 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
1848 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1850 load((type = syntheticArguments[i].type), resolvedPosition);
1851 if ((type == DoubleBinding) || (type == LongBinding))
1852 resolvedPosition += 2;
1857 for (int i = 0; i < length; i++) {
1858 load(parameters[i], resolvedPosition);
1859 if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
1860 resolvedPosition += 2;
1865 if (declaringClass.isNestedType()) {
1866 NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
1867 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
1868 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1870 load((type = syntheticArguments[i].type), resolvedPosition);
1871 if ((type == DoubleBinding) || (type == LongBinding))
1872 resolvedPosition += 2;
1877 this.invokespecial(constructorBinding);
1880 //static X[] values() {
1884 // System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length)
1887 public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
1888 ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
1889 FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
1890 initializeMaxLocals(methodBinding);
1891 TypeBinding enumArray = methodBinding.returnType;
1893 this.getstatic(enumValuesSyntheticfield);
1901 this.newArray((ArrayBinding) enumArray);
1906 this.invokeSystemArraycopy();
1910 //static X valueOf(String name) {
1912 // for (int i = (values = $VALUES).length; --i >= 0;) {
1914 // if (name.equals(value = values[i].name())) return value;
1916 // throw new IllegalArgumentException(name);
1918 public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
1919 ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
1920 FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
1921 initializeMaxLocals(methodBinding);
1922 Label loopCond = new Label(this);
1923 Label loopStart = new Label(this);
1924 Label wrongConstant = new Label(this);
1926 this.getstatic(enumValuesSyntheticfield);
1931 this.goto_(loopCond);
1939 this.invokeJavaLangEnumname(this.classFile.referenceBinding);
1940 this.invokeStringEquals();
1941 this.ifeq(wrongConstant);
1944 wrongConstant.place();
1948 this.ifge(loopStart);
1949 this.newJavaLangIllegalArgumentException();
1952 this.invokeJavaLangIllegalArgumentExceptionStringConstructor();
1955 public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
1956 initializeMaxLocals(accessBinding);
1957 FieldBinding fieldBinding = accessBinding.targetReadField;
1959 if (fieldBinding.isStatic())
1960 this.getstatic(fieldBinding);
1963 this.getfield(fieldBinding);
1965 if ((type = fieldBinding.type).isBaseType()) {
1966 if (type == IntBinding)
1969 if (type == FloatBinding)
1972 if (type == LongBinding)
1975 if (type == DoubleBinding)
1982 public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding accessBinding) {
1983 initializeMaxLocals(accessBinding);
1984 FieldBinding fieldBinding = accessBinding.targetWriteField;
1985 if (fieldBinding.isStatic()) {
1986 load(fieldBinding.type, 0);
1987 this.putstatic(fieldBinding);
1990 load(fieldBinding.type, 1);
1991 this.putfield(fieldBinding);
1995 public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessBinding) {
1997 initializeMaxLocals(accessBinding);
1998 MethodBinding methodBinding = accessBinding.targetMethod;
1999 TypeBinding[] parameters = methodBinding.parameters;
2000 int length = parameters.length;
2001 TypeBinding[] arguments = accessBinding.kind == SyntheticMethodBinding.BridgeMethod
2002 ? accessBinding.parameters
2004 int resolvedPosition;
2005 if (methodBinding.isStatic())
2006 resolvedPosition = 0;
2009 resolvedPosition = 1;
2011 for (int i = 0; i < length; i++) {
2012 TypeBinding parameter = parameters[i];
2013 if (arguments != null) { // for bridge methods
2014 TypeBinding argument = arguments[i];
2015 load(argument, resolvedPosition);
2016 if (argument != parameter)
2017 checkcast(parameter);
2019 load(parameter, resolvedPosition);
2021 if ((parameter == DoubleBinding) || (parameter == LongBinding))
2022 resolvedPosition += 2;
2027 if (methodBinding.isStatic())
2028 this.invokestatic(methodBinding);
2030 if (methodBinding.isConstructor()
2031 || methodBinding.isPrivate()
2032 // qualified super "X.super.foo()" targets methods from superclass
2033 || accessBinding.kind == SyntheticMethodBinding.SuperMethodAccess){
2034 this.invokespecial(methodBinding);
2036 if ((methodBinding.declaringClass.modifiers & AccInterface) != 0) { // interface or annotation type
2037 this.invokeinterface(methodBinding);
2039 this.invokevirtual(methodBinding);
2043 if ((type = methodBinding.returnType).isBaseType())
2044 if (type == VoidBinding)
2047 if (type == IntBinding)
2050 if (type == FloatBinding)
2053 if (type == LongBinding)
2056 if (type == DoubleBinding)
2063 public void generateBoxingConversion(int unboxedTypeID) {
2064 switch (unboxedTypeID) {
2066 // invokestatic: Byte.valueOf(byte)
2070 1, // return type size
2071 ConstantPool.JavaLangByteConstantPoolName,
2072 ConstantPool.ValueOf,
2073 ConstantPool.byteByteSignature); //$NON-NLS-1$
2076 // invokestatic: Short.valueOf(short)
2080 1, // return type size
2081 ConstantPool.JavaLangShortConstantPoolName,
2082 ConstantPool.ValueOf,
2083 ConstantPool.shortShortSignature); //$NON-NLS-1$
2086 // invokestatic: Character.valueOf(char)
2090 1, // return type size
2091 ConstantPool.JavaLangCharacterConstantPoolName,
2092 ConstantPool.ValueOf,
2093 ConstantPool.charCharacterSignature); //$NON-NLS-1$
2096 // invokestatic: Integer.valueOf(int)
2100 1, // return type size
2101 ConstantPool.JavaLangIntegerConstantPoolName,
2102 ConstantPool.ValueOf,
2103 ConstantPool.IntIntegerSignature); //$NON-NLS-1$
2106 // invokestatic: Long.valueOf(long)
2110 1, // return type size
2111 ConstantPool.JavaLangLongConstantPoolName,
2112 ConstantPool.ValueOf,
2113 ConstantPool.longLongSignature); //$NON-NLS-1$
2116 // invokestatic: Float.valueOf(float)
2120 1, // return type size
2121 ConstantPool.JavaLangFloatConstantPoolName,
2122 ConstantPool.ValueOf,
2123 ConstantPool.floatFloatSignature); //$NON-NLS-1$
2126 // invokestatic: Double.valueOf(double)
2130 1, // return type size
2131 ConstantPool.JavaLangDoubleConstantPoolName,
2132 ConstantPool.ValueOf,
2133 ConstantPool.doubleDoubleSignature); //$NON-NLS-1$
2136 // invokestatic: Boolean.valueOf(boolean)
2140 1, // return type size
2141 ConstantPool.JavaLangBooleanConstantPoolName,
2142 ConstantPool.ValueOf,
2143 ConstantPool.booleanBooleanSignature); //$NON-NLS-1$
2146 public void generateUnboxingConversion(int unboxedTypeID) {
2147 switch (unboxedTypeID) {
2149 // invokevirtual: byteValue()
2153 1, // return type size
2154 ConstantPool.JavaLangByteConstantPoolName,
2155 ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
2156 ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
2159 // invokevirtual: shortValue()
2163 1, // return type size
2164 ConstantPool.JavaLangShortConstantPoolName,
2165 ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
2166 ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
2169 // invokevirtual: charValue()
2173 1, // return type size
2174 ConstantPool.JavaLangCharacterConstantPoolName,
2175 ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
2176 ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
2179 // invokevirtual: intValue()
2183 1, // return type size
2184 ConstantPool.JavaLangIntegerConstantPoolName,
2185 ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
2186 ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
2189 // invokevirtual: longValue()
2193 2, // return type size
2194 ConstantPool.JavaLangLongConstantPoolName,
2195 ConstantPool.LONGVALUE_LONG_METHOD_NAME,
2196 ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
2199 // invokevirtual: floatValue()
2203 1, // return type size
2204 ConstantPool.JavaLangFloatConstantPoolName,
2205 ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
2206 ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
2209 // invokevirtual: doubleValue()
2213 2, // return type size
2214 ConstantPool.JavaLangDoubleConstantPoolName,
2215 ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
2216 ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
2219 // invokevirtual: booleanValue()
2223 1, // return type size
2224 ConstantPool.JavaLangBooleanConstantPoolName,
2225 ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
2226 ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
2229 final public byte[] getContents() {
2231 System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
2234 final public void getfield(FieldBinding fieldBinding) {
2235 if (DEBUG) System.out.println(position + "\t\tgetfield:"+fieldBinding); //$NON-NLS-1$
2236 int returnTypeSize = 1;
2237 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
2240 generateFieldAccess(
2243 fieldBinding.declaringClass.constantPoolName(),
2245 fieldBinding.type.signature());
2247 private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) {
2251 if (returnTypeSize == 2) {
2255 case OPC_getstatic :
2256 if (returnTypeSize == 2) {
2263 if (returnTypeSize == 2) {
2269 case OPC_putstatic :
2270 if (returnTypeSize == 2) {
2276 if (stackDepth > stackMax) {
2277 stackMax = stackDepth;
2279 if (classFileOffset + 2 >= bCodeStream.length) {
2283 bCodeStream[classFileOffset++] = opcode;
2284 writeUnsignedShort(constantPool.literalIndexForField(declaringClass, name, signature));
2286 final public void getstatic(FieldBinding fieldBinding) {
2287 if (DEBUG) System.out.println(position + "\t\tgetstatic:"+fieldBinding); //$NON-NLS-1$
2288 int returnTypeSize = 1;
2289 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
2292 generateFieldAccess(
2295 fieldBinding.declaringClass.constantPoolName(),
2297 fieldBinding.type.signature());
2299 public void getTYPE(int baseTypeID) {
2301 switch (baseTypeID) {
2303 // getstatic: java.lang.Byte.TYPE
2304 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$
2305 generateFieldAccess(
2308 ConstantPool.JavaLangByteConstantPoolName,
2310 ConstantPool.JavaLangClassSignature);
2313 // getstatic: java.lang.Short.TYPE
2314 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$
2315 generateFieldAccess(
2318 ConstantPool.JavaLangShortConstantPoolName,
2320 ConstantPool.JavaLangClassSignature);
2323 // getstatic: java.lang.Character.TYPE
2324 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$
2325 generateFieldAccess(
2328 ConstantPool.JavaLangCharacterConstantPoolName,
2330 ConstantPool.JavaLangClassSignature);
2333 // getstatic: java.lang.Integer.TYPE
2334 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$
2335 generateFieldAccess(
2338 ConstantPool.JavaLangIntegerConstantPoolName,
2340 ConstantPool.JavaLangClassSignature);
2343 // getstatic: java.lang.Long.TYPE
2344 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$
2345 generateFieldAccess(
2348 ConstantPool.JavaLangLongConstantPoolName,
2350 ConstantPool.JavaLangClassSignature);
2353 // getstatic: java.lang.Float.TYPE
2354 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$
2355 generateFieldAccess(
2358 ConstantPool.JavaLangFloatConstantPoolName,
2360 ConstantPool.JavaLangClassSignature);
2363 // getstatic: java.lang.Double.TYPE
2364 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$
2365 generateFieldAccess(
2368 ConstantPool.JavaLangDoubleConstantPoolName,
2370 ConstantPool.JavaLangClassSignature);
2373 // getstatic: java.lang.Boolean.TYPE
2374 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$
2375 generateFieldAccess(
2378 ConstantPool.JavaLangBooleanConstantPoolName,
2380 ConstantPool.JavaLangClassSignature);
2383 // getstatic: java.lang.Void.TYPE
2384 if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$
2385 generateFieldAccess(
2388 ConstantPool.JavaLangVoidConstantPoolName,
2390 ConstantPool.JavaLangClassSignature);
2395 * We didn't call it goto, because there is a conflit with the goto keyword
2397 final public void goto_(Label label) {
2398 if (this.wideMode) {
2402 if (DEBUG) System.out.println(position + "\t\tgoto:"+label); //$NON-NLS-1$
2403 if (classFileOffset >= bCodeStream.length) {
2406 label.inlineForwardReferencesFromLabelsTargeting(position);
2408 Possible optimization for code such as:
2409 public Object foo() {
2421 The goto around the else block for the first if will
2422 be unreachable, because the thenClause of the second if
2424 See inlineForwardReferencesFromLabelsTargeting defined
2425 on the Label class for the remaining part of this
2427 if (!lbl.isBranchTarget(position)) {
2428 switch(bCodeStream[classFileOffset-1]) {
2435 bCodeStream[classFileOffset++] = OPC_goto;
2439 final public void goto_w(Label lbl) {
2440 if (DEBUG) System.out.println(position + "\t\tgotow:"+lbl); //$NON-NLS-1$
2441 if (classFileOffset >= bCodeStream.length) {
2445 bCodeStream[classFileOffset++] = OPC_goto_w;
2448 final public void i2b() {
2449 if (DEBUG) System.out.println(position + "\t\ti2b"); //$NON-NLS-1$
2451 if (classFileOffset >= bCodeStream.length) {
2455 bCodeStream[classFileOffset++] = OPC_i2b;
2457 final public void i2c() {
2458 if (DEBUG) System.out.println(position + "\t\ti2c"); //$NON-NLS-1$
2460 if (classFileOffset >= bCodeStream.length) {
2464 bCodeStream[classFileOffset++] = OPC_i2c;
2466 final public void i2d() {
2467 if (DEBUG) System.out.println(position + "\t\ti2d"); //$NON-NLS-1$
2470 if (stackDepth > stackMax)
2471 stackMax = stackDepth;
2472 if (classFileOffset >= bCodeStream.length) {
2476 bCodeStream[classFileOffset++] = OPC_i2d;
2478 final public void i2f() {
2479 if (DEBUG) System.out.println(position + "\t\ti2f"); //$NON-NLS-1$
2481 if (classFileOffset >= bCodeStream.length) {
2485 bCodeStream[classFileOffset++] = OPC_i2f;
2487 final public void i2l() {
2488 if (DEBUG) System.out.println(position + "\t\ti2l"); //$NON-NLS-1$
2491 if (stackDepth > stackMax)
2492 stackMax = stackDepth;
2493 if (classFileOffset >= bCodeStream.length) {
2497 bCodeStream[classFileOffset++] = OPC_i2l;
2499 final public void i2s() {
2500 if (DEBUG) System.out.println(position + "\t\ti2s"); //$NON-NLS-1$
2502 if (classFileOffset >= bCodeStream.length) {
2506 bCodeStream[classFileOffset++] = OPC_i2s;
2508 final public void iadd() {
2509 if (DEBUG) System.out.println(position + "\t\tiadd"); //$NON-NLS-1$
2512 if (classFileOffset >= bCodeStream.length) {
2516 bCodeStream[classFileOffset++] = OPC_iadd;
2518 final public void iaload() {
2519 if (DEBUG) System.out.println(position + "\t\tiaload"); //$NON-NLS-1$
2522 if (classFileOffset >= bCodeStream.length) {
2526 bCodeStream[classFileOffset++] = OPC_iaload;
2528 final public void iand() {
2529 if (DEBUG) System.out.println(position + "\t\tiand"); //$NON-NLS-1$
2532 if (classFileOffset >= bCodeStream.length) {
2536 bCodeStream[classFileOffset++] = OPC_iand;
2538 final public void iastore() {
2539 if (DEBUG) System.out.println(position + "\t\tiastore"); //$NON-NLS-1$
2542 if (classFileOffset >= bCodeStream.length) {
2546 bCodeStream[classFileOffset++] = OPC_iastore;
2548 final public void iconst_0() {
2549 if (DEBUG) System.out.println(position + "\t\ticonst_0"); //$NON-NLS-1$
2552 if (stackDepth > stackMax)
2553 stackMax = stackDepth;
2554 if (classFileOffset >= bCodeStream.length) {
2558 bCodeStream[classFileOffset++] = OPC_iconst_0;
2560 final public void iconst_1() {
2561 if (DEBUG) System.out.println(position + "\t\ticonst_1"); //$NON-NLS-1$
2564 if (stackDepth > stackMax)
2565 stackMax = stackDepth;
2566 if (classFileOffset >= bCodeStream.length) {
2570 bCodeStream[classFileOffset++] = OPC_iconst_1;
2572 final public void iconst_2() {
2573 if (DEBUG) System.out.println(position + "\t\ticonst_2"); //$NON-NLS-1$
2576 if (stackDepth > stackMax)
2577 stackMax = stackDepth;
2578 if (classFileOffset >= bCodeStream.length) {
2582 bCodeStream[classFileOffset++] = OPC_iconst_2;
2584 final public void iconst_3() {
2585 if (DEBUG) System.out.println(position + "\t\ticonst_3"); //$NON-NLS-1$
2588 if (stackDepth > stackMax)
2589 stackMax = stackDepth;
2590 if (classFileOffset >= bCodeStream.length) {
2594 bCodeStream[classFileOffset++] = OPC_iconst_3;
2596 final public void iconst_4() {
2597 if (DEBUG) System.out.println(position + "\t\ticonst_4"); //$NON-NLS-1$
2600 if (stackDepth > stackMax)
2601 stackMax = stackDepth;
2602 if (classFileOffset >= bCodeStream.length) {
2606 bCodeStream[classFileOffset++] = OPC_iconst_4;
2608 final public void iconst_5() {
2609 if (DEBUG) System.out.println(position + "\t\ticonst_5"); //$NON-NLS-1$
2612 if (stackDepth > stackMax)
2613 stackMax = stackDepth;
2614 if (classFileOffset >= bCodeStream.length) {
2618 bCodeStream[classFileOffset++] = OPC_iconst_5;
2620 final public void iconst_m1() {
2621 if (DEBUG) System.out.println(position + "\t\ticonst_m1"); //$NON-NLS-1$
2624 if (stackDepth > stackMax)
2625 stackMax = stackDepth;
2626 if (classFileOffset >= bCodeStream.length) {
2630 bCodeStream[classFileOffset++] = OPC_iconst_m1;
2632 final public void idiv() {
2633 if (DEBUG) System.out.println(position + "\t\tidiv"); //$NON-NLS-1$
2636 if (classFileOffset >= bCodeStream.length) {
2640 bCodeStream[classFileOffset++] = OPC_idiv;
2642 final public void if_acmpeq(Label lbl) {
2643 if (DEBUG) System.out.println(position + "\t\tif_acmpeq:"+lbl); //$NON-NLS-1$
2646 if (this.wideMode) {
2647 generateWideRevertedConditionalBranch(OPC_if_acmpne, lbl);
2649 if (classFileOffset >= bCodeStream.length) {
2653 bCodeStream[classFileOffset++] = OPC_if_acmpeq;
2657 final public void if_acmpne(Label lbl) {
2658 if (DEBUG) System.out.println(position + "\t\tif_acmpne:"+lbl); //$NON-NLS-1$
2661 if (this.wideMode) {
2662 generateWideRevertedConditionalBranch(OPC_if_acmpeq, lbl);
2664 if (classFileOffset >= bCodeStream.length) {
2668 bCodeStream[classFileOffset++] = OPC_if_acmpne;
2672 final public void if_icmpeq(Label lbl) {
2673 if (DEBUG) System.out.println(position + "\t\tif_cmpeq:"+lbl); //$NON-NLS-1$
2676 if (this.wideMode) {
2677 generateWideRevertedConditionalBranch(OPC_if_icmpne, lbl);
2679 if (classFileOffset >= bCodeStream.length) {
2683 bCodeStream[classFileOffset++] = OPC_if_icmpeq;
2687 final public void if_icmpge(Label lbl) {
2688 if (DEBUG) System.out.println(position + "\t\tif_iacmpge:"+lbl); //$NON-NLS-1$
2691 if (this.wideMode) {
2692 generateWideRevertedConditionalBranch(OPC_if_icmplt, lbl);
2694 if (classFileOffset >= bCodeStream.length) {
2698 bCodeStream[classFileOffset++] = OPC_if_icmpge;
2702 final public void if_icmpgt(Label lbl) {
2703 if (DEBUG) System.out.println(position + "\t\tif_iacmpgt:"+lbl); //$NON-NLS-1$
2706 if (this.wideMode) {
2707 generateWideRevertedConditionalBranch(OPC_if_icmple, lbl);
2709 if (classFileOffset >= bCodeStream.length) {
2713 bCodeStream[classFileOffset++] = OPC_if_icmpgt;
2717 final public void if_icmple(Label lbl) {
2718 if (DEBUG) System.out.println(position + "\t\tif_iacmple:"+lbl); //$NON-NLS-1$
2721 if (this.wideMode) {
2722 generateWideRevertedConditionalBranch(OPC_if_icmpgt, lbl);
2724 if (classFileOffset >= bCodeStream.length) {
2728 bCodeStream[classFileOffset++] = OPC_if_icmple;
2732 final public void if_icmplt(Label lbl) {
2733 if (DEBUG) System.out.println(position + "\t\tif_iacmplt:"+lbl); //$NON-NLS-1$
2736 if (this.wideMode) {
2737 generateWideRevertedConditionalBranch(OPC_if_icmpge, lbl);
2739 if (classFileOffset >= bCodeStream.length) {
2743 bCodeStream[classFileOffset++] = OPC_if_icmplt;
2747 final public void if_icmpne(Label lbl) {
2748 if (DEBUG) System.out.println(position + "\t\tif_iacmpne:"+lbl); //$NON-NLS-1$
2751 if (this.wideMode) {
2752 generateWideRevertedConditionalBranch(OPC_if_icmpeq, lbl);
2754 if (classFileOffset >= bCodeStream.length) {
2758 bCodeStream[classFileOffset++] = OPC_if_icmpne;
2762 final public void ifeq(Label lbl) {
2763 if (DEBUG) System.out.println(position + "\t\tifeq:"+lbl); //$NON-NLS-1$
2766 if (this.wideMode) {
2767 generateWideRevertedConditionalBranch(OPC_ifne, lbl);
2769 if (classFileOffset >= bCodeStream.length) {
2773 bCodeStream[classFileOffset++] = OPC_ifeq;
2777 final public void ifge(Label lbl) {
2778 if (DEBUG) System.out.println(position + "\t\tifge:"+lbl); //$NON-NLS-1$
2781 if (this.wideMode) {
2782 generateWideRevertedConditionalBranch(OPC_iflt, lbl);
2784 if (classFileOffset >= bCodeStream.length) {
2788 bCodeStream[classFileOffset++] = OPC_ifge;
2792 final public void ifgt(Label lbl) {
2793 if (DEBUG) System.out.println(position + "\t\tifgt:"+lbl); //$NON-NLS-1$
2796 if (this.wideMode) {
2797 generateWideRevertedConditionalBranch(OPC_ifle, lbl);
2799 if (classFileOffset >= bCodeStream.length) {
2803 bCodeStream[classFileOffset++] = OPC_ifgt;
2807 final public void ifle(Label lbl) {
2808 if (DEBUG) System.out.println(position + "\t\tifle:"+lbl); //$NON-NLS-1$
2811 if (this.wideMode) {
2812 generateWideRevertedConditionalBranch(OPC_ifgt, lbl);
2814 if (classFileOffset >= bCodeStream.length) {
2818 bCodeStream[classFileOffset++] = OPC_ifle;
2822 final public void iflt(Label lbl) {
2823 if (DEBUG) System.out.println(position + "\t\tiflt:"+lbl); //$NON-NLS-1$
2826 if (this.wideMode) {
2827 generateWideRevertedConditionalBranch(OPC_ifge, lbl);
2829 if (classFileOffset >= bCodeStream.length) {
2833 bCodeStream[classFileOffset++] = OPC_iflt;
2837 final public void ifne(Label lbl) {
2838 if (DEBUG) System.out.println(position + "\t\tifne:"+lbl); //$NON-NLS-1$
2841 if (this.wideMode) {
2842 generateWideRevertedConditionalBranch(OPC_ifeq, lbl);
2844 if (classFileOffset >= bCodeStream.length) {
2848 bCodeStream[classFileOffset++] = OPC_ifne;
2852 final public void ifnonnull(Label lbl) {
2853 if (DEBUG) System.out.println(position + "\t\tifnonnull:"+lbl); //$NON-NLS-1$
2856 if (this.wideMode) {
2857 generateWideRevertedConditionalBranch(OPC_ifnull, lbl);
2859 if (classFileOffset >= bCodeStream.length) {
2863 bCodeStream[classFileOffset++] = OPC_ifnonnull;
2867 final public void ifnull(Label lbl) {
2868 if (DEBUG) System.out.println(position + "\t\tifnull:"+lbl); //$NON-NLS-1$
2871 if (this.wideMode) {
2872 generateWideRevertedConditionalBranch(OPC_ifnonnull, lbl);
2874 if (classFileOffset >= bCodeStream.length) {
2878 bCodeStream[classFileOffset++] = OPC_ifnull;
2882 final public void iinc(int index, int value) {
2883 if (DEBUG) System.out.println(position + "\t\tiinc:"+index+","+value); //$NON-NLS-1$ //$NON-NLS-2$
2885 if ((index > 255) || (value < -128 || value > 127)) { // have to widen
2886 if (classFileOffset + 3 >= bCodeStream.length) {
2890 bCodeStream[classFileOffset++] = OPC_wide;
2891 bCodeStream[classFileOffset++] = OPC_iinc;
2892 writeUnsignedShort(index);
2893 writeSignedShort(value);
2895 if (classFileOffset + 2 >= bCodeStream.length) {
2899 bCodeStream[classFileOffset++] = OPC_iinc;
2900 bCodeStream[classFileOffset++] = (byte) index;
2901 bCodeStream[classFileOffset++] = (byte) value;
2904 final public void iload(int iArg) {
2905 if (DEBUG) System.out.println(position + "\t\tiload:"+iArg); //$NON-NLS-1$
2908 if (maxLocals <= iArg) {
2909 maxLocals = iArg + 1;
2911 if (stackDepth > stackMax)
2912 stackMax = stackDepth;
2913 if (iArg > 255) { // Widen
2914 if (classFileOffset + 3 >= bCodeStream.length) {
2918 bCodeStream[classFileOffset++] = OPC_wide;
2919 bCodeStream[classFileOffset++] = OPC_iload;
2920 writeUnsignedShort(iArg);
2922 if (classFileOffset + 1 >= bCodeStream.length) {
2926 bCodeStream[classFileOffset++] = OPC_iload;
2927 bCodeStream[classFileOffset++] = (byte) iArg;
2930 final public void iload_0() {
2931 if (DEBUG) System.out.println(position + "\t\tiload_0"); //$NON-NLS-1$
2934 if (maxLocals <= 0) {
2937 if (stackDepth > stackMax)
2938 stackMax = stackDepth;
2939 if (classFileOffset >= bCodeStream.length) {
2943 bCodeStream[classFileOffset++] = OPC_iload_0;
2945 final public void iload_1() {
2946 if (DEBUG) System.out.println(position + "\t\tiload_1"); //$NON-NLS-1$
2949 if (maxLocals <= 1) {
2952 if (stackDepth > stackMax)
2953 stackMax = stackDepth;
2954 if (classFileOffset >= bCodeStream.length) {
2958 bCodeStream[classFileOffset++] = OPC_iload_1;
2960 final public void iload_2() {
2961 if (DEBUG) System.out.println(position + "\t\tiload_2"); //$NON-NLS-1$
2964 if (maxLocals <= 2) {
2967 if (stackDepth > stackMax)
2968 stackMax = stackDepth;
2969 if (classFileOffset >= bCodeStream.length) {
2973 bCodeStream[classFileOffset++] = OPC_iload_2;
2975 final public void iload_3() {
2976 if (DEBUG) System.out.println(position + "\t\tiload_3"); //$NON-NLS-1$
2979 if (maxLocals <= 3) {
2982 if (stackDepth > stackMax)
2983 stackMax = stackDepth;
2984 if (classFileOffset >= bCodeStream.length) {
2988 bCodeStream[classFileOffset++] = OPC_iload_3;
2990 final public void imul() {
2991 if (DEBUG) System.out.println(position + "\t\timul"); //$NON-NLS-1$
2994 if (classFileOffset >= bCodeStream.length) {
2998 bCodeStream[classFileOffset++] = OPC_imul;
3000 public void incrementTemp(LocalVariableBinding localBinding, int value) {
3001 if (value == (short) value) {
3002 this.iinc(localBinding.resolvedPosition, value);
3008 store(localBinding, false);
3010 public void incrStackSize(int offset) {
3011 if ((stackDepth += offset) > stackMax)
3012 stackMax = stackDepth;
3014 public int indexOfSameLineEntrySincePC(int pc, int line) {
3015 for (int index = pc, max = pcToSourceMapSize; index < max; index+=2) {
3016 if (pcToSourceMap[index+1] == line)
3021 final public void ineg() {
3022 if (DEBUG) System.out.println(position + "\t\tineg"); //$NON-NLS-1$
3024 if (classFileOffset >= bCodeStream.length) {
3028 bCodeStream[classFileOffset++] = OPC_ineg;
3030 public void init(ClassFile targetClassFile) {
3031 this.classFile = targetClassFile;
3032 this.constantPool = targetClassFile.constantPool;
3033 this.bCodeStream = targetClassFile.contents;
3034 this.classFileOffset = targetClassFile.contentsOffset;
3035 this.startingClassFileOffset = this.classFileOffset;
3036 pcToSourceMapSize = 0;
3038 int length = visibleLocals.length;
3039 if (noVisibleLocals.length < length) {
3040 noVisibleLocals = new LocalVariableBinding[length];
3042 System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
3043 visibleLocalsCount = 0;
3045 length = locals.length;
3046 if (noLocals.length < length) {
3047 noLocals = new LocalVariableBinding[length];
3049 System.arraycopy(noLocals, 0, locals, 0, length);
3050 allLocalsCounter = 0;
3052 length = exceptionHandlers.length;
3053 if (noExceptionHandlers.length < length) {
3054 noExceptionHandlers = new ExceptionLabel[length];
3056 System.arraycopy(noExceptionHandlers, 0, exceptionHandlers, 0, length);
3057 exceptionHandlersIndex = 0;
3058 exceptionHandlersCounter = 0;
3060 length = labels.length;
3061 if (noLabels.length < length) {
3062 noLabels = new Label[length];
3064 System.arraycopy(noLabels, 0, labels, 0, length);
3073 * @param methodBinding the given method binding to initialize the max locals
3075 public void initializeMaxLocals(MethodBinding methodBinding) {
3077 if (methodBinding == null) {
3082 this.maxLocals = methodBinding.isStatic() ? 0 : 1;
3084 // take into account enum constructor synthetic name+ordinal
3085 if (methodBinding.isConstructor() && methodBinding.declaringClass.isEnum()) {
3086 this.maxLocals += 2; // String and int (enum constant name+ordinal)
3089 // take into account the synthetic parameters
3090 if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
3091 ReferenceBinding enclosingInstanceTypes[];
3092 if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
3093 for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
3094 this.maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
3095 // LongBinding or DoubleBinding
3098 SyntheticArgumentBinding syntheticArguments[];
3099 if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
3100 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
3101 TypeBinding argType;
3102 if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) {
3103 this.maxLocals += 2;
3110 TypeBinding[] arguments;
3111 if ((arguments = methodBinding.parameters) != null) {
3112 for (int i = 0, max = arguments.length; i < max; i++) {
3113 TypeBinding argType;
3114 if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) {
3115 this.maxLocals += 2;
3123 * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
3124 * If there is an existing entry it returns -1 (no insertion required).
3125 * Otherwise it returns the index where the entry for the pc has to be inserted.
3126 * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
3128 * @param pcToSourceMap the given pcToSourceMap array
3129 * @param length the given length
3130 * @param pc the given pc
3133 public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
3139 // we search only on even indexes
3142 int currentPC = pcToSourceMap[m];
3143 if (pc < currentPC) {
3146 if (pc > currentPC) {
3152 if (pc < pcToSourceMap[m])
3157 * We didn't call it instanceof because there is a conflit with the
3158 * instanceof keyword
3160 final public void instance_of(TypeBinding typeBinding) {
3161 if (DEBUG) System.out.println(position + "\t\tinstance_of:"+typeBinding); //$NON-NLS-1$
3163 if (classFileOffset + 2 >= bCodeStream.length) {
3167 bCodeStream[classFileOffset++] = OPC_instanceof;
3168 writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
3170 public void invokeClassForName() {
3171 // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
3172 if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$
3176 1, // return type size
3177 ConstantPool.JavaLangClassConstantPoolName,
3178 ConstantPool.ForName,
3179 ConstantPool.ForNameSignature);
3181 public void invokeJavaLangClassDesiredAssertionStatus() {
3182 // invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
3183 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$
3187 1, // return type size
3188 ConstantPool.JavaLangClassConstantPoolName,
3189 ConstantPool.DesiredAssertionStatus,
3190 ConstantPool.DesiredAssertionStatusSignature);
3193 public void invokeJavaLangClassGetComponentType() {
3194 // invokevirtual: java.lang.Class.getComponentType()java.lang.Class;
3195 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.getComponentType()java.lang.Class;"); //$NON-NLS-1$
3199 1, // return type size
3200 ConstantPool.JavaLangClassConstantPoolName,
3201 ConstantPool.GetComponentType,
3202 ConstantPool.GetComponentTypeSignature);
3204 public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
3205 // invokevirtual: <enumConstantPoolName>.ordinal()
3206 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: "+new String(enumTypeConstantPoolName)+".ordinal()"); //$NON-NLS-1$ //$NON-NLS-2$
3210 1, // return type size
3211 enumTypeConstantPoolName,
3212 ConstantPool.Ordinal,
3213 ConstantPool.OrdinalSignature);
3215 final public void invokeinterface(MethodBinding methodBinding) {
3216 // initialized to 1 to take into account this immediately
3217 if (DEBUG) System.out.println(position + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$
3221 if (classFileOffset + 4 >= bCodeStream.length) {
3225 bCodeStream[classFileOffset++] = OPC_invokeinterface;
3226 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3227 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3228 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3232 bCodeStream[classFileOffset++] = (byte) argCount;
3233 // Generate a 0 into the byte array. Like the array is already fill with 0, we just need to increment
3234 // the number of bytes.
3235 bCodeStream[classFileOffset++] = 0;
3236 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long)) {
3237 stackDepth += (2 - argCount);
3240 stackDepth -= argCount;
3242 stackDepth += (1 - argCount);
3245 if (stackDepth > stackMax) {
3246 stackMax = stackDepth;
3249 public void invokeJavaLangErrorConstructor() {
3250 // invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
3251 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.Error<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3255 0, // return type size
3256 ConstantPool.JavaLangErrorConstantPoolName,
3258 ConstantPool.StringConstructorSignature);
3260 public void invokeNoClassDefFoundErrorStringConstructor() {
3261 // invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
3262 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3266 0, // return type size
3267 ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName,
3269 ConstantPool.StringConstructorSignature);
3271 public void invokeObjectGetClass() {
3272 // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
3273 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$
3277 1, // return type size
3278 ConstantPool.JavaLangObjectConstantPoolName,
3279 ConstantPool.GetClass,
3280 ConstantPool.GetClassSignature);
3283 final public void invokespecial(MethodBinding methodBinding) {
3284 if (DEBUG) System.out.println(position + "\t\tinvokespecial:"+methodBinding); //$NON-NLS-1$
3285 // initialized to 1 to take into account this immediately
3289 if (classFileOffset + 2 >= bCodeStream.length) {
3293 bCodeStream[classFileOffset++] = OPC_invokespecial;
3294 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3295 if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
3296 // enclosing instances
3297 TypeBinding[] syntheticArgumentTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes();
3298 if (syntheticArgumentTypes != null) {
3299 for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
3300 if (((id = syntheticArgumentTypes[i].id) == T_double) || (id == T_long)) {
3307 // outer local variables
3308 SyntheticArgumentBinding[] syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables();
3309 if (syntheticArguments != null) {
3310 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
3311 if (((id = syntheticArguments[i].type.id) == T_double) || (id == T_long)) {
3319 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3320 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3324 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3325 stackDepth += (2 - argCount);
3328 stackDepth -= argCount;
3330 stackDepth += (1 - argCount);
3331 if (stackDepth > stackMax)
3332 stackMax = stackDepth;
3334 final public void invokestatic(MethodBinding methodBinding) {
3335 if (DEBUG) System.out.println(position + "\t\tinvokestatic:"+methodBinding); //$NON-NLS-1$
3336 // initialized to 0 to take into account that there is no this for
3341 if (classFileOffset + 2 >= bCodeStream.length) {
3345 bCodeStream[classFileOffset++] = OPC_invokestatic;
3346 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3347 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3348 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3352 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3353 stackDepth += (2 - argCount);
3356 stackDepth -= argCount;
3358 stackDepth += (1 - argCount);
3359 if (stackDepth > stackMax)
3360 stackMax = stackDepth;
3363 * The equivalent code performs a string conversion of the TOS
3364 * @param typeID <CODE>int</CODE>
3366 public void invokeStringConcatenationAppendForType(int typeID) {
3368 if (this.targetLevel >= JDK1_5) {
3369 System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuilder.append(...)"); //$NON-NLS-1$
3371 System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$
3376 char[] declarinClass = null;
3377 char[] selector = ConstantPool.Append;
3378 char[] signature = null;
3383 if (this.targetLevel >= JDK1_5) {
3384 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3385 signature = ConstantPool.StringBuilderAppendIntSignature;
3387 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3388 signature = ConstantPool.StringBufferAppendIntSignature;
3392 if (this.targetLevel >= JDK1_5) {
3393 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3394 signature = ConstantPool.StringBuilderAppendLongSignature;
3396 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3397 signature = ConstantPool.StringBufferAppendLongSignature;
3402 if (this.targetLevel >= JDK1_5) {
3403 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3404 signature = ConstantPool.StringBuilderAppendFloatSignature;
3406 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3407 signature = ConstantPool.StringBufferAppendFloatSignature;
3411 if (this.targetLevel >= JDK1_5) {
3412 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3413 signature = ConstantPool.StringBuilderAppendDoubleSignature;
3415 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3416 signature = ConstantPool.StringBufferAppendDoubleSignature;
3421 if (this.targetLevel >= JDK1_5) {
3422 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3423 signature = ConstantPool.StringBuilderAppendCharSignature;
3425 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3426 signature = ConstantPool.StringBufferAppendCharSignature;
3430 if (this.targetLevel >= JDK1_5) {
3431 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3432 signature = ConstantPool.StringBuilderAppendBooleanSignature;
3434 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3435 signature = ConstantPool.StringBufferAppendBooleanSignature;
3439 case T_JavaLangObject :
3441 if (this.targetLevel >= JDK1_5) {
3442 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3443 signature = ConstantPool.StringBuilderAppendObjectSignature;
3445 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3446 signature = ConstantPool.StringBufferAppendObjectSignature;
3449 case T_JavaLangString :
3450 if (this.targetLevel >= JDK1_5) {
3451 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3452 signature = ConstantPool.StringBuilderAppendStringSignature;
3454 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3455 signature = ConstantPool.StringBufferAppendStringSignature;
3461 argCount, // argCount
3462 returnType, // return type size
3468 public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
3469 // invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
3470 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>(typeBindingID)V"); //$NON-NLS-1$
3472 char[] signature = null;
3473 switch (typeBindingID) {
3477 signature = ConstantPool.IntConstrSignature;
3480 signature = ConstantPool.LongConstrSignature;
3484 signature = ConstantPool.FloatConstrSignature;
3487 signature = ConstantPool.DoubleConstrSignature;
3491 signature = ConstantPool.CharConstrSignature;
3494 signature = ConstantPool.BooleanConstrSignature;
3496 case T_JavaLangObject :
3497 case T_JavaLangString :
3499 signature = ConstantPool.ObjectConstrSignature;
3504 argCount, // argCount
3505 0, // return type size
3506 ConstantPool.JavaLangAssertionErrorConstantPoolName,
3511 public void invokeJavaLangAssertionErrorDefaultConstructor() {
3512 // invokespecial: java.lang.AssertionError.<init>()V
3513 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>()V"); //$NON-NLS-1$
3517 0, // return type size
3518 ConstantPool.JavaLangAssertionErrorConstantPoolName,
3520 ConstantPool.DefaultConstructorSignature);
3522 public void invokeJavaLangEnumname(TypeBinding typeBinding) {
3523 // invokevirtual: java.lang.Enum.name()String
3524 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Enum.name()Ljava/lang/String;"); //$NON-NLS-1$
3529 typeBinding.constantPoolName(),
3531 ConstantPool.NameSignature);
3533 public void invokeJavaLangIllegalArgumentExceptionStringConstructor() {
3534 // invokespecial: java.lang.IllegalArgumentException.<init>(String)V
3535 if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.IllegalArgumentException.<init>(java.lang.String)V"); //$NON-NLS-1$
3539 0, // return type size
3540 ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName,
3542 ConstantPool.StringConstructorSignature);
3545 public void invokeJavaUtilIteratorHasNext() {
3546 // invokeinterface java.util.Iterator.hasNext()Z
3547 if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.hasNext()Z"); //$NON-NLS-1$
3549 OPC_invokeinterface,
3551 1, // return type size
3552 ConstantPool.JavaUtilIteratorConstantPoolName,
3553 ConstantPool.HasNext,
3554 ConstantPool.HasNextSignature);
3556 public void invokeJavaUtilIteratorNext() {
3557 // invokeinterface java.util.Iterator.next()java.lang.Object
3558 if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.next()java.lang.Object"); //$NON-NLS-1$
3560 OPC_invokeinterface,
3562 1, // return type size
3563 ConstantPool.JavaUtilIteratorConstantPoolName,
3565 ConstantPool.NextSignature);
3567 public void invokeStringConcatenationDefaultConstructor() {
3568 // invokespecial: java.lang.StringBuffer.<init>()V
3570 if (this.targetLevel >= JDK1_5) {
3571 System.out.println(position + "\t\tinvokespecial: java.lang.StringBuilder.<init>()V"); //$NON-NLS-1$
3573 System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.<init>()V"); //$NON-NLS-1$
3576 char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3577 if (this.targetLevel >= JDK1_5) {
3578 declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3583 0, // return type size
3586 ConstantPool.DefaultConstructorSignature);
3588 public void invokeStringConcatenationStringConstructor() {
3590 if (this.targetLevel >= JDK1_5) {
3591 System.out.println(position + "\t\tjava.lang.StringBuilder.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3593 System.out.println(position + "\t\tjava.lang.StringBuffer.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3596 char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3597 if (this.targetLevel >= JDK1_5) {
3598 declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3603 0, // return type size
3606 ConstantPool.StringConstructorSignature);
3609 public void invokeStringConcatenationToString() {
3611 if (this.targetLevel >= JDK1_5) {
3612 System.out.println(position + "\t\tinvokevirtual: StringBuilder.toString()Ljava.lang.String;"); //$NON-NLS-1$
3614 System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$
3617 char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3618 if (this.targetLevel >= JDK1_5) {
3619 declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3624 1, // return type size
3626 ConstantPool.ToString,
3627 ConstantPool.ToStringSignature);
3629 public void invokeStringEquals() {
3630 // invokevirtual: java.lang.String.equals(java.lang.Object)
3631 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.equals(...)"); //$NON-NLS-1$
3635 1, // return type size
3636 ConstantPool.JavaLangStringConstantPoolName,
3637 ConstantPool.Equals,
3638 ConstantPool.EqualsSignature);
3640 public void invokeStringIntern() {
3641 // invokevirtual: java.lang.String.intern()
3642 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$
3646 1, // return type size
3647 ConstantPool.JavaLangStringConstantPoolName,
3648 ConstantPool.Intern,
3649 ConstantPool.InternSignature);
3651 public void invokeStringValueOf(int typeID) {
3652 // invokestatic: java.lang.String.valueOf(argumentType)
3653 if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$
3655 char[] signature = null;
3660 signature = ConstantPool.ValueOfIntSignature;
3663 signature = ConstantPool.ValueOfLongSignature;
3667 signature = ConstantPool.ValueOfFloatSignature;
3670 signature = ConstantPool.ValueOfDoubleSignature;
3674 signature = ConstantPool.ValueOfCharSignature;
3677 signature = ConstantPool.ValueOfBooleanSignature;
3679 case T_JavaLangObject :
3680 case T_JavaLangString :
3683 signature = ConstantPool.ValueOfObjectSignature;
3688 argCount, // argCount
3689 1, // return type size
3690 ConstantPool.JavaLangStringConstantPoolName,
3691 ConstantPool.ValueOf,
3694 public void invokeSystemArraycopy() {
3695 // invokestatic #21 <Method java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>
3696 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V"); //$NON-NLS-1$
3700 0, // return type size
3701 ConstantPool.JavaLangSystemConstantPoolName,
3702 ConstantPool.ArrayCopy,
3703 ConstantPool.ArrayCopySignature);
3705 public void invokeThrowableGetMessage() {
3706 // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
3707 if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$
3711 1, // return type size
3712 ConstantPool.JavaLangThrowableConstantPoolName,
3713 ConstantPool.GetMessage,
3714 ConstantPool.GetMessageSignature);
3716 final public void invoke(int opcode, int argsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
3718 int argCount = argsSize;
3720 case OPC_invokeinterface :
3721 if (classFileOffset + 4 >= bCodeStream.length) {
3725 bCodeStream[classFileOffset++] = OPC_invokeinterface;
3726 writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
3728 bCodeStream[classFileOffset++] = (byte) argCount;
3729 bCodeStream[classFileOffset++] = 0;
3731 case OPC_invokevirtual :
3732 case OPC_invokespecial :
3733 if (classFileOffset + 2 >= bCodeStream.length) {
3737 bCodeStream[classFileOffset++] = (byte) opcode;
3738 writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3741 case OPC_invokestatic :
3742 if (classFileOffset + 2 >= bCodeStream.length) {
3746 bCodeStream[classFileOffset++] = OPC_invokestatic;
3747 writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3749 stackDepth += returnTypeSize - argCount;
3750 if (stackDepth > stackMax) {
3751 stackMax = stackDepth;
3754 final public void invokevirtual(MethodBinding methodBinding) {
3755 if (DEBUG) System.out.println(position + "\t\tinvokevirtual:"+methodBinding); //$NON-NLS-1$
3756 // initialized to 1 to take into account this immediately
3760 if (classFileOffset + 2 >= bCodeStream.length) {
3764 bCodeStream[classFileOffset++] = OPC_invokevirtual;
3765 writeUnsignedShort(constantPool.literalIndex(methodBinding));
3766 for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3767 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3771 if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3772 stackDepth += (2 - argCount);
3775 stackDepth -= argCount;
3777 stackDepth += (1 - argCount);
3778 if (stackDepth > stackMax)
3779 stackMax = stackDepth;
3781 final public void ior() {
3782 if (DEBUG) System.out.println(position + "\t\tior"); //$NON-NLS-1$
3785 if (classFileOffset >= bCodeStream.length) {
3789 bCodeStream[classFileOffset++] = OPC_ior;
3791 final public void irem() {
3792 if (DEBUG) System.out.println(position + "\t\tirem"); //$NON-NLS-1$
3795 if (classFileOffset >= bCodeStream.length) {
3799 bCodeStream[classFileOffset++] = OPC_irem;
3801 final public void ireturn() {
3802 if (DEBUG) System.out.println(position + "\t\tireturn"); //$NON-NLS-1$
3805 // the stackDepth should be equal to 0
3806 if (classFileOffset >= bCodeStream.length) {
3810 bCodeStream[classFileOffset++] = OPC_ireturn;
3812 public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
3813 // Dependant of UnconditionalFlowInfo.isDefinitelyAssigned(..)
3814 if (initStateIndex == -1)
3816 if (local.isArgument) {
3819 int localPosition = local.id + maxFieldCount;
3820 MethodScope methodScope = scope.methodScope();
3822 if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
3823 return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 0; // use bits
3826 long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
3827 if (extraInits == null)
3828 return false; // if vector not yet allocated, then not initialized
3830 if ((vectorIndex = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
3831 return false; // if not enough room in vector, then not initialized
3832 return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
3834 final public void ishl() {
3835 if (DEBUG) System.out.println(position + "\t\tishl"); //$NON-NLS-1$
3838 if (classFileOffset >= bCodeStream.length) {
3842 bCodeStream[classFileOffset++] = OPC_ishl;
3844 final public void ishr() {
3845 if (DEBUG) System.out.println(position + "\t\tishr"); //$NON-NLS-1$
3848 if (classFileOffset >= bCodeStream.length) {
3852 bCodeStream[classFileOffset++] = OPC_ishr;
3854 final public void istore(int iArg) {
3855 if (DEBUG) System.out.println(position + "\t\tistore:"+iArg); //$NON-NLS-1$
3858 if (maxLocals <= iArg) {
3859 maxLocals = iArg + 1;
3861 if (iArg > 255) { // Widen
3862 if (classFileOffset + 3 >= bCodeStream.length) {
3866 bCodeStream[classFileOffset++] = OPC_wide;
3867 bCodeStream[classFileOffset++] = OPC_istore;
3868 writeUnsignedShort(iArg);
3870 if (classFileOffset + 1 >= bCodeStream.length) {
3874 bCodeStream[classFileOffset++] = OPC_istore;
3875 bCodeStream[classFileOffset++] = (byte) iArg;
3878 final public void istore_0() {
3879 if (DEBUG) System.out.println(position + "\t\tistore_0"); //$NON-NLS-1$
3882 if (maxLocals == 0) {
3885 if (classFileOffset >= bCodeStream.length) {
3889 bCodeStream[classFileOffset++] = OPC_istore_0;
3891 final public void istore_1() {
3892 if (DEBUG) System.out.println(position + "\t\tistore_1"); //$NON-NLS-1$
3895 if (maxLocals <= 1) {
3898 if (classFileOffset >= bCodeStream.length) {
3902 bCodeStream[classFileOffset++] = OPC_istore_1;
3904 final public void istore_2() {
3905 if (DEBUG) System.out.println(position + "\t\tistore_2"); //$NON-NLS-1$
3908 if (maxLocals <= 2) {
3911 if (classFileOffset >= bCodeStream.length) {
3915 bCodeStream[classFileOffset++] = OPC_istore_2;
3917 final public void istore_3() {
3918 if (DEBUG) System.out.println(position + "\t\tistore_3"); //$NON-NLS-1$
3921 if (maxLocals <= 3) {
3924 if (classFileOffset >= bCodeStream.length) {
3928 bCodeStream[classFileOffset++] = OPC_istore_3;
3930 final public void isub() {
3931 if (DEBUG) System.out.println(position + "\t\tisub"); //$NON-NLS-1$
3934 if (classFileOffset >= bCodeStream.length) {
3938 bCodeStream[classFileOffset++] = OPC_isub;
3940 final public void iushr() {
3941 if (DEBUG) System.out.println(position + "\t\tiushr"); //$NON-NLS-1$
3944 if (classFileOffset >= bCodeStream.length) {
3948 bCodeStream[classFileOffset++] = OPC_iushr;
3950 final public void ixor() {
3951 if (DEBUG) System.out.println(position + "\t\tixor"); //$NON-NLS-1$
3954 if (classFileOffset >= bCodeStream.length) {
3958 bCodeStream[classFileOffset++] = OPC_ixor;
3960 final public void jsr(Label lbl) {
3961 if (this.wideMode) {
3965 if (DEBUG) System.out.println(position + "\t\tjsr"+lbl); //$NON-NLS-1$
3967 if (classFileOffset >= bCodeStream.length) {
3971 bCodeStream[classFileOffset++] = OPC_jsr;
3974 final public void jsr_w(Label lbl) {
3975 if (DEBUG) System.out.println(position + "\t\tjsr_w"+lbl); //$NON-NLS-1$
3977 if (classFileOffset >= bCodeStream.length) {
3981 bCodeStream[classFileOffset++] = OPC_jsr_w;
3984 final public void l2d() {
3985 if (DEBUG) System.out.println(position + "\t\tl2d"); //$NON-NLS-1$
3987 if (classFileOffset >= bCodeStream.length) {
3991 bCodeStream[classFileOffset++] = OPC_l2d;
3993 final public void l2f() {
3994 if (DEBUG) System.out.println(position + "\t\tl2f"); //$NON-NLS-1$
3997 if (classFileOffset >= bCodeStream.length) {
4001 bCodeStream[classFileOffset++] = OPC_l2f;
4003 final public void l2i() {
4004 if (DEBUG) System.out.println(position + "\t\tl2i"); //$NON-NLS-1$
4007 if (classFileOffset >= bCodeStream.length) {
4011 bCodeStream[classFileOffset++] = OPC_l2i;
4013 final public void ladd() {
4014 if (DEBUG) System.out.println(position + "\t\tladd"); //$NON-NLS-1$
4017 if (classFileOffset >= bCodeStream.length) {
4021 bCodeStream[classFileOffset++] = OPC_ladd;
4023 final public void laload() {
4024 if (DEBUG) System.out.println(position + "\t\tlaload"); //$NON-NLS-1$
4026 if (classFileOffset >= bCodeStream.length) {
4030 bCodeStream[classFileOffset++] = OPC_laload;
4032 final public void land() {
4033 if (DEBUG) System.out.println(position + "\t\tland"); //$NON-NLS-1$
4036 if (classFileOffset >= bCodeStream.length) {
4040 bCodeStream[classFileOffset++] = OPC_land;
4042 final public void lastore() {
4043 if (DEBUG) System.out.println(position + "\t\tlastore"); //$NON-NLS-1$
4046 if (classFileOffset >= bCodeStream.length) {
4050 bCodeStream[classFileOffset++] = OPC_lastore;
4052 final public void lcmp() {
4053 if (DEBUG) System.out.println(position + "\t\tlcmp"); //$NON-NLS-1$
4056 if (classFileOffset >= bCodeStream.length) {
4060 bCodeStream[classFileOffset++] = OPC_lcmp;
4062 final public void lconst_0() {
4063 if (DEBUG) System.out.println(position + "\t\tlconst_0"); //$NON-NLS-1$
4066 if (stackDepth > stackMax)
4067 stackMax = stackDepth;
4068 if (classFileOffset >= bCodeStream.length) {
4072 bCodeStream[classFileOffset++] = OPC_lconst_0;
4074 final public void lconst_1() {
4075 if (DEBUG) System.out.println(position + "\t\tlconst_1"); //$NON-NLS-1$
4078 if (stackDepth > stackMax)
4079 stackMax = stackDepth;
4080 if (classFileOffset >= bCodeStream.length) {
4084 bCodeStream[classFileOffset++] = OPC_lconst_1;
4086 final public void ldc(float constant) {
4088 int index = constantPool.literalIndex(constant);
4090 if (stackDepth > stackMax)
4091 stackMax = stackDepth;
4093 if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4095 if (classFileOffset + 2 >= bCodeStream.length) {
4099 bCodeStream[classFileOffset++] = OPC_ldc_w;
4100 writeUnsignedShort(index);
4102 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4104 if (classFileOffset + 1 >= bCodeStream.length) {
4108 bCodeStream[classFileOffset++] = OPC_ldc;
4109 bCodeStream[classFileOffset++] = (byte) index;
4112 final public void ldc(int constant) {
4114 int index = constantPool.literalIndex(constant);
4116 if (stackDepth > stackMax)
4117 stackMax = stackDepth;
4119 if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4121 if (classFileOffset + 2 >= bCodeStream.length) {
4125 bCodeStream[classFileOffset++] = OPC_ldc_w;
4126 writeUnsignedShort(index);
4128 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4130 if (classFileOffset + 1 >= bCodeStream.length) {
4134 bCodeStream[classFileOffset++] = OPC_ldc;
4135 bCodeStream[classFileOffset++] = (byte) index;
4138 final public void ldc(String constant) {
4140 int currentConstantPoolIndex = constantPool.currentIndex;
4141 int currentConstantPoolOffset = constantPool.currentOffset;
4142 int currentCodeStreamPosition = position;
4143 int index = constantPool.literalIndexForLdc(constant.toCharArray());
4145 // the string already exists inside the constant pool
4146 // we reuse the same index
4148 if (stackDepth > stackMax)
4149 stackMax = stackDepth;
4151 if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4153 if (classFileOffset + 2 >= bCodeStream.length) {
4157 bCodeStream[classFileOffset++] = OPC_ldc_w;
4158 writeUnsignedShort(index);
4160 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4162 if (classFileOffset + 1 >= bCodeStream.length) {
4166 bCodeStream[classFileOffset++] = OPC_ldc;
4167 bCodeStream[classFileOffset++] = (byte) index;
4170 // the string is too big to be utf8-encoded in one pass.
4171 // we have to split it into different pieces.
4172 // first we clean all side-effects due to the code above
4173 // this case is very rare, so we can afford to lose time to handle it
4174 char[] constantChars = constant.toCharArray();
4175 position = currentCodeStreamPosition;
4176 constantPool.currentIndex = currentConstantPoolIndex;
4177 constantPool.currentOffset = currentConstantPoolOffset;
4178 constantPool.stringCache.remove(constantChars);
4179 constantPool.UTF8Cache.remove(constantChars);
4182 int constantLength = constant.length();
4183 byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
4184 int utf8encodingLength = 0;
4185 while ((length < 65532) && (i < constantLength)) {
4186 char current = constantChars[i];
4187 // we resize the byte array immediately if necessary
4188 if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
4189 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
4191 if ((current >= 0x0001) && (current <= 0x007F)) {
4192 // we only need one byte: ASCII table
4193 utf8encoding[length++] = (byte) current;
4195 if (current > 0x07FF) {
4197 utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
4198 utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
4199 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4201 // we can be 0 or between 0x0080 and 0x07FF
4202 // In that case we only need 2 bytes
4203 utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
4204 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4209 // check if all the string is encoded (PR 1PR2DWJ)
4210 // the string is too big to be encoded in one pass
4211 newStringContatenation();
4213 // write the first part
4214 char[] subChars = new char[i];
4215 System.arraycopy(constantChars, 0, subChars, 0, i);
4216 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
4217 index = constantPool.literalIndex(subChars, utf8encoding);
4219 if (stackDepth > stackMax)
4220 stackMax = stackDepth;
4223 if (classFileOffset + 2 >= bCodeStream.length) {
4227 bCodeStream[classFileOffset++] = OPC_ldc_w;
4228 writeUnsignedShort(index);
4231 if (classFileOffset + 1 >= bCodeStream.length) {
4235 bCodeStream[classFileOffset++] = OPC_ldc;
4236 bCodeStream[classFileOffset++] = (byte) index;
4238 // write the remaining part
4239 invokeStringConcatenationStringConstructor();
4240 while (i < constantLength) {
4242 utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
4244 while ((length < 65532) && (i < constantLength)) {
4245 char current = constantChars[i];
4246 // we resize the byte array immediately if necessary
4247 if (constantLength + 2 > (utf8encodingLength = utf8encoding.length)) {
4248 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
4250 if ((current >= 0x0001) && (current <= 0x007F)) {
4251 // we only need one byte: ASCII table
4252 utf8encoding[length++] = (byte) current;
4254 if (current > 0x07FF) {
4256 utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
4257 utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
4258 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4260 // we can be 0 or between 0x0080 and 0x07FF
4261 // In that case we only need 2 bytes
4262 utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
4263 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4268 // the next part is done
4269 subChars = new char[i - startIndex];
4270 System.arraycopy(constantChars, startIndex, subChars, 0, i - startIndex);
4271 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
4272 index = constantPool.literalIndex(subChars, utf8encoding);
4274 if (stackDepth > stackMax)
4275 stackMax = stackDepth;
4278 if (classFileOffset + 2 >= bCodeStream.length) {
4282 bCodeStream[classFileOffset++] = OPC_ldc_w;
4283 writeUnsignedShort(index);
4286 if (classFileOffset + 1 >= bCodeStream.length) {
4290 bCodeStream[classFileOffset++] = OPC_ldc;
4291 bCodeStream[classFileOffset++] = (byte) index;
4293 // now on the stack it should be a StringBuffer and a string.
4294 invokeStringConcatenationAppendForType(T_JavaLangString);
4296 invokeStringConcatenationToString();
4297 invokeStringIntern();
4300 final public void ldc(TypeBinding typeBinding) {
4302 int index = constantPool.literalIndexForType(typeBinding.constantPoolName());
4304 if (stackDepth > stackMax)
4305 stackMax = stackDepth;
4307 if (DEBUG) System.out.println(position + "\t\tldc_w:"+ typeBinding); //$NON-NLS-1$
4309 if (classFileOffset + 2 >= bCodeStream.length) {
4313 bCodeStream[classFileOffset++] = OPC_ldc_w;
4314 writeUnsignedShort(index);
4316 if (DEBUG) System.out.println(position + "\t\tldw:"+ typeBinding); //$NON-NLS-1$
4318 if (classFileOffset + 1 >= bCodeStream.length) {
4322 bCodeStream[classFileOffset++] = OPC_ldc;
4323 bCodeStream[classFileOffset++] = (byte) index;
4326 final public void ldc2_w(double constant) {
4327 if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
4329 int index = constantPool.literalIndex(constant);
4331 if (stackDepth > stackMax)
4332 stackMax = stackDepth;
4333 // Generate a ldc2_w
4334 if (classFileOffset + 2 >= bCodeStream.length) {
4338 bCodeStream[classFileOffset++] = OPC_ldc2_w;
4339 writeUnsignedShort(index);
4341 final public void ldc2_w(long constant) {
4342 if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
4344 int index = constantPool.literalIndex(constant);
4346 if (stackDepth > stackMax)
4347 stackMax = stackDepth;
4348 // Generate a ldc2_w
4349 if (classFileOffset + 2 >= bCodeStream.length) {
4353 bCodeStream[classFileOffset++] = OPC_ldc2_w;
4354 writeUnsignedShort(index);
4356 final public void ldiv() {
4357 if (DEBUG) System.out.println(position + "\t\tldiv"); //$NON-NLS-1$
4360 if (classFileOffset >= bCodeStream.length) {
4364 bCodeStream[classFileOffset++] = OPC_ldiv;
4366 final public void lload(int iArg) {
4367 if (DEBUG) System.out.println(position + "\t\tlload:"+iArg); //$NON-NLS-1$
4370 if (maxLocals <= iArg + 1) {
4371 maxLocals = iArg + 2;
4373 if (stackDepth > stackMax)
4374 stackMax = stackDepth;
4375 if (iArg > 255) { // Widen
4376 if (classFileOffset + 3 >= bCodeStream.length) {
4380 bCodeStream[classFileOffset++] = OPC_wide;
4381 bCodeStream[classFileOffset++] = OPC_lload;
4382 writeUnsignedShort(iArg);
4384 if (classFileOffset + 1 >= bCodeStream.length) {
4388 bCodeStream[classFileOffset++] = OPC_lload;
4389 bCodeStream[classFileOffset++] = (byte) iArg;
4392 final public void lload_0() {
4393 if (DEBUG) System.out.println(position + "\t\tlload_0"); //$NON-NLS-1$
4396 if (maxLocals < 2) {
4399 if (stackDepth > stackMax)
4400 stackMax = stackDepth;
4401 if (classFileOffset >= bCodeStream.length) {
4405 bCodeStream[classFileOffset++] = OPC_lload_0;
4407 final public void lload_1() {
4408 if (DEBUG) System.out.println(position + "\t\tlload_1"); //$NON-NLS-1$
4411 if (maxLocals < 3) {
4414 if (stackDepth > stackMax)
4415 stackMax = stackDepth;
4416 if (classFileOffset >= bCodeStream.length) {
4420 bCodeStream[classFileOffset++] = OPC_lload_1;
4422 final public void lload_2() {
4423 if (DEBUG) System.out.println(position + "\t\tlload_2"); //$NON-NLS-1$
4426 if (maxLocals < 4) {
4429 if (stackDepth > stackMax)
4430 stackMax = stackDepth;
4431 if (classFileOffset >= bCodeStream.length) {
4435 bCodeStream[classFileOffset++] = OPC_lload_2;
4437 final public void lload_3() {
4438 if (DEBUG) System.out.println(position + "\t\tlload_3"); //$NON-NLS-1$
4441 if (maxLocals < 5) {
4444 if (stackDepth > stackMax)
4445 stackMax = stackDepth;
4446 if (classFileOffset >= bCodeStream.length) {
4450 bCodeStream[classFileOffset++] = OPC_lload_3;
4452 final public void lmul() {
4453 if (DEBUG) System.out.println(position + "\t\tlmul"); //$NON-NLS-1$
4456 if (classFileOffset >= bCodeStream.length) {
4460 bCodeStream[classFileOffset++] = OPC_lmul;
4462 final public void lneg() {
4463 if (DEBUG) System.out.println(position + "\t\tlneg"); //$NON-NLS-1$
4465 if (classFileOffset >= bCodeStream.length) {
4469 bCodeStream[classFileOffset++] = OPC_lneg;
4471 public final void load(LocalVariableBinding localBinding) {
4473 TypeBinding typeBinding = localBinding.type;
4474 int resolvedPosition = localBinding.resolvedPosition;
4475 // Using dedicated int bytecode
4476 if (typeBinding == IntBinding) {
4477 switch (resolvedPosition) {
4491 // internal failure: trying to load variable not supposed to be generated
4494 this.iload(resolvedPosition);
4498 // Using dedicated float bytecode
4499 if (typeBinding == FloatBinding) {
4500 switch (resolvedPosition) {
4514 this.fload(resolvedPosition);
4518 // Using dedicated long bytecode
4519 if (typeBinding == LongBinding) {
4520 switch (resolvedPosition) {
4534 this.lload(resolvedPosition);
4538 // Using dedicated double bytecode
4539 if (typeBinding == DoubleBinding) {
4540 switch (resolvedPosition) {
4554 this.dload(resolvedPosition);
4558 // boolean, byte, char and short are handled as int
4559 if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
4560 switch (resolvedPosition) {
4574 this.iload(resolvedPosition);
4580 switch (resolvedPosition) {
4594 this.aload(resolvedPosition);
4597 public final void load(TypeBinding typeBinding, int resolvedPosition) {
4599 // Using dedicated int bytecode
4600 if (typeBinding == IntBinding) {
4601 switch (resolvedPosition) {
4615 this.iload(resolvedPosition);
4619 // Using dedicated float bytecode
4620 if (typeBinding == FloatBinding) {
4621 switch (resolvedPosition) {
4635 this.fload(resolvedPosition);
4639 // Using dedicated long bytecode
4640 if (typeBinding == LongBinding) {
4641 switch (resolvedPosition) {
4655 this.lload(resolvedPosition);
4659 // Using dedicated double bytecode
4660 if (typeBinding == DoubleBinding) {
4661 switch (resolvedPosition) {
4675 this.dload(resolvedPosition);
4679 // boolean, byte, char and short are handled as int
4680 if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
4681 switch (resolvedPosition) {
4695 this.iload(resolvedPosition);
4701 switch (resolvedPosition) {
4715 this.aload(resolvedPosition);
4718 public final void loadInt(int resolvedPosition) {
4719 // Using dedicated int bytecode
4720 switch (resolvedPosition) {
4734 this.iload(resolvedPosition);
4737 public final void loadObject(int resolvedPosition) {
4738 switch (resolvedPosition) {
4752 this.aload(resolvedPosition);
4755 final public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
4756 if (DEBUG) System.out.println(position + "\t\tlookupswitch"); //$NON-NLS-1$
4759 int length = keys.length;
4761 defaultLabel.placeInstruction();
4762 for (int i = 0; i < length; i++) {
4763 casesLabel[i].placeInstruction();
4765 if (classFileOffset >= bCodeStream.length) {
4769 bCodeStream[classFileOffset++] = OPC_lookupswitch;
4770 for (int i = (3 - (pos % 4)); i > 0; i--) {
4771 if (classFileOffset >= bCodeStream.length) {
4775 bCodeStream[classFileOffset++] = 0;
4777 defaultLabel.branch();
4778 writeSignedWord(length);
4779 for (int i = 0; i < length; i++) {
4780 writeSignedWord(keys[sortedIndexes[i]]);
4781 casesLabel[sortedIndexes[i]].branch();
4784 final public void lor() {
4785 if (DEBUG) System.out.println(position + "\t\tlor"); //$NON-NLS-1$
4788 if (classFileOffset >= bCodeStream.length) {
4792 bCodeStream[classFileOffset++] = OPC_lor;
4794 final public void lrem() {
4795 if (DEBUG) System.out.println(position + "\t\tlrem"); //$NON-NLS-1$
4798 if (classFileOffset >= bCodeStream.length) {
4802 bCodeStream[classFileOffset++] = OPC_lrem;
4804 final public void lreturn() {
4805 if (DEBUG) System.out.println(position + "\t\tlreturn"); //$NON-NLS-1$
4808 // the stackDepth should be equal to 0
4809 if (classFileOffset >= bCodeStream.length) {
4813 bCodeStream[classFileOffset++] = OPC_lreturn;
4815 final public void lshl() {
4816 if (DEBUG) System.out.println(position + "\t\tlshl"); //$NON-NLS-1$
4819 if (classFileOffset >= bCodeStream.length) {
4823 bCodeStream[classFileOffset++] = OPC_lshl;
4825 final public void lshr() {
4826 if (DEBUG) System.out.println(position + "\t\tlshr"); //$NON-NLS-1$
4829 if (classFileOffset >= bCodeStream.length) {
4833 bCodeStream[classFileOffset++] = OPC_lshr;
4835 final public void lstore(int iArg) {
4836 if (DEBUG) System.out.println(position + "\t\tlstore:"+iArg); //$NON-NLS-1$
4839 if (maxLocals <= iArg + 1) {
4840 maxLocals = iArg + 2;
4842 if (iArg > 255) { // Widen
4843 if (classFileOffset + 3 >= bCodeStream.length) {
4847 bCodeStream[classFileOffset++] = OPC_wide;
4848 bCodeStream[classFileOffset++] = OPC_lstore;
4849 writeUnsignedShort(iArg);
4851 if (classFileOffset + 1 >= bCodeStream.length) {
4855 bCodeStream[classFileOffset++] = OPC_lstore;
4856 bCodeStream[classFileOffset++] = (byte) iArg;
4859 final public void lstore_0() {
4860 if (DEBUG) System.out.println(position + "\t\tlstore_0"); //$NON-NLS-1$
4863 if (maxLocals < 2) {
4866 if (classFileOffset >= bCodeStream.length) {
4870 bCodeStream[classFileOffset++] = OPC_lstore_0;
4872 final public void lstore_1() {
4873 if (DEBUG) System.out.println(position + "\t\tlstore_1"); //$NON-NLS-1$
4876 if (maxLocals < 3) {
4879 if (classFileOffset >= bCodeStream.length) {
4883 bCodeStream[classFileOffset++] = OPC_lstore_1;
4885 final public void lstore_2() {
4886 if (DEBUG) System.out.println(position + "\t\tlstore_2"); //$NON-NLS-1$
4889 if (maxLocals < 4) {
4892 if (classFileOffset >= bCodeStream.length) {
4896 bCodeStream[classFileOffset++] = OPC_lstore_2;
4898 final public void lstore_3() {
4899 if (DEBUG) System.out.println(position + "\t\tlstore_3"); //$NON-NLS-1$
4902 if (maxLocals < 5) {
4905 if (classFileOffset >= bCodeStream.length) {
4909 bCodeStream[classFileOffset++] = OPC_lstore_3;
4911 final public void lsub() {
4912 if (DEBUG) System.out.println(position + "\t\tlsub"); //$NON-NLS-1$
4915 if (classFileOffset >= bCodeStream.length) {
4919 bCodeStream[classFileOffset++] = OPC_lsub;
4921 final public void lushr() {
4922 if (DEBUG) System.out.println(position + "\t\tlushr"); //$NON-NLS-1$
4925 if (classFileOffset >= bCodeStream.length) {
4929 bCodeStream[classFileOffset++] = OPC_lushr;
4931 final public void lxor() {
4932 if (DEBUG) System.out.println(position + "\t\tlxor"); //$NON-NLS-1$
4935 if (classFileOffset >= bCodeStream.length) {
4939 bCodeStream[classFileOffset++] = OPC_lxor;
4941 final public void monitorenter() {
4942 if (DEBUG) System.out.println(position + "\t\tmonitorenter"); //$NON-NLS-1$
4945 if (classFileOffset >= bCodeStream.length) {
4949 bCodeStream[classFileOffset++] = OPC_monitorenter;
4951 final public void monitorexit() {
4952 if (DEBUG) System.out.println(position + "\t\tmonitorexit"); //$NON-NLS-1$
4955 if (classFileOffset >= bCodeStream.length) {
4959 bCodeStream[classFileOffset++] = OPC_monitorexit;
4961 final public void multianewarray(TypeBinding typeBinding, int dimensions) {
4962 if (DEBUG) System.out.println(position + "\t\tmultinewarray:"+typeBinding+","+dimensions); //$NON-NLS-1$ //$NON-NLS-2$
4964 stackDepth += (1 - dimensions);
4965 if (classFileOffset + 3 >= bCodeStream.length) {
4969 bCodeStream[classFileOffset++] = OPC_multianewarray;
4970 writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
4971 bCodeStream[classFileOffset++] = (byte) dimensions;
4974 * We didn't call it new, because there is a conflit with the new keyword
4976 final public void new_(TypeBinding typeBinding) {
4977 if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding.debugName()); //$NON-NLS-1$
4980 if (stackDepth > stackMax)
4981 stackMax = stackDepth;
4982 if (classFileOffset + 2 >= bCodeStream.length) {
4986 bCodeStream[classFileOffset++] = OPC_new;
4987 writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
4989 final public void newarray(int array_Type) {
4990 if (DEBUG) System.out.println(position + "\t\tnewarray:"+array_Type); //$NON-NLS-1$
4992 if (classFileOffset + 1 >= bCodeStream.length) {
4996 bCodeStream[classFileOffset++] = OPC_newarray;
4997 bCodeStream[classFileOffset++] = (byte) array_Type;
4999 public void newArray(ArrayBinding arrayBinding) {
5000 TypeBinding component = arrayBinding.elementsType();
5001 switch (component.id) {
5003 this.newarray(INT_ARRAY);
5006 this.newarray(BYTE_ARRAY);
5009 this.newarray(BOOLEAN_ARRAY);
5012 this.newarray(SHORT_ARRAY);
5015 this.newarray(CHAR_ARRAY);
5018 this.newarray(LONG_ARRAY);
5021 this.newarray(FLOAT_ARRAY);
5024 this.newarray(DOUBLE_ARRAY);
5027 this.anewarray(component);
5030 public void newJavaLangError() {
5031 // new: java.lang.Error
5032 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Error"); //$NON-NLS-1$
5035 if (stackDepth > stackMax)
5036 stackMax = stackDepth;
5037 if (classFileOffset + 2 >= bCodeStream.length) {
5041 bCodeStream[classFileOffset++] = OPC_new;
5042 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
5045 public void newJavaLangAssertionError() {
5046 // new: java.lang.AssertionError
5047 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.AssertionError"); //$NON-NLS-1$
5050 if (stackDepth > stackMax)
5051 stackMax = stackDepth;
5052 if (classFileOffset + 2 >= bCodeStream.length) {
5056 bCodeStream[classFileOffset++] = OPC_new;
5057 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName));
5059 public void newJavaLangIllegalArgumentException() {
5060 // new: java.lang.IllegalArgumentException
5061 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.IllegalArgumentException"); //$NON-NLS-1$
5064 if (stackDepth > stackMax)
5065 stackMax = stackDepth;
5066 if (classFileOffset + 2 >= bCodeStream.length) {
5070 bCodeStream[classFileOffset++] = OPC_new;
5071 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName));
5073 public void newNoClassDefFoundError() {
5074 // new: java.lang.NoClassDefFoundError
5075 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$
5078 if (stackDepth > stackMax)
5079 stackMax = stackDepth;
5080 if (classFileOffset + 2 >= bCodeStream.length) {
5084 bCodeStream[classFileOffset++] = OPC_new;
5085 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName));
5087 public void newStringContatenation() {
5088 // new: java.lang.StringBuffer
5089 // new: java.lang.StringBuilder
5091 if (this.targetLevel >= JDK1_5) {
5092 System.out.println(position + "\t\tnew: java.lang.StringBuilder"); //$NON-NLS-1$
5094 System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$
5099 if (stackDepth > stackMax) {
5100 stackMax = stackDepth;
5102 if (classFileOffset + 2 >= bCodeStream.length) {
5106 bCodeStream[classFileOffset++] = OPC_new;
5107 if (this.targetLevel >= JDK1_5) {
5108 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName));
5110 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName));
5113 public void newWrapperFor(int typeID) {
5116 if (stackDepth > stackMax)
5117 stackMax = stackDepth;
5118 if (classFileOffset + 2 >= bCodeStream.length) {
5122 bCodeStream[classFileOffset++] = OPC_new;
5124 case T_int : // new: java.lang.Integer
5125 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$
5126 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
5128 case T_boolean : // new: java.lang.Boolean
5129 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$
5130 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
5132 case T_byte : // new: java.lang.Byte
5133 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$
5134 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
5136 case T_char : // new: java.lang.Character
5137 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Character"); //$NON-NLS-1$
5138 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
5140 case T_float : // new: java.lang.Float
5141 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Float"); //$NON-NLS-1$
5142 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
5144 case T_double : // new: java.lang.Double
5145 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Double"); //$NON-NLS-1$
5146 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
5148 case T_short : // new: java.lang.Short
5149 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Short"); //$NON-NLS-1$
5150 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
5152 case T_long : // new: java.lang.Long
5153 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$
5154 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
5156 case T_void : // new: java.lang.Void
5157 if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$
5158 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName));
5161 final public void nop() {
5162 if (DEBUG) System.out.println(position + "\t\tnop"); //$NON-NLS-1$
5164 if (classFileOffset >= bCodeStream.length) {
5168 bCodeStream[classFileOffset++] = OPC_nop;
5170 final public void pop() {
5171 if (DEBUG) System.out.println(position + "\t\tpop"); //$NON-NLS-1$
5174 if (classFileOffset >= bCodeStream.length) {
5178 bCodeStream[classFileOffset++] = OPC_pop;
5180 final public void pop2() {
5181 if (DEBUG) System.out.println(position + "\t\tpop2"); //$NON-NLS-1$
5184 if (classFileOffset >= bCodeStream.length) {
5188 bCodeStream[classFileOffset++] = OPC_pop2;
5190 final public void putfield(FieldBinding fieldBinding) {
5191 if (DEBUG) System.out.println(position + "\t\tputfield:"+fieldBinding); //$NON-NLS-1$
5192 int returnTypeSize = 1;
5193 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
5196 generateFieldAccess(
5199 fieldBinding.declaringClass.constantPoolName(),
5201 fieldBinding.type.signature());
5203 final public void putstatic(FieldBinding fieldBinding) {
5204 if (DEBUG) System.out.println(position + "\t\tputstatic:"+fieldBinding); //$NON-NLS-1$
5205 int returnTypeSize = 1;
5206 if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
5209 generateFieldAccess(
5212 fieldBinding.declaringClass.constantPoolName(),
5214 fieldBinding.type.signature());
5216 public void record(LocalVariableBinding local) {
5217 if (!generateLocalVariableTableAttributes)
5219 if (allLocalsCounter == locals.length) {
5220 // resize the collection
5221 System.arraycopy(locals, 0, locals = new LocalVariableBinding[allLocalsCounter + LOCALS_INCREMENT], 0, allLocalsCounter);
5223 locals[allLocalsCounter++] = local;
5224 local.initializationPCs = new int[4];
5225 local.initializationCount = 0;
5227 public void recordPositionsFrom(int startPC, int sourcePos) {
5229 /* Record positions in the table, only if nothing has
5230 * already been recorded. Since we output them on the way
5231 * up (children first for more specific info)
5232 * The pcToSourceMap table is always sorted.
5235 if (!generateLineNumberAttributes)
5240 // no code generated for this node. e.g. field without any initialization
5241 if (position == startPC)
5244 // Widening an existing entry that already has the same source positions
5245 if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
5246 // resize the array pcToSourceMap
5247 System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
5249 int newLine = ClassFile.searchLineNumber(lineSeparatorPositions, sourcePos);
5250 // lastEntryPC represents the endPC of the lastEntry.
5251 if (pcToSourceMapSize > 0) {
5252 // in this case there is already an entry in the table
5253 if (pcToSourceMap[pcToSourceMapSize - 1] != newLine) {
5254 if (startPC < lastEntryPC) {
5255 // we forgot to add an entry.
5256 // search if an existing entry exists for startPC
5257 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5258 if (insertionIndex != -1) {
5259 // there is no existing entry starting with startPC.
5260 int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, newLine); // index for PC
5261 /* the existingEntryIndex corresponds to en entry with the same line and a PC >= startPC.
5262 in this case it is relevant to widen this entry instead of creating a new one.
5266 with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
5267 aload0 bytecode. The first entry is the one for the argument a.
5268 But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
5269 So we widen the existing entry (if there is one) or we create a new entry with the startPC.
5271 if (existingEntryIndex != -1) {
5272 // widen existing entry
5273 pcToSourceMap[existingEntryIndex] = startPC;
5274 } else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != newLine) {
5275 // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
5276 System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
5277 pcToSourceMap[insertionIndex++] = startPC;
5278 pcToSourceMap[insertionIndex] = newLine;
5279 pcToSourceMapSize += 2;
5281 } else if (position != lastEntryPC) { // no bytecode since last entry pc
5282 pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
5283 pcToSourceMap[pcToSourceMapSize++] = newLine;
5286 // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
5287 pcToSourceMap[pcToSourceMapSize++] = startPC;
5288 pcToSourceMap[pcToSourceMapSize++] = newLine;
5291 /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
5292 we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
5294 if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
5295 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5296 if (insertionIndex != -1) {
5297 // widen the existing entry
5298 // we have to figure out if we need to move the last entry at another location to keep a sorted table
5299 /* First we need to check if at the insertion position there is not an existing entry
5300 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
5301 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
5302 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
5304 if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == newLine))) {
5305 if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
5306 System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
5307 pcToSourceMap[insertionIndex++] = startPC;
5308 pcToSourceMap[insertionIndex] = newLine;
5310 pcToSourceMap[pcToSourceMapSize - 2] = startPC;
5316 lastEntryPC = position;
5318 // record the first entry
5319 pcToSourceMap[pcToSourceMapSize++] = startPC;
5320 pcToSourceMap[pcToSourceMapSize++] = newLine;
5321 lastEntryPC = position;
5325 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
5327 public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
5329 if (exceptionHandlersIndex >= (length = exceptionHandlers.length)) {
5330 // resize the exception handlers table
5331 System.arraycopy(exceptionHandlers, 0, exceptionHandlers = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
5333 // no need to resize. So just add the new exception label
5334 exceptionHandlers[exceptionHandlersIndex++] = anExceptionLabel;
5335 exceptionHandlersCounter++;
5337 public void removeExceptionHandler(ExceptionLabel exceptionLabel) {
5338 for (int i = 0; i < exceptionHandlersIndex; i++) {
5339 if (exceptionHandlers[i] == exceptionLabel) {
5340 exceptionHandlers[i] = null;
5341 exceptionHandlersCounter--;
5346 public final void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
5347 // given some flow info, make sure we did not loose some variables initialization
5348 // if this happens, then we must update their pc entries to reflect it in debug attributes
5349 if (!generateLocalVariableTableAttributes)
5351 /* if (initStateIndex == lastInitStateIndexWhenRemovingInits)
5354 lastInitStateIndexWhenRemovingInits = initStateIndex;
5355 if (lastInitStateIndexWhenAddingInits != initStateIndex){
5356 lastInitStateIndexWhenAddingInits = -2;// reinitialize add index
5357 // add(1)-remove(1)-add(1) -> ignore second add
5358 // add(1)-remove(2)-add(1) -> perform second add
5360 for (int i = 0; i < visibleLocalsCount; i++) {
5361 LocalVariableBinding localBinding = visibleLocals[i];
5362 if (localBinding != null) {
5363 if (initStateIndex == -1 || !isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
5364 if (localBinding.initializationCount > 0) {
5365 localBinding.recordInitializationEndPC(position);
5372 * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
5373 * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
5375 public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
5376 init(targetClassFile);
5377 this.methodDeclaration = referenceMethod;
5378 preserveUnusedLocals = referenceMethod.scope.problemReporter().options.preserveAllLocalVariables;
5379 initializeMaxLocals(referenceMethod.binding);
5382 * @param targetClassFile The given classfile to reset the code stream
5384 public void resetForProblemClinit(ClassFile targetClassFile) {
5385 init(targetClassFile);
5388 private final void resizeByteArray() {
5389 int length = bCodeStream.length;
5390 int requiredSize = length + length;
5391 if (classFileOffset > requiredSize) {
5392 // must be sure to grow by enough
5393 requiredSize = classFileOffset + length;
5395 System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length);
5397 final public void ret(int index) {
5398 if (DEBUG) System.out.println(position + "\t\tret:"+index); //$NON-NLS-1$
5400 if (index > 255) { // Widen
5401 if (classFileOffset + 3 >= bCodeStream.length) {
5405 bCodeStream[classFileOffset++] = OPC_wide;
5406 bCodeStream[classFileOffset++] = OPC_ret;
5407 writeUnsignedShort(index);
5408 } else { // Don't Widen
5409 if (classFileOffset + 1 >= bCodeStream.length) {
5413 bCodeStream[classFileOffset++] = OPC_ret;
5414 bCodeStream[classFileOffset++] = (byte) index;
5417 final public void return_() {
5418 if (DEBUG) System.out.println(position + "\t\treturn"); //$NON-NLS-1$
5420 // the stackDepth should be equal to 0
5421 if (classFileOffset >= bCodeStream.length) {
5425 bCodeStream[classFileOffset++] = OPC_return;
5427 final public void saload() {
5428 if (DEBUG) System.out.println(position + "\t\tsaload"); //$NON-NLS-1$
5431 if (classFileOffset >= bCodeStream.length) {
5435 bCodeStream[classFileOffset++] = OPC_saload;
5437 final public void sastore() {
5438 if (DEBUG) System.out.println(position + "\t\tsastore"); //$NON-NLS-1$
5441 if (classFileOffset >= bCodeStream.length) {
5445 bCodeStream[classFileOffset++] = OPC_sastore;
5448 * @param operatorConstant int
5449 * @param type_ID int
5451 public void sendOperator(int operatorConstant, int type_ID) {
5458 switch (operatorConstant) {
5480 case UNSIGNED_RIGHT_SHIFT :
5495 switch (operatorConstant) {
5517 case UNSIGNED_RIGHT_SHIFT :
5532 switch (operatorConstant) {
5550 switch (operatorConstant) {
5568 final public void sipush(int s) {
5569 if (DEBUG) System.out.println(position + "\t\tsipush:"+s); //$NON-NLS-1$
5572 if (stackDepth > stackMax)
5573 stackMax = stackDepth;
5574 if (classFileOffset >= bCodeStream.length) {
5578 bCodeStream[classFileOffset++] = OPC_sipush;
5579 writeSignedShort(s);
5581 public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
5586 /* Arbitrarily establishing partition element as the midpoint of
5589 mid = tab[ (lo0 + hi0) / 2];
5590 // loop through the array until indices cross
5592 /* find the first element that is greater than or equal to
5593 * the partition element starting from the left Index.
5595 while ((lo < hi0) && (tab[lo] < mid))
5597 /* find an element that is smaller than or equal to
5598 * the partition element starting from the right Index.
5600 while ((hi > lo0) && (tab[hi] > mid))
5602 // if the indexes have not crossed, swap
5604 swap(tab, lo, hi, result);
5609 /* If the right index has not reached the left side of array
5610 * must now sort the left partition.
5613 sort(tab, lo0, hi, result);
5614 /* If the left index has not reached the right side of array
5615 * must now sort the right partition.
5618 sort(tab, lo, hi0, result);
5622 public final void store(LocalVariableBinding localBinding, boolean valueRequired) {
5623 int localPosition = localBinding.resolvedPosition;
5624 // Using dedicated int bytecode
5625 switch(localBinding.type.id) {
5626 case TypeIds.T_int :
5627 case TypeIds.T_char :
5628 case TypeIds.T_byte :
5629 case TypeIds.T_short :
5630 case TypeIds.T_boolean :
5633 switch (localPosition) {
5647 // internal failure: trying to store into variable not supposed to be generated
5650 this.istore(localPosition);
5653 case TypeIds.T_float :
5656 switch (localPosition) {
5670 this.fstore(localPosition);
5673 case TypeIds.T_double :
5676 switch (localPosition) {
5690 this.dstore(localPosition);
5693 case TypeIds.T_long :
5696 switch (localPosition) {
5710 this.lstore(localPosition);
5717 switch (localPosition) {
5731 this.astore(localPosition);
5735 public final void store(TypeBinding type, int localPosition) {
5736 // Using dedicated int bytecode
5737 if ((type == IntBinding) || (type == CharBinding) || (type == ByteBinding) || (type == ShortBinding) || (type == BooleanBinding)) {
5738 switch (localPosition) {
5752 this.istore(localPosition);
5756 // Using dedicated float bytecode
5757 if (type == FloatBinding) {
5758 switch (localPosition) {
5772 this.fstore(localPosition);
5776 // Using dedicated long bytecode
5777 if (type == LongBinding) {
5778 switch (localPosition) {
5792 this.lstore(localPosition);
5796 // Using dedicated double bytecode
5797 if (type == DoubleBinding) {
5798 switch (localPosition) {
5812 this.dstore(localPosition);
5817 switch (localPosition) {
5831 this.astore(localPosition);
5834 public final void storeInt(int localPosition) {
5835 switch (localPosition) {
5849 this.istore(localPosition);
5852 public final void storeObject(int localPosition) {
5853 switch (localPosition) {
5867 this.astore(localPosition);
5870 final public void swap() {
5871 if (DEBUG) System.out.println(position + "\t\tswap"); //$NON-NLS-1$
5873 if (classFileOffset >= bCodeStream.length) {
5877 bCodeStream[classFileOffset++] = OPC_swap;
5879 private static final void swap(int a[], int i, int j, int result[]) {
5885 result[j] = result[i];
5888 final public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
5889 if (DEBUG) System.out.println(position + "\t\ttableswitch"); //$NON-NLS-1$
5892 int length = casesLabel.length;
5894 defaultLabel.placeInstruction();
5895 for (int i = 0; i < length; i++)
5896 casesLabel[i].placeInstruction();
5897 if (classFileOffset >= bCodeStream.length) {
5901 bCodeStream[classFileOffset++] = OPC_tableswitch;
5902 for (int i = (3 - (pos % 4)); i > 0; i--) {
5903 if (classFileOffset >= bCodeStream.length) {
5907 bCodeStream[classFileOffset++] = 0;
5909 defaultLabel.branch();
5910 writeSignedWord(low);
5911 writeSignedWord(high);
5912 int i = low, j = low;
5913 // the index j is used to know if the index i is one of the missing entries in case of an
5914 // optimized tableswitch
5917 int key = keys[index = sortedIndexes[j - low]];
5919 casesLabel[index].branch();
5921 if (i == high) break; // if high is maxint, then avoids wrapping to minint.
5923 defaultLabel.branch();
5928 public String toString() {
5929 StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
5930 buffer.append(position);
5931 buffer.append(",\nstackDepth:"); //$NON-NLS-1$
5932 buffer.append(stackDepth);
5933 buffer.append(",\nmaxStack:"); //$NON-NLS-1$
5934 buffer.append(stackMax);
5935 buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
5936 buffer.append(maxLocals);
5937 buffer.append(")"); //$NON-NLS-1$
5938 return buffer.toString();
5940 public void updateLastRecordedEndPC(int pos) {
5942 /* Tune positions in the table, this is due to some
5943 * extra bytecodes being
5944 * added to some user code (jumps). */
5946 if (!generateLineNumberAttributes)
5948 pcToSourceMap[pcToSourceMapSize - 1][1] = position;
5949 // need to update the initialization endPC in case of generation of local variable attributes.
5950 updateLocalVariablesAttribute(pos);
5953 if (!generateLineNumberAttributes)
5955 this.lastEntryPC = pos;
5956 // need to update the initialization endPC in case of generation of local variable attributes.
5957 updateLocalVariablesAttribute(pos);
5959 public void updateLocalVariablesAttribute(int pos) {
5960 // need to update the initialization endPC in case of generation of local variable attributes.
5961 if (generateLocalVariableTableAttributes) {
5962 for (int i = 0, max = locals.length; i < max; i++) {
5963 LocalVariableBinding local = locals[i];
5964 if ((local != null) && (local.initializationCount > 0)) {
5965 if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
5966 local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position;
5973 * Write a signed 16 bits value into the byte array
5974 * @param value the signed short
5976 public final void writeSignedShort(int value) {
5977 // we keep the resize in here because it is used outside the code stream
5978 if (classFileOffset + 1 >= bCodeStream.length) {
5982 bCodeStream[classFileOffset++] = (byte) (value >> 8);
5983 bCodeStream[classFileOffset++] = (byte) value;
5985 public final void writeSignedShort(int pos, int value) {
5986 int currentOffset = startingClassFileOffset + pos;
5987 if (currentOffset + 1 >= bCodeStream.length) {
5990 bCodeStream[currentOffset] = (byte) (value >> 8);
5991 bCodeStream[currentOffset + 1] = (byte) value;
5993 public final void writeSignedWord(int value) {
5994 // we keep the resize in here because it is used outside the code stream
5995 if (classFileOffset + 3 >= bCodeStream.length) {
5999 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
6000 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
6001 bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
6002 bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
6004 public final void writeSignedWord(int pos, int value) {
6005 int currentOffset = startingClassFileOffset + pos;
6006 if (currentOffset + 4 >= bCodeStream.length) {
6009 bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
6010 bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
6011 bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
6012 bCodeStream[currentOffset++] = (byte) (value & 0xFF);
6015 * Write a unsigned 16 bits value into the byte array
6016 * @param value the unsigned short
6018 protected final void writeUnsignedShort(int value) {
6020 bCodeStream[classFileOffset++] = (byte) (value >>> 8);
6021 bCodeStream[classFileOffset++] = (byte) value;
6024 * Wide conditional branch compare, improved by swapping comparison opcode
6031 public void generateWideRevertedConditionalBranch(byte revertedOpcode, Label wideTarget) {
6032 Label intermediate = new Label(this);
6033 if (classFileOffset >= bCodeStream.length) {
6037 bCodeStream[classFileOffset++] = revertedOpcode;
6038 intermediate.branch();
6039 this.goto_w(wideTarget);
6040 intermediate.place();