KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > codegen > CodeStream


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.codegen;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.internal.compiler.ClassFile;
15 import org.eclipse.jdt.internal.compiler.CompilationResult;
16 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
17 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
18 import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
19 import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
20 import org.eclipse.jdt.internal.compiler.ast.Expression;
21 import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
22 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
23 import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
24 import org.eclipse.jdt.internal.compiler.impl.Constant;
25 import org.eclipse.jdt.internal.compiler.lookup.*;
26 import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
27 import org.eclipse.jdt.internal.compiler.util.Util;
28
29 public class CodeStream {
30     public static final boolean DEBUG = false;
31     
32     // It will be responsible for the following items.
33
// -> Tracking Max Stack.
34

35     public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
36     public static final int LABELS_INCREMENT = 5;
37     // local variable attributes output
38
public static final int LOCALS_INCREMENT = 10;
39     static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
40     static BranchLabel[] noLabels = new BranchLabel[LABELS_INCREMENT];
41     static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
42     static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
43     public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
44     /**
45      * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
46      * If there is an existing entry it returns -1 (no insertion required).
47      * Otherwise it returns the index where the entry for the pc has to be inserted.
48      * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
49      *
50      * @param pcToSourceMap the given pcToSourceMap array
51      * @param length the given length
52      * @param pc the given pc
53      * @return int
54      */

55     public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
56         int g = 0;
57         int d = length - 2;
58         int m = 0;
59         while (g <= d) {
60             m = (g + d) / 2;
61             // we search only on even indexes
62
if ((m & 1) != 0) // faster than ((m % 2) != 0)
63
m--;
64             int currentPC = pcToSourceMap[m];
65             if (pc < currentPC) {
66                 d = m - 2;
67             } else
68                 if (pc > currentPC) {
69                     g = m + 2;
70                 } else {
71                     return -1;
72                 }
73         }
74         if (pc < pcToSourceMap[m])
75             return m;
76         return m + 2;
77     }
78     public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
79         int lo = lo0;
80         int hi = hi0;
81         int mid;
82         if (hi0 > lo0) {
83             /* Arbitrarily establishing partition element as the midpoint of
84               * the array.
85               */

86             mid = tab[lo0 + (hi0 - lo0) / 2];
87             // loop through the array until indices cross
88
while (lo <= hi) {
89                 /* find the first element that is greater than or equal to
90                  * the partition element starting from the left Index.
91                  */

92                 while ((lo < hi0) && (tab[lo] < mid))
93                     ++lo;
94                 /* find an element that is smaller than or equal to
95                  * the partition element starting from the right Index.
96                  */

97                 while ((hi > lo0) && (tab[hi] > mid))
98                     --hi;
99                 // if the indexes have not crossed, swap
100
if (lo <= hi) {
101                     swap(tab, lo, hi, result);
102                     ++lo;
103                     --hi;
104                 }
105             }
106             /* If the right index has not reached the left side of array
107               * must now sort the left partition.
108               */

109             if (lo0 < hi)
110                 sort(tab, lo0, hi, result);
111             /* If the left index has not reached the right side of array
112               * must now sort the right partition.
113               */

114             if (lo < hi0)
115                 sort(tab, lo, hi0, result);
116         }
117     }
118     private static final void swap(int a[], int i, int j, int result[]) {
119         int T;
120         T = a[i];
121         a[i] = a[j];
122         a[j] = T;
123         T = result[j];
124         result[j] = result[i];
125         result[i] = T;
126     }
127     public int allLocalsCounter;
128     public byte[] bCodeStream;
129     public ClassFile classFile; // The current classfile it is associated to.
130
public int classFileOffset;
131     public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
132
public int countLabels;
133     public ExceptionLabel[] exceptionLabels = new ExceptionLabel[LABELS_INCREMENT];
134     public int exceptionLabelsCounter;
135     public int generateAttributes;
136     // store all the labels placed at the current position to be able to optimize
137
// a jump to the next bytecode.
138
static final int L_UNKNOWN = 0, L_OPTIMIZABLE = 2, L_CANNOT_OPTIMIZE = 4;
139     public BranchLabel[] labels = new BranchLabel[LABELS_INCREMENT];
140     public int lastEntryPC; // last entry recorded
141
public int lastAbruptCompletion; // position of last instruction which abrupts completion: goto/return/athrow
142
public int[] lineSeparatorPositions;
143     
144     public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
145     public int maxFieldCount;
146     
147     public int maxLocals;
148     public AbstractMethodDeclaration methodDeclaration;
149     public int[] pcToSourceMap = new int[24];
150     public int pcToSourceMapSize;
151     public int position; // So when first set can be incremented
152
public boolean preserveUnusedLocals;
153     public int stackDepth; // Use Ints to keep from using extra bc when adding
154
public int stackMax; // Use Ints to keep from using extra bc when adding
155
public int startingClassFileOffset; // I need to keep the starting point inside the byte array
156

157     // target level to manage different code generation between different target levels
158
private long targetLevel;
159     
160 public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
161 int visibleLocalsCount;
162 // to handle goto_w
163
public boolean wideMode = false;
164 public CodeStream(ClassFile givenClassFile) {
165     this.targetLevel = givenClassFile.targetJDK;
166     this.generateAttributes = givenClassFile.produceAttributes;
167     if ((givenClassFile.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
168         this.lineSeparatorPositions = givenClassFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.getLineSeparatorPositions();
169     }
170 }
171 public void aaload() {
172     if (DEBUG) System.out.println(position + "\t\taaload"); //$NON-NLS-1$
173
countLabels = 0;
174     stackDepth--;
175     if (classFileOffset >= bCodeStream.length) {
176         resizeByteArray();
177     }
178     position++;
179     bCodeStream[classFileOffset++] = Opcodes.OPC_aaload;
180 }
181 public void aastore() {
182     if (DEBUG) System.out.println(position + "\t\taastore"); //$NON-NLS-1$
183
countLabels = 0;
184     stackDepth -= 3;
185     if (classFileOffset >= bCodeStream.length) {
186         resizeByteArray();
187     }
188     position++;
189     bCodeStream[classFileOffset++] = Opcodes.OPC_aastore;
190 }
191 public void aconst_null() {
192     if (DEBUG) System.out.println(position + "\t\taconst_null"); //$NON-NLS-1$
193
countLabels = 0;
194     stackDepth++;
195     if (stackDepth > stackMax) {
196         stackMax = stackDepth;
197     }
198     if (classFileOffset >= bCodeStream.length) {
199         resizeByteArray();
200     }
201     position++;
202     bCodeStream[classFileOffset++] = Opcodes.OPC_aconst_null;
203 }
204 public void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
205     // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
206
if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) == 0)
207         return;
208     for (int i = 0; i < visibleLocalsCount; i++) {
209         LocalVariableBinding localBinding = visibleLocals[i];
210         if (localBinding != null) {
211             // Check if the local is definitely assigned
212
if (isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
213                 if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
214                     /* There are two cases:
215                      * 1) there is no initialization interval opened ==> add an opened interval
216                      * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
217                      * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
218                      * is equals to -1.
219                      * initializationPCs is a collection of pairs of int:
220                      * first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
221                      * is not closed yet.
222                      */

223                     localBinding.recordInitializationStartPC(position);
224                 }
225             }
226         }
227     }
228 }
229 public void addLabel(BranchLabel aLabel) {
230     if (countLabels == labels.length)
231         System.arraycopy(labels, 0, labels = new BranchLabel[countLabels + LABELS_INCREMENT], 0, countLabels);
232     labels[countLabels++] = aLabel;
233 }
234 public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
235     if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) == 0)
236         return;
237
238     if (visibleLocalsCount >= visibleLocals.length)
239         System.arraycopy(visibleLocals, 0, visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2], 0, visibleLocalsCount);
240     visibleLocals[visibleLocalsCount++] = localBinding;
241 }
242
243 public void addVariable(LocalVariableBinding localBinding) {
244     /* do nothing */
245 }
246 public void aload(int iArg) {
247     if (DEBUG) System.out.println(position + "\t\taload:"+iArg); //$NON-NLS-1$
248
countLabels = 0;
249     stackDepth++;
250     if (stackDepth > stackMax)
251         stackMax = stackDepth;
252     if (maxLocals <= iArg) {
253         maxLocals = iArg + 1;
254     }
255     if (iArg > 255) { // Widen
256
if (classFileOffset + 3 >= bCodeStream.length) {
257             resizeByteArray();
258         }
259         position += 2;
260         bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
261         bCodeStream[classFileOffset++] = Opcodes.OPC_aload;
262         writeUnsignedShort(iArg);
263     } else {
264         // Don't need to use the wide bytecode
265
if (classFileOffset + 1 >= bCodeStream.length) {
266             resizeByteArray();
267         }
268         position += 2;
269         bCodeStream[classFileOffset++] = Opcodes.OPC_aload;
270         bCodeStream[classFileOffset++] = (byte) iArg;
271     }
272 }
273 public void aload_0() {
274     if (DEBUG) System.out.println(position + "\t\taload_0"); //$NON-NLS-1$
275
countLabels = 0;
276     stackDepth++;
277     if (stackDepth > stackMax) {
278         stackMax = stackDepth;
279     }
280     if (maxLocals == 0) {
281         maxLocals = 1;
282     }
283     if (classFileOffset >= bCodeStream.length) {
284         resizeByteArray();
285     }
286     position++;
287     bCodeStream[classFileOffset++] = Opcodes.OPC_aload_0;
288 }
289 public void aload_1() {
290     if (DEBUG) System.out.println(position + "\t\taload_1"); //$NON-NLS-1$
291
countLabels = 0;
292     stackDepth++;
293     if (stackDepth > stackMax)
294         stackMax = stackDepth;
295     if (maxLocals <= 1) {
296         maxLocals = 2;
297     }
298     if (classFileOffset >= bCodeStream.length) {
299         resizeByteArray();
300     }
301     position++;
302     bCodeStream[classFileOffset++] = Opcodes.OPC_aload_1;
303 }
304 public void aload_2() {
305     if (DEBUG) System.out.println(position + "\t\taload_2"); //$NON-NLS-1$
306
countLabels = 0;
307     stackDepth++;
308     if (stackDepth > stackMax)
309         stackMax = stackDepth;
310     if (maxLocals <= 2) {
311         maxLocals = 3;
312     }
313     if (classFileOffset >= bCodeStream.length) {
314         resizeByteArray();
315     }
316     position++;
317     bCodeStream[classFileOffset++] = Opcodes.OPC_aload_2;
318 }
319 public void aload_3() {
320     if (DEBUG) System.out.println(position + "\t\taload_3"); //$NON-NLS-1$
321
countLabels = 0;
322     stackDepth++;
323     if (stackDepth > stackMax)
324         stackMax = stackDepth;
325     if (maxLocals <= 3) {
326         maxLocals = 4;
327     }
328     if (classFileOffset >= bCodeStream.length) {
329         resizeByteArray();
330     }
331     position++;
332     bCodeStream[classFileOffset++] = Opcodes.OPC_aload_3;
333 }
334 public void anewarray(TypeBinding typeBinding) {
335     if (DEBUG) System.out.println(position + "\t\tanewarray: " + typeBinding); //$NON-NLS-1$
336
countLabels = 0;
337     if (classFileOffset + 2 >= bCodeStream.length) {
338         resizeByteArray();
339     }
340     position++;
341     bCodeStream[classFileOffset++] = Opcodes.OPC_anewarray;
342     writeUnsignedShort(constantPool.literalIndexForType(typeBinding));
343 }
344 public void areturn() {
345     if (DEBUG) System.out.println(position + "\t\tareturn"); //$NON-NLS-1$
346
countLabels = 0;
347     stackDepth--;
348     // the stackDepth should be equal to 0
349
if (classFileOffset >= bCodeStream.length) {
350         resizeByteArray();
351     }
352     position++;
353     bCodeStream[classFileOffset++] = Opcodes.OPC_areturn;
354     this.lastAbruptCompletion = this.position;
355 }
356 public void arrayAt(int typeBindingID) {
357     switch (typeBindingID) {
358         case TypeIds.T_int :
359             this.iaload();
360             break;
361         case TypeIds.T_byte :
362         case TypeIds.T_boolean :
363             this.baload();
364             break;
365         case TypeIds.T_short :
366             this.saload();
367             break;
368         case TypeIds.T_char :
369             this.caload();
370             break;
371         case TypeIds.T_long :
372             this.laload();
373             break;
374         case TypeIds.T_float :
375             this.faload();
376             break;
377         case TypeIds.T_double :
378             this.daload();
379             break;
380         default :
381             this.aaload();
382     }
383 }
384 public void arrayAtPut(int elementTypeID, boolean valueRequired) {
385     switch (elementTypeID) {
386         case TypeIds.T_int :
387             if (valueRequired)
388                 dup_x2();
389             iastore();
390             break;
391         case TypeIds.T_byte :
392         case TypeIds.T_boolean :
393             if (valueRequired)
394                 dup_x2();
395             bastore();
396             break;
397         case TypeIds.T_short :
398             if (valueRequired)
399                 dup_x2();
400             sastore();
401             break;
402         case TypeIds.T_char :
403             if (valueRequired)
404                 dup_x2();
405             castore();
406             break;
407         case TypeIds.T_long :
408             if (valueRequired)
409                 dup2_x2();
410             lastore();
411             break;
412         case TypeIds.T_float :
413             if (valueRequired)
414                 dup_x2();
415             fastore();
416             break;
417         case TypeIds.T_double :
418             if (valueRequired)
419                 dup2_x2();
420             dastore();
421             break;
422         default :
423             if (valueRequired)
424                 dup_x2();
425             aastore();
426     }
427 }
428 public void arraylength() {
429     if (DEBUG) System.out.println(position + "\t\tarraylength"); //$NON-NLS-1$
430
countLabels = 0;
431     if (classFileOffset >= bCodeStream.length) {
432         resizeByteArray();
433     }
434     position++;
435     bCodeStream[classFileOffset++] = Opcodes.OPC_arraylength;
436 }
437 public void astore(int iArg) {
438     if (DEBUG) System.out.println(position + "\t\tastore:"+iArg); //$NON-NLS-1$
439
countLabels = 0;
440     stackDepth--;
441     if (maxLocals <= iArg) {
442         maxLocals = iArg + 1;
443     }
444     if (iArg > 255) { // Widen
445
if (classFileOffset + 3 >= bCodeStream.length) {
446             resizeByteArray();
447         }
448         position+=2;
449         bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
450         bCodeStream[classFileOffset++] = Opcodes.OPC_astore;
451         writeUnsignedShort(iArg);
452     } else {
453         if (classFileOffset + 1 >= bCodeStream.length) {
454             resizeByteArray();
455         }
456         position+=2;
457         bCodeStream[classFileOffset++] = Opcodes.OPC_astore;
458         bCodeStream[classFileOffset++] = (byte) iArg;
459     }
460 }
461 public void astore_0() {
462     if (DEBUG) System.out.println(position + "\t\tastore_0"); //$NON-NLS-1$
463
countLabels = 0;
464     stackDepth--;
465     if (maxLocals == 0) {
466         maxLocals = 1;
467     }
468     if (classFileOffset >= bCodeStream.length) {
469         resizeByteArray();
470     }
471     position++;
472     bCodeStream[classFileOffset++] = Opcodes.OPC_astore_0;
473 }
474 public void astore_1() {
475     if (DEBUG) System.out.println(position + "\t\tastore_1"); //$NON-NLS-1$
476
countLabels = 0;
477     stackDepth--;
478     if (maxLocals <= 1) {
479         maxLocals = 2;
480     }
481     if (classFileOffset >= bCodeStream.length) {
482         resizeByteArray();
483     }
484     position++;
485     bCodeStream[classFileOffset++] = Opcodes.OPC_astore_1;
486 }
487 public void astore_2() {
488     if (DEBUG) System.out.println(position + "\t\tastore_2"); //$NON-NLS-1$
489
countLabels = 0;
490     stackDepth--;
491     if (maxLocals <= 2) {
492         maxLocals = 3;
493     }
494     if (classFileOffset >= bCodeStream.length) {
495         resizeByteArray();
496     }
497     position++;
498     bCodeStream[classFileOffset++] = Opcodes.OPC_astore_2;
499 }
500 public void astore_3() {
501     if (DEBUG) System.out.println(position + "\t\tastore_3"); //$NON-NLS-1$
502
countLabels = 0;
503     stackDepth--;
504     if (maxLocals <= 3) {
505         maxLocals = 4;
506     }
507     if (classFileOffset >= bCodeStream.length) {
508         resizeByteArray();
509     }
510     position++;
511     bCodeStream[classFileOffset++] = Opcodes.OPC_astore_3;
512 }
513 public void athrow() {
514     if (DEBUG) System.out.println(position + "\t\tathrow"); //$NON-NLS-1$
515
countLabels = 0;
516     stackDepth--;
517     if (classFileOffset >= bCodeStream.length) {
518         resizeByteArray();
519     }
520     position++;
521     bCodeStream[classFileOffset++] = Opcodes.OPC_athrow;
522     this.lastAbruptCompletion = this.position;
523 }
524 public void baload() {
525     if (DEBUG) System.out.println(position + "\t\tbaload"); //$NON-NLS-1$
526
countLabels = 0;
527     stackDepth--;
528     if (classFileOffset >= bCodeStream.length) {
529         resizeByteArray();
530     }
531     position++;
532     bCodeStream[classFileOffset++] = Opcodes.OPC_baload;
533 }
534 public void bastore() {
535     if (DEBUG) System.out.println(position + "\t\tbastore"); //$NON-NLS-1$
536
countLabels = 0;
537     stackDepth -= 3;
538     if (classFileOffset >= bCodeStream.length) {
539         resizeByteArray();
540     }
541     position++;
542     bCodeStream[classFileOffset++] = Opcodes.OPC_bastore;
543 }
544 public void bipush(byte b) {
545     if (DEBUG) System.out.println(position + "\t\tbipush "+b); //$NON-NLS-1$
546
countLabels = 0;
547     stackDepth++;
548     if (stackDepth > stackMax)
549         stackMax = stackDepth;
550     if (classFileOffset + 1 >= bCodeStream.length) {
551         resizeByteArray();
552     }
553     position += 2;
554     bCodeStream[classFileOffset++] = Opcodes.OPC_bipush;
555     bCodeStream[classFileOffset++] = b;
556 }
557 public void caload() {
558     if (DEBUG) System.out.println(position + "\t\tcaload"); //$NON-NLS-1$
559
countLabels = 0;
560     stackDepth--;
561     if (classFileOffset >= bCodeStream.length) {
562         resizeByteArray();
563     }
564     position++;
565     bCodeStream[classFileOffset++] = Opcodes.OPC_caload;
566 }
567 public void castore() {
568     if (DEBUG) System.out.println(position + "\t\tcastore"); //$NON-NLS-1$
569
countLabels = 0;
570     stackDepth -= 3;
571     if (classFileOffset >= bCodeStream.length) {
572         resizeByteArray();
573     }
574     position++;
575     bCodeStream[classFileOffset++] = Opcodes.OPC_castore;
576 }
577 public void checkcast(int baseId) {
578     this.countLabels = 0;
579     if (classFileOffset + 2 >= bCodeStream.length) {
580         resizeByteArray();
581     }
582     this.position++;
583     this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_checkcast;
584     switch (baseId) {
585         case TypeIds.T_byte :
586             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
587             break;
588         case TypeIds.T_short :
589             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
590             break;
591         case TypeIds.T_char :
592             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
593             break;
594         case TypeIds.T_int :
595             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
596             break;
597         case TypeIds.T_long :
598             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
599             break;
600         case TypeIds.T_float :
601             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
602             break;
603         case TypeIds.T_double :
604             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
605             break;
606         case TypeIds.T_boolean :
607             writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
608     }
609 }
610 public void checkcast(TypeBinding typeBinding) {
611     if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding.debugName()); //$NON-NLS-1$
612
countLabels = 0;
613     if (classFileOffset + 2 >= bCodeStream.length) {
614         resizeByteArray();
615     }
616     position++;
617     bCodeStream[classFileOffset++] = Opcodes.OPC_checkcast;
618     writeUnsignedShort(constantPool.literalIndexForType(typeBinding));
619 }
620 public void d2f() {
621     if (DEBUG) System.out.println(position + "\t\td2f"); //$NON-NLS-1$
622
countLabels = 0;
623     stackDepth--;
624     if (classFileOffset >= bCodeStream.length) {
625         resizeByteArray();
626     }
627     position++;
628     bCodeStream[classFileOffset++] = Opcodes.OPC_d2f;
629 }
630 public void d2i() {
631     if (DEBUG) System.out.println(position + "\t\td2i"); //$NON-NLS-1$
632
countLabels = 0;
633     stackDepth--;
634     if (classFileOffset >= bCodeStream.length) {
635         resizeByteArray();
636     }
637     position++;
638     bCodeStream[classFileOffset++] = Opcodes.OPC_d2i;
639 }
640 public void d2l() {
641     if (DEBUG) System.out.println(position + "\t\td2l"); //$NON-NLS-1$
642
countLabels = 0;
643     if (classFileOffset >= bCodeStream.length) {
644         resizeByteArray();
645     }
646     position++;
647     bCodeStream[classFileOffset++] = Opcodes.OPC_d2l;
648 }
649 public void dadd() {
650     if (DEBUG) System.out.println(position + "\t\tdadd"); //$NON-NLS-1$
651
countLabels = 0;
652     stackDepth -= 2;
653     if (classFileOffset >= bCodeStream.length) {
654         resizeByteArray();
655     }
656     position++;
657     bCodeStream[classFileOffset++] = Opcodes.OPC_dadd;
658 }
659 public void daload() {
660     if (DEBUG) System.out.println(position + "\t\tdaload"); //$NON-NLS-1$
661
countLabels = 0;
662     if (classFileOffset >= bCodeStream.length) {
663         resizeByteArray();
664     }
665     position++;
666     bCodeStream[classFileOffset++] = Opcodes.OPC_daload;
667 }
668 public void dastore() {
669     if (DEBUG) System.out.println(position + "\t\tdastore"); //$NON-NLS-1$
670
countLabels = 0;
671     stackDepth -= 4;
672     if (classFileOffset >= bCodeStream.length) {
673         resizeByteArray();
674     }
675     position++;
676     bCodeStream[classFileOffset++] = Opcodes.OPC_dastore;
677 }
678 public void dcmpg() {
679     if (DEBUG) System.out.println(position + "\t\tdcmpg"); //$NON-NLS-1$
680
countLabels = 0;
681     stackDepth -= 3;
682     if (classFileOffset >= bCodeStream.length) {
683         resizeByteArray();
684     }
685     position++;
686     bCodeStream[classFileOffset++] = Opcodes.OPC_dcmpg;
687 }
688 public void dcmpl() {
689     if (DEBUG) System.out.println(position + "\t\tdcmpl"); //$NON-NLS-1$
690
countLabels = 0;
691     stackDepth -= 3;
692     if (classFileOffset >= bCodeStream.length) {
693         resizeByteArray();
694     }
695     position++;
696     bCodeStream[classFileOffset++] = Opcodes.OPC_dcmpl;
697 }
698 public void dconst_0() {
699     if (DEBUG) System.out.println(position + "\t\tdconst_0"); //$NON-NLS-1$
700
countLabels = 0;
701     stackDepth += 2;
702     if (stackDepth > stackMax)
703         stackMax = stackDepth;
704     if (classFileOffset >= bCodeStream.length) {
705         resizeByteArray();
706     }
707     position++;
708     bCodeStream[classFileOffset++] = Opcodes.OPC_dconst_0;
709 }
710 public void dconst_1() {
711     if (DEBUG) System.out.println(position + "\t\tdconst_1"); //$NON-NLS-1$
712
countLabels = 0;
713     stackDepth += 2;
714     if (stackDepth > stackMax)
715         stackMax = stackDepth;
716     if (classFileOffset >= bCodeStream.length) {
717         resizeByteArray();
718     }
719     position++;
720     bCodeStream[classFileOffset++] = Opcodes.OPC_dconst_1;
721 }
722 public void ddiv() {
723     if (DEBUG) System.out.println(position + "\t\tddiv"); //$NON-NLS-1$
724
countLabels = 0;
725     stackDepth -= 2;
726     if (classFileOffset >= bCodeStream.length) {
727         resizeByteArray();
728     }
729     position++;
730     bCodeStream[classFileOffset++] = Opcodes.OPC_ddiv;
731 }
732 public void decrStackSize(int offset) {
733     stackDepth -= offset;
734 }
735 public void dload(int iArg) {
736     if (DEBUG) System.out.println(position + "\t\tdload:"+iArg); //$NON-NLS-1$
737
countLabels = 0;
738     stackDepth += 2;
739     if (stackDepth > stackMax)
740         stackMax = stackDepth;
741     if (maxLocals < iArg + 2) {
742         maxLocals = iArg + 2; // + 2 because it is a double
743
}
744     if (iArg > 255) { // Widen
745
if (classFileOffset + 3 >= bCodeStream.length) {
746             resizeByteArray();
747         }
748         position += 2;
749         bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
750         bCodeStream[classFileOffset++] = Opcodes.OPC_dload;
751         writeUnsignedShort(iArg);
752     } else {
753         // Don't need to use the wide bytecode
754
if (classFileOffset + 1 >= bCodeStream.length) {
755             resizeByteArray();
756         }
757         position += 2;
758         bCodeStream[classFileOffset++] = Opcodes.OPC_dload;
759         bCodeStream[classFileOffset++] = (byte) iArg;
760     }
761 }
762 public void dload_0() {
763     if (DEBUG) System.out.println(position + "\t\tdload_0"); //$NON-NLS-1$
764
countLabels = 0;
765     stackDepth += 2;
766     if (stackDepth > stackMax)
767         stackMax = stackDepth;
768     if (maxLocals < 2) {
769         maxLocals = 2;
770     }
771     if (classFileOffset >= bCodeStream.length) {
772         resizeByteArray();
773     }
774     position++;
775     bCodeStream[classFileOffset++] = Opcodes.OPC_dload_0;
776 }
777 public void dload_1() {
778     if (DEBUG) System.out.println(position + "\t\tdload_1"); //$NON-NLS-1$
779
countLabels = 0;
780     stackDepth += 2;
781     if (stackDepth > stackMax)
782         stackMax = stackDepth;
783     if (maxLocals < 3) {
784         maxLocals = 3;
785     }
786     if (classFileOffset >= bCodeStream.length) {
787         resizeByteArray();
788     }
789     position++;
790     bCodeStream[classFileOffset++] = Opcodes.OPC_dload_1;
791 }
792 public void dload_2() {
793     if (DEBUG) System.out.println(position + "\t\tdload_2"); //$NON-NLS-1$
794
countLabels = 0;
795     stackDepth += 2;
796     if (stackDepth > stackMax)
797         stackMax = stackDepth;
798     if (maxLocals < 4) {
799         maxLocals = 4;
800     }
801     if (classFileOffset >= bCodeStream.length) {
802         resizeByteArray();
803     }
804     position++;
805     bCodeStream[classFileOffset++] = Opcodes.OPC_dload_2;
806 }
807 public void dload_3() {
808     if (DEBUG) System.out.println(position + "\t\tdload_3"); //$NON-NLS-1$
809
countLabels = 0;
810     stackDepth += 2;
811     if (stackDepth > stackMax)
812         stackMax = stackDepth;
813     if (maxLocals < 5) {
814         maxLocals = 5;
815     }
816     if (classFileOffset >= bCodeStream.length) {
817         resizeByteArray();
818     }
819     position++;
820     bCodeStream[classFileOffset++] = Opcodes.OPC_dload_3;
821 }
822 public void dmul() {
823     if (DEBUG) System.out.println(position + "\t\tdmul"); //$NON-NLS-1$
824
countLabels = 0;
825     stackDepth -= 2;
826     if (classFileOffset >= bCodeStream.length) {
827         resizeByteArray();
828     }
829     position++;
830     bCodeStream[classFileOffset++] = Opcodes.OPC_dmul;
831 }
832 public void dneg() {
833     if (DEBUG) System.out.println(position + "\t\tdneg"); //$NON-NLS-1$
834
countLabels = 0;
835     if (classFileOffset >= bCodeStream.length) {
836         resizeByteArray();
837     }
838     position++;
839     bCodeStream[classFileOffset++] = Opcodes.OPC_dneg;
840 }
841 public void drem() {
842     if (DEBUG) System.out.println(position + "\t\tdrem"); //$NON-NLS-1$
843
countLabels = 0;
844     stackDepth -= 2;
845     if (classFileOffset >= bCodeStream.length) {
846         resizeByteArray();
847     }
848     position++;
849     bCodeStream[classFileOffset++] = Opcodes.OPC_drem;
850 }
851 public void dreturn() {
852     if (DEBUG) System.out.println(position + "\t\tdreturn"); //$NON-NLS-1$
853
countLabels = 0;
854     stackDepth -= 2;
855     // the stackDepth should be equal to 0
856
if (classFileOffset >= bCodeStream.length) {
857         resizeByteArray();
858     }
859     position++;
860     bCodeStream[classFileOffset++] = Opcodes.OPC_dreturn;
861     this.lastAbruptCompletion = this.position;
862 }
863 public void dstore(int iArg) {
864     if (DEBUG) System.out.println(position + "\t\tdstore:"+iArg); //$NON-NLS-1$
865
countLabels = 0;
866     stackDepth -= 2;
867     if (maxLocals <= iArg + 1) {
868         maxLocals = iArg + 2;
869     }
870     if (iArg > 255) { // Widen
871
if (classFileOffset + 3 >= bCodeStream.length) {
872             resizeByteArray();
873         }
874         position += 2;
875         bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
876         bCodeStream[classFileOffset++] = Opcodes.OPC_dstore;
877         writeUnsignedShort(iArg);
878     } else {
879         if (classFileOffset + 1 >= bCodeStream.length) {
880             resizeByteArray();
881         }
882         position += 2;
883         bCodeStream[classFileOffset++] = Opcodes.OPC_dstore;
884         bCodeStream[classFileOffset++] = (byte) iArg;
885     }
886 }
887 public void dstore_0() {
888     if (DEBUG) System.out.println(position + "\t\tdstore_0"); //$NON-NLS-1$
889
countLabels = 0;
890     stackDepth -= 2;
891     if (maxLocals < 2) {
892         maxLocals = 2;
893     }
894     if (classFileOffset >= bCodeStream.length) {
895         resizeByteArray();
896     }
897     position++;
898     bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_0;
899 }
900 public void dstore_1() {
901     if (DEBUG) System.out.println(position + "\t\tdstore_1"); //$NON-NLS-1$
902
countLabels = 0;
903     stackDepth -= 2;
904     if (maxLocals < 3) {
905         maxLocals = 3;
906     }
907     if (classFileOffset >= bCodeStream.length) {
908         resizeByteArray();
909     }
910     position++;
911     bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_1;
912 }
913 public void dstore_2() {
914     if (DEBUG) System.out.println(position + "\t\tdstore_2"); //$NON-NLS-1$
915
countLabels = 0;
916     stackDepth -= 2;
917     if (maxLocals < 4) {
918         maxLocals = 4;
919     }
920     if (classFileOffset >= bCodeStream.length) {
921         resizeByteArray();
922     }
923     position++;
924     bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_2;
925 }
926 public void dstore_3() {
927     if (DEBUG) System.out.println(position + "\t\tdstore_3"); //$NON-NLS-1$
928
countLabels = 0;
929     stackDepth -= 2;
930     if (maxLocals < 5) {
931         maxLocals = 5;
932     }
933     if (classFileOffset >= bCodeStream.length) {
934         resizeByteArray();
935     }
936     position++;
937     bCodeStream[classFileOffset++] = Opcodes.OPC_dstore_3;
938 }
939 public void dsub() {
940     if (DEBUG) System.out.println(position + "\t\tdsub"); //$NON-NLS-1$
941
countLabels = 0;
942     stackDepth -= 2;
943     if (classFileOffset >= bCodeStream.length) {
944         resizeByteArray();
945     }
946     position++;
947     bCodeStream[classFileOffset++] = Opcodes.OPC_dsub;
948 }
949 public void dup() {
950     if (DEBUG) System.out.println(position + "\t\tdup"); //$NON-NLS-1$
951
countLabels = 0;
952     stackDepth++;
953     if (stackDepth > stackMax) {
954         stackMax = stackDepth;
955     }
956     if (classFileOffset >= bCodeStream.length) {
957         resizeByteArray();
958     }
959     position++;
960     bCodeStream[classFileOffset++] = Opcodes.OPC_dup;
961 }
962 public void dup_x1() {
963     if (DEBUG) System.out.println(position + "\t\tdup_x1"); //$NON-NLS-1$
964
countLabels = 0;
965     stackDepth++;
966     if (stackDepth > stackMax)
967         stackMax = stackDepth;
968     if (classFileOffset >= bCodeStream.length) {
969         resizeByteArray();
970     }
971     position++;
972     bCodeStream[classFileOffset++] = Opcodes.OPC_dup_x1;
973 }
974 public void dup_x2() {
975     if (DEBUG) System.out.println(position + "\t\tdup_x2"); //$NON-NLS-1$
976
countLabels = 0;
977     stackDepth++;
978     if (stackDepth > stackMax)
979         stackMax = stackDepth;
980     if (classFileOffset >= bCodeStream.length) {
981         resizeByteArray();
982     }
983     position++;
984     bCodeStream[classFileOffset++] = Opcodes.OPC_dup_x2;
985 }
986 public void dup2() {
987     if (DEBUG) System.out.println(position + "\t\tdup2"); //$NON-NLS-1$
988
countLabels = 0;
989     stackDepth += 2;
990     if (stackDepth > stackMax)
991         stackMax = stackDepth;
992     if (classFileOffset >= bCodeStream.length) {
993         resizeByteArray();
994     }
995     position++;
996     bCodeStream[classFileOffset++] = Opcodes.OPC_dup2;
997 }
998 public void dup2_x1() {
999     if (DEBUG) System.out.println(position + "\t\tdup2_x1"); //$NON-NLS-1$
1000
countLabels = 0;
1001    stackDepth += 2;
1002    if (stackDepth > stackMax)
1003        stackMax = stackDepth;
1004    if (classFileOffset >= bCodeStream.length) {
1005        resizeByteArray();
1006    }
1007    position++;
1008    bCodeStream[classFileOffset++] = Opcodes.OPC_dup2_x1;
1009}
1010public void dup2_x2() {
1011    if (DEBUG) System.out.println(position + "\t\tdup2_x2"); //$NON-NLS-1$
1012
countLabels = 0;
1013    stackDepth += 2;
1014    if (stackDepth > stackMax)
1015        stackMax = stackDepth;
1016    if (classFileOffset >= bCodeStream.length) {
1017        resizeByteArray();
1018    }
1019    position++;
1020    bCodeStream[classFileOffset++] = Opcodes.OPC_dup2_x2;
1021}
1022public void exitUserScope(BlockScope currentScope) {
1023    // mark all the scope's locals as losing their definite assignment
1024

1025    if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) == 0)
1026        return;
1027    int index = this.visibleLocalsCount - 1;
1028    while (index >= 0) {
1029        LocalVariableBinding visibleLocal = visibleLocals[index];
1030        if (visibleLocal == null || visibleLocal.declaringScope != currentScope) {
1031            // left currentScope
1032
index--;
1033            continue;
1034        }
1035
1036        // there may be some preserved locals never initialized
1037
if (visibleLocal.initializationCount > 0) {
1038            visibleLocal.recordInitializationEndPC(position);
1039        }
1040        visibleLocals[index--] = null; // this variable is no longer visible afterwards
1041
}
1042}
1043public void exitUserScope(BlockScope currentScope, LocalVariableBinding binding) {
1044    // mark all the scope's locals as losing their definite assignment
1045
if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) == 0)
1046        return;
1047    int index = this.visibleLocalsCount - 1;
1048    while (index >= 0) {
1049        LocalVariableBinding visibleLocal = visibleLocals[index];
1050        if (visibleLocal == null || visibleLocal.declaringScope != currentScope || visibleLocal == binding) {
1051            // left currentScope
1052
index--;
1053            continue;
1054        }
1055        // there may be some preserved locals never initialized
1056
if (visibleLocal.initializationCount > 0) {
1057            visibleLocal.recordInitializationEndPC(position);
1058        }
1059        visibleLocals[index--] = null; // this variable is no longer visible afterwards
1060
}
1061}
1062public void f2d() {
1063    if (DEBUG) System.out.println(position + "\t\tf2d"); //$NON-NLS-1$
1064
countLabels = 0;
1065    stackDepth++;
1066    if (stackDepth > stackMax)
1067        stackMax = stackDepth;
1068    if (classFileOffset >= bCodeStream.length) {
1069        resizeByteArray();
1070    }
1071    position++;
1072    bCodeStream[classFileOffset++] = Opcodes.OPC_f2d;
1073}
1074public void f2i() {
1075    if (DEBUG) System.out.println(position + "\t\tf2i"); //$NON-NLS-1$
1076
countLabels = 0;
1077    if (classFileOffset >= bCodeStream.length) {
1078        resizeByteArray();
1079    }
1080    position++;
1081    bCodeStream[classFileOffset++] = Opcodes.OPC_f2i;
1082}
1083public void f2l() {
1084    if (DEBUG) System.out.println(position + "\t\tf2l"); //$NON-NLS-1$
1085
countLabels = 0;
1086    stackDepth++;
1087    if (stackDepth > stackMax)
1088        stackMax = stackDepth;
1089    if (classFileOffset >= bCodeStream.length) {
1090        resizeByteArray();
1091    }
1092    position++;
1093    bCodeStream[classFileOffset++] = Opcodes.OPC_f2l;
1094}
1095public void fadd() {
1096    if (DEBUG) System.out.println(position + "\t\tfadd"); //$NON-NLS-1$
1097
countLabels = 0;
1098    stackDepth--;
1099    if (classFileOffset >= bCodeStream.length) {
1100        resizeByteArray();
1101    }
1102    position++;
1103    bCodeStream[classFileOffset++] = Opcodes.OPC_fadd;
1104}
1105public void faload() {
1106    if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
1107
countLabels = 0;
1108    stackDepth--;
1109    if (classFileOffset >= bCodeStream.length) {
1110        resizeByteArray();
1111    }
1112    position++;
1113    bCodeStream[classFileOffset++] = Opcodes.OPC_faload;
1114}
1115public void fastore() {
1116    if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
1117
countLabels = 0;
1118    stackDepth -= 3;
1119    if (classFileOffset >= bCodeStream.length) {
1120        resizeByteArray();
1121    }
1122    position++;
1123    bCodeStream[classFileOffset++] = Opcodes.OPC_fastore;
1124}
1125public void fcmpg() {
1126    if (DEBUG) System.out.println(position + "\t\tfcmpg"); //$NON-NLS-1$
1127
countLabels = 0;
1128    stackDepth--;
1129    if (classFileOffset >= bCodeStream.length) {
1130        resizeByteArray();
1131    }
1132    position++;
1133    bCodeStream[classFileOffset++] = Opcodes.OPC_fcmpg;
1134}
1135public void fcmpl() {
1136    if (DEBUG) System.out.println(position + "\t\tfcmpl"); //$NON-NLS-1$
1137
countLabels = 0;
1138    stackDepth--;
1139    if (classFileOffset >= bCodeStream.length) {
1140        resizeByteArray();
1141    }
1142    position++;
1143    bCodeStream[classFileOffset++] = Opcodes.OPC_fcmpl;
1144}
1145public void fconst_0() {
1146    if (DEBUG) System.out.println(position + "\t\tfconst_0"); //$NON-NLS-1$
1147
countLabels = 0;
1148    stackDepth++;
1149    if (stackDepth > stackMax)
1150        stackMax = stackDepth;
1151    if (classFileOffset >= bCodeStream.length) {
1152        resizeByteArray();
1153    }
1154    position++;
1155    bCodeStream[classFileOffset++] = Opcodes.OPC_fconst_0;
1156}
1157public void fconst_1() {
1158    if (DEBUG) System.out.println(position + "\t\tfconst_1"); //$NON-NLS-1$
1159
countLabels = 0;
1160    stackDepth++;
1161    if (stackDepth > stackMax)
1162        stackMax = stackDepth;
1163    if (classFileOffset >= bCodeStream.length) {
1164        resizeByteArray();
1165    }
1166    position++;
1167    bCodeStream[classFileOffset++] = Opcodes.OPC_fconst_1;
1168}
1169public void fconst_2() {
1170    if (DEBUG) System.out.println(position + "\t\tfconst_2"); //$NON-NLS-1$
1171
countLabels = 0;
1172    stackDepth++;
1173    if (stackDepth > stackMax)
1174        stackMax = stackDepth;
1175    if (classFileOffset >= bCodeStream.length) {
1176        resizeByteArray();
1177    }
1178    position++;
1179    bCodeStream[classFileOffset++] = Opcodes.OPC_fconst_2;
1180}
1181public void fdiv() {
1182    if (DEBUG) System.out.println(position + "\t\tfdiv"); //$NON-NLS-1$
1183
countLabels = 0;
1184    stackDepth--;
1185    if (classFileOffset >= bCodeStream.length) {
1186        resizeByteArray();
1187    }
1188    position++;
1189    bCodeStream[classFileOffset++] = Opcodes.OPC_fdiv;
1190}
1191public void fload(int iArg) {
1192    if (DEBUG) System.out.println(position + "\t\tfload:"+iArg); //$NON-NLS-1$
1193
countLabels = 0;
1194    stackDepth++;
1195    if (maxLocals <= iArg) {
1196        maxLocals = iArg + 1;
1197    }
1198    if (stackDepth > stackMax)
1199        stackMax = stackDepth;
1200    if (iArg > 255) { // Widen
1201
if (classFileOffset + 3 >= bCodeStream.length) {
1202            resizeByteArray();
1203        }
1204        position += 2;
1205        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
1206        bCodeStream[classFileOffset++] = Opcodes.OPC_fload;
1207        writeUnsignedShort(iArg);
1208    } else {
1209        if (classFileOffset + 1 >= bCodeStream.length) {
1210            resizeByteArray();
1211        }
1212        position += 2;
1213        bCodeStream[classFileOffset++] = Opcodes.OPC_fload;
1214        bCodeStream[classFileOffset++] = (byte) iArg;
1215    }
1216}
1217public void fload_0() {
1218    if (DEBUG) System.out.println(position + "\t\tfload_0"); //$NON-NLS-1$
1219
countLabels = 0;
1220    stackDepth++;
1221    if (maxLocals == 0) {
1222        maxLocals = 1;
1223    }
1224    if (stackDepth > stackMax)
1225        stackMax = stackDepth;
1226    if (classFileOffset >= bCodeStream.length) {
1227        resizeByteArray();
1228    }
1229    position++;
1230    bCodeStream[classFileOffset++] = Opcodes.OPC_fload_0;
1231}
1232public void fload_1() {
1233    if (DEBUG) System.out.println(position + "\t\tfload_1"); //$NON-NLS-1$
1234
countLabels = 0;
1235    stackDepth++;
1236    if (maxLocals <= 1) {
1237        maxLocals = 2;
1238    }
1239    if (stackDepth > stackMax)
1240        stackMax = stackDepth;
1241    if (classFileOffset >= bCodeStream.length) {
1242        resizeByteArray();
1243    }
1244    position++;
1245    bCodeStream[classFileOffset++] = Opcodes.OPC_fload_1;
1246}
1247public void fload_2() {
1248    if (DEBUG) System.out.println(position + "\t\tfload_2"); //$NON-NLS-1$
1249
countLabels = 0;
1250    stackDepth++;
1251    if (maxLocals <= 2) {
1252        maxLocals = 3;
1253    }
1254    if (stackDepth > stackMax)
1255        stackMax = stackDepth;
1256    if (classFileOffset >= bCodeStream.length) {
1257        resizeByteArray();
1258    }
1259    position++;
1260    bCodeStream[classFileOffset++] = Opcodes.OPC_fload_2;
1261}
1262public void fload_3() {
1263    if (DEBUG) System.out.println(position + "\t\tfload_3"); //$NON-NLS-1$
1264
countLabels = 0;
1265    stackDepth++;
1266    if (maxLocals <= 3) {
1267        maxLocals = 4;
1268    }
1269    if (stackDepth > stackMax)
1270        stackMax = stackDepth;
1271    if (classFileOffset >= bCodeStream.length) {
1272        resizeByteArray();
1273    }
1274    position++;
1275    bCodeStream[classFileOffset++] = Opcodes.OPC_fload_3;
1276}
1277public void fmul() {
1278    if (DEBUG) System.out.println(position + "\t\tfmul"); //$NON-NLS-1$
1279
countLabels = 0;
1280    stackDepth--;
1281    if (classFileOffset >= bCodeStream.length) {
1282        resizeByteArray();
1283    }
1284    position++;
1285    bCodeStream[classFileOffset++] = Opcodes.OPC_fmul;
1286}
1287public void fneg() {
1288    if (DEBUG) System.out.println(position + "\t\tfneg"); //$NON-NLS-1$
1289
countLabels = 0;
1290    if (classFileOffset >= bCodeStream.length) {
1291        resizeByteArray();
1292    }
1293    position++;
1294    bCodeStream[classFileOffset++] = Opcodes.OPC_fneg;
1295}
1296public void frem() {
1297    if (DEBUG) System.out.println(position + "\t\tfrem"); //$NON-NLS-1$
1298
countLabels = 0;
1299    stackDepth--;
1300    if (classFileOffset >= bCodeStream.length) {
1301        resizeByteArray();
1302    }
1303    position++;
1304    bCodeStream[classFileOffset++] = Opcodes.OPC_frem;
1305}
1306public void freturn() {
1307    if (DEBUG) System.out.println(position + "\t\tfreturn"); //$NON-NLS-1$
1308
countLabels = 0;
1309    stackDepth--;
1310    // the stackDepth should be equal to 0
1311
if (classFileOffset >= bCodeStream.length) {
1312        resizeByteArray();
1313    }
1314    position++;
1315    bCodeStream[classFileOffset++] = Opcodes.OPC_freturn;
1316    this.lastAbruptCompletion = this.position;
1317}
1318public void fstore(int iArg) {
1319    if (DEBUG) System.out.println(position + "\t\tfstore:"+iArg); //$NON-NLS-1$
1320
countLabels = 0;
1321    stackDepth--;
1322    if (maxLocals <= iArg) {
1323        maxLocals = iArg + 1;
1324    }
1325    if (iArg > 255) { // Widen
1326
if (classFileOffset + 3 >= bCodeStream.length) {
1327            resizeByteArray();
1328        }
1329        position += 2;
1330        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
1331        bCodeStream[classFileOffset++] = Opcodes.OPC_fstore;
1332        writeUnsignedShort(iArg);
1333    } else {
1334        if (classFileOffset + 1 >= bCodeStream.length) {
1335            resizeByteArray();
1336        }
1337        position += 2;
1338        bCodeStream[classFileOffset++] = Opcodes.OPC_fstore;
1339        bCodeStream[classFileOffset++] = (byte) iArg;
1340    }
1341}
1342public void fstore_0() {
1343    if (DEBUG) System.out.println(position + "\t\tfstore_0"); //$NON-NLS-1$
1344
countLabels = 0;
1345    stackDepth--;
1346    if (maxLocals == 0) {
1347        maxLocals = 1;
1348    }
1349    if (classFileOffset >= bCodeStream.length) {
1350        resizeByteArray();
1351    }
1352    position++;
1353    bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_0;
1354}
1355public void fstore_1() {
1356    if (DEBUG) System.out.println(position + "\t\tfstore_1"); //$NON-NLS-1$
1357
countLabels = 0;
1358    stackDepth--;
1359    if (maxLocals <= 1) {
1360        maxLocals = 2;
1361    }
1362    if (classFileOffset >= bCodeStream.length) {
1363        resizeByteArray();
1364    }
1365    position++;
1366    bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_1;
1367}
1368public void fstore_2() {
1369    if (DEBUG) System.out.println(position + "\t\tfstore_2"); //$NON-NLS-1$
1370
countLabels = 0;
1371    stackDepth--;
1372    if (maxLocals <= 2) {
1373        maxLocals = 3;
1374    }
1375    if (classFileOffset >= bCodeStream.length) {
1376        resizeByteArray();
1377    }
1378    position++;
1379    bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_2;
1380}
1381public void fstore_3() {
1382    if (DEBUG) System.out.println(position + "\t\tfstore_3"); //$NON-NLS-1$
1383
countLabels = 0;
1384    stackDepth--;
1385    if (maxLocals <= 3) {
1386        maxLocals = 4;
1387    }
1388    if (classFileOffset >= bCodeStream.length) {
1389        resizeByteArray();
1390    }
1391    position++;
1392    bCodeStream[classFileOffset++] = Opcodes.OPC_fstore_3;
1393}
1394
1395public void fsub() {
1396    if (DEBUG) System.out.println(position + "\t\tfsub"); //$NON-NLS-1$
1397
countLabels = 0;
1398    stackDepth--;
1399    if (classFileOffset >= bCodeStream.length) {
1400        resizeByteArray();
1401    }
1402    position++;
1403    bCodeStream[classFileOffset++] = Opcodes.OPC_fsub;
1404}
1405public void generateBoxingConversion(int unboxedTypeID) {
1406    switch (unboxedTypeID) {
1407        case TypeIds.T_byte :
1408            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
1409                if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Byte.valueOf(byte)"); //$NON-NLS-1$
1410
// invokestatic: Byte.valueOf(byte)
1411
this.invoke(
1412                    Opcodes.OPC_invokestatic,
1413                    1, // argCount
1414
1, // return type size
1415
ConstantPool.JavaLangByteConstantPoolName,
1416                    ConstantPool.ValueOf,
1417                    ConstantPool.byteByteSignature);
1418            } else {
1419               // new Byte( byte )
1420
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Byte(byte)"); //$NON-NLS-1$
1421
newWrapperFor(unboxedTypeID);
1422                dup_x1();
1423                swap();
1424                this.invoke(
1425                    Opcodes.OPC_invokespecial,
1426                    1, // argCount
1427
0, // return type size
1428
ConstantPool.JavaLangByteConstantPoolName,
1429                    ConstantPool.Init,
1430                    ConstantPool.ByteConstrSignature);
1431            }
1432            break;
1433        case TypeIds.T_short :
1434            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
1435                // invokestatic: Short.valueOf(short)
1436
if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Short.valueOf(short)"); //$NON-NLS-1$
1437
this.invoke(
1438                    Opcodes.OPC_invokestatic,
1439                    1, // argCount
1440
1, // return type size
1441
ConstantPool.JavaLangShortConstantPoolName,
1442                    ConstantPool.ValueOf,
1443                    ConstantPool.shortShortSignature);
1444            } else {
1445                // new Short(short)
1446
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Short(short)"); //$NON-NLS-1$
1447
newWrapperFor(unboxedTypeID);
1448                dup_x1();
1449                swap();
1450                this.invoke(
1451                    Opcodes.OPC_invokespecial,
1452                    1, // argCount
1453
0, // return type size
1454
ConstantPool.JavaLangShortConstantPoolName,
1455                    ConstantPool.Init,
1456                    ConstantPool.ShortConstrSignature);
1457            }
1458            break;
1459        case TypeIds.T_char :
1460            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
1461                // invokestatic: Character.valueOf(char)
1462
if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Character.valueOf(char)"); //$NON-NLS-1$
1463
this.invoke(
1464                    Opcodes.OPC_invokestatic,
1465                    1, // argCount
1466
1, // return type size
1467
ConstantPool.JavaLangCharacterConstantPoolName,
1468                    ConstantPool.ValueOf,
1469                    ConstantPool.charCharacterSignature);
1470            } else {
1471                // new Char( char )
1472
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Character(char)"); //$NON-NLS-1$
1473
newWrapperFor(unboxedTypeID);
1474                dup_x1();
1475                swap();
1476                this.invoke(
1477                    Opcodes.OPC_invokespecial,
1478                    1, // argCount
1479
0, // return type size
1480
ConstantPool.JavaLangCharacterConstantPoolName,
1481                    ConstantPool.Init,
1482                    ConstantPool.CharConstrSignature);
1483            }
1484            break;
1485        case TypeIds.T_int :
1486            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
1487                // invokestatic: Integer.valueOf(int)
1488
if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Integer.valueOf(int)"); //$NON-NLS-1$
1489
this.invoke(
1490                    Opcodes.OPC_invokestatic,
1491                    1, // argCount
1492
1, // return type size
1493
ConstantPool.JavaLangIntegerConstantPoolName,
1494                    ConstantPool.ValueOf,
1495                    ConstantPool.IntIntegerSignature);
1496            } else {
1497                // new Integer(int)
1498
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Integer(int)"); //$NON-NLS-1$
1499
newWrapperFor(unboxedTypeID);
1500                dup_x1();
1501                swap();
1502                this.invoke(
1503                    Opcodes.OPC_invokespecial,
1504                    1, // argCount
1505
0, // return type size
1506
ConstantPool.JavaLangIntegerConstantPoolName,
1507                    ConstantPool.Init,
1508                    ConstantPool.IntConstrSignature);
1509            }
1510            break;
1511        case TypeIds.T_long :
1512            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
1513                // invokestatic: Long.valueOf(long)
1514
if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Long.valueOf(long)"); //$NON-NLS-1$
1515
this.invoke(
1516                    Opcodes.OPC_invokestatic,
1517                    2, // argCount
1518
1, // return type size
1519
ConstantPool.JavaLangLongConstantPoolName,
1520                    ConstantPool.ValueOf,
1521                    ConstantPool.longLongSignature);
1522            } else {
1523                // new Long( long )
1524
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Long(long)"); //$NON-NLS-1$
1525
newWrapperFor(unboxedTypeID);
1526                dup_x2();
1527                dup_x2();
1528                pop();
1529                this.invoke(
1530                    Opcodes.OPC_invokespecial,
1531                    2, // argCount
1532
0, // return type size
1533
ConstantPool.JavaLangLongConstantPoolName,
1534                    ConstantPool.Init,
1535                    ConstantPool.LongConstrSignature);
1536            }
1537            break;
1538        case TypeIds.T_float :
1539            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
1540                // invokestatic: Float.valueOf(float)
1541
if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Float.valueOf(float)"); //$NON-NLS-1$
1542
this.invoke(
1543                    Opcodes.OPC_invokestatic,
1544                    1, // argCount
1545
1, // return type size
1546
ConstantPool.JavaLangFloatConstantPoolName,
1547                    ConstantPool.ValueOf,
1548                    ConstantPool.floatFloatSignature);
1549            } else {
1550                // new Float(float)
1551
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Float(float)"); //$NON-NLS-1$
1552
newWrapperFor(unboxedTypeID);
1553                dup_x1();
1554                swap();
1555                this.invoke(
1556                    Opcodes.OPC_invokespecial,
1557                    1, // argCount
1558
0, // return type size
1559
ConstantPool.JavaLangFloatConstantPoolName,
1560                    ConstantPool.Init,
1561                    ConstantPool.FloatConstrSignature);
1562            }
1563            break;
1564        case TypeIds.T_double :
1565            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
1566                // invokestatic: Double.valueOf(double)
1567
if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Double.valueOf(double)"); //$NON-NLS-1$
1568
this.invoke(
1569                    Opcodes.OPC_invokestatic,
1570                    2, // argCount
1571
1, // return type size
1572
ConstantPool.JavaLangDoubleConstantPoolName,
1573                    ConstantPool.ValueOf,
1574                    ConstantPool.doubleDoubleSignature);
1575            } else {
1576                // new Double( double )
1577
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Double(double)"); //$NON-NLS-1$
1578
newWrapperFor(unboxedTypeID);
1579                dup_x2();
1580                dup_x2();
1581                pop();
1582                
1583                this.invoke(
1584                    Opcodes.OPC_invokespecial,
1585                    2, // argCount
1586
0, // return type size
1587
ConstantPool.JavaLangDoubleConstantPoolName,
1588                    ConstantPool.Init,
1589                    ConstantPool.DoubleConstrSignature);
1590            }
1591            
1592            break;
1593        case TypeIds.T_boolean :
1594            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
1595                // invokestatic: Boolean.valueOf(boolean)
1596
if (DEBUG) System.out.println(position + "\t\tinvokestatic java.lang.Boolean.valueOf(boolean)"); //$NON-NLS-1$
1597
this.invoke(
1598                    Opcodes.OPC_invokestatic,
1599                    1, // argCount
1600
1, // return type size
1601
ConstantPool.JavaLangBooleanConstantPoolName,
1602                    ConstantPool.ValueOf,
1603                    ConstantPool.booleanBooleanSignature);
1604            } else {
1605                // new Boolean(boolean)
1606
if (DEBUG) System.out.println(position + "\t\tinvokespecial java.lang.Boolean(boolean)"); //$NON-NLS-1$
1607
newWrapperFor(unboxedTypeID);
1608                dup_x1();
1609                swap();
1610                this.invoke(
1611                    Opcodes.OPC_invokespecial,
1612                    1, // argCount
1613
0, // return type size
1614
ConstantPool.JavaLangBooleanConstantPoolName,
1615                    ConstantPool.Init,
1616                    ConstantPool.BooleanConstrSignature);
1617            }
1618    }
1619}
1620/**
1621 * Macro for building a class descriptor object
1622 */

1623public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
1624    BranchLabel endLabel;
1625    ExceptionLabel anyExceptionHandler;
1626    int saveStackSize;
1627    if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) {
1628        this.getTYPE(accessedType.id);
1629        return;
1630    }
1631
1632    if (this.targetLevel >= ClassFileConstants.JDK1_5) {
1633        // generation using the new ldc_w bytecode
1634
this.ldc(accessedType);
1635    } else {
1636        endLabel = new BranchLabel(this);
1637        if (syntheticFieldBinding != null) { // non interface case
1638
this.getstatic(syntheticFieldBinding);
1639            this.dup();
1640            this.ifnonnull(endLabel);
1641            this.pop();
1642        }
1643
1644        /* Macro for building a class descriptor object... using or not a field cache to store it into...
1645        this sequence is responsible for building the actual class descriptor.
1646        
1647        If the fieldCache is set, then it is supposed to be the body of a synthetic access method
1648        factoring the actual descriptor creation out of the invocation site (saving space).
1649        If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
1650        we have no way to get a hand on the field cache to do better. */

1651    
1652    
1653        // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
1654

1655        anyExceptionHandler = new ExceptionLabel(this, TypeBinding.NULL /* represents ClassNotFoundException*/);
1656        anyExceptionHandler.placeStart();
1657        this.ldc(accessedType == TypeBinding.NULL ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
1658
this.invokeClassForName();
1659    
1660        /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
1661        if (accessedType == BaseTypes.NullBinding) {
1662            this.ldc("java.lang.Object"); //$NON-NLS-1$
1663        } else if (accessedType.isArrayType()) {
1664            this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
1665        } else {
1666            // we make it an array type (to avoid class initialization)
1667            this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
1668        }
1669        this.invokeClassForName();
1670        if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
1671            this.invokeJavaLangClassGetComponentType();
1672        }
1673        */

1674        /* We need to protect the runtime code from binary inconsistencies
1675        in case the accessedType is missing, the ClassNotFoundException has to be converted
1676        into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */

1677        anyExceptionHandler.placeEnd();
1678    
1679        if (syntheticFieldBinding != null) { // non interface case
1680
this.dup();
1681            this.putstatic(syntheticFieldBinding);
1682        }
1683        this.goto_(endLabel);
1684    
1685    
1686        // Generate the body of the exception handler
1687
saveStackSize = stackDepth;
1688        stackDepth = 1;
1689        /* ClassNotFoundException on stack -- the class literal could be doing more things
1690        on the stack, which means that the stack may not be empty at this point in the
1691        above code gen. So we save its state and restart it from 1. */

1692    
1693        anyExceptionHandler.place();
1694    
1695        // Transform the current exception, and repush and throw a
1696
// NoClassDefFoundError(ClassNotFound.getMessage())
1697

1698        this.newNoClassDefFoundError();
1699        this.dup_x1();
1700        this.swap();
1701    
1702        // Retrieve the message from the old exception
1703
this.invokeThrowableGetMessage();
1704    
1705        // Send the constructor taking a message string as an argument
1706
this.invokeNoClassDefFoundErrorStringConstructor();
1707        this.athrow();
1708        stackDepth = saveStackSize;
1709        endLabel.place();
1710    }
1711}
1712/**
1713 * This method generates the code attribute bytecode
1714 */

1715final public void generateCodeAttributeForProblemMethod(String JavaDoc problemMessage) {
1716    newJavaLangError();
1717    dup();
1718    ldc(problemMessage);
1719    invokeJavaLangErrorConstructor();
1720    athrow();
1721}
1722public void generateConstant(Constant constant, int implicitConversionCode) {
1723    int targetTypeID = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
1724    if (targetTypeID == 0) targetTypeID = constant.typeID(); // use default constant type
1725
switch (targetTypeID) {
1726        case TypeIds.T_boolean :
1727            generateInlinedValue(constant.booleanValue());
1728            break;
1729        case TypeIds.T_char :
1730            generateInlinedValue(constant.charValue());
1731            break;
1732        case TypeIds.T_byte :
1733            generateInlinedValue(constant.byteValue());
1734            break;
1735        case TypeIds.T_short :
1736            generateInlinedValue(constant.shortValue());
1737            break;
1738        case TypeIds.T_int :
1739            generateInlinedValue(constant.intValue());
1740            break;
1741        case TypeIds.T_long :
1742            generateInlinedValue(constant.longValue());
1743            break;
1744        case TypeIds.T_float :
1745            generateInlinedValue(constant.floatValue());
1746            break;
1747        case TypeIds.T_double :
1748            generateInlinedValue(constant.doubleValue());
1749            break;
1750        case TypeIds.T_JavaLangString :
1751            ldc(constant.stringValue());
1752    }
1753    if ((implicitConversionCode & TypeIds.BOXING) != 0) {
1754        // need boxing
1755
generateBoxingConversion(targetTypeID);
1756    }
1757}
1758public void generateEmulatedReadAccessForField(FieldBinding fieldBinding) {
1759    this.generateEmulationForField(fieldBinding);
1760    // swap the field with the receiver
1761
this.swap();
1762    this.invokeJavaLangReflectFieldGetter(fieldBinding.type.id);
1763    if (!fieldBinding.type.isBaseType()) {
1764        this.checkcast(fieldBinding.type);
1765    }
1766}
1767public void generateEmulatedWriteAccessForField(FieldBinding fieldBinding) {
1768    this.invokeJavaLangReflectFieldSetter(fieldBinding.type.id);
1769}
1770public void generateEmulationForConstructor(Scope scope, MethodBinding methodBinding) {
1771    // leave a java.lang.reflect.Field object on the stack
1772
this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
1773    this.invokeClassForName();
1774    int paramLength = methodBinding.parameters.length;
1775    this.generateInlinedValue(paramLength);
1776    this.newArray(scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1));
1777    if (paramLength > 0) {
1778        this.dup();
1779        for (int i = 0; i < paramLength; i++) {
1780            this.generateInlinedValue(i);
1781            TypeBinding parameter = methodBinding.parameters[i];
1782            if (parameter.isBaseType()) {
1783                this.getTYPE(parameter.id);
1784            } else if (parameter.isArrayType()) {
1785                ArrayBinding array = (ArrayBinding)parameter;
1786                if (array.leafComponentType.isBaseType()) {
1787                    this.getTYPE(array.leafComponentType.id);
1788                } else {
1789                    this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.'));
1790                    this.invokeClassForName();
1791                }
1792                int dimensions = array.dimensions;
1793                this.generateInlinedValue(dimensions);
1794                this.newarray(TypeIds.T_int);
1795                this.invokeArrayNewInstance();
1796                this.invokeObjectGetClass();
1797            } else {
1798                // parameter is a reference binding
1799
this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
1800                this.invokeClassForName();
1801            }
1802            this.aastore();
1803            if (i < paramLength - 1) {
1804                this.dup();
1805            }
1806        }
1807    }
1808    this.invokeClassGetDeclaredConstructor();
1809    this.dup();
1810    this.iconst_1();
1811    this.invokeAccessibleObjectSetAccessible();
1812}
1813public void generateEmulationForField(FieldBinding fieldBinding) {
1814    // leave a java.lang.reflect.Field object on the stack
1815
this.ldc(String.valueOf(fieldBinding.declaringClass.constantPoolName()).replace('/', '.'));
1816    this.invokeClassForName();
1817    this.ldc(String.valueOf(fieldBinding.name));
1818    this.invokeClassGetDeclaredField();
1819    this.dup();
1820    this.iconst_1();
1821    this.invokeAccessibleObjectSetAccessible();
1822}
1823public void generateEmulationForMethod(Scope scope, MethodBinding methodBinding) {
1824    // leave a java.lang.reflect.Field object on the stack
1825
this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
1826    this.invokeClassForName();
1827    this.ldc(String.valueOf(methodBinding.selector));
1828    int paramLength = methodBinding.parameters.length;
1829    this.generateInlinedValue(paramLength);
1830    this.newArray(scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1));
1831    if (paramLength > 0) {
1832        this.dup();
1833        for (int i = 0; i < paramLength; i++) {
1834            this.generateInlinedValue(i);
1835            TypeBinding parameter = methodBinding.parameters[i];
1836            if (parameter.isBaseType()) {
1837                this.getTYPE(parameter.id);
1838            } else if (parameter.isArrayType()) {
1839                ArrayBinding array = (ArrayBinding)parameter;
1840                if (array.leafComponentType.isBaseType()) {
1841                    this.getTYPE(array.leafComponentType.id);
1842                } else {
1843                    this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.'));
1844                    this.invokeClassForName();
1845                }
1846                int dimensions = array.dimensions;
1847                this.generateInlinedValue(dimensions);
1848                this.newarray(TypeIds.T_int);
1849                this.invokeArrayNewInstance();
1850                this.invokeObjectGetClass();
1851            } else {
1852                // parameter is a reference binding
1853
this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
1854                this.invokeClassForName();
1855            }
1856            this.aastore();
1857            if (i < paramLength - 1) {
1858                this.dup();
1859            }
1860        }
1861    }
1862    this.invokeClassGetDeclaredMethod();
1863    this.dup();
1864    this.iconst_1();
1865    this.invokeAccessibleObjectSetAccessible();
1866}
1867private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) {
1868    countLabels = 0;
1869    switch(opcode) {
1870        case Opcodes.OPC_getfield :
1871            if (returnTypeSize == 2) {
1872                stackDepth++;
1873            }
1874            break;
1875        case Opcodes.OPC_getstatic :
1876            if (returnTypeSize == 2) {
1877                stackDepth += 2;
1878            } else {
1879                stackDepth++;
1880            }
1881            break;
1882        case Opcodes.OPC_putfield :
1883            if (returnTypeSize == 2) {
1884                stackDepth -= 3;
1885            } else {
1886                stackDepth -= 2;
1887            }
1888            break;
1889        case Opcodes.OPC_putstatic :
1890            if (returnTypeSize == 2) {
1891                stackDepth -= 2;
1892            } else {
1893                stackDepth--;
1894            }
1895    }
1896    if (stackDepth > stackMax) {
1897        stackMax = stackDepth;
1898    }
1899    if (classFileOffset + 2 >= bCodeStream.length) {
1900        resizeByteArray();
1901    }
1902    position++;
1903    bCodeStream[classFileOffset++] = opcode;
1904    writeUnsignedShort(constantPool.literalIndexForField(declaringClass, name, signature));
1905}
1906private void generateFieldAccess(byte opcode, int returnTypeSize, ReferenceBinding binding, char[] name, TypeBinding type) {
1907    if (binding.isNestedType()) {
1908        this.classFile.recordInnerClasses(binding);
1909    }
1910    TypeBinding leafComponentType = type.leafComponentType();
1911    if (leafComponentType.isNestedType()) {
1912        this.classFile.recordInnerClasses(leafComponentType);
1913    }
1914    this.generateFieldAccess(opcode, returnTypeSize, binding.constantPoolName(), name, type.signature());
1915}
1916/**
1917 * Generates the sequence of instructions which will perform the conversion of the expression
1918 * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
1919 * @param implicitConversionCode int
1920 */

1921public void generateImplicitConversion(int implicitConversionCode) {
1922    if ((implicitConversionCode & TypeIds.UNBOXING) != 0) {
1923        final int typeId = implicitConversionCode & TypeIds.COMPILE_TYPE_MASK;
1924        generateUnboxingConversion(typeId);
1925        // unboxing can further involve base type conversions
1926
}
1927    switch (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) {
1928        case TypeIds.Float2Char :
1929            this.f2i();
1930            this.i2c();
1931            break;
1932        case TypeIds.Double2Char :
1933            this.d2i();
1934            this.i2c();
1935            break;
1936        case TypeIds.Int2Char :
1937        case TypeIds.Short2Char :
1938        case TypeIds.Byte2Char :
1939            this.i2c();
1940            break;
1941        case TypeIds.Long2Char :
1942            this.l2i();
1943            this.i2c();
1944            break;
1945        case TypeIds.Char2Float :
1946        case TypeIds.Short2Float :
1947        case TypeIds.Int2Float :
1948        case TypeIds.Byte2Float :
1949            this.i2f();
1950            break;
1951        case TypeIds.Double2Float :
1952            this.d2f();
1953            break;
1954        case TypeIds.Long2Float :
1955            this.l2f();
1956            break;
1957        case TypeIds.Float2Byte :
1958            this.f2i();
1959            this.i2b();
1960            break;
1961        case TypeIds.Double2Byte :
1962            this.d2i();
1963            this.i2b();
1964            break;
1965        case TypeIds.Int2Byte :
1966        case TypeIds.Short2Byte :
1967        case TypeIds.Char2Byte :
1968            this.i2b();
1969            break;
1970        case TypeIds.Long2Byte :
1971            this.l2i();
1972            this.i2b();
1973            break;
1974        case TypeIds.Byte2Double :
1975        case TypeIds.Char2Double :
1976        case TypeIds.Short2Double :
1977        case TypeIds.Int2Double :
1978            this.i2d();
1979            break;
1980        case TypeIds.Float2Double :
1981            this.f2d();
1982            break;
1983        case TypeIds.Long2Double :
1984            this.l2d();
1985            break;
1986        case TypeIds.Byte2Short :
1987        case TypeIds.Char2Short :
1988        case TypeIds.Int2Short :
1989            this.i2s();
1990            break;
1991        case TypeIds.Double2Short :
1992            this.d2i();
1993            this.i2s();
1994            break;
1995        case TypeIds.Long2Short :
1996            this.l2i();
1997            this.i2s();
1998            break;
1999        case TypeIds.Float2Short :
2000            this.f2i();
2001            this.i2s();
2002            break;
2003        case TypeIds.Double2Int :
2004            this.d2i();
2005            break;
2006        case TypeIds.Float2Int :
2007            this.f2i();
2008            break;
2009        case TypeIds.Long2Int :
2010            this.l2i();
2011            break;
2012        case TypeIds.Int2Long :
2013        case TypeIds.Char2Long :
2014        case TypeIds.Byte2Long :
2015        case TypeIds.Short2Long :
2016            this.i2l();
2017            break;
2018        case TypeIds.Double2Long :
2019            this.d2l();
2020            break;
2021        case TypeIds.Float2Long :
2022            this.f2l();
2023    }
2024    if ((implicitConversionCode & TypeIds.BOXING) != 0) {
2025        // need to unbox/box the constant
2026
final int typeId = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
2027        generateBoxingConversion(typeId);
2028    }
2029}
2030public void generateInlinedValue(boolean inlinedValue) {
2031    if (inlinedValue)
2032        this.iconst_1();
2033    else
2034        this.iconst_0();
2035}
2036
2037public void generateInlinedValue(byte inlinedValue) {
2038    switch (inlinedValue) {
2039        case -1 :
2040            this.iconst_m1();
2041            break;
2042        case 0 :
2043            this.iconst_0();
2044            break;
2045        case 1 :
2046            this.iconst_1();
2047            break;
2048        case 2 :
2049            this.iconst_2();
2050            break;
2051        case 3 :
2052            this.iconst_3();
2053            break;
2054        case 4 :
2055            this.iconst_4();
2056            break;
2057        case 5 :
2058            this.iconst_5();
2059            break;
2060        default :
2061            if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
2062                this.bipush(inlinedValue);
2063                return;
2064            }
2065    }
2066}
2067
2068public void generateInlinedValue(char inlinedValue) {
2069    switch (inlinedValue) {
2070        case 0 :
2071            this.iconst_0();
2072            break;
2073        case 1 :
2074            this.iconst_1();
2075            break;
2076        case 2 :
2077            this.iconst_2();
2078            break;
2079        case 3 :
2080            this.iconst_3();
2081            break;
2082        case 4 :
2083            this.iconst_4();
2084            break;
2085        case 5 :
2086            this.iconst_5();
2087            break;
2088        default :
2089            if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
2090                this.bipush((byte) inlinedValue);
2091                return;
2092            }
2093            if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
2094                this.sipush(inlinedValue);
2095                return;
2096            }
2097            this.ldc(inlinedValue);
2098    }
2099}
2100public void generateInlinedValue(double inlinedValue) {
2101    if (inlinedValue == 0.0) {
2102        if (Double.doubleToLongBits(inlinedValue) != 0L)
2103            this.ldc2_w(inlinedValue);
2104        else
2105            this.dconst_0();
2106        return;
2107    }
2108    if (inlinedValue == 1.0) {
2109        this.dconst_1();
2110        return;
2111    }
2112    this.ldc2_w(inlinedValue);
2113}
2114public void generateInlinedValue(float inlinedValue) {
2115    if (inlinedValue == 0.0f) {
2116        if (Float.floatToIntBits(inlinedValue) != 0)
2117            this.ldc(inlinedValue);
2118        else
2119            this.fconst_0();
2120        return;
2121    }
2122    if (inlinedValue == 1.0f) {
2123        this.fconst_1();
2124        return;
2125    }
2126    if (inlinedValue == 2.0f) {
2127        this.fconst_2();
2128        return;
2129    }
2130    this.ldc(inlinedValue);
2131}
2132public void generateInlinedValue(int inlinedValue) {
2133    switch (inlinedValue) {
2134        case -1 :
2135            this.iconst_m1();
2136            break;
2137        case 0 :
2138            this.iconst_0();
2139            break;
2140        case 1 :
2141            this.iconst_1();
2142            break;
2143        case 2 :
2144            this.iconst_2();
2145            break;
2146        case 3 :
2147            this.iconst_3();
2148            break;
2149        case 4 :
2150            this.iconst_4();
2151            break;
2152        case 5 :
2153            this.iconst_5();
2154            break;
2155        default :
2156            if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
2157                this.bipush((byte) inlinedValue);
2158                return;
2159            }
2160            if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
2161                this.sipush(inlinedValue);
2162                return;
2163            }
2164            this.ldc(inlinedValue);
2165    }
2166}
2167public void generateInlinedValue(long inlinedValue) {
2168    if (inlinedValue == 0) {
2169        this.lconst_0();
2170        return;
2171    }
2172    if (inlinedValue == 1) {
2173        this.lconst_1();
2174        return;
2175    }
2176    this.ldc2_w(inlinedValue);
2177}
2178public void generateInlinedValue(short inlinedValue) {
2179    switch (inlinedValue) {
2180        case -1 :
2181            this.iconst_m1();
2182            break;
2183        case 0 :
2184            this.iconst_0();
2185            break;
2186        case 1 :
2187            this.iconst_1();
2188            break;
2189        case 2 :
2190            this.iconst_2();
2191            break;
2192        case 3 :
2193            this.iconst_3();
2194            break;
2195        case 4 :
2196            this.iconst_4();
2197            break;
2198        case 5 :
2199            this.iconst_5();
2200            break;
2201        default :
2202            if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
2203                this.bipush((byte) inlinedValue);
2204                return;
2205            }
2206            this.sipush(inlinedValue);
2207    }
2208}
2209public void generateOuterAccess(Object JavaDoc[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
2210    if (mappingSequence == null) {
2211        if (target instanceof LocalVariableBinding) {
2212            scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
2213
} else {
2214            scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
2215        }
2216        return;
2217    }
2218    if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
2219        scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
2220        return;
2221    } else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
2222        scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
2223        return;
2224    }
2225    
2226    if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
2227        this.aload_0();
2228        return;
2229    } else if (mappingSequence[0] instanceof FieldBinding) {
2230        FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
2231        this.aload_0();
2232        this.getfield(fieldBinding);
2233    } else {
2234        load((LocalVariableBinding) mappingSequence[0]);
2235    }
2236    for (int i = 1, length = mappingSequence.length; i < length; i++) {
2237        if (mappingSequence[i] instanceof FieldBinding) {
2238            FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
2239            this.getfield(fieldBinding);
2240        } else {
2241            this.invokestatic((MethodBinding) mappingSequence[i]);
2242        }
2243    }
2244}
2245public void generateReturnBytecode(Expression expression) {
2246    
2247    if (expression == null) {
2248        this.return_();
2249    } else {
2250        final int implicitConversion = expression.implicitConversion;
2251        if ((implicitConversion & TypeIds.BOXING) != 0) {
2252            this.areturn();
2253            return;
2254        }
2255        int runtimeType = (implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
2256        switch (runtimeType) {
2257            case TypeIds.T_boolean :
2258            case TypeIds.T_int :
2259                this.ireturn();
2260                break;
2261            case TypeIds.T_float :
2262                this.freturn();
2263                break;
2264            case TypeIds.T_long :
2265                this.lreturn();
2266                break;
2267            case TypeIds.T_double :
2268                this.dreturn();
2269                break;
2270            default :
2271                this.areturn();
2272        }
2273    }
2274}
2275/**
2276 * The equivalent code performs a string conversion:
2277 *
2278 * @param blockScope the given blockScope
2279 * @param oper1 the first expression
2280 * @param oper2 the second expression
2281 */

2282public void generateStringConcatenationAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
2283    int pc;
2284    if (oper1 == null) {
2285        /* Operand is already on the stack, and maybe nil:
2286        note type1 is always to java.lang.String here.*/

2287        this.newStringContatenation();
2288        this.dup_x1();
2289        this.swap();
2290        // If argument is reference type, need to transform it
2291
// into a string (handles null case)
2292
this.invokeStringValueOf(TypeIds.T_JavaLangObject);
2293        this.invokeStringConcatenationStringConstructor();
2294    } else {
2295        pc = position;
2296        oper1.generateOptimizedStringConcatenationCreation(blockScope, this, oper1.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
2297        this.recordPositionsFrom(pc, oper1.sourceStart);
2298    }
2299    pc = position;
2300    oper2.generateOptimizedStringConcatenation(blockScope, this, oper2.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
2301    this.recordPositionsFrom(pc, oper2.sourceStart);
2302    this.invokeStringConcatenationToString();
2303}
2304/**
2305 * @param accessBinding the access method binding to generate
2306 */

2307public void generateSyntheticBodyForConstructorAccess(SyntheticMethodBinding accessBinding) {
2308
2309    initializeMaxLocals(accessBinding);
2310
2311    MethodBinding constructorBinding = accessBinding.targetMethod;
2312    TypeBinding[] parameters = constructorBinding.parameters;
2313    int length = parameters.length;
2314    int resolvedPosition = 1;
2315    this.aload_0();
2316    // special name&ordinal argument generation for enum constructors
2317
TypeBinding declaringClass = constructorBinding.declaringClass;
2318    if (declaringClass.erasure().id == TypeIds.T_JavaLangEnum || declaringClass.isEnum()) {
2319        this.aload_1(); // pass along name param as name arg
2320
this.iload_2(); // pass along ordinal param as ordinal arg
2321
resolvedPosition += 2;
2322    }
2323    if (declaringClass.isNestedType()) {
2324        NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
2325        SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
2326        for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
2327            TypeBinding type;
2328            load((type = syntheticArguments[i].type), resolvedPosition);
2329            if ((type == TypeBinding.DOUBLE) || (type == TypeBinding.LONG))
2330                resolvedPosition += 2;
2331            else
2332                resolvedPosition++;
2333        }
2334    }
2335    for (int i = 0; i < length; i++) {
2336        load(parameters[i], resolvedPosition);
2337        if ((parameters[i] == TypeBinding.DOUBLE) || (parameters[i] == TypeBinding.LONG))
2338            resolvedPosition += 2;
2339        else
2340            resolvedPosition++;
2341    }
2342    
2343    if (declaringClass.isNestedType()) {
2344        NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
2345        SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
2346        for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
2347            TypeBinding type;
2348            load((type = syntheticArguments[i].type), resolvedPosition);
2349            if ((type == TypeBinding.DOUBLE) || (type == TypeBinding.LONG))
2350                resolvedPosition += 2;
2351            else
2352                resolvedPosition++;
2353        }
2354    }
2355    this.invokespecial(constructorBinding);
2356    this.return_();
2357}
2358//static X valueOf(String name) {
2359
// return (X) Enum.valueOf(X.class, name);
2360
//}
2361
public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
2362    initializeMaxLocals(methodBinding);
2363    final ReferenceBinding declaringClass = methodBinding.declaringClass;
2364    this.ldc(declaringClass);
2365    this.aload_0();
2366    this.invokeJavaLangEnumvalueOf(declaringClass);
2367    this.checkcast(declaringClass);
2368    this.areturn();
2369}
2370//static X[] values() {
2371
// X[] values;
2372
// int length;
2373
// X[] result;
2374
// System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length)
2375
// return result;
2376
//}
2377
public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
2378    ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
2379    FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
2380    initializeMaxLocals(methodBinding);
2381    TypeBinding enumArray = methodBinding.returnType;
2382    
2383    this.getstatic(enumValuesSyntheticfield);
2384    this.dup();
2385    this.astore_0();
2386    this.iconst_0();
2387    this.aload_0();
2388    this.arraylength();
2389    this.dup();
2390    this.istore_1();
2391    this.newArray((ArrayBinding) enumArray);
2392    this.dup();
2393    this.astore_2();
2394    this.iconst_0();
2395    this.iload_1();
2396    this.invokeSystemArraycopy();
2397    this.aload_2();
2398    this.areturn();
2399}
2400public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
2401    initializeMaxLocals(accessBinding);
2402    FieldBinding fieldBinding = accessBinding.targetReadField;
2403    if (fieldBinding.isStatic())
2404        this.getstatic(fieldBinding);
2405    else {
2406        this.aload_0();
2407        this.getfield(fieldBinding);
2408    }
2409    switch (fieldBinding.type.id) {
2410// case T_void :
2411
// this.return_();
2412
// break;
2413
case TypeIds.T_boolean :
2414        case TypeIds.T_byte :
2415        case TypeIds.T_char :
2416        case TypeIds.T_short :
2417        case TypeIds.T_int :
2418            this.ireturn();
2419            break;
2420        case TypeIds.T_long :
2421            this.lreturn();
2422            break;
2423        case TypeIds.T_float :
2424            this.freturn();
2425            break;
2426        case TypeIds.T_double :
2427            this.dreturn();
2428            break;
2429        default :
2430            this.areturn();
2431    }
2432}
2433public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding accessBinding) {
2434    initializeMaxLocals(accessBinding);
2435    FieldBinding fieldBinding = accessBinding.targetWriteField;
2436    if (fieldBinding.isStatic()) {
2437        load(fieldBinding.type, 0);
2438        this.putstatic(fieldBinding);
2439    } else {
2440        this.aload_0();
2441        load(fieldBinding.type, 1);
2442        this.putfield(fieldBinding);
2443    }
2444    this.return_();
2445}
2446public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessMethod) {
2447
2448    initializeMaxLocals(accessMethod);
2449    MethodBinding targetMethod = accessMethod.targetMethod;
2450    TypeBinding[] parameters = targetMethod.parameters;
2451    int length = parameters.length;
2452    TypeBinding[] arguments = accessMethod.kind == SyntheticMethodBinding.BridgeMethod
2453                                                    ? accessMethod.parameters
2454                                                    : null;
2455    int resolvedPosition;
2456    if (targetMethod.isStatic())
2457        resolvedPosition = 0;
2458    else {
2459        this.aload_0();
2460        resolvedPosition = 1;
2461    }
2462    for (int i = 0; i < length; i++) {
2463        TypeBinding parameter = parameters[i];
2464        if (arguments != null) { // for bridge methods
2465
TypeBinding argument = arguments[i];
2466            load(argument, resolvedPosition);
2467            if (argument != parameter)
2468                checkcast(parameter);
2469        } else {
2470            load(parameter, resolvedPosition);
2471        }
2472        if ((parameter == TypeBinding.DOUBLE) || (parameter == TypeBinding.LONG))
2473            resolvedPosition += 2;
2474        else
2475            resolvedPosition++;
2476    }
2477    if (targetMethod.isStatic())
2478        this.invokestatic(targetMethod);
2479    else {
2480        if (targetMethod.isConstructor()
2481            || targetMethod.isPrivate()
2482            // qualified super "X.super.foo()" targets methods from superclass
2483
|| accessMethod.kind == SyntheticMethodBinding.SuperMethodAccess){
2484            this.invokespecial(targetMethod);
2485        } else {
2486            if (targetMethod.declaringClass.isInterface()) { // interface or annotation type
2487
this.invokeinterface(targetMethod);
2488            } else {
2489                this.invokevirtual(targetMethod);
2490            }
2491        }
2492    }
2493    switch (targetMethod.returnType.id) {
2494        case TypeIds.T_void :
2495            this.return_();
2496            break;
2497        case TypeIds.T_boolean :
2498        case TypeIds.T_byte :
2499        case TypeIds.T_char :
2500        case TypeIds.T_short :
2501        case TypeIds.T_int :
2502            this.ireturn();
2503            break;
2504        case TypeIds.T_long :
2505            this.lreturn();
2506            break;
2507        case TypeIds.T_float :
2508            this.freturn();
2509            break;
2510        case TypeIds.T_double :
2511            this.dreturn();
2512            break;
2513        default :
2514            TypeBinding accessErasure = accessMethod.returnType.erasure();
2515            if (!targetMethod.returnType.isCompatibleWith(accessErasure))
2516                this.checkcast(accessErasure); // for bridge methods
2517
this.areturn();
2518    }
2519}
2520public void generateSyntheticBodyForSwitchTable(SyntheticMethodBinding methodBinding) {
2521    ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
2522    initializeMaxLocals(methodBinding);
2523    final BranchLabel nullLabel = new BranchLabel(this);
2524    FieldBinding syntheticFieldBinding = methodBinding.targetReadField;
2525
2526    this.getstatic(syntheticFieldBinding);
2527    this.dup();
2528    this.ifnull(nullLabel);
2529    this.areturn();
2530    this.pushOnStack(syntheticFieldBinding.type);
2531    nullLabel.place();
2532    this.pop();
2533    ReferenceBinding enumBinding = (ReferenceBinding) methodBinding.targetEnumType;
2534    ArrayBinding arrayBinding = scope.createArrayType(enumBinding, 1);
2535    this.invokeJavaLangEnumValues(enumBinding, arrayBinding);
2536    this.arraylength();
2537    this.newarray(ClassFileConstants.INT_ARRAY);
2538    this.astore_0();
2539    final FieldBinding[] fields = enumBinding.fields();
2540    if (fields != null) {
2541        for (int i = 0, max = fields.length; i < max; i++) {
2542            FieldBinding fieldBinding = fields[i];
2543            if ((fieldBinding.getAccessFlags() & ClassFileConstants.AccEnum) != 0) {
2544                final BranchLabel endLabel = new BranchLabel(this);
2545                final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, TypeBinding.LONG /* represents NoSuchFieldError*/);
2546                anyExceptionHandler.placeStart();
2547                this.aload_0();
2548                this.getstatic(fieldBinding);
2549                this.invokeEnumOrdinal(enumBinding.constantPoolName());
2550                this.generateInlinedValue(fieldBinding.id + 1); // zero should not be returned see bug 141810
2551
this.iastore();
2552                anyExceptionHandler.placeEnd();
2553                this.goto_(endLabel);
2554                // Generate the body of the exception handler
2555
this.pushOnStack(scope.getJavaLangThrowable());
2556                anyExceptionHandler.place();
2557                this.pop(); // we don't use it so we can pop it
2558
endLabel.place();
2559            }
2560        }
2561    }
2562    this.aload_0();
2563    this.dup();
2564    this.putstatic(syntheticFieldBinding);
2565    areturn();
2566}
2567/**
2568 * Code responsible to generate the suitable code to supply values for the synthetic enclosing
2569 * instance arguments of a constructor invocation of a nested type.
2570 */

2571public void generateSyntheticEnclosingInstanceValues(
2572        BlockScope currentScope,
2573        ReferenceBinding targetType,
2574        Expression enclosingInstance,
2575        ASTNode invocationSite) {
2576
2577    // supplying enclosing instance for the anonymous type's superclass
2578
ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? (ReferenceBinding)targetType.superclass().erasure() : targetType;
2579    boolean hasExtraEnclosingInstance = enclosingInstance != null;
2580    if (hasExtraEnclosingInstance
2581            && (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
2582        currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
2583        return;
2584    }
2585
2586    // perform some emulation work in case there is some and we are inside a local type only
2587
ReferenceBinding[] syntheticArgumentTypes;
2588    if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
2589
2590        ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
2591        long compliance = currentScope.compilerOptions().complianceLevel;
2592
2593        // deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
2594
// always consider it if complying to 1.5
2595
boolean denyEnclosingArgInConstructorCall;
2596        if (compliance <= ClassFileConstants.JDK1_3) {
2597            denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression;
2598        } else if (compliance == ClassFileConstants.JDK1_4){
2599            denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
2600                || invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess();
2601        } else {
2602            //compliance >= JDK1_5
2603
denyEnclosingArgInConstructorCall = (invocationSite instanceof AllocationExpression
2604                    || invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess())
2605                && !targetType.isLocalType();
2606        }
2607        
2608        boolean complyTo14 = compliance >= ClassFileConstants.JDK1_4;
2609        for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
2610            ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
2611            if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
2612                hasExtraEnclosingInstance = false;
2613                enclosingInstance.generateCode(currentScope, this, true);
2614                if (complyTo14){
2615                    dup();
2616                    invokeObjectGetClass(); // will perform null check
2617
pop();
2618                }
2619            } else {
2620                Object JavaDoc[] emulationPath = currentScope.getEmulationPath(
2621                        syntheticArgType,
2622                        false /*not only exact match (that is, allow compatible)*/,
2623                        denyEnclosingArgInConstructorCall);
2624                this.generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
2625            }
2626        }
2627        if (hasExtraEnclosingInstance){
2628            currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
2629        }
2630    }
2631}
2632/**
2633 * Code responsible to generate the suitable code to supply values for the synthetic outer local
2634 * variable arguments of a constructor invocation of a nested type.
2635 * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
2636 */

2637public void generateSyntheticOuterArgumentValues(BlockScope currentScope, ReferenceBinding targetType, ASTNode invocationSite) {
2638
2639    // generate the synthetic outer arguments then
2640
SyntheticArgumentBinding syntheticArguments[];
2641    if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
2642        for (int i = 0, max = syntheticArguments.length; i < max; i++) {
2643            LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
2644            VariableBinding[] emulationPath = currentScope.getEmulationPath(targetVariable);
2645            this.generateOuterAccess(emulationPath, invocationSite, targetVariable, currentScope);
2646        }
2647    }
2648}
2649public void generateUnboxingConversion(int unboxedTypeID) {
2650    switch (unboxedTypeID) {
2651        case TypeIds.T_byte :
2652            // invokevirtual: byteValue()
2653
this.invoke(
2654                    Opcodes.OPC_invokevirtual,
2655                    0, // argCount
2656
1, // return type size
2657
ConstantPool.JavaLangByteConstantPoolName,
2658                    ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
2659                    ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
2660            break;
2661        case TypeIds.T_short :
2662            // invokevirtual: shortValue()
2663
this.invoke(
2664                    Opcodes.OPC_invokevirtual,
2665                    0, // argCount
2666
1, // return type size
2667
ConstantPool.JavaLangShortConstantPoolName,
2668                    ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
2669                    ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
2670            break;
2671        case TypeIds.T_char :
2672            // invokevirtual: charValue()
2673
this.invoke(
2674                    Opcodes.OPC_invokevirtual,
2675                    0, // argCount
2676
1, // return type size
2677
ConstantPool.JavaLangCharacterConstantPoolName,
2678                    ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
2679                    ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
2680            break;
2681        case TypeIds.T_int :
2682            // invokevirtual: intValue()
2683
this.invoke(
2684                    Opcodes.OPC_invokevirtual,
2685                    0, // argCount
2686
1, // return type size
2687
ConstantPool.JavaLangIntegerConstantPoolName,
2688                    ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
2689                    ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
2690            break;
2691        case TypeIds.T_long :
2692            // invokevirtual: longValue()
2693
this.invoke(
2694                    Opcodes.OPC_invokevirtual,
2695                    0, // argCount
2696
2, // return type size
2697
ConstantPool.JavaLangLongConstantPoolName,
2698                    ConstantPool.LONGVALUE_LONG_METHOD_NAME,
2699                    ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
2700            break;
2701        case TypeIds.T_float :
2702            // invokevirtual: floatValue()
2703
this.invoke(
2704                    Opcodes.OPC_invokevirtual,
2705                    0, // argCount
2706
1, // return type size
2707
ConstantPool.JavaLangFloatConstantPoolName,
2708                    ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
2709                    ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
2710            break;
2711        case TypeIds.T_double :
2712            // invokevirtual: doubleValue()
2713
this.invoke(
2714                    Opcodes.OPC_invokevirtual,
2715                    0, // argCount
2716
2, // return type size
2717
ConstantPool.JavaLangDoubleConstantPoolName,
2718                    ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
2719                    ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
2720            break;
2721        case TypeIds.T_boolean :
2722            // invokevirtual: booleanValue()
2723
this.invoke(
2724                    Opcodes.OPC_invokevirtual,
2725                    0, // argCount
2726
1, // return type size
2727
ConstantPool.JavaLangBooleanConstantPoolName,
2728                    ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
2729                    ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
2730    }
2731}
2732/*
2733 * Wide conditional branch compare, improved by swapping comparison opcode
2734 * ifeq WideTarget
2735 * becomes
2736 * ifne Intermediate
2737 * gotow WideTarget
2738 * Intermediate:
2739 */

2740public void generateWideRevertedConditionalBranch(byte revertedOpcode, BranchLabel wideTarget) {
2741        BranchLabel intermediate = new BranchLabel(this);
2742        if (classFileOffset >= bCodeStream.length) {
2743            resizeByteArray();
2744        }
2745        position++;
2746        bCodeStream[classFileOffset++] = revertedOpcode;
2747        intermediate.branch();
2748        this.goto_w(wideTarget);
2749        intermediate.place();
2750}
2751public void getBaseTypeValue(int baseTypeID) {
2752    switch (baseTypeID) {
2753        case TypeIds.T_byte :
2754            // invokevirtual: byteValue()
2755
this.invoke(
2756                    Opcodes.OPC_invokevirtual,
2757                    0, // argCount
2758
1, // return type size
2759
ConstantPool.JavaLangByteConstantPoolName,
2760                    ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
2761                    ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
2762            break;
2763        case TypeIds.T_short :
2764            // invokevirtual: shortValue()
2765
this.invoke(
2766                    Opcodes.OPC_invokevirtual,
2767                    0, // argCount
2768
1, // return type size
2769
ConstantPool.JavaLangShortConstantPoolName,
2770                    ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
2771                    ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
2772            break;
2773        case TypeIds.T_char :
2774            // invokevirtual: charValue()
2775
this.invoke(
2776                    Opcodes.OPC_invokevirtual,
2777                    0, // argCount
2778
1, // return type size
2779
ConstantPool.JavaLangCharacterConstantPoolName,
2780                    ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
2781                    ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
2782            break;
2783        case TypeIds.T_int :
2784            // invokevirtual: intValue()
2785
this.invoke(
2786                    Opcodes.OPC_invokevirtual,
2787                    0, // argCount
2788
1, // return type size
2789
ConstantPool.JavaLangIntegerConstantPoolName,
2790                    ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
2791                    ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
2792            break;
2793        case TypeIds.T_long :
2794            // invokevirtual: longValue()
2795
this.invoke(
2796                    Opcodes.OPC_invokevirtual,
2797                    0, // argCount
2798
2, // return type size
2799
ConstantPool.JavaLangLongConstantPoolName,
2800                    ConstantPool.LONGVALUE_LONG_METHOD_NAME,
2801                    ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
2802            break;
2803        case TypeIds.T_float :
2804            // invokevirtual: floatValue()
2805
this.invoke(
2806                    Opcodes.OPC_invokevirtual,
2807                    0, // argCount
2808
1, // return type size
2809
ConstantPool.JavaLangFloatConstantPoolName,
2810                    ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
2811                    ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
2812            break;
2813        case TypeIds.T_double :
2814            // invokevirtual: doubleValue()
2815
this.invoke(
2816                    Opcodes.OPC_invokevirtual,
2817                    0, // argCount
2818
2, // return type size
2819
ConstantPool.JavaLangDoubleConstantPoolName,
2820                    ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
2821                    ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
2822            break;
2823        case TypeIds.T_boolean :
2824            // invokevirtual: booleanValue()
2825
this.invoke(
2826                    Opcodes.OPC_invokevirtual,
2827                    0, // argCount
2828
1, // return type size
2829
ConstantPool.JavaLangBooleanConstantPoolName,
2830                    ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
2831                    ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
2832    }
2833}
2834final public byte[] getContents() {
2835    byte[] contents;
2836    System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
2837    return contents;
2838}
2839public void getfield(FieldBinding fieldBinding) {
2840    if (DEBUG) System.out.println(position + "\t\tgetfield:"+fieldBinding); //$NON-NLS-1$
2841
int returnTypeSize = 1;
2842    if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
2843        returnTypeSize = 2;
2844    }
2845    generateFieldAccess(
2846            Opcodes.OPC_getfield,
2847            returnTypeSize,
2848            fieldBinding.declaringClass,
2849            fieldBinding.name,
2850            fieldBinding.type);
2851}
2852protected int getPosition() {
2853    return this.position;
2854}
2855public void getstatic(FieldBinding fieldBinding) {
2856    if (DEBUG) System.out.println(position + "\t\tgetstatic:"+fieldBinding); //$NON-NLS-1$
2857
int returnTypeSize = 1;
2858    if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
2859        returnTypeSize = 2;
2860    }
2861    generateFieldAccess(
2862            Opcodes.OPC_getstatic,
2863            returnTypeSize,
2864            fieldBinding.declaringClass,
2865            fieldBinding.name,
2866            fieldBinding.type);
2867}
2868public void getTYPE(int baseTypeID) {
2869    countLabels = 0;
2870    switch (baseTypeID) {
2871        case TypeIds.T_byte :
2872            // getstatic: java.lang.Byte.TYPE
2873
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$
2874
generateFieldAccess(
2875                    Opcodes.OPC_getstatic,
2876                    1,
2877                    ConstantPool.JavaLangByteConstantPoolName,
2878                    ConstantPool.TYPE,
2879                    ConstantPool.JavaLangClassSignature);
2880            break;
2881        case TypeIds.T_short :
2882            // getstatic: java.lang.Short.TYPE
2883
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$
2884
generateFieldAccess(
2885                    Opcodes.OPC_getstatic,
2886                    1,
2887                    ConstantPool.JavaLangShortConstantPoolName,
2888                    ConstantPool.TYPE,
2889                    ConstantPool.JavaLangClassSignature);
2890            break;
2891        case TypeIds.T_char :
2892            // getstatic: java.lang.Character.TYPE
2893
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$
2894
generateFieldAccess(
2895                    Opcodes.OPC_getstatic,
2896                    1,
2897                    ConstantPool.JavaLangCharacterConstantPoolName,
2898                    ConstantPool.TYPE,
2899                    ConstantPool.JavaLangClassSignature);
2900            break;
2901        case TypeIds.T_int :
2902            // getstatic: java.lang.Integer.TYPE
2903
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$
2904
generateFieldAccess(
2905                    Opcodes.OPC_getstatic,
2906                    1,
2907                    ConstantPool.JavaLangIntegerConstantPoolName,
2908                    ConstantPool.TYPE,
2909                    ConstantPool.JavaLangClassSignature);
2910            break;
2911        case TypeIds.T_long :
2912            // getstatic: java.lang.Long.TYPE
2913
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$
2914
generateFieldAccess(
2915                    Opcodes.OPC_getstatic,
2916                    1,
2917                    ConstantPool.JavaLangLongConstantPoolName,
2918                    ConstantPool.TYPE,
2919                    ConstantPool.JavaLangClassSignature);
2920            break;
2921        case TypeIds.T_float :
2922            // getstatic: java.lang.Float.TYPE
2923
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$
2924
generateFieldAccess(
2925                    Opcodes.OPC_getstatic,
2926                    1,
2927                    ConstantPool.JavaLangFloatConstantPoolName,
2928                    ConstantPool.TYPE,
2929                    ConstantPool.JavaLangClassSignature);
2930            break;
2931        case TypeIds.T_double :
2932            // getstatic: java.lang.Double.TYPE
2933
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$
2934
generateFieldAccess(
2935                    Opcodes.OPC_getstatic,
2936                    1,
2937                    ConstantPool.JavaLangDoubleConstantPoolName,
2938                    ConstantPool.TYPE,
2939                    ConstantPool.JavaLangClassSignature);
2940            break;
2941        case TypeIds.T_boolean :
2942            // getstatic: java.lang.Boolean.TYPE
2943
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$
2944
generateFieldAccess(
2945                    Opcodes.OPC_getstatic,
2946                    1,
2947                    ConstantPool.JavaLangBooleanConstantPoolName,
2948                    ConstantPool.TYPE,
2949                    ConstantPool.JavaLangClassSignature);
2950            break;
2951        case TypeIds.T_void :
2952            // getstatic: java.lang.Void.TYPE
2953
if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$
2954
generateFieldAccess(
2955                    Opcodes.OPC_getstatic,
2956                    1,
2957                    ConstantPool.JavaLangVoidConstantPoolName,
2958                    ConstantPool.TYPE,
2959                    ConstantPool.JavaLangClassSignature);
2960            break;
2961    }
2962}
2963/**
2964 * We didn't call it goto, because there is a conflit with the goto keyword
2965 */

2966public void goto_(BranchLabel label) {
2967    if (this.wideMode) {
2968        this.goto_w(label);
2969        return;
2970    }
2971    if (DEBUG) System.out.println(position + "\t\tgoto:"+label); //$NON-NLS-1$
2972
if (classFileOffset >= bCodeStream.length) {
2973        resizeByteArray();
2974    }
2975    boolean chained = this.inlineForwardReferencesFromLabelsTargeting(label, position);
2976    if (DEBUG && chained) {
2977        if (DEBUG) {
2978            if (this.lastAbruptCompletion == this.position) {
2979                System.out.println("\t\t\t\t<branch chaining - goto eliminated : "+this.position+","+label+">");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
2980
} else {
2981                System.out.println("\t\t\t\t<branch chaining - goto issued : "+this.position+","+label+">");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
2982
}
2983        }
2984    }
2985    /*
2986     Possible optimization for code such as:
2987     public Object foo() {
2988        boolean b = true;
2989        if (b) {
2990            if (b)
2991                return null;
2992        } else {
2993            if (b) {
2994                return null;
2995            }
2996        }
2997        return null;
2998    }
2999    The goto around the else block for the first if will
3000    be unreachable, because the thenClause of the second if
3001    returns. Also see 114894
3002    }*/

3003    if (chained && this.lastAbruptCompletion == this.position) {
3004        if (label.position != Label.POS_NOT_SET) { // ensure existing forward references are updated
3005
int[] forwardRefs = label.forwardReferences();
3006            for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
3007                this.writePosition(label, forwardRefs[i]);
3008            }
3009            this.countLabels = 0; // backward jump, no further chaining allowed
3010
}
3011// this.lastAbruptCompletion = -1;
3012
return;
3013    }
3014    position++;
3015    bCodeStream[classFileOffset++] = Opcodes.OPC_goto;
3016    label.branch();
3017    this.lastAbruptCompletion = this.position;
3018}
3019public void goto_w(BranchLabel label) {
3020    if (DEBUG) System.out.println(position + "\t\tgotow:"+label); //$NON-NLS-1$
3021
if (classFileOffset >= bCodeStream.length) {
3022        resizeByteArray();
3023    }
3024    position++;
3025    bCodeStream[classFileOffset++] = Opcodes.OPC_goto_w;
3026    label.branchWide();
3027    this.lastAbruptCompletion = this.position;
3028}
3029public void i2b() {
3030    if (DEBUG) System.out.println(position + "\t\ti2b"); //$NON-NLS-1$
3031
countLabels = 0;
3032    if (classFileOffset >= bCodeStream.length) {
3033        resizeByteArray();
3034    }
3035    position++;
3036    bCodeStream[classFileOffset++] = Opcodes.OPC_i2b;
3037}
3038public void i2c() {
3039    if (DEBUG) System.out.println(position + "\t\ti2c"); //$NON-NLS-1$
3040
countLabels = 0;
3041    if (classFileOffset >= bCodeStream.length) {
3042        resizeByteArray();
3043    }
3044    position++;
3045    bCodeStream[classFileOffset++] = Opcodes.OPC_i2c;
3046}
3047public void i2d() {
3048    if (DEBUG) System.out.println(position + "\t\ti2d"); //$NON-NLS-1$
3049
countLabels = 0;
3050    stackDepth++;
3051    if (stackDepth > stackMax)
3052        stackMax = stackDepth;
3053    if (classFileOffset >= bCodeStream.length) {
3054        resizeByteArray();
3055    }
3056    position++;
3057    bCodeStream[classFileOffset++] = Opcodes.OPC_i2d;
3058}
3059public void i2f() {
3060    if (DEBUG) System.out.println(position + "\t\ti2f"); //$NON-NLS-1$
3061
countLabels = 0;
3062    if (classFileOffset >= bCodeStream.length) {
3063        resizeByteArray();
3064    }
3065    position++;
3066    bCodeStream[classFileOffset++] = Opcodes.OPC_i2f;
3067}
3068public void i2l() {
3069    if (DEBUG) System.out.println(position + "\t\ti2l"); //$NON-NLS-1$
3070
countLabels = 0;
3071    stackDepth++;
3072    if (stackDepth > stackMax)
3073        stackMax = stackDepth;
3074    if (classFileOffset >= bCodeStream.length) {
3075        resizeByteArray();
3076    }
3077    position++;
3078    bCodeStream[classFileOffset++] = Opcodes.OPC_i2l;
3079}
3080public void i2s() {
3081    if (DEBUG) System.out.println(position + "\t\ti2s"); //$NON-NLS-1$
3082
countLabels = 0;
3083    if (classFileOffset >= bCodeStream.length) {
3084        resizeByteArray();
3085    }
3086    position++;
3087    bCodeStream[classFileOffset++] = Opcodes.OPC_i2s;
3088}
3089public void iadd() {
3090    if (DEBUG) System.out.println(position + "\t\tiadd"); //$NON-NLS-1$
3091
countLabels = 0;
3092    stackDepth--;
3093    if (classFileOffset >= bCodeStream.length) {
3094        resizeByteArray();
3095    }
3096    position++;
3097    bCodeStream[classFileOffset++] = Opcodes.OPC_iadd;
3098}
3099public void iaload() {
3100    if (DEBUG) System.out.println(position + "\t\tiaload"); //$NON-NLS-1$
3101
countLabels = 0;
3102    stackDepth--;
3103    if (classFileOffset >= bCodeStream.length) {
3104        resizeByteArray();
3105    }
3106    position++;
3107    bCodeStream[classFileOffset++] = Opcodes.OPC_iaload;
3108}
3109public void iand() {
3110    if (DEBUG) System.out.println(position + "\t\tiand"); //$NON-NLS-1$
3111
countLabels = 0;
3112    stackDepth--;
3113    if (classFileOffset >= bCodeStream.length) {
3114        resizeByteArray();
3115    }
3116    position++;
3117    bCodeStream[classFileOffset++] = Opcodes.OPC_iand;
3118}
3119public void iastore() {
3120    if (DEBUG) System.out.println(position + "\t\tiastore"); //$NON-NLS-1$
3121
countLabels = 0;
3122    stackDepth -= 3;
3123    if (classFileOffset >= bCodeStream.length) {
3124        resizeByteArray();
3125    }
3126    position++;
3127    bCodeStream[classFileOffset++] = Opcodes.OPC_iastore;
3128}
3129public void iconst_0() {
3130    if (DEBUG) System.out.println(position + "\t\ticonst_0"); //$NON-NLS-1$
3131
countLabels = 0;
3132    stackDepth++;
3133    if (stackDepth > stackMax)
3134        stackMax = stackDepth;
3135    if (classFileOffset >= bCodeStream.length) {
3136        resizeByteArray();
3137    }
3138    position++;
3139    bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_0;
3140}
3141public void iconst_1() {
3142    if (DEBUG) System.out.println(position + "\t\ticonst_1"); //$NON-NLS-1$
3143
countLabels = 0;
3144    stackDepth++;
3145    if (stackDepth > stackMax)
3146        stackMax = stackDepth;
3147    if (classFileOffset >= bCodeStream.length) {
3148        resizeByteArray();
3149    }
3150    position++;
3151    bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_1;
3152}
3153public void iconst_2() {
3154    if (DEBUG) System.out.println(position + "\t\ticonst_2"); //$NON-NLS-1$
3155
countLabels = 0;
3156    stackDepth++;
3157    if (stackDepth > stackMax)
3158        stackMax = stackDepth;
3159    if (classFileOffset >= bCodeStream.length) {
3160        resizeByteArray();
3161    }
3162    position++;
3163    bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_2;
3164}
3165public void iconst_3() {
3166    if (DEBUG) System.out.println(position + "\t\ticonst_3"); //$NON-NLS-1$
3167
countLabels = 0;
3168    stackDepth++;
3169    if (stackDepth > stackMax)
3170        stackMax = stackDepth;
3171    if (classFileOffset >= bCodeStream.length) {
3172        resizeByteArray();
3173    }
3174    position++;
3175    bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_3;
3176}
3177public void iconst_4() {
3178    if (DEBUG) System.out.println(position + "\t\ticonst_4"); //$NON-NLS-1$
3179
countLabels = 0;
3180    stackDepth++;
3181    if (stackDepth > stackMax)
3182        stackMax = stackDepth;
3183    if (classFileOffset >= bCodeStream.length) {
3184        resizeByteArray();
3185    }
3186    position++;
3187    bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_4;
3188}
3189public void iconst_5() {
3190    if (DEBUG) System.out.println(position + "\t\ticonst_5"); //$NON-NLS-1$
3191
countLabels = 0;
3192    stackDepth++;
3193    if (stackDepth > stackMax)
3194        stackMax = stackDepth;
3195    if (classFileOffset >= bCodeStream.length) {
3196        resizeByteArray();
3197    }
3198    position++;
3199    bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_5;
3200}
3201public void iconst_m1() {
3202    if (DEBUG) System.out.println(position + "\t\ticonst_m1"); //$NON-NLS-1$
3203
countLabels = 0;
3204    stackDepth++;
3205    if (stackDepth > stackMax)
3206        stackMax = stackDepth;
3207    if (classFileOffset >= bCodeStream.length) {
3208        resizeByteArray();
3209    }
3210    position++;
3211    bCodeStream[classFileOffset++] = Opcodes.OPC_iconst_m1;
3212}
3213public void idiv() {
3214    if (DEBUG) System.out.println(position + "\t\tidiv"); //$NON-NLS-1$
3215
countLabels = 0;
3216    stackDepth--;
3217    if (classFileOffset >= bCodeStream.length) {
3218        resizeByteArray();
3219    }
3220    position++;
3221    bCodeStream[classFileOffset++] = Opcodes.OPC_idiv;
3222}
3223public void if_acmpeq(BranchLabel lbl) {
3224    if (DEBUG) System.out.println(position + "\t\tif_acmpeq:"+lbl); //$NON-NLS-1$
3225
countLabels = 0;
3226    stackDepth-=2;
3227    if (this.wideMode) {
3228        generateWideRevertedConditionalBranch(Opcodes.OPC_if_acmpne, lbl);
3229    } else {
3230        if (classFileOffset >= bCodeStream.length) {
3231            resizeByteArray();
3232        }
3233        position++;
3234        bCodeStream[classFileOffset++] = Opcodes.OPC_if_acmpeq;
3235        lbl.branch();
3236    }
3237}
3238public void if_acmpne(BranchLabel lbl) {
3239    if (DEBUG) System.out.println(position + "\t\tif_acmpne:"+lbl); //$NON-NLS-1$
3240
countLabels = 0;
3241    stackDepth-=2;
3242    if (this.wideMode) {
3243        generateWideRevertedConditionalBranch(Opcodes.OPC_if_acmpeq, lbl);
3244    } else {
3245        if (classFileOffset >= bCodeStream.length) {
3246            resizeByteArray();
3247        }
3248        position++;
3249        bCodeStream[classFileOffset++] = Opcodes.OPC_if_acmpne;
3250        lbl.branch();
3251    }
3252}
3253public void if_icmpeq(BranchLabel lbl) {
3254    if (DEBUG) System.out.println(position + "\t\tif_cmpeq:"+lbl); //$NON-NLS-1$
3255
countLabels = 0;
3256    stackDepth -= 2;
3257    if (this.wideMode) {
3258        generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpne, lbl);
3259    } else {
3260        if (classFileOffset >= bCodeStream.length) {
3261            resizeByteArray();
3262        }
3263        position++;
3264        bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpeq;
3265        lbl.branch();
3266    }
3267}
3268public void if_icmpge(BranchLabel lbl) {
3269    if (DEBUG) System.out.println(position + "\t\tif_icmpge:"+lbl); //$NON-NLS-1$
3270
countLabels = 0;
3271    stackDepth -= 2;
3272    if (this.wideMode) {
3273        generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmplt, lbl);
3274    } else {
3275        if (classFileOffset >= bCodeStream.length) {
3276            resizeByteArray();
3277        }
3278        position++;
3279        bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpge;
3280        lbl.branch();
3281    }
3282}
3283public void if_icmpgt(BranchLabel lbl) {
3284    if (DEBUG) System.out.println(position + "\t\tif_icmpgt:"+lbl); //$NON-NLS-1$
3285
countLabels = 0;
3286    stackDepth -= 2;
3287    if (this.wideMode) {
3288        generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmple, lbl);
3289    } else {
3290        if (classFileOffset >= bCodeStream.length) {
3291            resizeByteArray();
3292        }
3293        position++;
3294        bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpgt;
3295        lbl.branch();
3296    }
3297}
3298public void if_icmple(BranchLabel lbl) {
3299    if (DEBUG) System.out.println(position + "\t\tif_icmple:"+lbl); //$NON-NLS-1$
3300
countLabels = 0;
3301    stackDepth -= 2;
3302    if (this.wideMode) {
3303        generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpgt, lbl);
3304    } else {
3305        if (classFileOffset >= bCodeStream.length) {
3306            resizeByteArray();
3307        }
3308        position++;
3309        bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmple;
3310        lbl.branch();
3311    }
3312}
3313public void if_icmplt(BranchLabel lbl) {
3314    if (DEBUG) System.out.println(position + "\t\tif_icmplt:"+lbl); //$NON-NLS-1$
3315
countLabels = 0;
3316    stackDepth -= 2;
3317    if (this.wideMode) {
3318        generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpge, lbl);
3319    } else {
3320        if (classFileOffset >= bCodeStream.length) {
3321            resizeByteArray();
3322        }
3323        position++;
3324        bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmplt;
3325        lbl.branch();
3326    }
3327}
3328public void if_icmpne(BranchLabel lbl) {
3329    if (DEBUG) System.out.println(position + "\t\tif_icmpne:"+lbl); //$NON-NLS-1$
3330
countLabels = 0;
3331    stackDepth -= 2;
3332    if (this.wideMode) {
3333        generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpeq, lbl);
3334    } else {
3335        if (classFileOffset >= bCodeStream.length) {
3336            resizeByteArray();
3337        }
3338        position++;
3339        bCodeStream[classFileOffset++] = Opcodes.OPC_if_icmpne;
3340        lbl.branch();
3341    }
3342}
3343public void ifeq(BranchLabel lbl) {
3344    if (DEBUG) System.out.println(position + "\t\tifeq:"+lbl); //$NON-NLS-1$
3345
countLabels = 0;
3346    stackDepth--;
3347    if (this.wideMode) {
3348        generateWideRevertedConditionalBranch(Opcodes.OPC_ifne, lbl);
3349    } else {
3350        if (classFileOffset >= bCodeStream.length) {
3351            resizeByteArray();
3352        }
3353        position++;
3354        bCodeStream[classFileOffset++] = Opcodes.OPC_ifeq;
3355        lbl.branch();
3356    }
3357}
3358public void ifge(BranchLabel lbl) {
3359    if (DEBUG) System.out.println(position + "\t\tifge:"+lbl); //$NON-NLS-1$
3360
countLabels = 0;
3361    stackDepth--;
3362    if (this.wideMode) {
3363        generateWideRevertedConditionalBranch(Opcodes.OPC_iflt, lbl);
3364    } else {
3365        if (classFileOffset >= bCodeStream.length) {
3366            resizeByteArray();
3367        }
3368        position++;
3369        bCodeStream[classFileOffset++] = Opcodes.OPC_ifge;
3370        lbl.branch();
3371    }
3372}
3373public void ifgt(BranchLabel lbl) {
3374    if (DEBUG) System.out.println(position + "\t\tifgt:"+lbl); //$NON-NLS-1$
3375
countLabels = 0;
3376    stackDepth--;
3377    if (this.wideMode) {
3378        generateWideRevertedConditionalBranch(Opcodes.OPC_ifle, lbl);
3379    } else {
3380        if (classFileOffset >= bCodeStream.length) {
3381            resizeByteArray();
3382        }
3383        position++;
3384        bCodeStream[classFileOffset++] = Opcodes.OPC_ifgt;
3385        lbl.branch();
3386    }
3387}
3388public void ifle(BranchLabel lbl) {
3389    if (DEBUG) System.out.println(position + "\t\tifle:"+lbl); //$NON-NLS-1$
3390
countLabels = 0;
3391    stackDepth--;
3392    if (this.wideMode) {
3393        generateWideRevertedConditionalBranch(Opcodes.OPC_ifgt, lbl);
3394    } else {
3395        if (classFileOffset >= bCodeStream.length) {
3396            resizeByteArray();
3397        }
3398        position++;
3399        bCodeStream[classFileOffset++] = Opcodes.OPC_ifle;
3400        lbl.branch();
3401    }
3402}
3403public void iflt(BranchLabel lbl) {
3404    if (DEBUG) System.out.println(position + "\t\tiflt:"+lbl); //$NON-NLS-1$
3405
countLabels = 0;
3406    stackDepth--;
3407    if (this.wideMode) {
3408        generateWideRevertedConditionalBranch(Opcodes.OPC_ifge, lbl);
3409    } else {
3410        if (classFileOffset >= bCodeStream.length) {
3411            resizeByteArray();
3412        }
3413        position++;
3414        bCodeStream[classFileOffset++] = Opcodes.OPC_iflt;
3415        lbl.branch();
3416    }
3417}
3418public void ifne(BranchLabel lbl) {
3419    if (DEBUG) System.out.println(position + "\t\tifne:"+lbl); //$NON-NLS-1$
3420
countLabels = 0;
3421    stackDepth--;
3422    if (this.wideMode) {
3423        generateWideRevertedConditionalBranch(Opcodes.OPC_ifeq, lbl);
3424    } else {
3425        if (classFileOffset >= bCodeStream.length) {
3426            resizeByteArray();
3427        }
3428        position++;
3429        bCodeStream[classFileOffset++] = Opcodes.OPC_ifne;
3430        lbl.branch();
3431    }
3432}
3433public void ifnonnull(BranchLabel lbl) {
3434    if (DEBUG) System.out.println(position + "\t\tifnonnull:"+lbl); //$NON-NLS-1$
3435
countLabels = 0;
3436    stackDepth--;
3437    if (this.wideMode) {
3438        generateWideRevertedConditionalBranch(Opcodes.OPC_ifnull, lbl);
3439    } else {
3440        if (classFileOffset >= bCodeStream.length) {
3441            resizeByteArray();
3442        }
3443        position++;
3444        bCodeStream[classFileOffset++] = Opcodes.OPC_ifnonnull;
3445        lbl.branch();
3446    }
3447}
3448public void ifnull(BranchLabel lbl) {
3449    if (DEBUG) System.out.println(position + "\t\tifnull:"+lbl); //$NON-NLS-1$
3450
countLabels = 0;
3451    stackDepth--;
3452    if (this.wideMode) {
3453        generateWideRevertedConditionalBranch(Opcodes.OPC_ifnonnull, lbl);
3454    } else {
3455        if (classFileOffset >= bCodeStream.length) {
3456            resizeByteArray();
3457        }
3458        position++;
3459        bCodeStream[classFileOffset++] = Opcodes.OPC_ifnull;
3460        lbl.branch();
3461    }
3462}
3463final public void iinc(int index, int value) {
3464    if (DEBUG) System.out.println(position + "\t\tiinc:"+index+","+value); //$NON-NLS-1$ //$NON-NLS-2$
3465
countLabels = 0;
3466    if ((index > 255) || (value < -128 || value > 127)) { // have to widen
3467
if (classFileOffset + 3 >= bCodeStream.length) {
3468            resizeByteArray();
3469        }
3470        position += 2;
3471        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
3472        bCodeStream[classFileOffset++] = Opcodes.OPC_iinc;
3473        writeUnsignedShort(index);
3474        writeSignedShort(value);
3475    } else {
3476        if (classFileOffset + 2 >= bCodeStream.length) {
3477            resizeByteArray();
3478        }
3479        position += 3;
3480        bCodeStream[classFileOffset++] = Opcodes.OPC_iinc;
3481        bCodeStream[classFileOffset++] = (byte) index;
3482        bCodeStream[classFileOffset++] = (byte) value;
3483    }
3484}
3485public void iload(int iArg) {
3486    if (DEBUG) System.out.println(position + "\t\tiload:"+iArg); //$NON-NLS-1$
3487
countLabels = 0;
3488    stackDepth++;
3489    if (maxLocals <= iArg) {
3490        maxLocals = iArg + 1;
3491    }
3492    if (stackDepth > stackMax)
3493        stackMax = stackDepth;
3494    if (iArg > 255) { // Widen
3495
if (classFileOffset + 3 >= bCodeStream.length) {
3496            resizeByteArray();
3497        }
3498        position += 2;
3499        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
3500        bCodeStream[classFileOffset++] = Opcodes.OPC_iload;
3501        writeUnsignedShort(iArg);
3502    } else {
3503        if (classFileOffset + 1 >= bCodeStream.length) {
3504            resizeByteArray();
3505        }
3506        position += 2;
3507        bCodeStream[classFileOffset++] = Opcodes.OPC_iload;
3508        bCodeStream[classFileOffset++] = (byte) iArg;
3509    }
3510}
3511public void iload_0() {
3512    if (DEBUG) System.out.println(position + "\t\tiload_0"); //$NON-NLS-1$
3513
countLabels = 0;
3514    stackDepth++;
3515    if (maxLocals <= 0) {
3516        maxLocals = 1;
3517    }
3518    if (stackDepth > stackMax)
3519        stackMax = stackDepth;
3520    if (classFileOffset >= bCodeStream.length) {
3521        resizeByteArray();
3522    }
3523    position++;
3524    bCodeStream[classFileOffset++] = Opcodes.OPC_iload_0;
3525}
3526public void iload_1() {
3527    if (DEBUG) System.out.println(position + "\t\tiload_1"); //$NON-NLS-1$
3528
countLabels = 0;
3529    stackDepth++;
3530    if (maxLocals <= 1) {
3531        maxLocals = 2;
3532    }
3533    if (stackDepth > stackMax)
3534        stackMax = stackDepth;
3535    if (classFileOffset >= bCodeStream.length) {
3536        resizeByteArray();
3537    }
3538    position++;
3539    bCodeStream[classFileOffset++] = Opcodes.OPC_iload_1;
3540}
3541public void iload_2() {
3542    if (DEBUG) System.out.println(position + "\t\tiload_2"); //$NON-NLS-1$
3543
countLabels = 0;
3544    stackDepth++;
3545    if (maxLocals <= 2) {
3546        maxLocals = 3;
3547    }
3548    if (stackDepth > stackMax)
3549        stackMax = stackDepth;
3550    if (classFileOffset >= bCodeStream.length) {
3551        resizeByteArray();
3552    }
3553    position++;
3554    bCodeStream[classFileOffset++] = Opcodes.OPC_iload_2;
3555}
3556public void iload_3() {
3557    if (DEBUG) System.out.println(position + "\t\tiload_3"); //$NON-NLS-1$
3558
countLabels = 0;
3559    stackDepth++;
3560    if (maxLocals <= 3) {
3561        maxLocals = 4;
3562    }
3563    if (stackDepth > stackMax)
3564        stackMax = stackDepth;
3565    if (classFileOffset >= bCodeStream.length) {
3566        resizeByteArray();
3567    }
3568    position++;
3569    bCodeStream[classFileOffset++] = Opcodes.OPC_iload_3;
3570}
3571public void imul() {
3572    if (DEBUG) System.out.println(position + "\t\timul"); //$NON-NLS-1$
3573
countLabels = 0;
3574    stackDepth--;
3575    if (classFileOffset >= bCodeStream.length) {
3576        resizeByteArray();
3577    }
3578    position++;
3579    bCodeStream[classFileOffset++] = Opcodes.OPC_imul;
3580}
3581public int indexOfSameLineEntrySincePC(int pc, int line) {
3582    for (int index = pc, max = pcToSourceMapSize; index < max; index+=2) {
3583        if (pcToSourceMap[index+1] == line)
3584            return index;
3585    }
3586    return -1;
3587}
3588public void ineg() {
3589    if (DEBUG) System.out.println(position + "\t\tineg"); //$NON-NLS-1$
3590
countLabels = 0;
3591    if (classFileOffset >= bCodeStream.length) {
3592        resizeByteArray();
3593    }
3594    position++;
3595    bCodeStream[classFileOffset++] = Opcodes.OPC_ineg;
3596}
3597/*
3598 * Some placed labels might be branching to a goto bytecode which we can optimize better.
3599 */

3600public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel targetLabel, int gotoLocation) {
3601    if (targetLabel.delegate != null) return false; // already inlined
3602
int chaining = L_UNKNOWN;
3603    for (int i = this.countLabels - 1; i >= 0; i--) {
3604        BranchLabel currentLabel = labels[i];
3605        if (currentLabel.position != gotoLocation) break;
3606        if (currentLabel == targetLabel) {
3607            chaining |= L_CANNOT_OPTIMIZE; // recursive
3608
continue;
3609        }
3610        if (currentLabel.isStandardLabel()) {
3611            if (currentLabel.delegate != null) continue; // ignore since already inlined
3612
targetLabel.becomeDelegateFor(currentLabel);
3613            chaining |= L_OPTIMIZABLE; // optimizable, providing no vetoing
3614
continue;
3615        }
3616        // case label
3617
chaining |= L_CANNOT_OPTIMIZE;
3618    }
3619    return (chaining & (L_OPTIMIZABLE|L_CANNOT_OPTIMIZE)) == L_OPTIMIZABLE; // check was some standards, and no case/recursive
3620
}
3621public void init(ClassFile targetClassFile) {
3622    this.classFile = targetClassFile;
3623    this.constantPool = targetClassFile.constantPool;
3624    this.bCodeStream = targetClassFile.contents;
3625    this.classFileOffset = targetClassFile.contentsOffset;
3626    this.startingClassFileOffset = this.classFileOffset;
3627    pcToSourceMapSize = 0;
3628    lastEntryPC = 0;
3629    int length = visibleLocals.length;
3630    if (noVisibleLocals.length < length) {
3631        noVisibleLocals = new LocalVariableBinding[length];
3632    }
3633    System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
3634    visibleLocalsCount = 0;
3635    
3636    length = locals.length;
3637    if (noLocals.length < length) {
3638        noLocals = new LocalVariableBinding[length];
3639    }
3640    System.arraycopy(noLocals, 0, locals, 0, length);
3641    allLocalsCounter = 0;
3642
3643    length = exceptionLabels.length;
3644    if (noExceptionHandlers.length < length) {
3645        noExceptionHandlers = new ExceptionLabel[length];
3646    }
3647    System.arraycopy(noExceptionHandlers, 0, exceptionLabels, 0, length);
3648    exceptionLabelsCounter = 0;
3649    
3650    length = labels.length;
3651    if (noLabels.length < length) {
3652        noLabels = new BranchLabel[length];
3653    }
3654    System.arraycopy(noLabels, 0, labels, 0, length);
3655    countLabels = 0;
3656    this.lastAbruptCompletion = -1;
3657
3658    stackMax = 0;
3659    stackDepth = 0;
3660    maxLocals = 0;
3661    position = 0;
3662}
3663/**
3664 * @param methodBinding the given method binding to initialize the max locals
3665 */

3666public void initializeMaxLocals(MethodBinding methodBinding) {
3667
3668    if (methodBinding == null) {
3669        this.maxLocals = 0;
3670        return;
3671    }
3672    
3673    this.maxLocals = methodBinding.isStatic() ? 0 : 1;
3674    
3675    // take into account enum constructor synthetic name+ordinal
3676
if (methodBinding.isConstructor() && methodBinding.declaringClass.isEnum()) {
3677        this.maxLocals += 2; // String and int (enum constant name+ordinal)
3678
}
3679    
3680    // take into account the synthetic parameters
3681
if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
3682        ReferenceBinding enclosingInstanceTypes[];
3683        if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
3684            for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
3685                this.maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
3686
// LongBinding or DoubleBinding
3687
}
3688        }
3689        SyntheticArgumentBinding syntheticArguments[];
3690        if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
3691            for (int i = 0, max = syntheticArguments.length; i < max; i++) {
3692                TypeBinding argType;
3693                if (((argType = syntheticArguments[i].type) == TypeBinding.LONG) || (argType == TypeBinding.DOUBLE)) {
3694                    this.maxLocals += 2;
3695                } else {
3696                    this.maxLocals++;
3697                }
3698            }
3699        }
3700    }
3701    TypeBinding[] arguments;
3702    if ((arguments = methodBinding.parameters) != null) {
3703        for (int i = 0, max = arguments.length; i < max; i++) {
3704            TypeBinding argType;
3705            if (((argType = arguments[i]) == TypeBinding.LONG) || (argType == TypeBinding.DOUBLE)) {
3706                this.maxLocals += 2;
3707            } else {
3708                this.maxLocals++;
3709            }
3710        }
3711    }
3712}
3713/**
3714 * We didn't call it instanceof because there is a conflit with the
3715 * instanceof keyword
3716 */

3717public void instance_of(TypeBinding typeBinding) {
3718    if (DEBUG) System.out.println(position + "\t\tinstance_of:"+typeBinding); //$NON-NLS-1$
3719
countLabels = 0;
3720    if (classFileOffset + 2 >= bCodeStream.length) {
3721        resizeByteArray();
3722    }
3723    position++;
3724    bCodeStream[classFileOffset++] = Opcodes.OPC_instanceof;
3725    writeUnsignedShort(constantPool.literalIndexForType(typeBinding));
3726}
3727protected void invoke(int opcode, int argsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
3728    countLabels = 0;
3729    int argCount = argsSize;
3730    switch(opcode) {
3731        case Opcodes.OPC_invokeinterface :
3732            if (classFileOffset + 4 >= bCodeStream.length) {
3733                resizeByteArray();
3734            }
3735            position +=3;
3736            bCodeStream[classFileOffset++] = Opcodes.OPC_invokeinterface;
3737            writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
3738            argCount++;
3739            bCodeStream[classFileOffset++] = (byte) argCount;
3740            bCodeStream[classFileOffset++] = 0;
3741            break;
3742        case Opcodes.OPC_invokevirtual :
3743        case Opcodes.OPC_invokespecial :
3744            if (classFileOffset + 2 >= bCodeStream.length) {
3745                resizeByteArray();
3746            }
3747            position++;
3748            bCodeStream[classFileOffset++] = (byte) opcode;
3749            writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3750            argCount++;
3751            break;
3752        case Opcodes.OPC_invokestatic :
3753            if (classFileOffset + 2 >= bCodeStream.length) {
3754                resizeByteArray();
3755            }
3756            position++;
3757            bCodeStream[classFileOffset++] = Opcodes.OPC_invokestatic;
3758            writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3759    }
3760    stackDepth += returnTypeSize - argCount;
3761    if (stackDepth > stackMax) {
3762        stackMax = stackDepth;
3763    }
3764}
3765protected void invokeAccessibleObjectSetAccessible() {
3766    // invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V;
3767
this.invoke(
3768            Opcodes.OPC_invokevirtual,
3769            1, // argCount
3770
0, // return type size
3771
ConstantPool.JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME,
3772            ConstantPool.SETACCESSIBLE_NAME,
3773            ConstantPool.SETACCESSIBLE_SIGNATURE);
3774}
3775protected void invokeArrayNewInstance() {
3776    // invokestatic: java.lang.reflect.Array.newInstance(Ljava.lang.Class;int[])Ljava.lang.Object;
3777
this.invoke(
3778            Opcodes.OPC_invokestatic,
3779            2, // argCount
3780
1, // return type size
3781
ConstantPool.JAVALANGREFLECTARRAY_CONSTANTPOOLNAME,
3782            ConstantPool.NewInstance,
3783            ConstantPool.NewInstanceSignature);
3784}
3785public void invokeClassForName() {
3786    // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
3787
if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$
3788
this.invoke(
3789        Opcodes.OPC_invokestatic,
3790        1, // argCount
3791
1, // return type size
3792
ConstantPool.JavaLangClassConstantPoolName,
3793        ConstantPool.ForName,
3794        ConstantPool.ForNameSignature);
3795}
3796protected void invokeClassGetDeclaredConstructor() {
3797    // invokevirtual: java.lang.Class getDeclaredConstructor([Ljava.lang.Class)Ljava.lang.reflect.Constructor;
3798
this.invoke(
3799            Opcodes.OPC_invokevirtual,
3800            1, // argCount
3801
1, // return type size
3802
ConstantPool.JavaLangClassConstantPoolName,
3803            ConstantPool.GETDECLAREDCONSTRUCTOR_NAME,
3804            ConstantPool.GETDECLAREDCONSTRUCTOR_SIGNATURE);
3805}
3806protected void invokeClassGetDeclaredField() {
3807    // invokevirtual: java.lang.Class.getDeclaredField(Ljava.lang.String)Ljava.lang.reflect.Field;
3808
this.invoke(
3809            Opcodes.OPC_invokevirtual,
3810            1, // argCount
3811
1, // return type size
3812
ConstantPool.JavaLangClassConstantPoolName,
3813            ConstantPool.GETDECLAREDFIELD_NAME,
3814            ConstantPool.GETDECLAREDFIELD_SIGNATURE);
3815}
3816protected void invokeClassGetDeclaredMethod() {
3817    // invokevirtual: java.lang.Class getDeclaredMethod(Ljava.lang.String, [Ljava.lang.Class)Ljava.lang.reflect.Method;
3818
this.invoke(
3819            Opcodes.OPC_invokevirtual,
3820            2, // argCount
3821
1, // return type size
3822
ConstantPool.JavaLangClassConstantPoolName,
3823            ConstantPool.GETDECLAREDMETHOD_NAME,
3824            ConstantPool.GETDECLAREDMETHOD_SIGNATURE);
3825}
3826public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
3827    // invokevirtual: <enumConstantPoolName>.ordinal()
3828
if (DEBUG) System.out.println(position + "\t\tinvokevirtual: "+new String JavaDoc(enumTypeConstantPoolName)+".ordinal()"); //$NON-NLS-1$ //$NON-NLS-2$
3829
this.invoke(
3830            Opcodes.OPC_invokevirtual,
3831            0, // argCount
3832
1, // return type size
3833
enumTypeConstantPoolName,
3834            ConstantPool.Ordinal,
3835            ConstantPool.OrdinalSignature);
3836}
3837public void invokeinterface(MethodBinding methodBinding) {
3838    if (DEBUG) System.out.println(position + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$
3839
countLabels = 0;
3840    // initialized to 1 to take into account this immediately
3841
int argCount = 1;
3842    int id;
3843    if (classFileOffset + 4 >= bCodeStream.length) {
3844        resizeByteArray();
3845    }
3846    position += 3;
3847    bCodeStream[classFileOffset++] = Opcodes.OPC_invokeinterface;
3848    writeUnsignedShort(
3849        constantPool.literalIndexForMethod(
3850            methodBinding.constantPoolDeclaringClass(),
3851            methodBinding.selector,
3852            methodBinding.signature(classFile),
3853            true));
3854    for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3855        if (((id = methodBinding.parameters[i].id) == TypeIds.T_double) || (id == TypeIds.T_long))
3856            argCount += 2;
3857        else
3858            argCount += 1;
3859    bCodeStream[classFileOffset++] = (byte) argCount;
3860    // Generate a 0 into the byte array. Like the array is already fill with 0, we just need to increment
3861
// the number of bytes.
3862
bCodeStream[classFileOffset++] = 0;
3863    if (((id = methodBinding.returnType.id) == TypeIds.T_double) || (id == TypeIds.T_long)) {
3864        stackDepth += (2 - argCount);
3865    } else {
3866        if (id == TypeIds.T_void) {
3867            stackDepth -= argCount;
3868        } else {
3869            stackDepth += (1 - argCount);
3870        }
3871    }
3872    if (stackDepth > stackMax) {
3873        stackMax = stackDepth;
3874    }
3875}
3876public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
3877    // invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
3878
if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>(typeBindingID)V"); //$NON-NLS-1$
3879
int argCount = 1;
3880    char[] signature = null;
3881    switch (typeBindingID) {
3882        case TypeIds.T_int :
3883        case TypeIds.T_byte :
3884        case TypeIds.T_short :
3885            signature = ConstantPool.IntConstrSignature;
3886            break;
3887        case TypeIds.T_long :
3888            signature = ConstantPool.LongConstrSignature;
3889            argCount = 2;
3890            break;
3891        case TypeIds.T_float :
3892            signature = ConstantPool.FloatConstrSignature;
3893            break;
3894        case TypeIds.T_double :
3895            signature = ConstantPool.DoubleConstrSignature;
3896            argCount = 2;
3897            break;
3898        case TypeIds.T_char :
3899            signature = ConstantPool.CharConstrSignature;
3900            break;
3901        case TypeIds.T_boolean :
3902            signature = ConstantPool.BooleanConstrSignature;
3903            break;
3904        case TypeIds.T_JavaLangObject :
3905        case TypeIds.T_JavaLangString :
3906        case TypeIds.T_null :
3907            signature = ConstantPool.ObjectConstrSignature;
3908            break;
3909    }
3910    this.invoke(
3911            Opcodes.OPC_invokespecial,
3912            argCount, // argCount
3913
0, // return type size
3914
ConstantPool.JavaLangAssertionErrorConstantPoolName,
3915            ConstantPool.Init,
3916            signature);
3917}
3918public void invokeJavaLangAssertionErrorDefaultConstructor() {
3919    // invokespecial: java.lang.AssertionError.<init>()V
3920
if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>()V"); //$NON-NLS-1$
3921
this.invoke(
3922            Opcodes.OPC_invokespecial,
3923            0, // argCount
3924
0, // return type size
3925
ConstantPool.JavaLangAssertionErrorConstantPoolName,
3926            ConstantPool.Init,
3927            ConstantPool.DefaultConstructorSignature);
3928}
3929public void invokeJavaLangClassDesiredAssertionStatus() {
3930    // invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
3931
if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$
3932
this.invoke(
3933            Opcodes.OPC_invokevirtual,
3934            0, // argCount
3935
1, // return type size
3936
ConstantPool.JavaLangClassConstantPoolName,
3937            ConstantPool.DesiredAssertionStatus,
3938            ConstantPool.DesiredAssertionStatusSignature);
3939}
3940public void invokeJavaLangEnumvalueOf(ReferenceBinding binding) {
3941    // invokestatic: java.lang.Enum.valueOf(Class,String)
3942
if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Enum.valueOf(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;"); //$NON-NLS-1$
3943
this.invoke(
3944            Opcodes.OPC_invokestatic,
3945            2, // argCount
3946
1, // return type size
3947
ConstantPool.JavaLangEnumConstantPoolName,
3948            ConstantPool.ValueOf,
3949            ConstantPool.ValueOfStringClassSignature);
3950}
3951public void invokeJavaLangEnumValues(TypeBinding enumBinding, ArrayBinding arrayBinding) {
3952    char[] signature = "()".toCharArray(); //$NON-NLS-1$
3953
signature = CharOperation.concat(signature, arrayBinding.constantPoolName());
3954    this.invoke(Opcodes.OPC_invokestatic, 0, 1, enumBinding.constantPoolName(), TypeConstants.VALUES, signature);
3955}
3956public void invokeJavaLangErrorConstructor() {
3957    // invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
3958
if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.Error<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3959
this.invoke(
3960            Opcodes.OPC_invokespecial,
3961            1, // argCount
3962
0, // return type size
3963
ConstantPool.JavaLangErrorConstantPoolName,
3964            ConstantPool.Init,
3965            ConstantPool.StringConstructorSignature);
3966}
3967public void invokeJavaLangReflectConstructorNewInstance() {
3968    // invokevirtual: java.lang.reflect.Constructor.newInstance([Ljava.lang.Object;)Ljava.lang.Object;
3969
this.invoke(
3970            Opcodes.OPC_invokevirtual,
3971            1, // argCount
3972
1, // return type size
3973
ConstantPool.JavaLangReflectConstructorConstantPoolName,
3974            ConstantPool.NewInstance,
3975            ConstantPool.JavaLangReflectConstructorNewInstanceSignature);
3976}
3977protected void invokeJavaLangReflectFieldGetter(int typeID) {
3978    int returnTypeSize = 1;
3979    char[] signature = null;
3980    char[] selector = null;
3981    switch (typeID) {
3982        case TypeIds.T_int :
3983            selector = ConstantPool.GET_INT_METHOD_NAME;
3984            signature = ConstantPool.GET_INT_METHOD_SIGNATURE;
3985            break;
3986        case TypeIds.T_byte :
3987            selector = ConstantPool.GET_BYTE_METHOD_NAME;
3988            signature = ConstantPool.GET_BYTE_METHOD_SIGNATURE;
3989            break;
3990        case TypeIds.T_short :
3991            selector = ConstantPool.GET_SHORT_METHOD_NAME;
3992            signature = ConstantPool.GET_SHORT_METHOD_SIGNATURE;
3993            break;
3994        case TypeIds.T_long :
3995            selector = ConstantPool.GET_LONG_METHOD_NAME;
3996            signature = ConstantPool.GET_LONG_METHOD_SIGNATURE;
3997            returnTypeSize = 2;
3998            break;
3999        case TypeIds.T_float :
4000            selector = ConstantPool.GET_FLOAT_METHOD_NAME;
4001            signature = ConstantPool.GET_FLOAT_METHOD_SIGNATURE;
4002            break;
4003        case TypeIds.T_double :
4004            selector = ConstantPool.GET_DOUBLE_METHOD_NAME;
4005            signature = ConstantPool.GET_DOUBLE_METHOD_SIGNATURE;
4006            returnTypeSize = 2;
4007            break;
4008        case TypeIds.T_char :
4009            selector = ConstantPool.GET_CHAR_METHOD_NAME;
4010            signature = ConstantPool.GET_CHAR_METHOD_SIGNATURE;
4011            break;
4012        case TypeIds.T_boolean :
4013            selector = ConstantPool.GET_BOOLEAN_METHOD_NAME;
4014            signature = ConstantPool.GET_BOOLEAN_METHOD_SIGNATURE;
4015            break;
4016        default :
4017            selector = ConstantPool.GET_OBJECT_METHOD_NAME;
4018            signature = ConstantPool.GET_OBJECT_METHOD_SIGNATURE;
4019            break;
4020    }
4021    this.invoke(
4022            Opcodes.OPC_invokevirtual,
4023            1, // argCount
4024
returnTypeSize, // return type size
4025
ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
4026            selector,
4027            signature);
4028}
4029protected void invokeJavaLangReflectFieldSetter(int typeID) {
4030    int argCount = 2;
4031    char[] signature = null;
4032    char[] selector = null;
4033    switch (typeID) {
4034        case TypeIds.T_int :
4035            selector = ConstantPool.SET_INT_METHOD_NAME;
4036            signature = ConstantPool.SET_INT_METHOD_SIGNATURE;
4037            break;
4038        case TypeIds.T_byte :
4039            selector = ConstantPool.SET_BYTE_METHOD_NAME;
4040            signature = ConstantPool.SET_BYTE_METHOD_SIGNATURE;
4041            break;
4042        case TypeIds.T_short :
4043            selector = ConstantPool.SET_SHORT_METHOD_NAME;
4044            signature = ConstantPool.SET_SHORT_METHOD_SIGNATURE;
4045            break;
4046        case TypeIds.T_long :
4047            selector = ConstantPool.SET_LONG_METHOD_NAME;
4048            signature = ConstantPool.SET_LONG_METHOD_SIGNATURE;
4049            argCount = 3;
4050            break;
4051        case TypeIds.T_float :
4052            selector = ConstantPool.SET_FLOAT_METHOD_NAME;
4053            signature = ConstantPool.SET_FLOAT_METHOD_SIGNATURE;
4054            break;
4055        case TypeIds.T_double :
4056            selector = ConstantPool.SET_DOUBLE_METHOD_NAME;
4057            signature = ConstantPool.SET_DOUBLE_METHOD_SIGNATURE;
4058            argCount = 3;
4059            break;
4060        case TypeIds.T_char :
4061            selector = ConstantPool.SET_CHAR_METHOD_NAME;
4062            signature = ConstantPool.SET_CHAR_METHOD_SIGNATURE;
4063            break;
4064        case TypeIds.T_boolean :
4065            selector = ConstantPool.SET_BOOLEAN_METHOD_NAME;
4066            signature = ConstantPool.SET_BOOLEAN_METHOD_SIGNATURE;
4067            break;
4068        default :
4069            selector = ConstantPool.SET_OBJECT_METHOD_NAME;
4070            signature = ConstantPool.SET_OBJECT_METHOD_SIGNATURE;
4071            break;
4072    }
4073    this.invoke(
4074            Opcodes.OPC_invokevirtual,
4075            argCount, // argCount
4076
0, // return type size
4077
ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
4078            selector,
4079            signature);
4080}
4081public void invokeJavaLangReflectMethodInvoke() {
4082    // invokevirtual: java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;
4083
this.invoke(
4084            Opcodes.OPC_invokevirtual,
4085            2, // argCount
4086
1, // return type size
4087
ConstantPool.JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME,
4088            ConstantPool.INVOKE_METHOD_METHOD_NAME,
4089            ConstantPool.INVOKE_METHOD_METHOD_SIGNATURE);
4090}
4091public void invokeJavaUtilIteratorHasNext() {
4092    // invokeinterface java.util.Iterator.hasNext()Z
4093
if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.hasNext()Z"); //$NON-NLS-1$
4094
this.invoke(
4095            Opcodes.OPC_invokeinterface,
4096            0, // argCount
4097
1, // return type size
4098
ConstantPool.JavaUtilIteratorConstantPoolName,
4099            ConstantPool.HasNext,
4100            ConstantPool.HasNextSignature);
4101}
4102public void invokeJavaUtilIteratorNext() {
4103    // invokeinterface java.util.Iterator.next()java.lang.Object
4104
if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.next()java.lang.Object"); //$NON-NLS-1$
4105
this.invoke(
4106            Opcodes.OPC_invokeinterface,
4107            0, // argCount
4108
1, // return type size
4109
ConstantPool.JavaUtilIteratorConstantPoolName,
4110            ConstantPool.Next,
4111            ConstantPool.NextSignature);
4112}
4113public void invokeNoClassDefFoundErrorStringConstructor() {
4114    // invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
4115
if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
4116
this.invoke(
4117            Opcodes.OPC_invokespecial,
4118            1, // argCount
4119
0, // return type size
4120
ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName,
4121            ConstantPool.Init,
4122            ConstantPool.StringConstructorSignature);
4123}
4124public void invokeObjectGetClass() {
4125    // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
4126
if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$
4127
this.invoke(
4128            Opcodes.OPC_invokevirtual,
4129            0, // argCount
4130
1, // return type size
4131
ConstantPool.JavaLangObjectConstantPoolName,
4132            ConstantPool.GetClass,
4133            ConstantPool.GetClassSignature);
4134}
4135public void invokespecial(MethodBinding methodBinding) {
4136    if (DEBUG) System.out.println(position + "\t\tinvokespecial:"+methodBinding); //$NON-NLS-1$
4137
countLabels = 0;
4138    // initialized to 1 to take into account this immediately
4139
int argCount = 1;
4140    int id;
4141    if (classFileOffset + 2 >= bCodeStream.length) {
4142        resizeByteArray();
4143    }
4144    position++;
4145    bCodeStream[classFileOffset++] = Opcodes.OPC_invokespecial;
4146    writeUnsignedShort(
4147        constantPool.literalIndexForMethod(
4148            methodBinding.constantPoolDeclaringClass(),
4149            methodBinding.selector,
4150            methodBinding.signature(classFile),
4151            false));
4152    if (methodBinding.isConstructor()) {
4153        final ReferenceBinding declaringClass = methodBinding.declaringClass;
4154        if (declaringClass.isNestedType()) {
4155            // enclosing instances
4156
TypeBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes();
4157            if (syntheticArgumentTypes != null) {
4158                for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
4159                    if (((id = syntheticArgumentTypes[i].id) == TypeIds.T_double) || (id == TypeIds.T_long)) {
4160                        argCount += 2;
4161                    } else {
4162                        argCount++;
4163                    }
4164                }
4165            }
4166            // outer local variables
4167
SyntheticArgumentBinding[] syntheticArguments = declaringClass.syntheticOuterLocalVariables();
4168            if (syntheticArguments != null) {
4169                for (int i = 0, max = syntheticArguments.length; i < max; i++) {
4170                    if (((id = syntheticArguments[i].type.id) == TypeIds.T_double) || (id == TypeIds.T_long)) {
4171                        argCount += 2;
4172                    } else {
4173                        argCount++;
4174                    }
4175                }
4176            }
4177        }
4178        if (declaringClass.isEnum()) {
4179            // adding String and int
4180
argCount += 2;
4181        }
4182    }
4183    for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
4184        if (((id = methodBinding.parameters[i].id) == TypeIds.T_double) || (id == TypeIds.T_long))
4185            argCount += 2;
4186        else
4187            argCount++;
4188    if (((id = methodBinding.returnType.id) == TypeIds.T_double) || (id == TypeIds.T_long))
4189        stackDepth += (2 - argCount);
4190    else
4191        if (id == TypeIds.T_void)
4192            stackDepth -= argCount;
4193        else
4194            stackDepth += (1 - argCount);
4195    if (stackDepth > stackMax)
4196        stackMax = stackDepth;
4197}
4198public void invokestatic(MethodBinding methodBinding) {
4199    if (DEBUG) System.out.println(position + "\t\tinvokestatic:"+methodBinding); //$NON-NLS-1$
4200
// initialized to 0 to take into account that there is no this for
4201
// a static method
4202
countLabels = 0;
4203    int argCount = 0;
4204    int id;
4205    if (classFileOffset + 2 >= bCodeStream.length) {
4206        resizeByteArray();
4207    }
4208    position++;
4209    bCodeStream[classFileOffset++] = Opcodes.OPC_invokestatic;
4210    writeUnsignedShort(
4211        constantPool.literalIndexForMethod(
4212            methodBinding.constantPoolDeclaringClass(),
4213            methodBinding.selector,
4214            methodBinding.signature(classFile),
4215            false));
4216    for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
4217        if (((id = methodBinding.parameters[i].id) == TypeIds.T_double) || (id == TypeIds.T_long))
4218            argCount += 2;
4219        else
4220            argCount += 1;
4221    if (((id = methodBinding.returnType.id) == TypeIds.T_double) || (id == TypeIds.T_long))
4222        stackDepth += (2 - argCount);
4223    else
4224        if (id == TypeIds.T_void)
4225            stackDepth -= argCount;
4226        else
4227            stackDepth += (1 - argCount);
4228    if (stackDepth > stackMax)
4229        stackMax = stackDepth;
4230}
4231/**
4232 * The equivalent code performs a string conversion of the TOS
4233 * @param typeID <CODE>int</CODE>
4234 */

4235public void invokeStringConcatenationAppendForType(int typeID) {
4236    if (DEBUG) {
4237        if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4238            System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuilder.append(...)"); //$NON-NLS-1$
4239
} else {
4240            System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$
4241
}
4242    }
4243    int argCount = 1;
4244    int returnType = 1;
4245    char[] declaringClass = null;
4246    char[] selector = ConstantPool.Append;
4247    char[] signature = null;
4248    switch (typeID) {
4249        case TypeIds.T_int :
4250        case TypeIds.T_byte :
4251        case TypeIds.T_short :
4252            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4253                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4254                signature = ConstantPool.StringBuilderAppendIntSignature;
4255            } else {
4256                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4257                signature = ConstantPool.StringBufferAppendIntSignature;
4258            }
4259            break;
4260        case TypeIds.T_long :
4261            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4262                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4263                signature = ConstantPool.StringBuilderAppendLongSignature;
4264            } else {
4265                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4266                signature = ConstantPool.StringBufferAppendLongSignature;
4267            }
4268            argCount = 2;
4269            break;
4270        case TypeIds.T_float :
4271            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4272                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4273                signature = ConstantPool.StringBuilderAppendFloatSignature;
4274            } else {
4275                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4276                signature = ConstantPool.StringBufferAppendFloatSignature;
4277            }
4278            break;
4279        case TypeIds.T_double :
4280            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4281                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4282                signature = ConstantPool.StringBuilderAppendDoubleSignature;
4283            } else {
4284                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4285                signature = ConstantPool.StringBufferAppendDoubleSignature;
4286            }
4287            argCount = 2;
4288            break;
4289        case TypeIds.T_char :
4290            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4291                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4292                signature = ConstantPool.StringBuilderAppendCharSignature;
4293            } else {
4294                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4295                signature = ConstantPool.StringBufferAppendCharSignature;
4296            }
4297            break;
4298        case TypeIds.T_boolean :
4299            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4300                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4301                signature = ConstantPool.StringBuilderAppendBooleanSignature;
4302            } else {
4303                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4304                signature = ConstantPool.StringBufferAppendBooleanSignature;
4305            }
4306            break;
4307        case TypeIds.T_undefined :
4308        case TypeIds.T_JavaLangObject :
4309        case TypeIds.T_null :
4310            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4311                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4312                signature = ConstantPool.StringBuilderAppendObjectSignature;
4313            } else {
4314                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4315                signature = ConstantPool.StringBufferAppendObjectSignature;
4316            }
4317            break;
4318        case TypeIds.T_JavaLangString :
4319            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4320                declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4321                signature = ConstantPool.StringBuilderAppendStringSignature;
4322            } else {
4323                declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4324                signature = ConstantPool.StringBufferAppendStringSignature;
4325            }
4326            break;
4327    }
4328    this.invoke(
4329            Opcodes.OPC_invokevirtual,
4330            argCount, // argCount
4331
returnType, // return type size
4332
declaringClass,
4333            selector,
4334            signature);
4335}
4336public void invokeStringConcatenationDefaultConstructor() {
4337    // invokespecial: java.lang.StringBuffer.<init>()V
4338
if (DEBUG) {
4339        if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4340            System.out.println(position + "\t\tinvokespecial: java.lang.StringBuilder.<init>()V"); //$NON-NLS-1$
4341
} else {
4342            System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.<init>()V"); //$NON-NLS-1$
4343
}
4344    }
4345    char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4346    if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4347        declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4348    }
4349    this.invoke(
4350            Opcodes.OPC_invokespecial,
4351            0, // argCount
4352
0, // return type size
4353
declaringClass,
4354            ConstantPool.Init,
4355            ConstantPool.DefaultConstructorSignature);
4356}
4357public void invokeStringConcatenationStringConstructor() {
4358    if (DEBUG) {
4359        if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4360            System.out.println(position + "\t\tjava.lang.StringBuilder.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
4361
} else {
4362            System.out.println(position + "\t\tjava.lang.StringBuffer.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
4363
}
4364    }
4365    char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4366    if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4367        declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4368    }
4369    this.invoke(
4370            Opcodes.OPC_invokespecial,
4371            1, // argCount
4372
0, // return type size
4373
declaringClass,
4374            ConstantPool.Init,
4375            ConstantPool.StringConstructorSignature);
4376}
4377public void invokeStringConcatenationToString() {
4378    if (DEBUG) {
4379        if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4380            System.out.println(position + "\t\tinvokevirtual: StringBuilder.toString()Ljava.lang.String;"); //$NON-NLS-1$
4381
} else {
4382            System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$
4383
}
4384    }
4385    char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
4386    if (this.targetLevel >= ClassFileConstants.JDK1_5) {
4387        declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
4388    }
4389    this.invoke(
4390            Opcodes.OPC_invokevirtual,
4391            0, // argCount
4392
1, // return type size
4393
declaringClass,
4394            ConstantPool.ToString,
4395            ConstantPool.ToStringSignature);
4396}
4397public void invokeStringIntern() {
4398    // invokevirtual: java.lang.String.intern()
4399
if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$
4400
this.invoke(
4401            Opcodes.OPC_invokevirtual,
4402            0, // argCount
4403
1, // return type size
4404
ConstantPool.JavaLangStringConstantPoolName,
4405            ConstantPool.Intern,
4406            ConstantPool.InternSignature);
4407}
4408public void invokeStringValueOf(int typeID) {
4409    // invokestatic: java.lang.String.valueOf(argumentType)
4410
if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$
4411
int argCount = 1;
4412    char[] signature = null;
4413    switch (typeID) {
4414        case TypeIds.T_int :
4415        case TypeIds.T_byte :
4416        case TypeIds.T_short :
4417            signature = ConstantPool.ValueOfIntSignature;
4418            break;
4419        case TypeIds.T_long :
4420            signature = ConstantPool.ValueOfLongSignature;
4421            argCount = 2;
4422            break;
4423        case TypeIds.T_float :
4424            signature = ConstantPool.ValueOfFloatSignature;
4425            break;
4426        case TypeIds.T_double :
4427            signature = ConstantPool.ValueOfDoubleSignature;
4428            argCount = 2;
4429            break;
4430        case TypeIds.T_char :
4431            signature = ConstantPool.ValueOfCharSignature;
4432            break;
4433        case TypeIds.T_boolean :
4434            signature = ConstantPool.ValueOfBooleanSignature;
4435            break;
4436        case TypeIds.T_JavaLangObject :
4437        case TypeIds.T_JavaLangString :
4438        case TypeIds.T_null :
4439        case TypeIds.T_undefined :
4440            signature = ConstantPool.ValueOfObjectSignature;
4441            break;
4442    }
4443    this.invoke(
4444            Opcodes.OPC_invokestatic,
4445            argCount, // argCount
4446
1, // return type size
4447
ConstantPool.JavaLangStringConstantPoolName,
4448            ConstantPool.ValueOf,
4449            signature);
4450}
4451public void invokeSystemArraycopy() {
4452    // invokestatic #21 <Method java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>
4453
if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V"); //$NON-NLS-1$
4454
this.invoke(
4455            Opcodes.OPC_invokestatic,
4456            5, // argCount
4457
0, // return type size
4458
ConstantPool.JavaLangSystemConstantPoolName,
4459            ConstantPool.ArrayCopy,
4460            ConstantPool.ArrayCopySignature);
4461}
4462public void invokeThrowableGetMessage() {
4463    // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
4464
if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$
4465
this.invoke(
4466            Opcodes.OPC_invokevirtual,
4467            0, // argCount
4468
1, // return type size
4469
ConstantPool.JavaLangThrowableConstantPoolName,
4470            ConstantPool.GetMessage,
4471            ConstantPool.GetMessageSignature);
4472}
4473public void invokevirtual(MethodBinding methodBinding) {
4474    if (DEBUG) System.out.println(position + "\t\tinvokevirtual:"+methodBinding); //$NON-NLS-1$
4475
countLabels = 0;
4476    // initialized to 1 to take into account this immediately
4477
int argCount = 1;
4478    int id;
4479    if (classFileOffset + 2 >= bCodeStream.length) {
4480        resizeByteArray();
4481    }
4482    position++;
4483    bCodeStream[classFileOffset++] = Opcodes.OPC_invokevirtual;
4484    writeUnsignedShort(
4485        constantPool.literalIndexForMethod(
4486            methodBinding.constantPoolDeclaringClass(),
4487            methodBinding.selector,
4488            methodBinding.signature(classFile),
4489            false));
4490    for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
4491        if (((id = methodBinding.parameters[i].id) == TypeIds.T_double) || (id == TypeIds.T_long))
4492            argCount += 2;
4493        else
4494            argCount++;
4495    if (((id = methodBinding.returnType.id) == TypeIds.T_double) || (id == TypeIds.T_long))
4496        stackDepth += (2 - argCount);
4497    else
4498        if (id == TypeIds.T_void)
4499            stackDepth -= argCount;
4500        else
4501            stackDepth += (1 - argCount);
4502    if (stackDepth > stackMax)
4503        stackMax = stackDepth;
4504}
4505public void ior() {
4506    if (DEBUG) System.out.println(position + "\t\tior"); //$NON-NLS-1$
4507
countLabels = 0;
4508    stackDepth--;
4509    if (classFileOffset >= bCodeStream.length) {
4510        resizeByteArray();
4511    }
4512    position++;
4513    bCodeStream[classFileOffset++] = Opcodes.OPC_ior;
4514}
4515public void irem() {
4516    if (DEBUG) System.out.println(position + "\t\tirem"); //$NON-NLS-1$
4517
countLabels = 0;
4518    stackDepth--;
4519    if (classFileOffset >= bCodeStream.length) {
4520        resizeByteArray();
4521    }
4522    position++;
4523    bCodeStream[classFileOffset++] = Opcodes.OPC_irem;
4524}
4525public void ireturn() {
4526    if (DEBUG) System.out.println(position + "\t\tireturn"); //$NON-NLS-1$
4527
countLabels = 0;
4528    stackDepth--;
4529    // the stackDepth should be equal to 0
4530
if (classFileOffset >= bCodeStream.length) {
4531        resizeByteArray();
4532    }
4533    position++;
4534    bCodeStream[classFileOffset++] = Opcodes.OPC_ireturn;
4535    this.lastAbruptCompletion = this.position;
4536}
4537public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
4538    // Mirror of UnconditionalFlowInfo.isDefinitelyAssigned(..)
4539
if ((local.tagBits & TagBits.IsArgument) != 0) {
4540        return true;
4541    }
4542    if (initStateIndex == -1)
4543        return false;
4544    int localPosition = local.id + maxFieldCount;
4545    MethodScope methodScope = scope.methodScope();
4546    // id is zero-based
4547
if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
4548        return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 0; // use bits
4549
}
4550    // use extra vector
4551
long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
4552    if (extraInits == null)
4553        return false; // if vector not yet allocated, then not initialized
4554
int vectorIndex;
4555    if ((vectorIndex = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
4556        return false; // if not enough room in vector, then not initialized
4557
return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
4558}
4559public void ishl() {
4560    if (DEBUG) System.out.println(position + "\t\tishl"); //$NON-NLS-1$
4561
countLabels = 0;
4562    stackDepth--;
4563    if (classFileOffset >= bCodeStream.length) {
4564        resizeByteArray();
4565    }
4566    position++;
4567    bCodeStream[classFileOffset++] = Opcodes.OPC_ishl;
4568}
4569public void ishr() {
4570    if (DEBUG) System.out.println(position + "\t\tishr"); //$NON-NLS-1$
4571
countLabels = 0;
4572    stackDepth--;
4573    if (classFileOffset >= bCodeStream.length) {
4574        resizeByteArray();
4575    }
4576    position++;
4577    bCodeStream[classFileOffset++] = Opcodes.OPC_ishr;
4578}
4579public void istore(int iArg) {
4580    if (DEBUG) System.out.println(position + "\t\tistore:"+iArg); //$NON-NLS-1$
4581
countLabels = 0;
4582    stackDepth--;
4583    if (maxLocals <= iArg) {
4584        maxLocals = iArg + 1;
4585    }
4586    if (iArg > 255) { // Widen
4587
if (classFileOffset + 3 >= bCodeStream.length) {
4588            resizeByteArray();
4589        }
4590        position += 2;
4591        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
4592        bCodeStream[classFileOffset++] = Opcodes.OPC_istore;
4593        writeUnsignedShort(iArg);
4594    } else {
4595        if (classFileOffset + 1 >= bCodeStream.length) {
4596            resizeByteArray();
4597        }
4598        position += 2;
4599        bCodeStream[classFileOffset++] = Opcodes.OPC_istore;
4600        bCodeStream[classFileOffset++] = (byte) iArg;
4601    }
4602}
4603public void istore_0() {
4604    if (DEBUG) System.out.println(position + "\t\tistore_0"); //$NON-NLS-1$
4605
countLabels = 0;
4606    stackDepth--;
4607    if (maxLocals == 0) {
4608        maxLocals = 1;
4609    }
4610    if (classFileOffset >= bCodeStream.length) {
4611        resizeByteArray();
4612    }
4613    position++;
4614    bCodeStream[classFileOffset++] = Opcodes.OPC_istore_0;
4615}
4616public void istore_1() {
4617    if (DEBUG) System.out.println(position + "\t\tistore_1"); //$NON-NLS-1$
4618
countLabels = 0;
4619    stackDepth--;
4620    if (maxLocals <= 1) {
4621        maxLocals = 2;
4622    }
4623    if (classFileOffset >= bCodeStream.length) {
4624        resizeByteArray();
4625    }
4626    position++;
4627    bCodeStream[classFileOffset++] = Opcodes.OPC_istore_1;
4628}
4629public void istore_2() {
4630    if (DEBUG) System.out.println(position + "\t\tistore_2"); //$NON-NLS-1$
4631
countLabels = 0;
4632    stackDepth--;
4633    if (maxLocals <= 2) {
4634        maxLocals = 3;
4635    }
4636    if (classFileOffset >= bCodeStream.length) {
4637        resizeByteArray();
4638    }
4639    position++;
4640    bCodeStream[classFileOffset++] = Opcodes.OPC_istore_2;
4641}
4642public void istore_3() {
4643    if (DEBUG) System.out.println(position + "\t\tistore_3"); //$NON-NLS-1$
4644
countLabels = 0;
4645    stackDepth--;
4646    if (maxLocals <= 3) {
4647        maxLocals = 4;
4648    }
4649    if (classFileOffset >= bCodeStream.length) {
4650        resizeByteArray();
4651    }
4652    position++;
4653    bCodeStream[classFileOffset++] = Opcodes.OPC_istore_3;
4654}
4655public void isub() {
4656    if (DEBUG) System.out.println(position + "\t\tisub"); //$NON-NLS-1$
4657
countLabels = 0;
4658    stackDepth--;
4659    if (classFileOffset >= bCodeStream.length) {
4660        resizeByteArray();
4661    }
4662    position++;
4663    bCodeStream[classFileOffset++] = Opcodes.OPC_isub;
4664}
4665public void iushr() {
4666    if (DEBUG) System.out.println(position + "\t\tiushr"); //$NON-NLS-1$
4667
countLabels = 0;
4668    stackDepth--;
4669    if (classFileOffset >= bCodeStream.length) {
4670        resizeByteArray();
4671    }
4672    position++;
4673    bCodeStream[classFileOffset++] = Opcodes.OPC_iushr;
4674}
4675public void ixor() {
4676    if (DEBUG) System.out.println(position + "\t\tixor"); //$NON-NLS-1$
4677
countLabels = 0;
4678    stackDepth--;
4679    if (classFileOffset >= bCodeStream.length) {
4680        resizeByteArray();
4681    }
4682    position++;
4683    bCodeStream[classFileOffset++] = Opcodes.OPC_ixor;
4684}
4685final public void jsr(BranchLabel lbl) {
4686    if (this.wideMode) {
4687        this.jsr_w(lbl);
4688        return;
4689    }
4690    if (DEBUG) System.out.println(position + "\t\tjsr"+lbl); //$NON-NLS-1$
4691
countLabels = 0;
4692    if (classFileOffset >= bCodeStream.length) {
4693        resizeByteArray();
4694    }
4695    position++;
4696    bCodeStream[classFileOffset++] = Opcodes.OPC_jsr;
4697    lbl.branch();
4698}
4699final public void jsr_w(BranchLabel lbl) {
4700    if (DEBUG) System.out.println(position + "\t\tjsr_w"+lbl); //$NON-NLS-1$
4701
countLabels = 0;
4702    if (classFileOffset >= bCodeStream.length) {
4703        resizeByteArray();
4704    }
4705    position++;
4706    bCodeStream[classFileOffset++] = Opcodes.OPC_jsr_w;
4707    lbl.branchWide();
4708}
4709public void l2d() {
4710    if (DEBUG) System.out.println(position + "\t\tl2d"); //$NON-NLS-1$
4711
countLabels = 0;
4712    if (classFileOffset >= bCodeStream.length) {
4713        resizeByteArray();
4714    }
4715    position++;
4716    bCodeStream[classFileOffset++] = Opcodes.OPC_l2d;
4717}
4718public void l2f() {
4719    if (DEBUG) System.out.println(position + "\t\tl2f"); //$NON-NLS-1$
4720
countLabels = 0;
4721    stackDepth--;
4722    if (classFileOffset >= bCodeStream.length) {
4723        resizeByteArray();
4724    }
4725    position++;
4726    bCodeStream[classFileOffset++] = Opcodes.OPC_l2f;
4727}
4728public void l2i() {
4729    if (DEBUG) System.out.println(position + "\t\tl2i"); //$NON-NLS-1$
4730
countLabels = 0;
4731    stackDepth--;
4732    if (classFileOffset >= bCodeStream.length) {
4733        resizeByteArray();
4734    }
4735    position++;
4736    bCodeStream[classFileOffset++] = Opcodes.OPC_l2i;
4737}
4738public void ladd() {
4739    if (DEBUG) System.out.println(position + "\t\tladd"); //$NON-NLS-1$
4740
countLabels = 0;
4741    stackDepth -= 2;
4742    if (classFileOffset >= bCodeStream.length) {
4743        resizeByteArray();
4744    }
4745    position++;
4746    bCodeStream[classFileOffset++] = Opcodes.OPC_ladd;
4747}
4748public void laload() {
4749    if (DEBUG) System.out.println(position + "\t\tlaload"); //$NON-NLS-1$
4750
countLabels = 0;
4751    if (classFileOffset >= bCodeStream.length) {
4752        resizeByteArray();
4753    }
4754    position++;
4755    bCodeStream[classFileOffset++] = Opcodes.OPC_laload;
4756}
4757public void land() {
4758    if (DEBUG) System.out.println(position + "\t\tland"); //$NON-NLS-1$
4759
countLabels = 0;
4760    stackDepth -= 2;
4761    if (classFileOffset >= bCodeStream.length) {
4762        resizeByteArray();
4763    }
4764    position++;
4765    bCodeStream[classFileOffset++] = Opcodes.OPC_land;
4766}
4767public void lastore() {
4768    if (DEBUG) System.out.println(position + "\t\tlastore"); //$NON-NLS-1$
4769
countLabels = 0;
4770    stackDepth -= 4;
4771    if (classFileOffset >= bCodeStream.length) {
4772        resizeByteArray();
4773    }
4774    position++;
4775    bCodeStream[classFileOffset++] = Opcodes.OPC_lastore;
4776}
4777public void lcmp() {
4778    if (DEBUG) System.out.println(position + "\t\tlcmp"); //$NON-NLS-1$
4779
countLabels = 0;
4780    stackDepth -= 3;
4781    if (classFileOffset >= bCodeStream.length) {
4782        resizeByteArray();
4783    }
4784    position++;
4785    bCodeStream[classFileOffset++] = Opcodes.OPC_lcmp;
4786}
4787public void lconst_0() {
4788    if (DEBUG) System.out.println(position + "\t\tlconst_0"); //$NON-NLS-1$
4789
countLabels = 0;
4790    stackDepth += 2;
4791    if (stackDepth > stackMax)
4792        stackMax = stackDepth;
4793    if (classFileOffset >= bCodeStream.length) {
4794        resizeByteArray();
4795    }
4796    position++;
4797    bCodeStream[classFileOffset++] = Opcodes.OPC_lconst_0;
4798}
4799public void lconst_1() {
4800    if (DEBUG) System.out.println(position + "\t\tlconst_1"); //$NON-NLS-1$
4801
countLabels = 0;
4802    stackDepth += 2;
4803    if (stackDepth > stackMax)
4804        stackMax = stackDepth;
4805    if (classFileOffset >= bCodeStream.length) {
4806        resizeByteArray();
4807    }
4808    position++;
4809    bCodeStream[classFileOffset++] = Opcodes.OPC_lconst_1;
4810}
4811public void ldc(float constant) {
4812    countLabels = 0;
4813    int index = constantPool.literalIndex(constant);
4814    stackDepth++;
4815    if (stackDepth > stackMax)
4816        stackMax = stackDepth;
4817    if (index > 255) {
4818        if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4819
// Generate a ldc_w
4820
if (classFileOffset + 2 >= bCodeStream.length) {
4821            resizeByteArray();
4822        }
4823        position++;
4824        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
4825        writeUnsignedShort(index);
4826    } else {
4827        if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4828
// Generate a ldc
4829
if (classFileOffset + 1 >= bCodeStream.length) {
4830            resizeByteArray();
4831        }
4832        position += 2;
4833        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
4834        bCodeStream[classFileOffset++] = (byte) index;
4835    }
4836}
4837public void ldc(int constant) {
4838    countLabels = 0;
4839    int index = constantPool.literalIndex(constant);
4840    stackDepth++;
4841    if (stackDepth > stackMax)
4842        stackMax = stackDepth;
4843    if (index > 255) {
4844        if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4845
// Generate a ldc_w
4846
if (classFileOffset + 2 >= bCodeStream.length) {
4847            resizeByteArray();
4848        }
4849        position++;
4850        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
4851        writeUnsignedShort(index);
4852    } else {
4853        if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4854
// Generate a ldc
4855
if (classFileOffset + 1 >= bCodeStream.length) {
4856            resizeByteArray();
4857        }
4858        position += 2;
4859        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
4860        bCodeStream[classFileOffset++] = (byte) index;
4861    }
4862}
4863public void ldc(String JavaDoc constant) {
4864    countLabels = 0;
4865    int currentCodeStreamPosition = position;
4866    char[] constantChars = constant.toCharArray();
4867    int index = constantPool.literalIndexForLdc(constantChars);
4868    if (index > 0) {
4869        // the string already exists inside the constant pool
4870
// we reuse the same index
4871
this.ldcForIndex(index, constantChars);
4872    } else {
4873        // the string is too big to be utf8-encoded in one pass.
4874
// we have to split it into different pieces.
4875
// first we clean all side-effects due to the code above
4876
// this case is very rare, so we can afford to lose time to handle it
4877
position = currentCodeStreamPosition;
4878        int i = 0;
4879        int length = 0;
4880        int constantLength = constant.length();
4881        byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
4882        int utf8encodingLength = 0;
4883        while ((length < 65532) && (i < constantLength)) {
4884            char current = constantChars[i];
4885            // we resize the byte array immediately if necessary
4886
if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
4887                System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
4888            }
4889            if ((current >= 0x0001) && (current <= 0x007F)) {
4890                // we only need one byte: ASCII table
4891
utf8encoding[length++] = (byte) current;
4892            } else {
4893                if (current > 0x07FF) {
4894                    // we need 3 bytes
4895
utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
4896
utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
4897
utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4898
} else {
4899                    // we can be 0 or between 0x0080 and 0x07FF
4900
// In that case we only need 2 bytes
4901
utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
4902
utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4903
}
4904            }
4905            i++;
4906        }
4907        // check if all the string is encoded (PR 1PR2DWJ)
4908
// the string is too big to be encoded in one pass
4909
newStringContatenation();
4910        dup();
4911        // write the first part
4912
char[] subChars = new char[i];
4913        System.arraycopy(constantChars, 0, subChars, 0, i);
4914        System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
4915        index = constantPool.literalIndex(subChars, utf8encoding);
4916        this.ldcForIndex(index, subChars);
4917        // write the remaining part
4918
invokeStringConcatenationStringConstructor();
4919        while (i < constantLength) {
4920            length = 0;
4921            utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
4922            int startIndex = i;
4923            while ((length < 65532) && (i < constantLength)) {
4924                char current = constantChars[i];
4925                // we resize the byte array immediately if necessary
4926
if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
4927                    System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
4928                }
4929                if ((current >= 0x0001) && (current <= 0x007F)) {
4930                    // we only need one byte: ASCII table
4931
utf8encoding[length++] = (byte) current;
4932                } else {
4933                    if (current > 0x07FF) {
4934                        // we need 3 bytes
4935
utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
4936
utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
4937
utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4938
} else {
4939                        // we can be 0 or between 0x0080 and 0x07FF
4940
// In that case we only need 2 bytes
4941
utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
4942
utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4943
}
4944                }
4945                i++;
4946            }
4947            // the next part is done
4948
int newCharLength = i - startIndex;
4949            subChars = new char[newCharLength];
4950            System.arraycopy(constantChars, startIndex, subChars, 0, newCharLength);
4951            System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
4952            index = constantPool.literalIndex(subChars, utf8encoding);
4953            this.ldcForIndex(index, subChars);
4954            // now on the stack it should be a StringBuffer and a string.
4955
invokeStringConcatenationAppendForType(TypeIds.T_JavaLangString);
4956        }
4957        invokeStringConcatenationToString();
4958        invokeStringIntern();
4959    }
4960}
4961public void ldc(TypeBinding typeBinding) {
4962    countLabels = 0;
4963    int index = constantPool.literalIndexForType(typeBinding);
4964    stackDepth++;
4965    if (stackDepth > stackMax)
4966        stackMax = stackDepth;
4967    if (index > 255) {
4968        if (DEBUG) System.out.println(position + "\t\tldc_w:"+ typeBinding); //$NON-NLS-1$
4969
// Generate a ldc_w
4970
if (classFileOffset + 2 >= bCodeStream.length) {
4971            resizeByteArray();
4972        }
4973        position++;
4974        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
4975        writeUnsignedShort(index);
4976    } else {
4977        if (DEBUG) System.out.println(position + "\t\tldw:"+ typeBinding); //$NON-NLS-1$
4978
// Generate a ldc
4979
if (classFileOffset + 1 >= bCodeStream.length) {
4980            resizeByteArray();
4981        }
4982        position += 2;
4983        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
4984        bCodeStream[classFileOffset++] = (byte) index;
4985    }
4986}
4987public void ldc2_w(double constant) {
4988    if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
4989
countLabels = 0;
4990    int index = constantPool.literalIndex(constant);
4991    stackDepth += 2;
4992    if (stackDepth > stackMax)
4993        stackMax = stackDepth;
4994    // Generate a ldc2_w
4995
if (classFileOffset + 2 >= bCodeStream.length) {
4996        resizeByteArray();
4997    }
4998    position++;
4999    bCodeStream[classFileOffset++] = Opcodes.OPC_ldc2_w;
5000    writeUnsignedShort(index);
5001}
5002public void ldc2_w(long constant) {
5003    if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
5004
countLabels = 0;
5005    int index = constantPool.literalIndex(constant);
5006    stackDepth += 2;
5007    if (stackDepth > stackMax)
5008        stackMax = stackDepth;
5009    // Generate a ldc2_w
5010
if (classFileOffset + 2 >= bCodeStream.length) {
5011        resizeByteArray();
5012    }
5013    position++;
5014    bCodeStream[classFileOffset++] = Opcodes.OPC_ldc2_w;
5015    writeUnsignedShort(index);
5016}
5017public void ldcForIndex(int index, char[] constant) {
5018    stackDepth++;
5019    if (stackDepth > stackMax) {
5020        stackMax = stackDepth;
5021    }
5022    if (index > 255) {
5023        // Generate a ldc_w
5024
if (DEBUG) System.out.println(position + "\t\tldc_w:"+ new String JavaDoc(constant)); //$NON-NLS-1$
5025
if (classFileOffset + 2 >= bCodeStream.length) {
5026            resizeByteArray();
5027        }
5028        position++;
5029        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc_w;
5030        writeUnsignedShort(index);
5031    } else {
5032        // Generate a ldc
5033
if (DEBUG) System.out.println(position + "\t\tldc:"+ new String JavaDoc(constant)); //$NON-NLS-1$
5034
if (classFileOffset + 1 >= bCodeStream.length) {
5035            resizeByteArray();
5036        }
5037        position += 2;
5038        bCodeStream[classFileOffset++] = Opcodes.OPC_ldc;
5039        bCodeStream[classFileOffset++] = (byte) index;
5040    }
5041}
5042public void ldiv() {
5043    if (DEBUG) System.out.println(position + "\t\tldiv"); //$NON-NLS-1$
5044
countLabels = 0;
5045    stackDepth -= 2;
5046    if (classFileOffset >= bCodeStream.length) {
5047        resizeByteArray();
5048    }
5049    position++;
5050    bCodeStream[classFileOffset++] = Opcodes.OPC_ldiv;
5051}
5052public void lload(int iArg) {
5053    if (DEBUG) System.out.println(position + "\t\tlload:"+iArg); //$NON-NLS-1$
5054
countLabels = 0;
5055    stackDepth += 2;
5056    if (maxLocals <= iArg + 1) {
5057        maxLocals = iArg + 2;
5058    }
5059    if (stackDepth > stackMax)
5060        stackMax = stackDepth;
5061    if (iArg > 255) { // Widen
5062
if (classFileOffset + 3 >= bCodeStream.length) {
5063            resizeByteArray();
5064        }
5065        position += 2;
5066        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
5067        bCodeStream[classFileOffset++] = Opcodes.OPC_lload;
5068        writeUnsignedShort(iArg);
5069    } else {
5070        if (classFileOffset + 1 >= bCodeStream.length) {
5071            resizeByteArray();
5072        }
5073        position += 2;
5074        bCodeStream[classFileOffset++] = Opcodes.OPC_lload;
5075        bCodeStream[classFileOffset++] = (byte) iArg;
5076    }
5077}
5078public void lload_0() {
5079    if (DEBUG) System.out.println(position + "\t\tlload_0"); //$NON-NLS-1$
5080
countLabels = 0;
5081    stackDepth += 2;
5082    if (maxLocals < 2) {
5083        maxLocals = 2;
5084    }
5085    if (stackDepth > stackMax)
5086        stackMax = stackDepth;
5087    if (classFileOffset >= bCodeStream.length) {
5088        resizeByteArray();
5089    }
5090    position++;
5091    bCodeStream[classFileOffset++] = Opcodes.OPC_lload_0;
5092}
5093public void lload_1() {
5094    if (DEBUG) System.out.println(position + "\t\tlload_1"); //$NON-NLS-1$
5095
countLabels = 0;
5096    stackDepth += 2;
5097    if (maxLocals < 3) {
5098        maxLocals = 3;
5099    }
5100    if (stackDepth > stackMax)
5101        stackMax = stackDepth;
5102    if (classFileOffset >= bCodeStream.length) {
5103        resizeByteArray();
5104    }
5105    position++;
5106    bCodeStream[classFileOffset++] = Opcodes.OPC_lload_1;
5107}
5108public void lload_2() {
5109    if (DEBUG) System.out.println(position + "\t\tlload_2"); //$NON-NLS-1$
5110
countLabels = 0;
5111    stackDepth += 2;
5112    if (maxLocals < 4) {
5113        maxLocals = 4;
5114    }
5115    if (stackDepth > stackMax)
5116        stackMax = stackDepth;
5117    if (classFileOffset >= bCodeStream.length) {
5118        resizeByteArray();
5119    }
5120    position++;
5121    bCodeStream[classFileOffset++] = Opcodes.OPC_lload_2;
5122}
5123public void lload_3() {
5124    if (DEBUG) System.out.println(position + "\t\tlload_3"); //$NON-NLS-1$
5125
countLabels = 0;
5126    stackDepth += 2;
5127    if (maxLocals < 5) {
5128        maxLocals = 5;
5129    }
5130    if (stackDepth > stackMax)
5131        stackMax = stackDepth;
5132    if (classFileOffset >= bCodeStream.length) {
5133        resizeByteArray();
5134    }
5135    position++;
5136    bCodeStream[classFileOffset++] = Opcodes.OPC_lload_3;
5137}
5138public void lmul() {
5139    if (DEBUG) System.out.println(position + "\t\tlmul"); //$NON-NLS-1$
5140
countLabels = 0;
5141    stackDepth -= 2;
5142    if (classFileOffset >= bCodeStream.length) {
5143        resizeByteArray();
5144    }
5145    position++;
5146    bCodeStream[classFileOffset++] = Opcodes.OPC_lmul;
5147}
5148public void lneg() {
5149    if (DEBUG) System.out.println(position + "\t\tlneg"); //$NON-NLS-1$
5150
countLabels = 0;
5151    if (classFileOffset >= bCodeStream.length) {
5152        resizeByteArray();
5153    }
5154    position++;
5155    bCodeStream[classFileOffset++] = Opcodes.OPC_lneg;
5156}
5157public final void load(LocalVariableBinding localBinding) {
5158    load(localBinding.type, localBinding.resolvedPosition);
5159}
5160public final void load(TypeBinding typeBinding, int resolvedPosition) {
5161    countLabels = 0;
5162    // Using dedicated int bytecode
5163
switch(typeBinding.id) {
5164        case TypeIds.T_int :
5165        case TypeIds.T_byte :
5166        case TypeIds.T_char :
5167        case TypeIds.T_boolean :
5168        case TypeIds.T_short :
5169            switch (resolvedPosition) {
5170                case 0 :
5171                    this.iload_0();
5172                    break;
5173                case 1 :
5174                    this.iload_1();
5175                    break;
5176                case 2 :
5177                    this.iload_2();
5178                    break;
5179                case 3 :
5180                    this.iload_3();
5181                    break;
5182                //case -1 :
5183
// internal failure: trying to load variable not supposed to be generated
5184
// break;
5185
default :
5186                    this.iload(resolvedPosition);
5187            }
5188            break;
5189        case TypeIds.T_float :
5190            switch (resolvedPosition) {
5191                case 0 :
5192                    this.fload_0();
5193                    break;
5194                case 1 :
5195                    this.fload_1();
5196                    break;
5197                case 2 :
5198                    this.fload_2();
5199                    break;
5200                case 3 :
5201                    this.fload_3();
5202                    break;
5203                default :
5204                    this.fload(resolvedPosition);
5205            }
5206            break;
5207        case TypeIds.T_long :
5208            switch (resolvedPosition) {
5209                case 0 :
5210                    this.lload_0();
5211                    break;
5212                case 1 :
5213                    this.lload_1();
5214                    break;
5215                case 2 :
5216                    this.lload_2();
5217                    break;
5218                case 3 :
5219                    this.lload_3();
5220                    break;
5221                default :
5222                    this.lload(resolvedPosition);
5223            }
5224            break;
5225        case TypeIds.T_double :
5226            switch (resolvedPosition) {
5227                case 0 :
5228                    this.dload_0();
5229                    break;
5230                case 1 :
5231                    this.dload_1();
5232                    break;
5233                case 2 :
5234                    this.dload_2();
5235                    break;
5236                case 3 :
5237                    this.dload_3();
5238                    break;
5239                default :
5240                    this.dload(resolvedPosition);
5241            }
5242            break;
5243        default :
5244            switch (resolvedPosition) {
5245                case 0 :
5246                    this.aload_0();
5247                    break;
5248                case 1 :
5249                    this.aload_1();
5250                    break;
5251                case 2 :
5252                    this.aload_2();
5253                    break;
5254                case 3 :
5255                    this.aload_3();
5256                    break;
5257                default :
5258                    this.aload(resolvedPosition);
5259            }
5260    }
5261}
5262public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
5263    if (DEBUG) System.out.println(position + "\t\tlookupswitch"); //$NON-NLS-1$
5264
countLabels = 0;
5265    stackDepth--;
5266    int length = keys.length;
5267    int pos = position;
5268    defaultLabel.placeInstruction();
5269    for (int i = 0; i < length; i++) {
5270        casesLabel[i].placeInstruction();
5271    }
5272    if (classFileOffset >= bCodeStream.length) {
5273        resizeByteArray();
5274    }
5275    position++;
5276    bCodeStream[classFileOffset++] = Opcodes.OPC_lookupswitch;
5277    for (int i = (3 - (pos & 3)); i > 0; i--) { // faster than % 4
5278
if (classFileOffset >= bCodeStream.length) {
5279            resizeByteArray();
5280        }
5281        position++;
5282        bCodeStream[classFileOffset++] = 0;
5283    }
5284    defaultLabel.branch();
5285    writeSignedWord(length);
5286    for (int i = 0; i < length; i++) {
5287        writeSignedWord(keys[sortedIndexes[i]]);
5288        casesLabel[sortedIndexes[i]].branch();
5289    }
5290}
5291public void lor() {
5292    if (DEBUG) System.out.println(position + "\t\tlor"); //$NON-NLS-1$
5293
countLabels = 0;
5294    stackDepth -= 2;
5295    if (classFileOffset >= bCodeStream.length) {
5296        resizeByteArray();
5297    }
5298    position++;
5299    bCodeStream[classFileOffset++] = Opcodes.OPC_lor;
5300}
5301public void lrem() {
5302    if (DEBUG) System.out.println(position + "\t\tlrem"); //$NON-NLS-1$
5303
countLabels = 0;
5304    stackDepth -= 2;
5305    if (classFileOffset >= bCodeStream.length) {
5306        resizeByteArray();
5307    }
5308    position++;
5309    bCodeStream[classFileOffset++] = Opcodes.OPC_lrem;
5310}
5311public void lreturn() {
5312    if (DEBUG) System.out.println(position + "\t\tlreturn"); //$NON-NLS-1$
5313
countLabels = 0;
5314    stackDepth -= 2;
5315    // the stackDepth should be equal to 0
5316
if (classFileOffset >= bCodeStream.length) {
5317        resizeByteArray();
5318    }
5319    position++;
5320    bCodeStream[classFileOffset++] = Opcodes.OPC_lreturn;
5321    this.lastAbruptCompletion = this.position;
5322}
5323public void lshl() {
5324    if (DEBUG) System.out.println(position + "\t\tlshl"); //$NON-NLS-1$
5325
countLabels = 0;
5326    stackDepth--;
5327    if (classFileOffset >= bCodeStream.length) {
5328        resizeByteArray();
5329    }
5330    position++;
5331    bCodeStream[classFileOffset++] = Opcodes.OPC_lshl;
5332}
5333public void lshr() {
5334    if (DEBUG) System.out.println(position + "\t\tlshr"); //$NON-NLS-1$
5335
countLabels = 0;
5336    stackDepth--;
5337    if (classFileOffset >= bCodeStream.length) {
5338        resizeByteArray();
5339    }
5340    position++;
5341    bCodeStream[classFileOffset++] = Opcodes.OPC_lshr;
5342}
5343public void lstore(int iArg) {
5344    if (DEBUG) System.out.println(position + "\t\tlstore:"+iArg); //$NON-NLS-1$
5345
countLabels = 0;
5346    stackDepth -= 2;
5347    if (maxLocals <= iArg + 1) {
5348        maxLocals = iArg + 2;
5349    }
5350    if (iArg > 255) { // Widen
5351
if (classFileOffset + 3 >= bCodeStream.length) {
5352            resizeByteArray();
5353        }
5354        position += 2;
5355        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
5356        bCodeStream[classFileOffset++] = Opcodes.OPC_lstore;
5357        writeUnsignedShort(iArg);
5358    } else {
5359        if (classFileOffset + 1 >= bCodeStream.length) {
5360            resizeByteArray();
5361        }
5362        position += 2;
5363        bCodeStream[classFileOffset++] = Opcodes.OPC_lstore;
5364        bCodeStream[classFileOffset++] = (byte) iArg;
5365    }
5366}
5367public void lstore_0() {
5368    if (DEBUG) System.out.println(position + "\t\tlstore_0"); //$NON-NLS-1$
5369
countLabels = 0;
5370    stackDepth -= 2;
5371    if (maxLocals < 2) {
5372        maxLocals = 2;
5373    }
5374    if (classFileOffset >= bCodeStream.length) {
5375        resizeByteArray();
5376    }
5377    position++;
5378    bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_0;
5379}
5380public void lstore_1() {
5381    if (DEBUG) System.out.println(position + "\t\tlstore_1"); //$NON-NLS-1$
5382
countLabels = 0;
5383    stackDepth -= 2;
5384    if (maxLocals < 3) {
5385        maxLocals = 3;
5386    }
5387    if (classFileOffset >= bCodeStream.length) {
5388        resizeByteArray();
5389    }
5390    position++;
5391    bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_1;
5392}
5393public void lstore_2() {
5394    if (DEBUG) System.out.println(position + "\t\tlstore_2"); //$NON-NLS-1$
5395
countLabels = 0;
5396    stackDepth -= 2;
5397    if (maxLocals < 4) {
5398        maxLocals = 4;
5399    }
5400    if (classFileOffset >= bCodeStream.length) {
5401        resizeByteArray();
5402    }
5403    position++;
5404    bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_2;
5405}
5406public void lstore_3() {
5407    if (DEBUG) System.out.println(position + "\t\tlstore_3"); //$NON-NLS-1$
5408
countLabels = 0;
5409    stackDepth -= 2;
5410    if (maxLocals < 5) {
5411        maxLocals = 5;
5412    }
5413    if (classFileOffset >= bCodeStream.length) {
5414        resizeByteArray();
5415    }
5416    position++;
5417    bCodeStream[classFileOffset++] = Opcodes.OPC_lstore_3;
5418}
5419public void lsub() {
5420    if (DEBUG) System.out.println(position + "\t\tlsub"); //$NON-NLS-1$
5421
countLabels = 0;
5422    stackDepth -= 2;
5423    if (classFileOffset >= bCodeStream.length) {
5424        resizeByteArray();
5425    }
5426    position++;
5427    bCodeStream[classFileOffset++] = Opcodes.OPC_lsub;
5428}
5429public void lushr() {
5430    if (DEBUG) System.out.println(position + "\t\tlushr"); //$NON-NLS-1$
5431
countLabels = 0;
5432    stackDepth--;
5433    if (classFileOffset >= bCodeStream.length) {
5434        resizeByteArray();
5435    }
5436    position++;
5437    bCodeStream[classFileOffset++] = Opcodes.OPC_lushr;
5438}
5439public void lxor() {
5440    if (DEBUG) System.out.println(position + "\t\tlxor"); //$NON-NLS-1$
5441
countLabels = 0;
5442    stackDepth -= 2;
5443    if (classFileOffset >= bCodeStream.length) {
5444        resizeByteArray();
5445    }
5446    position++;
5447    bCodeStream[classFileOffset++] = Opcodes.OPC_lxor;
5448}
5449public void monitorenter() {
5450    if (DEBUG) System.out.println(position + "\t\tmonitorenter"); //$NON-NLS-1$
5451
countLabels = 0;
5452    stackDepth--;
5453    if (classFileOffset >= bCodeStream.length) {
5454        resizeByteArray();
5455    }
5456    position++;
5457    bCodeStream[classFileOffset++] = Opcodes.OPC_monitorenter;
5458}
5459public void monitorexit() {
5460    if (DEBUG) System.out.println(position + "\t\tmonitorexit"); //$NON-NLS-1$
5461
countLabels = 0;
5462    stackDepth--;
5463    if (classFileOffset >= bCodeStream.length) {
5464        resizeByteArray();
5465    }
5466    position++;
5467    bCodeStream[classFileOffset++] = Opcodes.OPC_monitorexit;
5468}
5469public void multianewarray(TypeBinding typeBinding, int dimensions) {
5470    if (DEBUG) System.out.println(position + "\t\tmultinewarray:"+typeBinding+","+dimensions); //$NON-NLS-1$ //$NON-NLS-2$
5471
countLabels = 0;
5472    stackDepth += (1 - dimensions);
5473    if (classFileOffset + 3 >= bCodeStream.length) {
5474        resizeByteArray();
5475    }
5476    position += 2;
5477    bCodeStream[classFileOffset++] = Opcodes.OPC_multianewarray;
5478    writeUnsignedShort(constantPool.literalIndexForType(typeBinding));
5479    bCodeStream[classFileOffset++] = (byte) dimensions;
5480}
5481// We didn't call it new, because there is a conflit with the new keyword
5482
public void new_(TypeBinding typeBinding) {
5483    if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding.debugName()); //$NON-NLS-1$
5484
countLabels = 0;
5485    stackDepth++;
5486    if (stackDepth > stackMax)
5487        stackMax = stackDepth;
5488    if (classFileOffset + 2 >= bCodeStream.length) {
5489        resizeByteArray();
5490    }
5491    position++;
5492    bCodeStream[classFileOffset++] = Opcodes.OPC_new;
5493    writeUnsignedShort(constantPool.literalIndexForType(typeBinding));
5494}
5495public void newarray(int array_Type) {
5496    if (DEBUG) System.out.println(position + "\t\tnewarray:"+array_Type); //$NON-NLS-1$
5497
countLabels = 0;
5498    if (classFileOffset + 1 >= bCodeStream.length) {
5499        resizeByteArray();
5500    }
5501    position += 2;
5502    bCodeStream[classFileOffset++] = Opcodes.OPC_newarray;
5503    bCodeStream[classFileOffset++] = (byte) array_Type;
5504}
5505public void newArray(ArrayBinding arrayBinding) {
5506    TypeBinding component = arrayBinding.elementsType();
5507    switch (component.id) {
5508        case TypeIds.T_int :
5509            this.newarray(ClassFileConstants.INT_ARRAY);
5510            break;
5511        case TypeIds.T_byte :
5512            this.newarray(ClassFileConstants.BYTE_ARRAY);
5513            break;
5514        case TypeIds.T_boolean :
5515            this.newarray(ClassFileConstants.BOOLEAN_ARRAY);
5516            break;
5517        case TypeIds.T_short :
5518            this.newarray(ClassFileConstants.SHORT_ARRAY);
5519            break;
5520        case TypeIds.T_char :
5521            this.newarray(ClassFileConstants.CHAR_ARRAY);
5522            break;
5523        case TypeIds.T_long :
5524            this.newarray(ClassFileConstants.LONG_ARRAY);
5525            break;
5526        case TypeIds.T_float :
5527            this.newarray(ClassFileConstants.FLOAT_ARRAY);
5528            break;
5529        case TypeIds.T_double :
5530            this.newarray(ClassFileConstants.DOUBLE_ARRAY);
5531            break;
5532        default :
5533            this.anewarray(component);
5534    }
5535}
5536public void newJavaLangAssertionError() {
5537    // new: java.lang.AssertionError
5538
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.AssertionError"); //$NON-NLS-1$
5539
countLabels = 0;
5540    stackDepth++;
5541    if (stackDepth > stackMax)
5542        stackMax = stackDepth;
5543    if (classFileOffset + 2 >= bCodeStream.length) {
5544        resizeByteArray();
5545    }
5546    position++;
5547    bCodeStream[classFileOffset++] = Opcodes.OPC_new;
5548    writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName));
5549}
5550public void newJavaLangError() {
5551    // new: java.lang.Error
5552
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Error"); //$NON-NLS-1$
5553
countLabels = 0;
5554    stackDepth++;
5555    if (stackDepth > stackMax)
5556        stackMax = stackDepth;
5557    if (classFileOffset + 2 >= bCodeStream.length) {
5558        resizeByteArray();
5559    }
5560    position++;
5561    bCodeStream[classFileOffset++] = Opcodes.OPC_new;
5562    writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
5563}
5564public void newNoClassDefFoundError() {
5565    // new: java.lang.NoClassDefFoundError
5566
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$
5567
countLabels = 0;
5568    stackDepth++;
5569    if (stackDepth > stackMax)
5570        stackMax = stackDepth;
5571    if (classFileOffset + 2 >= bCodeStream.length) {
5572        resizeByteArray();
5573    }
5574    position++;
5575    bCodeStream[classFileOffset++] = Opcodes.OPC_new;
5576    writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName));
5577}
5578public void newStringContatenation() {
5579    // new: java.lang.StringBuffer
5580
// new: java.lang.StringBuilder
5581
if (DEBUG) {
5582        if (this.targetLevel >= ClassFileConstants.JDK1_5) {
5583            System.out.println(position + "\t\tnew: java.lang.StringBuilder"); //$NON-NLS-1$
5584
} else {
5585            System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$
5586
}
5587    }
5588    countLabels = 0;
5589    stackDepth++;
5590    if (stackDepth > stackMax) {
5591        stackMax = stackDepth;
5592    }
5593    if (classFileOffset + 2 >= bCodeStream.length) {
5594        resizeByteArray();
5595    }
5596    position++;
5597    bCodeStream[classFileOffset++] = Opcodes.OPC_new;
5598    if (this.targetLevel >= ClassFileConstants.JDK1_5) {
5599        writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName));
5600    } else {
5601        writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName));
5602    }
5603}
5604public void newWrapperFor(int typeID) {
5605    countLabels = 0;
5606    stackDepth++;
5607    if (stackDepth > stackMax)
5608        stackMax = stackDepth;
5609    if (classFileOffset + 2 >= bCodeStream.length) {
5610        resizeByteArray();
5611    }
5612    position++;
5613    bCodeStream[classFileOffset++] = Opcodes.OPC_new;
5614    switch (typeID) {
5615        case TypeIds.T_int : // new: java.lang.Integer
5616
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$
5617
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
5618            break;
5619        case TypeIds.T_boolean : // new: java.lang.Boolean
5620
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$
5621
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
5622            break;
5623        case TypeIds.T_byte : // new: java.lang.Byte
5624
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$
5625
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
5626            break;
5627        case TypeIds.T_char : // new: java.lang.Character
5628
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Character"); //$NON-NLS-1$
5629
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
5630            break;
5631        case TypeIds.T_float : // new: java.lang.Float
5632
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Float"); //$NON-NLS-1$
5633
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
5634            break;
5635        case TypeIds.T_double : // new: java.lang.Double
5636
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Double"); //$NON-NLS-1$
5637
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
5638            break;
5639        case TypeIds.T_short : // new: java.lang.Short
5640
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Short"); //$NON-NLS-1$
5641
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
5642            break;
5643        case TypeIds.T_long : // new: java.lang.Long
5644
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$
5645
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
5646            break;
5647        case TypeIds.T_void : // new: java.lang.Void
5648
if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$
5649
writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName));
5650    }
5651}
5652public void nop() {
5653    if (DEBUG) System.out.println(position + "\t\tnop"); //$NON-NLS-1$
5654
countLabels = 0;
5655    if (classFileOffset >= bCodeStream.length) {
5656        resizeByteArray();
5657    }
5658    position++;
5659    bCodeStream[classFileOffset++] = Opcodes.OPC_nop;
5660}
5661public void optimizeBranch(int oldPosition, BranchLabel lbl) {
5662    for (int i = 0; i < this.countLabels; i++) {
5663        BranchLabel label = this.labels[i];
5664        if (oldPosition == label.position) {
5665            label.position = position;
5666            if (label instanceof CaseLabel) {
5667                int offset = position - ((CaseLabel) label).instructionPosition;
5668                int[] forwardRefs = label.forwardReferences();
5669                for (int j = 0, length = label.forwardReferenceCount(); j < length; j++) {
5670                    int forwardRef = forwardRefs[j];
5671                    this.writeSignedWord(forwardRef, offset);
5672                }
5673            } else {
5674                int[] forwardRefs = label.forwardReferences();
5675                for (int j = 0, length = label.forwardReferenceCount(); j < length; j++) {
5676                    final int forwardRef = forwardRefs[j];
5677                    this.writePosition(lbl, forwardRef);
5678                }
5679            }
5680        }
5681    }
5682}
5683public void pop() {
5684    if (DEBUG) System.out.println(position + "\t\tpop"); //$NON-NLS-1$
5685
countLabels = 0;
5686    stackDepth--;
5687    if (classFileOffset >= bCodeStream.length) {
5688        resizeByteArray();
5689    }
5690    position++;
5691    bCodeStream[classFileOffset++] = Opcodes.OPC_pop;
5692}
5693public void pop2() {
5694    if (DEBUG) System.out.println(position + "\t\tpop2"); //$NON-NLS-1$
5695
countLabels = 0;
5696    stackDepth -= 2;
5697    if (classFileOffset >= bCodeStream.length) {
5698        resizeByteArray();
5699    }
5700    position++;
5701    bCodeStream[classFileOffset++] = Opcodes.OPC_pop2;
5702}
5703public void pushOnStack(TypeBinding binding) {
5704    if (++stackDepth > stackMax)
5705        stackMax = stackDepth;
5706}
5707public void putfield(FieldBinding fieldBinding) {
5708    if (DEBUG) System.out.println(position + "\t\tputfield:"+fieldBinding); //$NON-NLS-1$
5709
int returnTypeSize = 1;
5710    if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
5711        returnTypeSize = 2;
5712    }
5713    generateFieldAccess(
5714            Opcodes.OPC_putfield,
5715            returnTypeSize,
5716            fieldBinding.declaringClass,
5717            fieldBinding.name,
5718            fieldBinding.type);
5719}
5720public void putstatic(FieldBinding fieldBinding) {
5721    if (DEBUG) System.out.println(position + "\t\tputstatic:"+fieldBinding); //$NON-NLS-1$
5722
int returnTypeSize = 1;
5723    if ((fieldBinding.type.id == TypeIds.T_double) || (fieldBinding.type.id == TypeIds.T_long)) {
5724        returnTypeSize = 2;
5725    }
5726    generateFieldAccess(
5727            Opcodes.OPC_putstatic,
5728            returnTypeSize,
5729            fieldBinding.declaringClass,
5730            fieldBinding.name,
5731            fieldBinding.type);
5732}
5733public void record(LocalVariableBinding local) {
5734    if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) == 0)
5735        return;
5736    if (allLocalsCounter == locals.length) {
5737        // resize the collection
5738
System.arraycopy(locals, 0, locals = new LocalVariableBinding[allLocalsCounter + LOCALS_INCREMENT], 0, allLocalsCounter);
5739    }
5740    locals[allLocalsCounter++] = local;
5741    local.initializationPCs = new int[4];
5742    local.initializationCount = 0;
5743}
5744
5745public void recordExpressionType(TypeBinding typeBinding) {
5746    // nothing to do
5747
}
5748public void recordPositionsFrom(int startPC, int sourcePos) {
5749    this.recordPositionsFrom(startPC, sourcePos, false);
5750}
5751public void recordPositionsFrom(int startPC, int sourcePos, boolean widen) {
5752
5753    /* Record positions in the table, only if nothing has
5754     * already been recorded. Since we output them on the way
5755     * up (children first for more specific info)
5756     * The pcToSourceMap table is always sorted.
5757     */

5758
5759    if ((this.generateAttributes & ClassFileConstants.ATTR_LINES) == 0
5760            || sourcePos == 0
5761            || (startPC == position && !widen))
5762        return;
5763
5764    // Widening an existing entry that already has the same source positions
5765
if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
5766        // resize the array pcToSourceMap
5767
System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
5768    }
5769    int lineNumber = Util.getLineNumber(sourcePos, lineSeparatorPositions, 0, lineSeparatorPositions.length-1);
5770    // lastEntryPC represents the endPC of the lastEntry.
5771
if (pcToSourceMapSize > 0) {
5772        // in this case there is already an entry in the table
5773
if (pcToSourceMap[pcToSourceMapSize - 1] != lineNumber) {
5774            if (startPC <= lastEntryPC) {
5775                // we forgot to add an entry.
5776
// search if an existing entry exists for startPC
5777
int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5778                if (insertionIndex != -1) {
5779                    // there is no existing entry starting with startPC.
5780
int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
5781
/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
5782                        in this case it is relevant to widen this entry instead of creating a new one.
5783                        line1: this(a,
5784                          b,
5785                          c);
5786                        with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
5787                        aload0 bytecode. The first entry is the one for the argument a.
5788                        But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
5789                        So we widen the existing entry (if there is one) or we create a new entry with the startPC.
5790                    */

5791                    if (existingEntryIndex != -1) {
5792                        // widen existing entry
5793
pcToSourceMap[existingEntryIndex] = startPC;
5794                    } else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != lineNumber) {
5795                        // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
5796
System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
5797                        pcToSourceMap[insertionIndex++] = startPC;
5798                        pcToSourceMap[insertionIndex] = lineNumber;
5799                        pcToSourceMapSize += 2;
5800                    }
5801                } else if (position != lastEntryPC) { // no bytecode since last entry pc
5802
if (lastEntryPC == startPC || lastEntryPC == pcToSourceMap[pcToSourceMapSize - 2]) {
5803                        pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5804                    } else {
5805                        pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
5806                        pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5807                    }
5808                } else if (pcToSourceMap[pcToSourceMapSize - 1] < lineNumber && widen) {
5809                    // see if we can widen the existing entry
5810
pcToSourceMap[pcToSourceMapSize - 1] = lineNumber;
5811                }
5812            } else {
5813                // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
5814
pcToSourceMap[pcToSourceMapSize++] = startPC;
5815                pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5816            }
5817        } else {
5818            /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
5819               we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
5820            */

5821            if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
5822                int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5823                if (insertionIndex != -1) {
5824                    // widen the existing entry
5825
// we have to figure out if we need to move the last entry at another location to keep a sorted table
5826
/* First we need to check if at the insertion position there is not an existing entry
5827                     * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
5828                     * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
5829                     * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
5830                     */

5831                    if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == lineNumber))) {
5832                        if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
5833                            System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
5834                            pcToSourceMap[insertionIndex++] = startPC;
5835                            pcToSourceMap[insertionIndex] = lineNumber;
5836                        } else {
5837                            pcToSourceMap[pcToSourceMapSize - 2] = startPC;
5838                        }
5839                    }
5840                }
5841            }
5842        }
5843        lastEntryPC = position;
5844    } else {
5845        // record the first entry
5846
pcToSourceMap[pcToSourceMapSize++] = startPC;
5847        pcToSourceMap[pcToSourceMapSize++] = lineNumber;
5848        lastEntryPC = position;
5849    }
5850}
5851/**
5852 * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
5853 */

5854public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
5855    int length;
5856    if (exceptionLabelsCounter == (length = exceptionLabels.length)) {
5857        // resize the exception handlers table
5858
System.arraycopy(exceptionLabels, 0, exceptionLabels = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
5859    }
5860    // no need to resize. So just add the new exception label
5861
exceptionLabels[exceptionLabelsCounter++] = anExceptionLabel;
5862}
5863public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
5864    // given some flow info, make sure we did not loose some variables initialization
5865
// if this happens, then we must update their pc entries to reflect it in debug attributes
5866
if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) == 0)
5867        return;
5868    for (int i = 0; i < visibleLocalsCount; i++) {
5869        LocalVariableBinding localBinding = visibleLocals[i];
5870        if (localBinding != null && !isDefinitelyAssigned(scope, initStateIndex, localBinding) && localBinding.initializationCount > 0) {
5871            localBinding.recordInitializationEndPC(position);
5872        }
5873    }
5874}
5875/**
5876 * Remove all entries in pcToSourceMap table that are beyond this.position
5877 */

5878public void removeUnusedPcToSourceMapEntries() {
5879    if (this.pcToSourceMapSize != 0) {
5880        while (this.pcToSourceMapSize >= 2 && this.pcToSourceMap[this.pcToSourceMapSize - 2] > this.position) {
5881            this.pcToSourceMapSize -= 2;
5882        }
5883    }
5884}
5885public void removeVariable(LocalVariableBinding localBinding) {
5886    if (localBinding == null) return;
5887    if (localBinding.initializationCount > 0) {
5888        localBinding.recordInitializationEndPC(position);
5889    }
5890    for (int i = visibleLocalsCount - 1; i >= 0; i--) {
5891        LocalVariableBinding visibleLocal = visibleLocals[i];
5892        if (visibleLocal == localBinding){
5893            visibleLocals[i] = null; // this variable is no longer visible afterwards
5894
return;
5895        }
5896    }
5897}
5898/**
5899 * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
5900 * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
5901 */

5902public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
5903    init(targetClassFile);
5904    this.methodDeclaration = referenceMethod;
5905    this.preserveUnusedLocals = referenceMethod.scope.compilerOptions().preserveAllLocalVariables;
5906    initializeMaxLocals(referenceMethod.binding);
5907}
5908public void reset(ClassFile givenClassFile) {
5909    this.targetLevel = givenClassFile.targetJDK;
5910    this.generateAttributes = givenClassFile.produceAttributes;
5911    if ((givenClassFile.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
5912        this.lineSeparatorPositions = givenClassFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.getLineSeparatorPositions();
5913    }
5914}
5915/**
5916 * @param targetClassFile The given classfile to reset the code stream
5917 */

5918public void resetForProblemClinit(ClassFile targetClassFile) {
5919    init(targetClassFile);
5920    initializeMaxLocals(null);
5921}
5922private final void resizeByteArray() {
5923    int length = bCodeStream.length;
5924    int requiredSize = length + length;
5925    if (classFileOffset >= requiredSize) {
5926        // must be sure to grow enough
5927
requiredSize = classFileOffset + length;
5928    }
5929    System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length);
5930}
5931final public void ret(int index) {
5932    if (DEBUG) System.out.println(position + "\t\tret:"+index); //$NON-NLS-1$
5933
countLabels = 0;
5934    if (index > 255) { // Widen
5935
if (classFileOffset + 3 >= bCodeStream.length) {
5936            resizeByteArray();
5937        }
5938        position += 2;
5939        bCodeStream[classFileOffset++] = Opcodes.OPC_wide;
5940        bCodeStream[classFileOffset++] = Opcodes.OPC_ret;
5941        writeUnsignedShort(index);
5942    } else { // Don't Widen
5943
if (classFileOffset + 1 >= bCodeStream.length) {
5944            resizeByteArray();
5945        }
5946        position += 2;
5947        bCodeStream[classFileOffset++] = Opcodes.OPC_ret;
5948        bCodeStream[classFileOffset++] = (byte) index;
5949    }
5950}
5951public void return_() {
5952    if (DEBUG) System.out.println(position + "\t\treturn"); //$NON-NLS-1$
5953
countLabels = 0;
5954    // the stackDepth should be equal to 0
5955
if (classFileOffset >= bCodeStream.length) {
5956        resizeByteArray();
5957    }
5958    position++;
5959    bCodeStream[classFileOffset++] = Opcodes.OPC_return;
5960    this.lastAbruptCompletion = this.position;
5961}
5962public void saload() {
5963    if (DEBUG) System.out.println(position + "\t\tsaload"); //$NON-NLS-1$
5964
countLabels = 0;
5965    stackDepth--;
5966    if (classFileOffset >= bCodeStream.length) {
5967        resizeByteArray();
5968    }
5969    position++;
5970    bCodeStream[classFileOffset++] = Opcodes.OPC_saload;
5971}
5972public void sastore() {
5973    if (DEBUG) System.out.println(position + "\t\tsastore"); //$NON-NLS-1$
5974
countLabels = 0;
5975    stackDepth -= 3;
5976    if (classFileOffset >= bCodeStream.length) {
5977        resizeByteArray();
5978    }
5979    position++;
5980    bCodeStream[classFileOffset++] = Opcodes.OPC_sastore;
5981}
5982/**
5983 * @param operatorConstant int
5984 * @param type_ID int
5985 */

5986public void sendOperator(int operatorConstant, int type_ID) {
5987    switch (type_ID) {
5988        case TypeIds.T_int :
5989        case TypeIds.T_boolean :
5990        case TypeIds.T_char :
5991        case TypeIds.T_byte :
5992        case TypeIds.T_short :
5993            switch (operatorConstant) {
5994                case OperatorIds.PLUS :
5995                    this.iadd();
5996                    break;
5997                case OperatorIds.MINUS :
5998                    this.isub();
5999                    break;
6000                case OperatorIds.MULTIPLY :
6001                    this.imul();
6002                    break;
6003                case OperatorIds.DIVIDE :
6004                    this.idiv();
6005                    break;
6006                case OperatorIds.REMAINDER :
6007                    this.irem();
6008                    break;
6009                case OperatorIds.LEFT_SHIFT :
6010                    this.ishl();
6011                    break;
6012                case OperatorIds.RIGHT_SHIFT :
6013                    this.ishr();
6014                    break;
6015                case OperatorIds.UNSIGNED_RIGHT_SHIFT :
6016                    this.iushr();
6017                    break;
6018                case OperatorIds.AND :
6019                    this.iand();
6020                    break;
6021                case OperatorIds.OR :
6022                    this.ior();
6023                    break;
6024                case OperatorIds.XOR :
6025                    this.ixor();
6026                    break;
6027            }
6028            break;
6029        case TypeIds.T_long :
6030            switch (operatorConstant) {
6031                case OperatorIds.PLUS :
6032                    this.ladd();
6033                    break;
6034                case OperatorIds.MINUS :
6035                    this.lsub();
6036                    break;
6037                case OperatorIds.MULTIPLY :
6038                    this.lmul();
6039                    break;
6040                case OperatorIds.DIVIDE :
6041                    this.ldiv();
6042                    break;
6043                case OperatorIds.REMAINDER :
6044                    this.lrem();
6045                    break;
6046                case OperatorIds.LEFT_SHIFT :
6047                    this.lshl();
6048                    break;
6049                case OperatorIds.RIGHT_SHIFT :
6050                    this.lshr();
6051                    break;
6052                case OperatorIds.UNSIGNED_RIGHT_SHIFT :
6053                    this.lushr();
6054                    break;
6055                case OperatorIds.AND :
6056                    this.land();
6057                    break;
6058                case OperatorIds.OR :
6059                    this.lor();
6060                    break;
6061                case OperatorIds.XOR :
6062                    this.lxor();
6063                    break;
6064            }
6065            break;
6066        case TypeIds.T_float :
6067            switch (operatorConstant) {
6068                case OperatorIds.PLUS :
6069                    this.fadd();
6070                    break;
6071                case OperatorIds.MINUS :
6072                    this.fsub();
6073                    break;
6074                case OperatorIds.MULTIPLY :
6075                    this.fmul();
6076                    break;
6077                case OperatorIds.DIVIDE :
6078                    this.fdiv();
6079                    break;
6080                case OperatorIds.REMAINDER :
6081                    this.frem();
6082            }
6083            break;
6084        case TypeIds.T_double :
6085            switch (operatorConstant) {
6086                case OperatorIds.PLUS :
6087                    this.dadd();
6088                    break;
6089                case OperatorIds.MINUS :
6090                    this.dsub();
6091                    break;
6092                case OperatorIds.MULTIPLY :
6093                    this.dmul();
6094                    break;
6095                case OperatorIds.DIVIDE :
6096                    this.ddiv();
6097                    break;
6098                case OperatorIds.REMAINDER :
6099                    this.drem();
6100            }
6101    }
6102}
6103
6104public void sipush(int s) {
6105    if (DEBUG) System.out.println(position + "\t\tsipush:"+s); //$NON-NLS-1$
6106
countLabels = 0;
6107    stackDepth++;
6108    if (stackDepth > stackMax)
6109        stackMax = stackDepth;
6110    if (classFileOffset >= bCodeStream.length) {
6111        resizeByteArray();
6112    }
6113    position++;
6114    bCodeStream[classFileOffset++] = Opcodes.OPC_sipush;
6115    writeSignedShort(s);
6116}
6117public void store(LocalVariableBinding localBinding, boolean valueRequired) {
6118    int localPosition = localBinding.resolvedPosition;
6119    // Using dedicated int bytecode
6120
switch(localBinding.type.id) {
6121        case TypeIds.T_int :
6122        case TypeIds.T_char :
6123        case TypeIds.T_byte :
6124        case TypeIds.T_short :
6125        case TypeIds.T_boolean :
6126            if (valueRequired)
6127                this.dup();
6128            switch (localPosition) {
6129                case 0 :
6130                    this.istore_0();
6131                    break;
6132                case 1 :
6133                    this.istore_1();
6134                    break;
6135                case 2 :
6136                    this.istore_2();
6137                    break;
6138                case 3 :
6139                    this.istore_3();
6140                    break;
6141                //case -1 :
6142
// internal failure: trying to store into variable not supposed to be generated
6143
// break;
6144
default :
6145                    this.istore(localPosition);
6146            }
6147            break;
6148        case TypeIds.T_float :
6149            if (valueRequired)
6150                this.dup();
6151            switch (localPosition) {
6152                case 0 :
6153                    this.fstore_0();
6154                    break;
6155                case 1 :
6156                    this.fstore_1();
6157                    break;
6158                case 2 :
6159                    this.fstore_2();
6160                    break;
6161                case 3 :
6162                    this.fstore_3();
6163                    break;
6164                default :
6165                    this.fstore(localPosition);
6166            }
6167            break;
6168        case TypeIds.T_double :
6169            if (valueRequired)
6170                this.dup2();
6171            switch (localPosition) {
6172                case 0 :
6173                    this.dstore_0();
6174                    break;
6175                case 1 :
6176                    this.dstore_1();
6177                    break;
6178                case 2 :
6179                    this.dstore_2();
6180                    break;
6181                case 3 :
6182                    this.dstore_3();
6183                    break;
6184                default :
6185                    this.dstore(localPosition);
6186            }
6187            break;
6188        case TypeIds.T_long :
6189            if (valueRequired)
6190                this.dup2();
6191            switch (localPosition) {
6192                case 0 :
6193                    this.lstore_0();
6194                    break;
6195                case 1 :
6196                    this.lstore_1();
6197                    break;
6198                case 2 :
6199                    this.lstore_2();
6200                    break;
6201                case 3 :
6202                    this.lstore_3();
6203                    break;
6204                default :
6205                    this.lstore(localPosition);
6206            }
6207            break;
6208        default:
6209            // Reference object
6210
if (valueRequired)
6211                this.dup();
6212            switch (localPosition) {
6213                case 0 :
6214                    this.astore_0();
6215                    break;
6216                case 1 :
6217                    this.astore_1();
6218                    break;
6219                case 2 :
6220                    this.astore_2();
6221                    break;
6222                case 3 :
6223                    this.astore_3();
6224                    break;
6225                default :
6226                    this.astore(localPosition);
6227            }
6228    }
6229}
6230public void swap() {
6231    if (DEBUG) System.out.println(position + "\t\tswap"); //$NON-NLS-1$
6232
countLabels = 0;
6233    if (classFileOffset >= bCodeStream.length) {
6234        resizeByteArray();
6235    }
6236    position++;
6237    bCodeStream[classFileOffset++] = Opcodes.OPC_swap;
6238}
6239public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
6240    if (DEBUG) System.out.println(position + "\t\ttableswitch"); //$NON-NLS-1$
6241
countLabels = 0;
6242    stackDepth--;
6243    int length = casesLabel.length;
6244    int pos = position;
6245    defaultLabel.placeInstruction();
6246    for (int i = 0; i < length; i++)
6247        casesLabel[i].placeInstruction();
6248    if (classFileOffset >= bCodeStream.length) {
6249        resizeByteArray();
6250    }
6251    position++;
6252    bCodeStream[classFileOffset++] = Opcodes.OPC_tableswitch;
6253    // padding
6254
for (int i = (3 - (pos & 3)); i > 0; i--) {
6255        if (classFileOffset >= bCodeStream.length) {
6256            resizeByteArray();
6257        }
6258        position++;
6259        bCodeStream[classFileOffset++] = 0;
6260    }
6261    defaultLabel.branch();
6262    writeSignedWord(low);
6263    writeSignedWord(high);
6264    int i = low, j = low;
6265    // the index j is used to know if the index i is one of the missing entries in case of an
6266
// optimized tableswitch
6267
while (true) {
6268        int index;
6269        int key = keys[index = sortedIndexes[j - low]];
6270        if (key == i) {
6271            casesLabel[index].branch();
6272            j++;
6273            if (i == high) break; // if high is maxint, then avoids wrapping to minint.
6274
} else {
6275            defaultLabel.branch();
6276        }
6277        i++;
6278    }
6279}
6280public void throwAnyException(LocalVariableBinding anyExceptionVariable) {
6281    this.load(anyExceptionVariable);
6282    this.athrow();
6283}
6284public String JavaDoc toString() {
6285    StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("( position:"); //$NON-NLS-1$
6286
buffer.append(position);
6287    buffer.append(",\nstackDepth:"); //$NON-NLS-1$
6288
buffer.append(stackDepth);
6289    buffer.append(",\nmaxStack:"); //$NON-NLS-1$
6290
buffer.append(stackMax);
6291    buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
6292
buffer.append(maxLocals);
6293    buffer.append(")"); //$NON-NLS-1$
6294
return buffer.toString();
6295}
6296/**
6297 * Note: it will walk the locals table and extend the end range for all matching ones, no matter if
6298 * visible or not.
6299 * { int i = 0;
6300 * { int j = 1; }
6301 * } <== would process both 'i' and 'j'
6302 * Processing non-visible ones is mandated in some cases (include goto instruction after if-then block)
6303 */

6304public void updateLastRecordedEndPC(Scope scope, int pos) {
6305
6306    /* Tune positions in the table, this is due to some
6307     * extra bytecodes being
6308     * added to some user code (jumps). */

6309    /** OLD CODE
6310        if (!generateLineNumberAttributes)
6311            return;
6312        pcToSourceMap[pcToSourceMapSize - 1][1] = position;
6313        // need to update the initialization endPC in case of generation of local variable attributes.
6314        updateLocalVariablesAttribute(pos);
6315    */

6316
6317    if ((this.generateAttributes & ClassFileConstants.ATTR_LINES) != 0) {
6318        this.lastEntryPC = pos;
6319    }
6320    // need to update the initialization endPC in case of generation of local variable attributes.
6321
if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP)) != 0) {
6322        for (int i = 0, max = this.locals.length; i < max; i++) {
6323            LocalVariableBinding local = this.locals[i];
6324            if (local != null && local.declaringScope == scope && local.initializationCount > 0) {
6325                if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
6326                    local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = this.position;
6327                }
6328            }
6329        }
6330    }
6331}
6332protected void writePosition(BranchLabel label) {
6333    int offset = label.position - this.position + 1;
6334    if (Math.abs(offset) > 0x7FFF && !this.wideMode) {
6335        throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE, null);
6336    }
6337    this.writeSignedShort(offset);
6338    int[] forwardRefs = label.forwardReferences();
6339    for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
6340        this.writePosition(label, forwardRefs[i]);
6341    }
6342}
6343protected void writePosition(BranchLabel label, int forwardReference) {
6344    final int offset = label.position - forwardReference + 1;
6345    if (Math.abs(offset) > 0x7FFF && !this.wideMode) {
6346        throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE, null);
6347    }
6348    if (this.wideMode) {
6349        if ((label.tagBits & BranchLabel.WIDE) != 0) {
6350            this.writeSignedWord(forwardReference, offset);
6351        } else {
6352            this.writeSignedShort(forwardReference, offset);
6353        }
6354    } else {
6355        this.writeSignedShort(forwardReference, offset);
6356    }
6357}
6358/**
6359 * Write a signed 16 bits value into the byte array
6360 * @param value the signed short
6361 */

6362private final void writeSignedShort(int value) {
6363    // we keep the resize in here because it is used outside the code stream
6364
if (classFileOffset + 1 >= bCodeStream.length) {
6365        resizeByteArray();
6366    }
6367    position += 2;
6368    bCodeStream[classFileOffset++] = (byte) (value >> 8);
6369    bCodeStream[classFileOffset++] = (byte) value;
6370}
6371private final void writeSignedShort(int pos, int value) {
6372    int currentOffset = startingClassFileOffset + pos;
6373    if (currentOffset + 1 >= bCodeStream.length) {
6374        resizeByteArray();
6375    }
6376    bCodeStream[currentOffset] = (byte) (value >> 8);
6377    bCodeStream[currentOffset + 1] = (byte) value;
6378}
6379protected final void writeSignedWord(int value) {
6380    // we keep the resize in here because it is used outside the code stream
6381
if (classFileOffset + 3 >= bCodeStream.length) {
6382        resizeByteArray();
6383    }
6384    position += 4;
6385    bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
6386    bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
6387    bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
6388    bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
6389}
6390protected final void writeSignedWord(int pos, int value) {
6391    int currentOffset = startingClassFileOffset + pos;
6392    if (currentOffset + 3 >= bCodeStream.length) {
6393        resizeByteArray();
6394    }
6395    bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
6396    bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
6397    bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
6398    bCodeStream[currentOffset++] = (byte) (value & 0xFF);
6399}
6400/**
6401 * Write a unsigned 16 bits value into the byte array
6402 * @param value the unsigned short
6403 */

6404private final void writeUnsignedShort(int value) {
6405    // no bound check since used only from within codestream where already checked
6406
position += 2;
6407    bCodeStream[classFileOffset++] = (byte) (value >>> 8);
6408    bCodeStream[classFileOffset++] = (byte) value;
6409}
6410protected void writeWidePosition(BranchLabel label) {
6411    int labelPos = label.position;
6412    int offset = labelPos - this.position + 1;
6413    this.writeSignedWord(offset);
6414    int[] forwardRefs = label.forwardReferences();
6415    for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
6416        int forward = forwardRefs[i];
6417        offset = labelPos - forward + 1;
6418        this.writeSignedWord(forward, offset);
6419    }
6420}
6421}
6422
Popular Tags