added -J option to preserve unmodified files in preexisting jarfile
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / codegen / CodeStream.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
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.internal.compiler.*;
14
15 import org.eclipse.jdt.internal.compiler.impl.*;
16 import org.eclipse.jdt.internal.compiler.ast.*;
17 import org.eclipse.jdt.internal.compiler.classfmt.*;
18 import org.eclipse.jdt.internal.compiler.flow.*;
19 import org.eclipse.jdt.internal.compiler.lookup.*;
20
21 public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, BaseTypes, TypeConstants, TypeIds {
22
23         public static final boolean DEBUG = false;
24         
25         // It will be responsible for the following items.
26         // -> Tracking Max Stack.
27
28         public int stackMax; // Use Ints to keep from using extra bc when adding
29         public int stackDepth; // Use Ints to keep from using extra bc when adding
30         public int maxLocals;
31         public static final int LABELS_INCREMENT = 5;
32         public byte[] bCodeStream;
33         public int pcToSourceMapSize;
34         public int[] pcToSourceMap = new int[24];
35         public int lastEntryPC; // last entry recorded
36         public int[] lineSeparatorPositions;
37         public int position; // So when first set can be incremented
38         public int classFileOffset;
39         public int startingClassFileOffset; // I need to keep the starting point inside the byte array
40         public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
41         public ClassFile classFile; // The current classfile it is associated to.
42         // local variable attributes output
43         public static final int LOCALS_INCREMENT = 10;
44         public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
45         static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
46         public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
47         static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
48         int visibleLocalsCount;
49         public AbstractMethodDeclaration methodDeclaration;
50         public ExceptionLabel[] exceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
51         static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
52         public int exceptionHandlersIndex;
53         public int exceptionHandlersCounter;
54         
55         public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
56         public boolean generateLineNumberAttributes;
57         public boolean generateLocalVariableTableAttributes;
58         public boolean preserveUnusedLocals;
59         // store all the labels placed at the current position to be able to optimize
60         // a jump to the next bytecode.
61         public Label[] labels = new Label[LABELS_INCREMENT];
62         static Label[] noLabels = new Label[LABELS_INCREMENT];
63         public int countLabels;
64         public int allLocalsCounter;
65         public int maxFieldCount;
66         // to handle goto_w
67         public boolean wideMode = false;
68         public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
69         
70         // target level to manage different code generation between different target levels
71         private long targetLevel;
72         
73 public CodeStream(ClassFile classFile, long targetLevel) {
74         this.targetLevel = targetLevel;
75         this.generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0;
76         this.generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0;
77         if (this.generateLineNumberAttributes) {
78                 this.lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions;
79         }
80 }
81 final public void aaload() {
82         if (DEBUG) System.out.println(position + "\t\taaload"); //$NON-NLS-1$
83         countLabels = 0;
84         stackDepth--;
85         if (classFileOffset >= bCodeStream.length) {
86                 resizeByteArray();
87         }
88         position++;
89         bCodeStream[classFileOffset++] = OPC_aaload;
90 }
91 final public void aastore() {
92         if (DEBUG) System.out.println(position + "\t\taastore"); //$NON-NLS-1$
93         countLabels = 0;
94         stackDepth -= 3;
95         if (classFileOffset >= bCodeStream.length) {
96                 resizeByteArray();
97         }
98         position++;
99         bCodeStream[classFileOffset++] = OPC_aastore;
100 }
101 final public void aconst_null() {
102         if (DEBUG) System.out.println(position + "\t\taconst_null"); //$NON-NLS-1$
103         countLabels = 0;
104         stackDepth++;
105         if (stackDepth > stackMax) {
106                 stackMax = stackDepth;
107         }
108         if (classFileOffset >= bCodeStream.length) {
109                 resizeByteArray();
110         }
111         position++;
112         bCodeStream[classFileOffset++] = OPC_aconst_null;
113 }
114 public final void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
115         // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
116         if (!generateLocalVariableTableAttributes)
117                 return;
118 /*      if (initStateIndex == lastInitStateIndexWhenAddingInits)
119                 return;
120         lastInitStateIndexWhenAddingInits = initStateIndex;
121         if (lastInitStateIndexWhenRemovingInits != initStateIndex){
122                 lastInitStateIndexWhenRemovingInits = -2; // reinitialize remove index 
123                 // remove(1)-add(1)-remove(1) -> ignore second remove
124                 // remove(1)-add(2)-remove(1) -> perform second remove
125         }
126         
127 */      for (int i = 0; i < visibleLocalsCount; i++) {
128                 LocalVariableBinding localBinding = visibleLocals[i];
129                 if (localBinding != null) {
130                         // Check if the local is definitely assigned
131                         if ((initStateIndex != -1) && isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
132                                 if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
133                                         /* There are two cases:
134                                          * 1) there is no initialization interval opened ==> add an opened interval
135                                          * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
136                                          * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
137                                          * is equals to -1.
138                                          * initializationPCs is a collection of pairs of int:
139                                          *      first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
140                                          *      is not closed yet.
141                                          */
142                                         localBinding.recordInitializationStartPC(position);
143                                 }
144                         }
145                 }
146         }
147 }
148 public void addLabel(Label aLabel) {
149         if (countLabels == labels.length)
150                 System.arraycopy(labels, 0, labels = new Label[countLabels + LABELS_INCREMENT], 0, countLabels);
151         labels[countLabels++] = aLabel;
152 }
153 public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
154         if (!generateLocalVariableTableAttributes)
155                 return;
156
157         if (visibleLocalsCount >= visibleLocals.length)
158                 System.arraycopy(visibleLocals, 0, visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2], 0, visibleLocalsCount);
159         visibleLocals[visibleLocalsCount++] = localBinding;
160 }
161 final public void aload(int iArg) {
162         if (DEBUG) System.out.println(position + "\t\taload:"+iArg); //$NON-NLS-1$
163         countLabels = 0;
164         stackDepth++;
165         if (stackDepth > stackMax)
166                 stackMax = stackDepth;
167         if (maxLocals <= iArg) {
168                 maxLocals = iArg + 1;
169         }
170         if (iArg > 255) { // Widen
171                 if (classFileOffset + 3 >= bCodeStream.length) {
172                         resizeByteArray();
173                 }
174                 position += 2;
175                 bCodeStream[classFileOffset++] = OPC_wide;
176                 bCodeStream[classFileOffset++] = OPC_aload;
177                 writeUnsignedShort(iArg);
178         } else {
179                 // Don't need to use the wide bytecode
180                 if (classFileOffset + 1 >= bCodeStream.length) {
181                         resizeByteArray();
182                 }
183                 position += 2;
184                 bCodeStream[classFileOffset++] = OPC_aload;
185                 bCodeStream[classFileOffset++] = (byte) iArg;
186         }
187 }
188 final public void aload_0() {
189         if (DEBUG) System.out.println(position + "\t\taload_0"); //$NON-NLS-1$
190         countLabels = 0;
191         stackDepth++;
192         if (stackDepth > stackMax) {
193                 stackMax = stackDepth;
194         }
195         if (maxLocals == 0) {
196                 maxLocals = 1;
197         }
198         if (classFileOffset >= bCodeStream.length) {
199                 resizeByteArray();
200         }
201         position++;
202         bCodeStream[classFileOffset++] = OPC_aload_0;
203 }
204 final public void aload_1() {
205         if (DEBUG) System.out.println(position + "\t\taload_1"); //$NON-NLS-1$
206         countLabels = 0;
207         stackDepth++;
208         if (stackDepth > stackMax)
209                 stackMax = stackDepth;
210         if (maxLocals <= 1) {
211                 maxLocals = 2;
212         }
213         if (classFileOffset >= bCodeStream.length) {
214                 resizeByteArray();
215         }
216         position++;
217         bCodeStream[classFileOffset++] = OPC_aload_1;
218 }
219 final public void aload_2() {
220         if (DEBUG) System.out.println(position + "\t\taload_2"); //$NON-NLS-1$
221         countLabels = 0;
222         stackDepth++;
223         if (stackDepth > stackMax)
224                 stackMax = stackDepth;
225         if (maxLocals <= 2) {
226                 maxLocals = 3;
227         }
228         if (classFileOffset >= bCodeStream.length) {
229                 resizeByteArray();
230         }
231         position++;
232         bCodeStream[classFileOffset++] = OPC_aload_2;
233 }
234 final public void aload_3() {
235         if (DEBUG) System.out.println(position + "\t\taload_3"); //$NON-NLS-1$
236         countLabels = 0;
237         stackDepth++;
238         if (stackDepth > stackMax)
239                 stackMax = stackDepth;
240         if (maxLocals <= 3) {
241                 maxLocals = 4;
242         }
243         if (classFileOffset >= bCodeStream.length) {
244                 resizeByteArray();
245         }
246         position++;
247         bCodeStream[classFileOffset++] = OPC_aload_3;
248 }
249 public final void anewarray(TypeBinding typeBinding) {
250         if (DEBUG) System.out.println(position + "\t\tanewarray: " + typeBinding); //$NON-NLS-1$
251         countLabels = 0;
252         if (classFileOffset + 2 >= bCodeStream.length) {
253                 resizeByteArray();
254         }
255         position++;
256         bCodeStream[classFileOffset++] = OPC_anewarray;
257         writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
258 }
259 final public void areturn() {
260         if (DEBUG) System.out.println(position + "\t\tareturn"); //$NON-NLS-1$
261         countLabels = 0;
262         stackDepth--;
263         // the stackDepth should be equal to 0 
264         if (classFileOffset >= bCodeStream.length) {
265                 resizeByteArray();
266         }
267         position++;
268         bCodeStream[classFileOffset++] = OPC_areturn;
269 }
270 public void arrayAt(int typeBindingID) {
271         switch (typeBindingID) {
272                 case T_int :
273                         this.iaload();
274                         break;
275                 case T_byte :
276                 case T_boolean :
277                         this.baload();
278                         break;
279                 case T_short :
280                         this.saload();
281                         break;
282                 case T_char :
283                         this.caload();
284                         break;
285                 case T_long :
286                         this.laload();
287                         break;
288                 case T_float :
289                         this.faload();
290                         break;
291                 case T_double :
292                         this.daload();
293                         break;
294                 default :
295                         this.aaload();
296         }
297 }
298 public void arrayAtPut(int elementTypeID, boolean valueRequired) {
299         switch (elementTypeID) {
300                 case T_int :
301                         if (valueRequired)
302                                 dup_x2();
303                         iastore();
304                         break;
305                 case T_byte :
306                 case T_boolean :
307                         if (valueRequired)
308                                 dup_x2();
309                         bastore();
310                         break;
311                 case T_short :
312                         if (valueRequired)
313                                 dup_x2();
314                         sastore();
315                         break;
316                 case T_char :
317                         if (valueRequired)
318                                 dup_x2();
319                         castore();
320                         break;
321                 case T_long :
322                         if (valueRequired)
323                                 dup2_x2();
324                         lastore();
325                         break;
326                 case T_float :
327                         if (valueRequired)
328                                 dup_x2();
329                         fastore();
330                         break;
331                 case T_double :
332                         if (valueRequired)
333                                 dup2_x2();
334                         dastore();
335                         break;
336                 default :
337                         if (valueRequired)
338                                 dup_x2();
339                         aastore();
340         }
341 }
342 final public void arraylength() {
343         if (DEBUG) System.out.println(position + "\t\tarraylength"); //$NON-NLS-1$
344         countLabels = 0;
345         if (classFileOffset >= bCodeStream.length) {
346                 resizeByteArray();
347         }
348         position++;
349         bCodeStream[classFileOffset++] = OPC_arraylength;
350 }
351 final public void astore(int iArg) {
352         if (DEBUG) System.out.println(position + "\t\tastore:"+iArg); //$NON-NLS-1$
353         countLabels = 0;
354         stackDepth--;
355         if (maxLocals <= iArg) {
356                 maxLocals = iArg + 1;
357         }
358         if (iArg > 255) { // Widen
359                 if (classFileOffset + 3 >= bCodeStream.length) {
360                         resizeByteArray();
361                 }
362                 position+=2;
363                 bCodeStream[classFileOffset++] = OPC_wide;
364                 bCodeStream[classFileOffset++] = OPC_astore;
365                 writeUnsignedShort(iArg);
366         } else {
367                 if (classFileOffset + 1 >= bCodeStream.length) {
368                         resizeByteArray();
369                 }
370                 position+=2;
371                 bCodeStream[classFileOffset++] = OPC_astore;
372                 bCodeStream[classFileOffset++] = (byte) iArg;
373         }
374 }
375 final public void astore_0() {
376         if (DEBUG) System.out.println(position + "\t\tastore_0"); //$NON-NLS-1$
377         countLabels = 0;
378         stackDepth--;
379         if (maxLocals == 0) {
380                 maxLocals = 1;
381         }
382         if (classFileOffset >= bCodeStream.length) {
383                 resizeByteArray();
384         }
385         position++;
386         bCodeStream[classFileOffset++] = OPC_astore_0;
387 }
388 final public void astore_1() {
389         if (DEBUG) System.out.println(position + "\t\tastore_1"); //$NON-NLS-1$
390         countLabels = 0;
391         stackDepth--;
392         if (maxLocals <= 1) {
393                 maxLocals = 2;
394         }
395         if (classFileOffset >= bCodeStream.length) {
396                 resizeByteArray();
397         }
398         position++;
399         bCodeStream[classFileOffset++] = OPC_astore_1;
400 }
401 final public void astore_2() {
402         if (DEBUG) System.out.println(position + "\t\tastore_2"); //$NON-NLS-1$
403         countLabels = 0;
404         stackDepth--;
405         if (maxLocals <= 2) {
406                 maxLocals = 3;
407         }
408         if (classFileOffset >= bCodeStream.length) {
409                 resizeByteArray();
410         }
411         position++;
412         bCodeStream[classFileOffset++] = OPC_astore_2;
413 }
414 final public void astore_3() {
415         if (DEBUG) System.out.println(position + "\t\tastore_3"); //$NON-NLS-1$
416         countLabels = 0;
417         stackDepth--;
418         if (maxLocals <= 3) {
419                 maxLocals = 4;
420         }
421         if (classFileOffset >= bCodeStream.length) {
422                 resizeByteArray();
423         }
424         position++;
425         bCodeStream[classFileOffset++] = OPC_astore_3;
426 }
427 final public void athrow() {
428         if (DEBUG) System.out.println(position + "\t\tathrow"); //$NON-NLS-1$
429         countLabels = 0;
430         stackDepth--;
431         if (classFileOffset >= bCodeStream.length) {
432                 resizeByteArray();
433         }
434         position++;
435         bCodeStream[classFileOffset++] = OPC_athrow;
436 }
437 final public void baload() {
438         if (DEBUG) System.out.println(position + "\t\tbaload"); //$NON-NLS-1$
439         countLabels = 0;
440         stackDepth--;
441         if (classFileOffset >= bCodeStream.length) {
442                 resizeByteArray();
443         }
444         position++;
445         bCodeStream[classFileOffset++] = OPC_baload;
446 }
447 final public void bastore() {
448         if (DEBUG) System.out.println(position + "\t\tbastore"); //$NON-NLS-1$
449         countLabels = 0;
450         stackDepth -= 3;
451         if (classFileOffset >= bCodeStream.length) {
452                 resizeByteArray();
453         }
454         position++;
455         bCodeStream[classFileOffset++] = OPC_bastore;
456 }
457 final public void bipush(byte b) {
458         if (DEBUG) System.out.println(position + "\t\tbipush "+b); //$NON-NLS-1$
459         countLabels = 0;
460         stackDepth++;
461         if (stackDepth > stackMax)
462                 stackMax = stackDepth;
463         if (classFileOffset + 1 >= bCodeStream.length) {
464                 resizeByteArray();
465         }
466         position += 2;
467         bCodeStream[classFileOffset++] = OPC_bipush;
468         bCodeStream[classFileOffset++] = b;
469 }
470 final public void caload() {
471         if (DEBUG) System.out.println(position + "\t\tcaload"); //$NON-NLS-1$
472         countLabels = 0;
473         stackDepth--;
474         if (classFileOffset >= bCodeStream.length) {
475                 resizeByteArray();
476         }
477         position++;
478         bCodeStream[classFileOffset++] = OPC_caload;
479 }
480 final public void castore() {
481         if (DEBUG) System.out.println(position + "\t\tcastore"); //$NON-NLS-1$
482         countLabels = 0;
483         stackDepth -= 3;
484         if (classFileOffset >= bCodeStream.length) {
485                 resizeByteArray();
486         }
487         position++;
488         bCodeStream[classFileOffset++] = OPC_castore;
489 }
490 public final void checkcast(TypeBinding typeBinding) {
491         if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding.debugName()); //$NON-NLS-1$
492         countLabels = 0;
493         if (classFileOffset + 2 >= bCodeStream.length) {
494                 resizeByteArray();
495         }
496         position++;
497         bCodeStream[classFileOffset++] = OPC_checkcast;
498         writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
499 }
500 final public void d2f() {
501         if (DEBUG) System.out.println(position + "\t\td2f"); //$NON-NLS-1$
502         countLabels = 0;
503         stackDepth--;
504         if (classFileOffset >= bCodeStream.length) {
505                 resizeByteArray();
506         }
507         position++;
508         bCodeStream[classFileOffset++] = OPC_d2f;
509 }
510 final public void d2i() {
511         if (DEBUG) System.out.println(position + "\t\td2i"); //$NON-NLS-1$
512         countLabels = 0;
513         stackDepth--;
514         if (classFileOffset >= bCodeStream.length) {
515                 resizeByteArray();
516         }
517         position++;
518         bCodeStream[classFileOffset++] = OPC_d2i;
519 }
520 final public void d2l() {
521         if (DEBUG) System.out.println(position + "\t\td2l"); //$NON-NLS-1$
522         countLabels = 0;
523         if (classFileOffset >= bCodeStream.length) {
524                 resizeByteArray();
525         }
526         position++;
527         bCodeStream[classFileOffset++] = OPC_d2l;
528 }
529 final public void dadd() {
530         if (DEBUG) System.out.println(position + "\t\tdadd"); //$NON-NLS-1$
531         countLabels = 0;
532         stackDepth -= 2;
533         if (classFileOffset >= bCodeStream.length) {
534                 resizeByteArray();
535         }
536         position++;
537         bCodeStream[classFileOffset++] = OPC_dadd;
538 }
539 final public void daload() {
540         if (DEBUG) System.out.println(position + "\t\tdaload"); //$NON-NLS-1$
541         countLabels = 0;
542         if (classFileOffset >= bCodeStream.length) {
543                 resizeByteArray();
544         }
545         position++;
546         bCodeStream[classFileOffset++] = OPC_daload;
547 }
548 final public void dastore() {
549         if (DEBUG) System.out.println(position + "\t\tdastore"); //$NON-NLS-1$
550         countLabels = 0;
551         stackDepth -= 4;
552         if (classFileOffset >= bCodeStream.length) {
553                 resizeByteArray();
554         }
555         position++;
556         bCodeStream[classFileOffset++] = OPC_dastore;
557 }
558 final public void dcmpg() {
559         if (DEBUG) System.out.println(position + "\t\tdcmpg"); //$NON-NLS-1$
560         countLabels = 0;
561         stackDepth -= 3;
562         if (classFileOffset >= bCodeStream.length) {
563                 resizeByteArray();
564         }
565         position++;
566         bCodeStream[classFileOffset++] = OPC_dcmpg;
567 }
568 final public void dcmpl() {
569         if (DEBUG) System.out.println(position + "\t\tdcmpl"); //$NON-NLS-1$
570         countLabels = 0;
571         stackDepth -= 3;
572         if (classFileOffset >= bCodeStream.length) {
573                 resizeByteArray();
574         }
575         position++;
576         bCodeStream[classFileOffset++] = OPC_dcmpl;
577 }
578 final public void dconst_0() {
579         if (DEBUG) System.out.println(position + "\t\tdconst_0"); //$NON-NLS-1$
580         countLabels = 0;
581         stackDepth += 2;
582         if (stackDepth > stackMax)
583                 stackMax = stackDepth;
584         if (classFileOffset >= bCodeStream.length) {
585                 resizeByteArray();
586         }
587         position++;
588         bCodeStream[classFileOffset++] = OPC_dconst_0;
589 }
590 final public void dconst_1() {
591         if (DEBUG) System.out.println(position + "\t\tdconst_1"); //$NON-NLS-1$
592         countLabels = 0;
593         stackDepth += 2;
594         if (stackDepth > stackMax)
595                 stackMax = stackDepth;
596         if (classFileOffset >= bCodeStream.length) {
597                 resizeByteArray();
598         }
599         position++;
600         bCodeStream[classFileOffset++] = OPC_dconst_1;
601 }
602 final public void ddiv() {
603         if (DEBUG) System.out.println(position + "\t\tddiv"); //$NON-NLS-1$
604         countLabels = 0;
605         stackDepth -= 2;
606         if (classFileOffset >= bCodeStream.length) {
607                 resizeByteArray();
608         }
609         position++;
610         bCodeStream[classFileOffset++] = OPC_ddiv;
611 }
612 public void decrStackSize(int offset) {
613         stackDepth -= offset;
614 }
615 final public void dload(int iArg) {
616         if (DEBUG) System.out.println(position + "\t\tdload:"+iArg); //$NON-NLS-1$
617         countLabels = 0;
618         stackDepth += 2;
619         if (stackDepth > stackMax)
620                 stackMax = stackDepth;
621         if (maxLocals < iArg + 2) {
622                 maxLocals = iArg + 2; // + 2 because it is a double
623         }
624         if (iArg > 255) { // Widen
625                 if (classFileOffset + 3 >= bCodeStream.length) {
626                         resizeByteArray();
627                 }
628                 position += 2;
629                 bCodeStream[classFileOffset++] = OPC_wide;
630                 bCodeStream[classFileOffset++] = OPC_dload;
631                 writeUnsignedShort(iArg);
632         } else {
633                 // Don't need to use the wide bytecode
634                 if (classFileOffset + 1 >= bCodeStream.length) {
635                         resizeByteArray();
636                 }
637                 position += 2;
638                 bCodeStream[classFileOffset++] = OPC_dload;
639                 bCodeStream[classFileOffset++] = (byte) iArg;
640         }
641 }
642 final public void dload_0() {
643         if (DEBUG) System.out.println(position + "\t\tdload_0"); //$NON-NLS-1$
644         countLabels = 0;
645         stackDepth += 2;
646         if (stackDepth > stackMax)
647                 stackMax = stackDepth;
648         if (maxLocals < 2) {
649                 maxLocals = 2;
650         }
651         if (classFileOffset >= bCodeStream.length) {
652                 resizeByteArray();
653         }
654         position++;
655         bCodeStream[classFileOffset++] = OPC_dload_0;
656 }
657 final public void dload_1() {
658         if (DEBUG) System.out.println(position + "\t\tdload_1"); //$NON-NLS-1$
659         countLabels = 0;
660         stackDepth += 2;
661         if (stackDepth > stackMax)
662                 stackMax = stackDepth;
663         if (maxLocals < 3) {
664                 maxLocals = 3;
665         }
666         if (classFileOffset >= bCodeStream.length) {
667                 resizeByteArray();
668         }
669         position++;
670         bCodeStream[classFileOffset++] = OPC_dload_1;
671 }
672 final public void dload_2() {
673         if (DEBUG) System.out.println(position + "\t\tdload_2"); //$NON-NLS-1$
674         countLabels = 0;
675         stackDepth += 2;
676         if (stackDepth > stackMax)
677                 stackMax = stackDepth;
678         if (maxLocals < 4) {
679                 maxLocals = 4;
680         }
681         if (classFileOffset >= bCodeStream.length) {
682                 resizeByteArray();
683         }
684         position++;
685         bCodeStream[classFileOffset++] = OPC_dload_2;
686 }
687 final public void dload_3() {
688         if (DEBUG) System.out.println(position + "\t\tdload_3"); //$NON-NLS-1$
689         countLabels = 0;
690         stackDepth += 2;
691         if (stackDepth > stackMax)
692                 stackMax = stackDepth;
693         if (maxLocals < 5) {
694                 maxLocals = 5;
695         }
696         if (classFileOffset >= bCodeStream.length) {
697                 resizeByteArray();
698         }
699         position++;
700         bCodeStream[classFileOffset++] = OPC_dload_3;
701 }
702 final public void dmul() {
703         if (DEBUG) System.out.println(position + "\t\tdmul"); //$NON-NLS-1$
704         countLabels = 0;
705         stackDepth -= 2;
706         if (classFileOffset >= bCodeStream.length) {
707                 resizeByteArray();
708         }
709         position++;
710         bCodeStream[classFileOffset++] = OPC_dmul;
711 }
712 final public void dneg() {
713         if (DEBUG) System.out.println(position + "\t\tdneg"); //$NON-NLS-1$
714         countLabels = 0;
715         if (classFileOffset >= bCodeStream.length) {
716                 resizeByteArray();
717         }
718         position++;
719         bCodeStream[classFileOffset++] = OPC_dneg;
720 }
721 final public void drem() {
722         if (DEBUG) System.out.println(position + "\t\tdrem"); //$NON-NLS-1$
723         countLabels = 0;
724         stackDepth -= 2;
725         if (classFileOffset >= bCodeStream.length) {
726                 resizeByteArray();
727         }
728         position++;
729         bCodeStream[classFileOffset++] = OPC_drem;
730 }
731 final public void dreturn() {
732         if (DEBUG) System.out.println(position + "\t\tdreturn"); //$NON-NLS-1$
733         countLabels = 0;
734         stackDepth -= 2;
735         // the stackDepth should be equal to 0 
736         if (classFileOffset >= bCodeStream.length) {
737                 resizeByteArray();
738         }
739         position++;
740         bCodeStream[classFileOffset++] = OPC_dreturn;
741 }
742 final public void dstore(int iArg) {
743         if (DEBUG) System.out.println(position + "\t\tdstore:"+iArg); //$NON-NLS-1$
744         countLabels = 0;
745         stackDepth -= 2;
746         if (maxLocals <= iArg + 1) {
747                 maxLocals = iArg + 2;
748         }
749         if (iArg > 255) { // Widen
750                 if (classFileOffset + 3 >= bCodeStream.length) {
751                         resizeByteArray();
752                 }
753                 position += 2;
754                 bCodeStream[classFileOffset++] = OPC_wide;
755                 bCodeStream[classFileOffset++] = OPC_dstore;
756                 writeUnsignedShort(iArg);
757         } else {
758                 if (classFileOffset + 1 >= bCodeStream.length) {
759                         resizeByteArray();
760                 }
761                 position += 2;
762                 bCodeStream[classFileOffset++] = OPC_dstore;
763                 bCodeStream[classFileOffset++] = (byte) iArg;
764         }
765 }
766 final public void dstore_0() {
767         if (DEBUG) System.out.println(position + "\t\tdstore_0"); //$NON-NLS-1$
768         countLabels = 0;
769         stackDepth -= 2;
770         if (maxLocals < 2) {
771                 maxLocals = 2;
772         }
773         if (classFileOffset >= bCodeStream.length) {
774                 resizeByteArray();
775         }
776         position++;
777         bCodeStream[classFileOffset++] = OPC_dstore_0;
778 }
779 final public void dstore_1() {
780         if (DEBUG) System.out.println(position + "\t\tdstore_1"); //$NON-NLS-1$
781         countLabels = 0;
782         stackDepth -= 2;
783         if (maxLocals < 3) {
784                 maxLocals = 3;
785         }
786         if (classFileOffset >= bCodeStream.length) {
787                 resizeByteArray();
788         }
789         position++;
790         bCodeStream[classFileOffset++] = OPC_dstore_1;
791 }
792 final public void dstore_2() {
793         if (DEBUG) System.out.println(position + "\t\tdstore_2"); //$NON-NLS-1$
794         countLabels = 0;
795         stackDepth -= 2;
796         if (maxLocals < 4) {
797                 maxLocals = 4;
798         }
799         if (classFileOffset >= bCodeStream.length) {
800                 resizeByteArray();
801         }
802         position++;
803         bCodeStream[classFileOffset++] = OPC_dstore_2;
804 }
805 final public void dstore_3() {
806         if (DEBUG) System.out.println(position + "\t\tdstore_3"); //$NON-NLS-1$
807         countLabels = 0;
808         stackDepth -= 2;
809         if (maxLocals < 5) {
810                 maxLocals = 5;
811         }
812         if (classFileOffset >= bCodeStream.length) {
813                 resizeByteArray();
814         }
815         position++;
816         bCodeStream[classFileOffset++] = OPC_dstore_3;
817 }
818 final public void dsub() {
819         if (DEBUG) System.out.println(position + "\t\tdsub"); //$NON-NLS-1$
820         countLabels = 0;
821         stackDepth -= 2;
822         if (classFileOffset >= bCodeStream.length) {
823                 resizeByteArray();
824         }
825         position++;
826         bCodeStream[classFileOffset++] = OPC_dsub;
827 }
828 final public void dup() {
829         if (DEBUG) System.out.println(position + "\t\tdup"); //$NON-NLS-1$
830         countLabels = 0;
831         stackDepth++;
832         if (stackDepth > stackMax) {
833                 stackMax = stackDepth;
834         }
835         if (classFileOffset >= bCodeStream.length) {
836                 resizeByteArray();
837         }
838         position++;
839         bCodeStream[classFileOffset++] = OPC_dup;
840 }
841 final public void dup_x1() {
842         if (DEBUG) System.out.println(position + "\t\tdup_x1"); //$NON-NLS-1$
843         countLabels = 0;
844         stackDepth++;
845         if (stackDepth > stackMax)
846                 stackMax = stackDepth;
847         if (classFileOffset >= bCodeStream.length) {
848                 resizeByteArray();
849         }
850         position++;
851         bCodeStream[classFileOffset++] = OPC_dup_x1;
852 }
853 final public void dup_x2() {
854         if (DEBUG) System.out.println(position + "\t\tdup_x2"); //$NON-NLS-1$
855         countLabels = 0;
856         stackDepth++;
857         if (stackDepth > stackMax)
858                 stackMax = stackDepth;
859         if (classFileOffset >= bCodeStream.length) {
860                 resizeByteArray();
861         }
862         position++;
863         bCodeStream[classFileOffset++] = OPC_dup_x2;
864 }
865 final public void dup2() {
866         if (DEBUG) System.out.println(position + "\t\tdup2"); //$NON-NLS-1$
867         countLabels = 0;
868         stackDepth += 2;
869         if (stackDepth > stackMax)
870                 stackMax = stackDepth;
871         if (classFileOffset >= bCodeStream.length) {
872                 resizeByteArray();
873         }
874         position++;
875         bCodeStream[classFileOffset++] = OPC_dup2;
876 }
877 final public void dup2_x1() {
878         if (DEBUG) System.out.println(position + "\t\tdup2_x1"); //$NON-NLS-1$
879         countLabels = 0;
880         stackDepth += 2;
881         if (stackDepth > stackMax)
882                 stackMax = stackDepth;
883         if (classFileOffset >= bCodeStream.length) {
884                 resizeByteArray();
885         }
886         position++;
887         bCodeStream[classFileOffset++] = OPC_dup2_x1;
888 }
889 final public void dup2_x2() {
890         if (DEBUG) System.out.println(position + "\t\tdup2_x2"); //$NON-NLS-1$
891         countLabels = 0;
892         stackDepth += 2;
893         if (stackDepth > stackMax)
894                 stackMax = stackDepth;
895         if (classFileOffset >= bCodeStream.length) {
896                 resizeByteArray();
897         }
898         position++;
899         bCodeStream[classFileOffset++] = OPC_dup2_x2;
900 }
901 public void exitUserScope(BlockScope blockScope) {
902         // mark all the scope's locals as loosing their definite assignment
903
904         if (!generateLocalVariableTableAttributes)
905                 return;
906         for (int i = 0; i < visibleLocalsCount; i++) {
907                 LocalVariableBinding visibleLocal = visibleLocals[i];
908                 if ((visibleLocal != null) && (visibleLocal.declaringScope == blockScope)) { 
909                         // there maybe some some preserved locals never initialized
910                         if (visibleLocal.initializationCount > 0){
911                                 visibleLocals[i].recordInitializationEndPC(position);
912                         }
913                         visibleLocals[i] = null; // this variable is no longer visible afterwards
914                 }
915         }
916 }
917 final public void f2d() {
918         if (DEBUG) System.out.println(position + "\t\tf2d"); //$NON-NLS-1$
919         countLabels = 0;
920         stackDepth++;
921         if (stackDepth > stackMax)
922                 stackMax = stackDepth;
923         if (classFileOffset >= bCodeStream.length) {
924                 resizeByteArray();
925         }
926         position++;
927         bCodeStream[classFileOffset++] = OPC_f2d;
928 }
929 final public void f2i() {
930         if (DEBUG) System.out.println(position + "\t\tf2i"); //$NON-NLS-1$
931         countLabels = 0;
932         if (classFileOffset >= bCodeStream.length) {
933                 resizeByteArray();
934         }
935         position++;
936         bCodeStream[classFileOffset++] = OPC_f2i;
937 }
938 final public void f2l() {
939         if (DEBUG) System.out.println(position + "\t\tf2l"); //$NON-NLS-1$
940         countLabels = 0;
941         stackDepth++;
942         if (stackDepth > stackMax)
943                 stackMax = stackDepth;
944         if (classFileOffset >= bCodeStream.length) {
945                 resizeByteArray();
946         }
947         position++;
948         bCodeStream[classFileOffset++] = OPC_f2l;
949 }
950 final public void fadd() {
951         if (DEBUG) System.out.println(position + "\t\tfadd"); //$NON-NLS-1$
952         countLabels = 0;
953         stackDepth--;
954         if (classFileOffset >= bCodeStream.length) {
955                 resizeByteArray();
956         }
957         position++;
958         bCodeStream[classFileOffset++] = OPC_fadd;
959 }
960 final public void faload() {
961         if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
962         countLabels = 0;
963         stackDepth--;
964         if (classFileOffset >= bCodeStream.length) {
965                 resizeByteArray();
966         }
967         position++;
968         bCodeStream[classFileOffset++] = OPC_faload;
969 }
970 final public void fastore() {
971         if (DEBUG) System.out.println(position + "\t\tfaload"); //$NON-NLS-1$
972         countLabels = 0;
973         stackDepth -= 3;
974         if (classFileOffset >= bCodeStream.length) {
975                 resizeByteArray();
976         }
977         position++;
978         bCodeStream[classFileOffset++] = OPC_fastore;
979 }
980 final public void fcmpg() {
981         if (DEBUG) System.out.println(position + "\t\tfcmpg"); //$NON-NLS-1$
982         countLabels = 0;
983         stackDepth--;
984         if (classFileOffset >= bCodeStream.length) {
985                 resizeByteArray();
986         }
987         position++;
988         bCodeStream[classFileOffset++] = OPC_fcmpg;
989 }
990 final public void fcmpl() {
991         if (DEBUG) System.out.println(position + "\t\tfcmpl"); //$NON-NLS-1$
992         countLabels = 0;
993         stackDepth--;
994         if (classFileOffset >= bCodeStream.length) {
995                 resizeByteArray();
996         }
997         position++;
998         bCodeStream[classFileOffset++] = OPC_fcmpl;
999 }
1000 final public void fconst_0() {
1001         if (DEBUG) System.out.println(position + "\t\tfconst_0"); //$NON-NLS-1$
1002         countLabels = 0;
1003         stackDepth++;
1004         if (stackDepth > stackMax)
1005                 stackMax = stackDepth;
1006         if (classFileOffset >= bCodeStream.length) {
1007                 resizeByteArray();
1008         }
1009         position++;
1010         bCodeStream[classFileOffset++] = OPC_fconst_0;
1011 }
1012 final public void fconst_1() {
1013         if (DEBUG) System.out.println(position + "\t\tfconst_1"); //$NON-NLS-1$
1014         countLabels = 0;
1015         stackDepth++;
1016         if (stackDepth > stackMax)
1017                 stackMax = stackDepth;
1018         if (classFileOffset >= bCodeStream.length) {
1019                 resizeByteArray();
1020         }
1021         position++;
1022         bCodeStream[classFileOffset++] = OPC_fconst_1;
1023 }
1024 final public void fconst_2() {
1025         if (DEBUG) System.out.println(position + "\t\tfconst_2"); //$NON-NLS-1$
1026         countLabels = 0;
1027         stackDepth++;
1028         if (stackDepth > stackMax)
1029                 stackMax = stackDepth;
1030         if (classFileOffset >= bCodeStream.length) {
1031                 resizeByteArray();
1032         }
1033         position++;
1034         bCodeStream[classFileOffset++] = OPC_fconst_2;
1035 }
1036 final public void fdiv() {
1037         if (DEBUG) System.out.println(position + "\t\tfdiv"); //$NON-NLS-1$
1038         countLabels = 0;
1039         stackDepth--;
1040         if (classFileOffset >= bCodeStream.length) {
1041                 resizeByteArray();
1042         }
1043         position++;
1044         bCodeStream[classFileOffset++] = OPC_fdiv;
1045 }
1046 final public void fload(int iArg) {
1047         if (DEBUG) System.out.println(position + "\t\tfload:"+iArg); //$NON-NLS-1$
1048         countLabels = 0;
1049         stackDepth++;
1050         if (maxLocals <= iArg) {
1051                 maxLocals = iArg + 1;
1052         }
1053         if (stackDepth > stackMax)
1054                 stackMax = stackDepth;
1055         if (iArg > 255) { // Widen
1056                 if (classFileOffset + 3 >= bCodeStream.length) {
1057                         resizeByteArray();
1058                 }
1059                 position += 2;
1060                 bCodeStream[classFileOffset++] = OPC_wide;
1061                 bCodeStream[classFileOffset++] = OPC_fload;
1062                 writeUnsignedShort(iArg);
1063         } else {
1064                 if (classFileOffset + 1 >= bCodeStream.length) {
1065                         resizeByteArray();
1066                 }
1067                 position += 2;
1068                 bCodeStream[classFileOffset++] = OPC_fload;
1069                 bCodeStream[classFileOffset++] = (byte) iArg;
1070         }
1071 }
1072 final public void fload_0() {
1073         if (DEBUG) System.out.println(position + "\t\tfload_0"); //$NON-NLS-1$
1074         countLabels = 0;
1075         stackDepth++;
1076         if (maxLocals == 0) {
1077                 maxLocals = 1;
1078         }
1079         if (stackDepth > stackMax)
1080                 stackMax = stackDepth;
1081         if (classFileOffset >= bCodeStream.length) {
1082                 resizeByteArray();
1083         }
1084         position++;
1085         bCodeStream[classFileOffset++] = OPC_fload_0;
1086 }
1087 final public void fload_1() {
1088         if (DEBUG) System.out.println(position + "\t\tfload_1"); //$NON-NLS-1$
1089         countLabels = 0;
1090         stackDepth++;
1091         if (maxLocals <= 1) {
1092                 maxLocals = 2;
1093         }
1094         if (stackDepth > stackMax)
1095                 stackMax = stackDepth;
1096         if (classFileOffset >= bCodeStream.length) {
1097                 resizeByteArray();
1098         }
1099         position++;
1100         bCodeStream[classFileOffset++] = OPC_fload_1;
1101 }
1102 final public void fload_2() {
1103         if (DEBUG) System.out.println(position + "\t\tfload_2"); //$NON-NLS-1$
1104         countLabels = 0;
1105         stackDepth++;
1106         if (maxLocals <= 2) {
1107                 maxLocals = 3;
1108         }
1109         if (stackDepth > stackMax)
1110                 stackMax = stackDepth;
1111         if (classFileOffset >= bCodeStream.length) {
1112                 resizeByteArray();
1113         }
1114         position++;
1115         bCodeStream[classFileOffset++] = OPC_fload_2;
1116 }
1117 final public void fload_3() {
1118         if (DEBUG) System.out.println(position + "\t\tfload_3"); //$NON-NLS-1$
1119         countLabels = 0;
1120         stackDepth++;
1121         if (maxLocals <= 3) {
1122                 maxLocals = 4;
1123         }
1124         if (stackDepth > stackMax)
1125                 stackMax = stackDepth;
1126         if (classFileOffset >= bCodeStream.length) {
1127                 resizeByteArray();
1128         }
1129         position++;
1130         bCodeStream[classFileOffset++] = OPC_fload_3;
1131 }
1132 final public void fmul() {
1133         if (DEBUG) System.out.println(position + "\t\tfmul"); //$NON-NLS-1$
1134         countLabels = 0;
1135         stackDepth--;
1136         if (classFileOffset >= bCodeStream.length) {
1137                 resizeByteArray();
1138         }
1139         position++;
1140         bCodeStream[classFileOffset++] = OPC_fmul;
1141 }
1142 final public void fneg() {
1143         if (DEBUG) System.out.println(position + "\t\tfneg"); //$NON-NLS-1$
1144         countLabels = 0;
1145         if (classFileOffset >= bCodeStream.length) {
1146                 resizeByteArray();
1147         }
1148         position++;
1149         bCodeStream[classFileOffset++] = OPC_fneg;
1150 }
1151 final public void frem() {
1152         if (DEBUG) System.out.println(position + "\t\tfrem"); //$NON-NLS-1$
1153         countLabels = 0;
1154         stackDepth--;
1155         if (classFileOffset >= bCodeStream.length) {
1156                 resizeByteArray();
1157         }
1158         position++;
1159         bCodeStream[classFileOffset++] = OPC_frem;
1160 }
1161 final public void freturn() {
1162         if (DEBUG) System.out.println(position + "\t\tfreturn"); //$NON-NLS-1$
1163         countLabels = 0;
1164         stackDepth--;
1165         // the stackDepth should be equal to 0 
1166         if (classFileOffset >= bCodeStream.length) {
1167                 resizeByteArray();
1168         }
1169         position++;
1170         bCodeStream[classFileOffset++] = OPC_freturn;
1171 }
1172 final public void fstore(int iArg) {
1173         if (DEBUG) System.out.println(position + "\t\tfstore:"+iArg); //$NON-NLS-1$
1174         countLabels = 0;
1175         stackDepth--;
1176         if (maxLocals <= iArg) {
1177                 maxLocals = iArg + 1;
1178         }
1179         if (iArg > 255) { // Widen
1180                 if (classFileOffset + 3 >= bCodeStream.length) {
1181                         resizeByteArray();
1182                 }
1183                 position += 2;
1184                 bCodeStream[classFileOffset++] = OPC_wide;
1185                 bCodeStream[classFileOffset++] = OPC_fstore;
1186                 writeUnsignedShort(iArg);
1187         } else {
1188                 if (classFileOffset + 1 >= bCodeStream.length) {
1189                         resizeByteArray();
1190                 }
1191                 position += 2;
1192                 bCodeStream[classFileOffset++] = OPC_fstore;
1193                 bCodeStream[classFileOffset++] = (byte) iArg;
1194         }
1195 }
1196 final public void fstore_0() {
1197         if (DEBUG) System.out.println(position + "\t\tfstore_0"); //$NON-NLS-1$
1198         countLabels = 0;
1199         stackDepth--;
1200         if (maxLocals == 0) {
1201                 maxLocals = 1;
1202         }
1203         if (classFileOffset >= bCodeStream.length) {
1204                 resizeByteArray();
1205         }
1206         position++;
1207         bCodeStream[classFileOffset++] = OPC_fstore_0;
1208 }
1209 final public void fstore_1() {
1210         if (DEBUG) System.out.println(position + "\t\tfstore_1"); //$NON-NLS-1$
1211         countLabels = 0;
1212         stackDepth--;
1213         if (maxLocals <= 1) {
1214                 maxLocals = 2;
1215         }
1216         if (classFileOffset >= bCodeStream.length) {
1217                 resizeByteArray();
1218         }
1219         position++;
1220         bCodeStream[classFileOffset++] = OPC_fstore_1;
1221 }
1222 final public void fstore_2() {
1223         if (DEBUG) System.out.println(position + "\t\tfstore_2"); //$NON-NLS-1$
1224         countLabels = 0;
1225         stackDepth--;
1226         if (maxLocals <= 2) {
1227                 maxLocals = 3;
1228         }
1229         if (classFileOffset >= bCodeStream.length) {
1230                 resizeByteArray();
1231         }
1232         position++;
1233         bCodeStream[classFileOffset++] = OPC_fstore_2;
1234 }
1235 final public void fstore_3() {
1236         if (DEBUG) System.out.println(position + "\t\tfstore_3"); //$NON-NLS-1$
1237         countLabels = 0;
1238         stackDepth--;
1239         if (maxLocals <= 3) {
1240                 maxLocals = 4;
1241         }
1242         if (classFileOffset >= bCodeStream.length) {
1243                 resizeByteArray();
1244         }
1245         position++;
1246         bCodeStream[classFileOffset++] = OPC_fstore_3;
1247 }
1248 final public void fsub() {
1249         if (DEBUG) System.out.println(position + "\t\tfsub"); //$NON-NLS-1$
1250         countLabels = 0;
1251         stackDepth--;
1252         if (classFileOffset >= bCodeStream.length) {
1253                 resizeByteArray();
1254         }
1255         position++;
1256         bCodeStream[classFileOffset++] = OPC_fsub;
1257 }
1258 /**
1259  * Macro for building a class descriptor object
1260  */
1261 public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
1262         Label endLabel;
1263         ExceptionLabel anyExceptionHandler;
1264         int saveStackSize;
1265         if (accessedType.isBaseType() && accessedType != NullBinding) {
1266                 this.getTYPE(accessedType.id);
1267                 return;
1268         }
1269
1270         if (this.targetLevel >= ClassFileConstants.JDK1_5) {
1271                 // generation using the new ldc_w bytecode
1272                 this.ldc(accessedType);
1273         } else {
1274                 endLabel = new Label(this);
1275                 if (syntheticFieldBinding != null) { // non interface case
1276                         this.getstatic(syntheticFieldBinding);
1277                         this.dup();
1278                         this.ifnonnull(endLabel);
1279                         this.pop();
1280                 }
1281
1282                 /* Macro for building a class descriptor object... using or not a field cache to store it into...
1283                 this sequence is responsible for building the actual class descriptor.
1284                 
1285                 If the fieldCache is set, then it is supposed to be the body of a synthetic access method
1286                 factoring the actual descriptor creation out of the invocation site (saving space).
1287                 If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
1288                 we have no way to get a hand on the field cache to do better. */
1289         
1290         
1291                 // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
1292         
1293                 anyExceptionHandler = new ExceptionLabel(this, BaseTypes.NullBinding /* represents ClassNotFoundException*/);
1294                 this.ldc(accessedType == BaseTypes.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
1295                 this.invokeClassForName();
1296         
1297                 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
1298                 if (accessedType == BaseTypes.NullBinding) {
1299                         this.ldc("java.lang.Object"); //$NON-NLS-1$
1300                 } else if (accessedType.isArrayType()) {
1301                         this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
1302                 } else {
1303                         // we make it an array type (to avoid class initialization)
1304                         this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
1305                 }
1306                 this.invokeClassForName();
1307                 if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
1308                         this.invokeJavaLangClassGetComponentType();
1309                 }       
1310                 */
1311                 /* We need to protect the runtime code from binary inconsistencies
1312                 in case the accessedType is missing, the ClassNotFoundException has to be converted
1313                 into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
1314                 anyExceptionHandler.placeEnd();
1315         
1316                 if (syntheticFieldBinding != null) { // non interface case
1317                         this.dup();
1318                         this.putstatic(syntheticFieldBinding);
1319                 }
1320                 this.goto_(endLabel);
1321         
1322         
1323                 // Generate the body of the exception handler
1324                 saveStackSize = stackDepth;
1325                 stackDepth = 1;
1326                 /* ClassNotFoundException on stack -- the class literal could be doing more things
1327                 on the stack, which means that the stack may not be empty at this point in the
1328                 above code gen. So we save its state and restart it from 1. */
1329         
1330                 anyExceptionHandler.place();
1331         
1332                 // Transform the current exception, and repush and throw a 
1333                 // NoClassDefFoundError(ClassNotFound.getMessage())
1334         
1335                 this.newNoClassDefFoundError();
1336                 this.dup_x1();
1337                 this.swap();
1338         
1339                 // Retrieve the message from the old exception
1340                 this.invokeThrowableGetMessage();
1341         
1342                 // Send the constructor taking a message string as an argument
1343                 this.invokeNoClassDefFoundErrorStringConstructor();
1344                 this.athrow();
1345                 stackDepth = saveStackSize;
1346                 endLabel.place();
1347         }
1348 }
1349 /**
1350  * This method generates the code attribute bytecode
1351  */
1352 final public void generateCodeAttributeForProblemMethod(String problemMessage) {
1353         newJavaLangError();
1354         dup();
1355         ldc(problemMessage);
1356         invokeJavaLangErrorConstructor();
1357         athrow();
1358 }
1359 public void generateConstant(Constant constant, int implicitConversionCode) {
1360         int targetTypeID = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
1361         if (targetTypeID != 0) {
1362                 switch (targetTypeID) {
1363                         case T_boolean :
1364                                 generateInlinedValue(constant.booleanValue());
1365                                 break;
1366                         case T_char :
1367                                 generateInlinedValue(constant.charValue());
1368                                 break;
1369                         case T_byte :
1370                                 generateInlinedValue(constant.byteValue());
1371                                 break;
1372                         case T_short :
1373                                 generateInlinedValue(constant.shortValue());
1374                                 break;
1375                         case T_int :
1376                                 generateInlinedValue(constant.intValue());
1377                                 break;
1378                         case T_long :
1379                                 generateInlinedValue(constant.longValue());
1380                                 break;
1381                         case T_float :
1382                                 generateInlinedValue(constant.floatValue());
1383                                 break;
1384                         case T_double :
1385                                 generateInlinedValue(constant.doubleValue());
1386                                 break;
1387                         case T_JavaLangString :
1388                                 ldc(constant.stringValue());
1389                 }
1390         } else {
1391                 ldc(constant.stringValue());
1392         }
1393         if ((implicitConversionCode & BOXING) != 0) {
1394                 // need boxing
1395                 generateBoxingConversion(targetTypeID);
1396         }
1397 }
1398
1399 /**
1400  * Generates the sequence of instructions which will perform the conversion of the expression
1401  * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
1402  * @param implicitConversionCode int
1403  */
1404 public void generateImplicitConversion(int implicitConversionCode) {
1405         if ((implicitConversionCode & UNBOXING) != 0) {
1406                 final int typeId = implicitConversionCode & COMPILE_TYPE_MASK;
1407                 generateUnboxingConversion(typeId);
1408                 // unboxing can further involve base type conversions
1409         }
1410         switch (implicitConversionCode & IMPLICIT_CONVERSION_MASK) {
1411                 case Float2Char :
1412                         this.f2i();
1413                         this.i2c();
1414                         break;
1415                 case Double2Char :
1416                         this.d2i();
1417                         this.i2c();
1418                         break;
1419                 case Int2Char :
1420                 case Short2Char :
1421                 case Byte2Char :
1422                         this.i2c();
1423                         break;
1424                 case Long2Char :
1425                         this.l2i();
1426                         this.i2c();
1427                         break;
1428                 case Char2Float :
1429                 case Short2Float :
1430                 case Int2Float :
1431                 case Byte2Float :
1432                         this.i2f();
1433                         break;
1434                 case Double2Float :
1435                         this.d2f();
1436                         break;
1437                 case Long2Float :
1438                         this.l2f();
1439                         break;
1440                 case Float2Byte :
1441                         this.f2i();
1442                         this.i2b();
1443                         break;
1444                 case Double2Byte :
1445                         this.d2i();
1446                         this.i2b();
1447                         break;
1448                 case Int2Byte :
1449                 case Short2Byte :
1450                 case Char2Byte :
1451                         this.i2b();
1452                         break;
1453                 case Long2Byte :
1454                         this.l2i();
1455                         this.i2b();
1456                         break;
1457                 case Byte2Double :
1458                 case Char2Double :
1459                 case Short2Double :
1460                 case Int2Double :
1461                         this.i2d();
1462                         break;
1463                 case Float2Double :
1464                         this.f2d();
1465                         break;
1466                 case Long2Double :
1467                         this.l2d();
1468                         break;
1469                 case Byte2Short :
1470                 case Char2Short :
1471                 case Int2Short :
1472                         this.i2s();
1473                         break;
1474                 case Double2Short :
1475                         this.d2i();
1476                         this.i2s();
1477                         break;
1478                 case Long2Short :
1479                         this.l2i();
1480                         this.i2s();
1481                         break;
1482                 case Float2Short :
1483                         this.f2i();
1484                         this.i2s();
1485                         break;
1486                 case Double2Int :
1487                         this.d2i();
1488                         break;
1489                 case Float2Int :
1490                         this.f2i();
1491                         break;
1492                 case Long2Int :
1493                         this.l2i();
1494                         break;
1495                 case Int2Long :
1496                 case Char2Long :
1497                 case Byte2Long :
1498                 case Short2Long :
1499                         this.i2l();
1500                         break;
1501                 case Double2Long :
1502                         this.d2l();
1503                         break;
1504                 case Float2Long :
1505                         this.f2l();
1506         }
1507         if ((implicitConversionCode & BOXING) != 0) {
1508                 // need to unbox/box the constant
1509                 final int typeId = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4;
1510                 generateBoxingConversion(typeId);
1511         }
1512 }
1513 public void generateInlinedValue(byte inlinedValue) {
1514         switch (inlinedValue) {
1515                 case -1 :
1516                         this.iconst_m1();
1517                         break;
1518                 case 0 :
1519                         this.iconst_0();
1520                         break;
1521                 case 1 :
1522                         this.iconst_1();
1523                         break;
1524                 case 2 :
1525                         this.iconst_2();
1526                         break;
1527                 case 3 :
1528                         this.iconst_3();
1529                         break;
1530                 case 4 :
1531                         this.iconst_4();
1532                         break;
1533                 case 5 :
1534                         this.iconst_5();
1535                         break;
1536                 default :
1537                         if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1538                                 this.bipush(inlinedValue);
1539                                 return;
1540                         }
1541         }
1542 }
1543 public void generateInlinedValue(char inlinedValue) {
1544         switch (inlinedValue) {
1545                 case 0 :
1546                         this.iconst_0();
1547                         break;
1548                 case 1 :
1549                         this.iconst_1();
1550                         break;
1551                 case 2 :
1552                         this.iconst_2();
1553                         break;
1554                 case 3 :
1555                         this.iconst_3();
1556                         break;
1557                 case 4 :
1558                         this.iconst_4();
1559                         break;
1560                 case 5 :
1561                         this.iconst_5();
1562                         break;
1563                 default :
1564                         if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
1565                                 this.bipush((byte) inlinedValue);
1566                                 return;
1567                         }
1568                         if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
1569                                 this.sipush(inlinedValue);
1570                                 return;
1571                         }
1572                         this.ldc(inlinedValue);
1573         }
1574 }
1575 public void generateInlinedValue(double inlinedValue) {
1576         if (inlinedValue == 0.0) {
1577                 if (Double.doubleToLongBits(inlinedValue) != 0L)
1578                         this.ldc2_w(inlinedValue);
1579                 else
1580                         this.dconst_0();
1581                 return;
1582         }
1583         if (inlinedValue == 1.0) {
1584                 this.dconst_1();
1585                 return;
1586         }
1587         this.ldc2_w(inlinedValue);
1588 }
1589 public void generateInlinedValue(float inlinedValue) {
1590         if (inlinedValue == 0.0f) {
1591                 if (Float.floatToIntBits(inlinedValue) != 0)
1592                         this.ldc(inlinedValue);
1593                 else
1594                         this.fconst_0();
1595                 return;
1596         }
1597         if (inlinedValue == 1.0f) {
1598                 this.fconst_1();
1599                 return;
1600         }
1601         if (inlinedValue == 2.0f) {
1602                 this.fconst_2();
1603                 return;
1604         }
1605         this.ldc(inlinedValue);
1606 }
1607 public void generateInlinedValue(int inlinedValue) {
1608         switch (inlinedValue) {
1609                 case -1 :
1610                         this.iconst_m1();
1611                         break;
1612                 case 0 :
1613                         this.iconst_0();
1614                         break;
1615                 case 1 :
1616                         this.iconst_1();
1617                         break;
1618                 case 2 :
1619                         this.iconst_2();
1620                         break;
1621                 case 3 :
1622                         this.iconst_3();
1623                         break;
1624                 case 4 :
1625                         this.iconst_4();
1626                         break;
1627                 case 5 :
1628                         this.iconst_5();
1629                         break;
1630                 default :
1631                         if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1632                                 this.bipush((byte) inlinedValue);
1633                                 return;
1634                         }
1635                         if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
1636                                 this.sipush(inlinedValue);
1637                                 return;
1638                         }
1639                         this.ldc(inlinedValue);
1640         }
1641 }
1642 public void generateInlinedValue(long inlinedValue) {
1643         if (inlinedValue == 0) {
1644                 this.lconst_0();
1645                 return;
1646         }
1647         if (inlinedValue == 1) {
1648                 this.lconst_1();
1649                 return;
1650         }
1651         this.ldc2_w(inlinedValue);
1652 }
1653 public void generateInlinedValue(short inlinedValue) {
1654         switch (inlinedValue) {
1655                 case -1 :
1656                         this.iconst_m1();
1657                         break;
1658                 case 0 :
1659                         this.iconst_0();
1660                         break;
1661                 case 1 :
1662                         this.iconst_1();
1663                         break;
1664                 case 2 :
1665                         this.iconst_2();
1666                         break;
1667                 case 3 :
1668                         this.iconst_3();
1669                         break;
1670                 case 4 :
1671                         this.iconst_4();
1672                         break;
1673                 case 5 :
1674                         this.iconst_5();
1675                         break;
1676                 default :
1677                         if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
1678                                 this.bipush((byte) inlinedValue);
1679                                 return;
1680                         }
1681                         this.sipush(inlinedValue);
1682         }
1683 }
1684 public void generateInlinedValue(boolean inlinedValue) {
1685         if (inlinedValue)
1686                 this.iconst_1();
1687         else
1688                 this.iconst_0();
1689 }
1690 public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
1691         if (mappingSequence == null) {
1692                 if (target instanceof LocalVariableBinding) {
1693                         scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
1694                 } else {
1695                         scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
1696                 }
1697                 return;
1698         }
1699         if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
1700                 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
1701                 return;
1702         } else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
1703                 scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
1704                 return;
1705         }
1706         
1707         if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
1708                 this.aload_0();
1709                 return;
1710         } else if (mappingSequence[0] instanceof FieldBinding) {
1711                 FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
1712                 this.aload_0();
1713                 this.getfield(fieldBinding);
1714         } else {
1715                 load((LocalVariableBinding) mappingSequence[0]);
1716         }
1717         for (int i = 1, length = mappingSequence.length; i < length; i++) {
1718                 if (mappingSequence[i] instanceof FieldBinding) {
1719                         FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
1720                         this.getfield(fieldBinding);
1721                 } else {
1722                         this.invokestatic((MethodBinding) mappingSequence[i]);
1723                 }
1724         }
1725 }
1726
1727 /**
1728  * The equivalent code performs a string conversion:
1729  *
1730  * @param blockScope the given blockScope
1731  * @param oper1 the first expression
1732  * @param oper2 the second expression
1733  */
1734 public void generateStringConcatenationAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
1735         int pc;
1736         if (oper1 == null) {
1737                 /* Operand is already on the stack, and maybe nil:
1738                 note type1 is always to  java.lang.String here.*/
1739                 this.newStringContatenation();
1740                 this.dup_x1();
1741                 this.swap();
1742                 // If argument is reference type, need to transform it 
1743                 // into a string (handles null case)
1744                 this.invokeStringValueOf(T_JavaLangObject);
1745                 this.invokeStringConcatenationStringConstructor();
1746         } else {
1747                 pc = position;
1748                 oper1.generateOptimizedStringConcatenationCreation(blockScope, this, oper1.implicitConversion & COMPILE_TYPE_MASK);
1749                 this.recordPositionsFrom(pc, oper1.sourceStart);
1750         }
1751         pc = position;
1752         oper2.generateOptimizedStringConcatenation(blockScope, this, oper2.implicitConversion & COMPILE_TYPE_MASK);
1753         this.recordPositionsFrom(pc, oper2.sourceStart);
1754         this.invokeStringConcatenationToString();
1755 }
1756 /**
1757  * Code responsible to generate the suitable code to supply values for the synthetic enclosing
1758  * instance arguments of a constructor invocation of a nested type.
1759  */
1760 public void generateSyntheticEnclosingInstanceValues(
1761                 BlockScope currentScope, 
1762                 ReferenceBinding targetType, 
1763                 Expression enclosingInstance, 
1764                 ASTNode invocationSite) {
1765
1766         // supplying enclosing instance for the anonymous type's superclass
1767         ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? targetType.superclass() : targetType;
1768         boolean hasExtraEnclosingInstance = enclosingInstance != null;
1769         if (hasExtraEnclosingInstance 
1770                         && (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
1771                 currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
1772                 return;
1773         }
1774
1775         // perform some emulation work in case there is some and we are inside a local type only
1776         ReferenceBinding[] syntheticArgumentTypes;
1777         if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
1778
1779                 ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
1780                 boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
1781                 // deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
1782                 boolean ignoreEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
1783                                         || (complyTo14 && ((invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess())));
1784                                                 
1785                 for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
1786                         ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
1787                         if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
1788                                 hasExtraEnclosingInstance = false;
1789                                 enclosingInstance.generateCode(currentScope, this, true);
1790                                 if (complyTo14){
1791                                         dup();
1792                                         invokeObjectGetClass(); // will perform null check
1793                                         pop();
1794                                 }
1795                         } else {
1796                                 Object[] emulationPath = currentScope.getEmulationPath(
1797                                                 syntheticArgType, 
1798                                                 false /*not only exact match (that is, allow compatible)*/,
1799                                                 ignoreEnclosingArgInConstructorCall);
1800                                 this.generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
1801                         }
1802                 }
1803                 if (hasExtraEnclosingInstance){
1804                         currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
1805                 }
1806         }
1807 }
1808
1809 /**
1810  * Code responsible to generate the suitable code to supply values for the synthetic outer local
1811  * variable arguments of a constructor invocation of a nested type.
1812  * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
1813  */
1814 public void generateSyntheticOuterArgumentValues(BlockScope currentScope, ReferenceBinding targetType, ASTNode invocationSite) {
1815
1816         // generate the synthetic outer arguments then
1817         SyntheticArgumentBinding syntheticArguments[];
1818         if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
1819                 for (int i = 0, max = syntheticArguments.length; i < max; i++) {
1820                         LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
1821                         VariableBinding[] emulationPath = currentScope.getEmulationPath(targetVariable);
1822                         this.generateOuterAccess(emulationPath, invocationSite, targetVariable, currentScope);
1823                 }
1824         }
1825 }
1826
1827 /**
1828  * @param accessBinding the access method binding to generate
1829  */
1830 public void generateSyntheticBodyForConstructorAccess(SyntheticMethodBinding accessBinding) {
1831
1832         initializeMaxLocals(accessBinding);
1833
1834         MethodBinding constructorBinding = accessBinding.targetMethod;
1835         TypeBinding[] parameters = constructorBinding.parameters;
1836         int length = parameters.length;
1837         int resolvedPosition = 1;
1838         this.aload_0();
1839         // special name&ordinal argument generation for enum constructors
1840         TypeBinding declaringClass = constructorBinding.declaringClass;
1841         if (declaringClass.erasure().id == T_JavaLangEnum || declaringClass.isEnum()) {
1842                 this.aload_1(); // pass along name param as name arg
1843                 this.iload_2(); // pass along ordinal param as ordinal arg
1844         }       
1845         if (declaringClass.isNestedType()) {
1846                 NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
1847                 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
1848                 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1849                         TypeBinding type;
1850                         load((type = syntheticArguments[i].type), resolvedPosition);
1851                         if ((type == DoubleBinding) || (type == LongBinding))
1852                                 resolvedPosition += 2;
1853                         else
1854                                 resolvedPosition++;
1855                 }
1856         }
1857         for (int i = 0; i < length; i++) {
1858                 load(parameters[i], resolvedPosition);
1859                 if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding))
1860                         resolvedPosition += 2;
1861                 else
1862                         resolvedPosition++;
1863         }
1864         
1865         if (declaringClass.isNestedType()) {
1866                 NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
1867                 SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
1868                 for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
1869                         TypeBinding type;
1870                         load((type = syntheticArguments[i].type), resolvedPosition);
1871                         if ((type == DoubleBinding) || (type == LongBinding))
1872                                 resolvedPosition += 2;
1873                         else
1874                                 resolvedPosition++;
1875                 }
1876         }
1877         this.invokespecial(constructorBinding);
1878         this.return_();
1879 }
1880 //static X[] values() {
1881 // X[] values;
1882 // int length;
1883 // X[] result;
1884 // System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length)
1885 // return result;
1886 //}
1887 public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
1888         ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
1889         FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
1890         initializeMaxLocals(methodBinding);
1891         TypeBinding enumArray = methodBinding.returnType;
1892         
1893         this.getstatic(enumValuesSyntheticfield);
1894         this.dup();
1895         this.astore_0();
1896         this.iconst_0();
1897         this.aload_0();
1898         this.arraylength();
1899         this.dup();
1900         this.istore_1();
1901         this.newArray((ArrayBinding) enumArray);
1902         this.dup();
1903         this.astore_2();
1904         this.iconst_0();
1905         this.iload_1();
1906         this.invokeSystemArraycopy();
1907         this.aload_2();
1908         this.areturn();
1909 }
1910 //static X valueOf(String name) {
1911 // X[] values;
1912 // for (int i = (values = $VALUES).length; --i >= 0;) {
1913 //               X value;
1914 //               if (name.equals(value = values[i].name())) return value;
1915 // }
1916 // throw new IllegalArgumentException(name);
1917 //}             
1918 public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
1919         ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
1920         FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield;
1921         initializeMaxLocals(methodBinding);
1922         Label loopCond = new Label(this);
1923         Label loopStart = new Label(this);
1924         Label wrongConstant = new Label(this);
1925
1926         this.getstatic(enumValuesSyntheticfield);
1927         this.dup();
1928         this.astore_1();
1929         this.arraylength();
1930         this.istore_2();
1931         this.goto_(loopCond);
1932         loopStart.place();
1933         this.aload_0();
1934         this.aload_1();
1935         this.iload_2();
1936         this.aaload();
1937         this.dup();
1938         this.astore_3();
1939         this.invokeJavaLangEnumname(this.classFile.referenceBinding);
1940         this.invokeStringEquals();
1941         this.ifeq(wrongConstant);
1942         this.aload_3();
1943         this.areturn();
1944         wrongConstant.place();
1945         loopCond.place();
1946         this.iinc(2, -1);               
1947         this.iload_2();
1948         this.ifge(loopStart);
1949         this.newJavaLangIllegalArgumentException();
1950         this.dup();
1951         this.aload_0();
1952         this.invokeJavaLangIllegalArgumentExceptionStringConstructor();
1953         this.athrow();
1954 }
1955 public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
1956         initializeMaxLocals(accessBinding);
1957         FieldBinding fieldBinding = accessBinding.targetReadField;
1958         TypeBinding type;
1959         if (fieldBinding.isStatic())
1960                 this.getstatic(fieldBinding);
1961         else {
1962                 this.aload_0();
1963                 this.getfield(fieldBinding);
1964         }
1965         if ((type = fieldBinding.type).isBaseType()) {
1966                 if (type == IntBinding)
1967                         this.ireturn();
1968                 else
1969                         if (type == FloatBinding)
1970                                 this.freturn();
1971                         else
1972                                 if (type == LongBinding)
1973                                         this.lreturn();
1974                                 else
1975                                         if (type == DoubleBinding)
1976                                                 this.dreturn();
1977                                         else
1978                                                 this.ireturn();
1979         } else
1980                 this.areturn();
1981 }
1982 public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding accessBinding) {
1983         initializeMaxLocals(accessBinding);
1984         FieldBinding fieldBinding = accessBinding.targetWriteField;
1985         if (fieldBinding.isStatic()) {
1986                 load(fieldBinding.type, 0);
1987                 this.putstatic(fieldBinding);
1988         } else {
1989                 this.aload_0();
1990                 load(fieldBinding.type, 1);
1991                 this.putfield(fieldBinding);
1992         }
1993         this.return_();
1994 }
1995 public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessBinding) {
1996
1997         initializeMaxLocals(accessBinding);
1998         MethodBinding methodBinding = accessBinding.targetMethod;
1999         TypeBinding[] parameters = methodBinding.parameters;
2000         int length = parameters.length;
2001         TypeBinding[] arguments = accessBinding.kind == SyntheticMethodBinding.BridgeMethod 
2002                                                                                                         ? accessBinding.parameters
2003                                                                                                         : null;
2004         int resolvedPosition;
2005         if (methodBinding.isStatic())
2006                 resolvedPosition = 0;
2007         else {
2008                 this.aload_0();
2009                 resolvedPosition = 1;
2010         }
2011         for (int i = 0; i < length; i++) {
2012             TypeBinding parameter = parameters[i];
2013             if (arguments != null) { // for bridge methods
2014                     TypeBinding argument = arguments[i];
2015                         load(argument, resolvedPosition);
2016                         if (argument != parameter) 
2017                             checkcast(parameter);
2018             } else {
2019                         load(parameter, resolvedPosition);
2020                 }
2021                 if ((parameter == DoubleBinding) || (parameter == LongBinding))
2022                         resolvedPosition += 2;
2023                 else
2024                         resolvedPosition++;
2025         }
2026         TypeBinding type;
2027         if (methodBinding.isStatic())
2028                 this.invokestatic(methodBinding);
2029         else {
2030                 if (methodBinding.isConstructor()
2031                         || methodBinding.isPrivate()
2032                         // qualified super "X.super.foo()" targets methods from superclass
2033                         || accessBinding.kind == SyntheticMethodBinding.SuperMethodAccess){
2034                         this.invokespecial(methodBinding);
2035                 } else {
2036                         if ((methodBinding.declaringClass.modifiers & AccInterface) != 0) { // interface or annotation type
2037                                 this.invokeinterface(methodBinding);
2038                         } else {
2039                                 this.invokevirtual(methodBinding);
2040                         }
2041                 }
2042         }
2043         if ((type = methodBinding.returnType).isBaseType())
2044                 if (type == VoidBinding)
2045                         this.return_();
2046                 else
2047                         if (type == IntBinding)
2048                                 this.ireturn();
2049                         else
2050                                 if (type == FloatBinding)
2051                                         this.freturn();
2052                                 else
2053                                         if (type == LongBinding)
2054                                                 this.lreturn();
2055                                         else
2056                                                 if (type == DoubleBinding)
2057                                                         this.dreturn();
2058                                                 else
2059                                                         this.ireturn();
2060         else
2061                 this.areturn();
2062 }
2063 public void generateBoxingConversion(int unboxedTypeID) {
2064         switch (unboxedTypeID) {
2065                 case T_byte :
2066                         // invokestatic: Byte.valueOf(byte)
2067                         this.invoke(
2068                                 OPC_invokestatic,
2069                                 1, // argCount
2070                                 1, // return type size
2071                                 ConstantPool.JavaLangByteConstantPoolName,
2072                                 ConstantPool.ValueOf,
2073                                 ConstantPool.byteByteSignature); //$NON-NLS-1$
2074                         break;
2075                 case T_short :
2076                         // invokestatic: Short.valueOf(short)
2077                         this.invoke(
2078                                 OPC_invokestatic,
2079                                 1, // argCount
2080                                 1, // return type size
2081                                 ConstantPool.JavaLangShortConstantPoolName,
2082                                 ConstantPool.ValueOf,
2083                                 ConstantPool.shortShortSignature); //$NON-NLS-1$
2084                         break;
2085                 case T_char :
2086                         // invokestatic: Character.valueOf(char)
2087                         this.invoke(
2088                                 OPC_invokestatic,
2089                                 1, // argCount
2090                                 1, // return type size
2091                                 ConstantPool.JavaLangCharacterConstantPoolName,
2092                                 ConstantPool.ValueOf,
2093                                 ConstantPool.charCharacterSignature); //$NON-NLS-1$
2094                         break;
2095                 case T_int :
2096                         // invokestatic: Integer.valueOf(int)
2097                         this.invoke(
2098                                 OPC_invokestatic,
2099                                 1, // argCount
2100                                 1, // return type size
2101                                 ConstantPool.JavaLangIntegerConstantPoolName,
2102                                 ConstantPool.ValueOf,
2103                                 ConstantPool.IntIntegerSignature); //$NON-NLS-1$
2104                         break;
2105                 case T_long :
2106                         // invokestatic: Long.valueOf(long)
2107                         this.invoke(
2108                                 OPC_invokestatic,
2109                                 2, // argCount
2110                                 1, // return type size
2111                                 ConstantPool.JavaLangLongConstantPoolName,
2112                                 ConstantPool.ValueOf,
2113                                 ConstantPool.longLongSignature); //$NON-NLS-1$
2114                         break;
2115                 case T_float :
2116                         // invokestatic: Float.valueOf(float)
2117                         this.invoke(
2118                                 OPC_invokestatic,
2119                                 1, // argCount
2120                                 1, // return type size
2121                                 ConstantPool.JavaLangFloatConstantPoolName,
2122                                 ConstantPool.ValueOf,
2123                                 ConstantPool.floatFloatSignature); //$NON-NLS-1$
2124                         break;
2125                 case T_double :
2126                         // invokestatic: Double.valueOf(double)
2127                         this.invoke(
2128                                 OPC_invokestatic,
2129                                 2, // argCount
2130                                 1, // return type size
2131                                 ConstantPool.JavaLangDoubleConstantPoolName,
2132                                 ConstantPool.ValueOf,
2133                                 ConstantPool.doubleDoubleSignature); //$NON-NLS-1$
2134                         break;
2135                 case T_boolean :
2136                         // invokestatic: Boolean.valueOf(boolean)
2137                         this.invoke(
2138                                 OPC_invokestatic,
2139                                 1, // argCount
2140                                 1, // return type size
2141                                 ConstantPool.JavaLangBooleanConstantPoolName,
2142                                 ConstantPool.ValueOf,
2143                                 ConstantPool.booleanBooleanSignature); //$NON-NLS-1$
2144         }
2145 }
2146 public void generateUnboxingConversion(int unboxedTypeID) {
2147         switch (unboxedTypeID) {
2148                 case T_byte :
2149                         // invokevirtual: byteValue()
2150                         this.invoke(
2151                                         OPC_invokevirtual,
2152                                         0, // argCount
2153                                         1, // return type size
2154                                         ConstantPool.JavaLangByteConstantPoolName,
2155                                         ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
2156                                         ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
2157                         break;
2158                 case T_short :
2159                         // invokevirtual: shortValue()
2160                         this.invoke(
2161                                         OPC_invokevirtual,
2162                                         0, // argCount
2163                                         1, // return type size
2164                                         ConstantPool.JavaLangShortConstantPoolName,
2165                                         ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
2166                                         ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
2167                         break;
2168                 case T_char :
2169                         // invokevirtual: charValue()
2170                         this.invoke(
2171                                         OPC_invokevirtual,
2172                                         0, // argCount
2173                                         1, // return type size
2174                                         ConstantPool.JavaLangCharacterConstantPoolName,
2175                                         ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
2176                                         ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
2177                         break;
2178                 case T_int :
2179                         // invokevirtual: intValue()
2180                         this.invoke(
2181                                         OPC_invokevirtual,
2182                                         0, // argCount
2183                                         1, // return type size
2184                                         ConstantPool.JavaLangIntegerConstantPoolName,
2185                                         ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
2186                                         ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
2187                         break;
2188                 case T_long :
2189                         // invokevirtual: longValue()
2190                         this.invoke(
2191                                         OPC_invokevirtual,
2192                                         0, // argCount
2193                                         2, // return type size
2194                                         ConstantPool.JavaLangLongConstantPoolName,
2195                                         ConstantPool.LONGVALUE_LONG_METHOD_NAME,
2196                                         ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
2197                         break;
2198                 case T_float :
2199                         // invokevirtual: floatValue()
2200                         this.invoke(
2201                                         OPC_invokevirtual,
2202                                         0, // argCount
2203                                         1, // return type size
2204                                         ConstantPool.JavaLangFloatConstantPoolName,
2205                                         ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
2206                                         ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
2207                         break;
2208                 case T_double :
2209                         // invokevirtual: doubleValue()
2210                         this.invoke(
2211                                         OPC_invokevirtual,
2212                                         0, // argCount
2213                                         2, // return type size
2214                                         ConstantPool.JavaLangDoubleConstantPoolName,
2215                                         ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
2216                                         ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
2217                         break;
2218                 case T_boolean :
2219                         // invokevirtual: booleanValue()
2220                         this.invoke(
2221                                         OPC_invokevirtual,
2222                                         0, // argCount
2223                                         1, // return type size
2224                                         ConstantPool.JavaLangBooleanConstantPoolName,
2225                                         ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
2226                                         ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
2227         }
2228 }
2229 final public byte[] getContents() {
2230         byte[] contents;
2231         System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position);
2232         return contents;
2233 }
2234 final public void getfield(FieldBinding fieldBinding) {
2235         if (DEBUG) System.out.println(position + "\t\tgetfield:"+fieldBinding); //$NON-NLS-1$
2236         int returnTypeSize = 1;
2237         if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
2238                 returnTypeSize = 2;
2239         }
2240         generateFieldAccess(
2241                         OPC_getfield,
2242                         returnTypeSize,
2243                         fieldBinding.declaringClass.constantPoolName(),
2244                         fieldBinding.name,
2245                         fieldBinding.type.signature());
2246 }
2247 private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) {
2248         countLabels = 0;
2249         switch(opcode) {
2250                 case OPC_getfield :
2251                         if (returnTypeSize == 2) {
2252                                 stackDepth++;
2253                         }
2254                         break;
2255                 case OPC_getstatic :
2256                         if (returnTypeSize == 2) {
2257                                 stackDepth += 2;
2258                         } else {
2259                                 stackDepth++;
2260                         }
2261                         break;
2262                 case OPC_putfield :
2263                         if (returnTypeSize == 2) {
2264                                 stackDepth -= 3;
2265                         } else {
2266                                 stackDepth -= 2;
2267                         }
2268                         break;
2269                 case OPC_putstatic :
2270                         if (returnTypeSize == 2) {
2271                                 stackDepth -= 2;
2272                         } else {
2273                                 stackDepth--;
2274                         }
2275         }
2276         if (stackDepth > stackMax) {
2277                 stackMax = stackDepth;
2278         }
2279         if (classFileOffset + 2 >= bCodeStream.length) {
2280                 resizeByteArray();
2281         }
2282         position++;
2283         bCodeStream[classFileOffset++] = opcode;
2284         writeUnsignedShort(constantPool.literalIndexForField(declaringClass, name, signature));
2285 }
2286 final public void getstatic(FieldBinding fieldBinding) {
2287         if (DEBUG) System.out.println(position + "\t\tgetstatic:"+fieldBinding); //$NON-NLS-1$
2288         int returnTypeSize = 1;
2289         if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
2290                 returnTypeSize = 2;
2291         }
2292         generateFieldAccess(
2293                         OPC_getstatic,
2294                         returnTypeSize,
2295                         fieldBinding.declaringClass.constantPoolName(),
2296                         fieldBinding.name,
2297                         fieldBinding.type.signature());
2298 }
2299 public void getTYPE(int baseTypeID) {
2300         countLabels = 0;
2301         switch (baseTypeID) {
2302                 case T_byte :
2303                         // getstatic: java.lang.Byte.TYPE                       
2304                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$
2305                         generateFieldAccess(
2306                                         OPC_getstatic,
2307                                         1,
2308                                         ConstantPool.JavaLangByteConstantPoolName,
2309                                         ConstantPool.TYPE,
2310                                         ConstantPool.JavaLangClassSignature);
2311                         break;
2312                 case T_short :
2313                         // getstatic: java.lang.Short.TYPE                      
2314                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$
2315                         generateFieldAccess(
2316                                         OPC_getstatic,
2317                                         1,
2318                                         ConstantPool.JavaLangShortConstantPoolName,
2319                                         ConstantPool.TYPE,
2320                                         ConstantPool.JavaLangClassSignature);
2321                         break;
2322                 case T_char :
2323                         // getstatic: java.lang.Character.TYPE                  
2324                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$
2325                         generateFieldAccess(
2326                                         OPC_getstatic,
2327                                         1,
2328                                         ConstantPool.JavaLangCharacterConstantPoolName,
2329                                         ConstantPool.TYPE,
2330                                         ConstantPool.JavaLangClassSignature);
2331                         break;
2332                 case T_int :
2333                         // getstatic: java.lang.Integer.TYPE                    
2334                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$
2335                         generateFieldAccess(
2336                                         OPC_getstatic,
2337                                         1,
2338                                         ConstantPool.JavaLangIntegerConstantPoolName,
2339                                         ConstantPool.TYPE,
2340                                         ConstantPool.JavaLangClassSignature);
2341                         break;
2342                 case T_long :
2343                         // getstatic: java.lang.Long.TYPE                       
2344                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$
2345                         generateFieldAccess(
2346                                         OPC_getstatic,
2347                                         1,
2348                                         ConstantPool.JavaLangLongConstantPoolName,
2349                                         ConstantPool.TYPE,
2350                                         ConstantPool.JavaLangClassSignature);
2351                         break;
2352                 case T_float :
2353                         // getstatic: java.lang.Float.TYPE                      
2354                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$
2355                         generateFieldAccess(
2356                                         OPC_getstatic,
2357                                         1,
2358                                         ConstantPool.JavaLangFloatConstantPoolName,
2359                                         ConstantPool.TYPE,
2360                                         ConstantPool.JavaLangClassSignature);
2361                         break;
2362                 case T_double :
2363                         // getstatic: java.lang.Double.TYPE                     
2364                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$
2365                         generateFieldAccess(
2366                                         OPC_getstatic,
2367                                         1,
2368                                         ConstantPool.JavaLangDoubleConstantPoolName,
2369                                         ConstantPool.TYPE,
2370                                         ConstantPool.JavaLangClassSignature);
2371                         break;
2372                 case T_boolean :
2373                         // getstatic: java.lang.Boolean.TYPE                    
2374                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$
2375                         generateFieldAccess(
2376                                         OPC_getstatic,
2377                                         1,
2378                                         ConstantPool.JavaLangBooleanConstantPoolName,
2379                                         ConstantPool.TYPE,
2380                                         ConstantPool.JavaLangClassSignature);
2381                         break;
2382                 case T_void :
2383                         // getstatic: java.lang.Void.TYPE
2384                         if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$
2385                         generateFieldAccess(
2386                                         OPC_getstatic,
2387                                         1,
2388                                         ConstantPool.JavaLangVoidConstantPoolName,
2389                                         ConstantPool.TYPE,
2390                                         ConstantPool.JavaLangClassSignature);
2391                         break;
2392         }
2393 }
2394 /**
2395  * We didn't call it goto, because there is a conflit with the goto keyword
2396  */
2397 final public void goto_(Label label) {
2398         if (this.wideMode) {
2399                 this.goto_w(label);
2400                 return;
2401         }
2402         if (DEBUG) System.out.println(position + "\t\tgoto:"+label); //$NON-NLS-1$
2403         if (classFileOffset >= bCodeStream.length) {
2404                 resizeByteArray();
2405         }
2406         label.inlineForwardReferencesFromLabelsTargeting(position);
2407         /*
2408          Possible optimization for code such as:
2409          public Object foo() {
2410                 boolean b = true;
2411                 if (b) {
2412                         if (b)
2413                                 return null;
2414                 } else {
2415                         if (b) {
2416                                 return null;
2417                         }
2418                 }
2419                 return null;
2420         }
2421         The goto around the else block for the first if will
2422         be unreachable, because the thenClause of the second if
2423         returns.
2424         See inlineForwardReferencesFromLabelsTargeting defined
2425         on the Label class for the remaining part of this
2426         optimization.
2427          if (!lbl.isBranchTarget(position)) {
2428                 switch(bCodeStream[classFileOffset-1]) {
2429                         case OPC_return :
2430                         case OPC_areturn:
2431                                 return;
2432                 }
2433         }*/
2434         position++;
2435         bCodeStream[classFileOffset++] = OPC_goto;
2436         label.branch();
2437 }
2438
2439 final public void goto_w(Label lbl) {
2440         if (DEBUG) System.out.println(position + "\t\tgotow:"+lbl); //$NON-NLS-1$
2441         if (classFileOffset >= bCodeStream.length) {
2442                 resizeByteArray();
2443         }
2444         position++;
2445         bCodeStream[classFileOffset++] = OPC_goto_w;
2446         lbl.branchWide();
2447 }
2448 final public void i2b() {
2449         if (DEBUG) System.out.println(position + "\t\ti2b"); //$NON-NLS-1$
2450         countLabels = 0;
2451         if (classFileOffset >= bCodeStream.length) {
2452                 resizeByteArray();
2453         }
2454         position++;
2455         bCodeStream[classFileOffset++] = OPC_i2b;
2456 }
2457 final public void i2c() {
2458         if (DEBUG) System.out.println(position + "\t\ti2c"); //$NON-NLS-1$
2459         countLabels = 0;
2460         if (classFileOffset >= bCodeStream.length) {
2461                 resizeByteArray();
2462         }
2463         position++;
2464         bCodeStream[classFileOffset++] = OPC_i2c;
2465 }
2466 final public void i2d() {
2467         if (DEBUG) System.out.println(position + "\t\ti2d"); //$NON-NLS-1$
2468         countLabels = 0;
2469         stackDepth++;
2470         if (stackDepth > stackMax)
2471                 stackMax = stackDepth;
2472         if (classFileOffset >= bCodeStream.length) {
2473                 resizeByteArray();
2474         }
2475         position++;
2476         bCodeStream[classFileOffset++] = OPC_i2d;
2477 }
2478 final public void i2f() {
2479         if (DEBUG) System.out.println(position + "\t\ti2f"); //$NON-NLS-1$
2480         countLabels = 0;
2481         if (classFileOffset >= bCodeStream.length) {
2482                 resizeByteArray();
2483         }
2484         position++;
2485         bCodeStream[classFileOffset++] = OPC_i2f;
2486 }
2487 final public void i2l() {
2488         if (DEBUG) System.out.println(position + "\t\ti2l"); //$NON-NLS-1$
2489         countLabels = 0;
2490         stackDepth++;
2491         if (stackDepth > stackMax)
2492                 stackMax = stackDepth;
2493         if (classFileOffset >= bCodeStream.length) {
2494                 resizeByteArray();
2495         }
2496         position++;
2497         bCodeStream[classFileOffset++] = OPC_i2l;
2498 }
2499 final public void i2s() {
2500         if (DEBUG) System.out.println(position + "\t\ti2s"); //$NON-NLS-1$
2501         countLabels = 0;
2502         if (classFileOffset >= bCodeStream.length) {
2503                 resizeByteArray();
2504         }
2505         position++;
2506         bCodeStream[classFileOffset++] = OPC_i2s;
2507 }
2508 final public void iadd() {
2509         if (DEBUG) System.out.println(position + "\t\tiadd"); //$NON-NLS-1$
2510         countLabels = 0;
2511         stackDepth--;
2512         if (classFileOffset >= bCodeStream.length) {
2513                 resizeByteArray();
2514         }
2515         position++;
2516         bCodeStream[classFileOffset++] = OPC_iadd;
2517 }
2518 final public void iaload() {
2519         if (DEBUG) System.out.println(position + "\t\tiaload"); //$NON-NLS-1$
2520         countLabels = 0;
2521         stackDepth--;
2522         if (classFileOffset >= bCodeStream.length) {
2523                 resizeByteArray();
2524         }
2525         position++;
2526         bCodeStream[classFileOffset++] = OPC_iaload;
2527 }
2528 final public void iand() {
2529         if (DEBUG) System.out.println(position + "\t\tiand"); //$NON-NLS-1$
2530         countLabels = 0;
2531         stackDepth--;
2532         if (classFileOffset >= bCodeStream.length) {
2533                 resizeByteArray();
2534         }
2535         position++;
2536         bCodeStream[classFileOffset++] = OPC_iand;
2537 }
2538 final public void iastore() {
2539         if (DEBUG) System.out.println(position + "\t\tiastore"); //$NON-NLS-1$
2540         countLabels = 0;
2541         stackDepth -= 3;
2542         if (classFileOffset >= bCodeStream.length) {
2543                 resizeByteArray();
2544         }
2545         position++;
2546         bCodeStream[classFileOffset++] = OPC_iastore;
2547 }
2548 final public void iconst_0() {
2549         if (DEBUG) System.out.println(position + "\t\ticonst_0"); //$NON-NLS-1$
2550         countLabels = 0;
2551         stackDepth++;
2552         if (stackDepth > stackMax)
2553                 stackMax = stackDepth;
2554         if (classFileOffset >= bCodeStream.length) {
2555                 resizeByteArray();
2556         }
2557         position++;
2558         bCodeStream[classFileOffset++] = OPC_iconst_0;
2559 }
2560 final public void iconst_1() {
2561         if (DEBUG) System.out.println(position + "\t\ticonst_1"); //$NON-NLS-1$
2562         countLabels = 0;
2563         stackDepth++;
2564         if (stackDepth > stackMax)
2565                 stackMax = stackDepth;
2566         if (classFileOffset >= bCodeStream.length) {
2567                 resizeByteArray();
2568         }
2569         position++;
2570         bCodeStream[classFileOffset++] = OPC_iconst_1;
2571 }
2572 final public void iconst_2() {
2573         if (DEBUG) System.out.println(position + "\t\ticonst_2"); //$NON-NLS-1$
2574         countLabels = 0;
2575         stackDepth++;
2576         if (stackDepth > stackMax)
2577                 stackMax = stackDepth;
2578         if (classFileOffset >= bCodeStream.length) {
2579                 resizeByteArray();
2580         }
2581         position++;
2582         bCodeStream[classFileOffset++] = OPC_iconst_2;
2583 }
2584 final public void iconst_3() {
2585         if (DEBUG) System.out.println(position + "\t\ticonst_3"); //$NON-NLS-1$
2586         countLabels = 0;
2587         stackDepth++;
2588         if (stackDepth > stackMax)
2589                 stackMax = stackDepth;
2590         if (classFileOffset >= bCodeStream.length) {
2591                 resizeByteArray();
2592         }
2593         position++;
2594         bCodeStream[classFileOffset++] = OPC_iconst_3;
2595 }
2596 final public void iconst_4() {
2597         if (DEBUG) System.out.println(position + "\t\ticonst_4"); //$NON-NLS-1$
2598         countLabels = 0;
2599         stackDepth++;
2600         if (stackDepth > stackMax)
2601                 stackMax = stackDepth;
2602         if (classFileOffset >= bCodeStream.length) {
2603                 resizeByteArray();
2604         }
2605         position++;
2606         bCodeStream[classFileOffset++] = OPC_iconst_4;
2607 }
2608 final public void iconst_5() {
2609         if (DEBUG) System.out.println(position + "\t\ticonst_5"); //$NON-NLS-1$
2610         countLabels = 0;
2611         stackDepth++;
2612         if (stackDepth > stackMax)
2613                 stackMax = stackDepth;
2614         if (classFileOffset >= bCodeStream.length) {
2615                 resizeByteArray();
2616         }
2617         position++;
2618         bCodeStream[classFileOffset++] = OPC_iconst_5;
2619 }
2620 final public void iconst_m1() {
2621         if (DEBUG) System.out.println(position + "\t\ticonst_m1"); //$NON-NLS-1$
2622         countLabels = 0;
2623         stackDepth++;
2624         if (stackDepth > stackMax)
2625                 stackMax = stackDepth;
2626         if (classFileOffset >= bCodeStream.length) {
2627                 resizeByteArray();
2628         }
2629         position++;
2630         bCodeStream[classFileOffset++] = OPC_iconst_m1;
2631 }
2632 final public void idiv() {
2633         if (DEBUG) System.out.println(position + "\t\tidiv"); //$NON-NLS-1$
2634         countLabels = 0;
2635         stackDepth--;
2636         if (classFileOffset >= bCodeStream.length) {
2637                 resizeByteArray();
2638         }
2639         position++;
2640         bCodeStream[classFileOffset++] = OPC_idiv;
2641 }
2642 final public void if_acmpeq(Label lbl) {
2643         if (DEBUG) System.out.println(position + "\t\tif_acmpeq:"+lbl); //$NON-NLS-1$
2644         countLabels = 0;
2645         stackDepth-=2;
2646         if (this.wideMode) {
2647                 generateWideRevertedConditionalBranch(OPC_if_acmpne, lbl);
2648         } else {        
2649                 if (classFileOffset >= bCodeStream.length) {
2650                         resizeByteArray();
2651                 }
2652                 position++;
2653                 bCodeStream[classFileOffset++] = OPC_if_acmpeq;
2654                 lbl.branch();
2655         }
2656 }
2657 final public void if_acmpne(Label lbl) {
2658         if (DEBUG) System.out.println(position + "\t\tif_acmpne:"+lbl); //$NON-NLS-1$
2659         countLabels = 0;
2660         stackDepth-=2;
2661         if (this.wideMode) {
2662                 generateWideRevertedConditionalBranch(OPC_if_acmpeq, lbl);
2663         } else {        
2664                 if (classFileOffset >= bCodeStream.length) {
2665                         resizeByteArray();
2666                 }
2667                 position++;
2668                 bCodeStream[classFileOffset++] = OPC_if_acmpne;
2669                 lbl.branch();
2670         }
2671 }
2672 final public void if_icmpeq(Label lbl) {
2673         if (DEBUG) System.out.println(position + "\t\tif_cmpeq:"+lbl); //$NON-NLS-1$
2674         countLabels = 0;
2675         stackDepth -= 2;
2676         if (this.wideMode) {
2677                 generateWideRevertedConditionalBranch(OPC_if_icmpne, lbl);
2678         } else {        
2679                 if (classFileOffset >= bCodeStream.length) {
2680                         resizeByteArray();
2681                 }
2682                 position++;
2683                 bCodeStream[classFileOffset++] = OPC_if_icmpeq;
2684                 lbl.branch();
2685         }
2686 }
2687 final public void if_icmpge(Label lbl) {
2688         if (DEBUG) System.out.println(position + "\t\tif_iacmpge:"+lbl); //$NON-NLS-1$
2689         countLabels = 0;
2690         stackDepth -= 2;
2691         if (this.wideMode) {
2692                 generateWideRevertedConditionalBranch(OPC_if_icmplt, lbl);
2693         } else {        
2694                 if (classFileOffset >= bCodeStream.length) {
2695                         resizeByteArray();
2696                 }
2697                 position++;
2698                 bCodeStream[classFileOffset++] = OPC_if_icmpge;
2699                 lbl.branch();
2700         }
2701 }
2702 final public void if_icmpgt(Label lbl) {
2703         if (DEBUG) System.out.println(position + "\t\tif_iacmpgt:"+lbl); //$NON-NLS-1$
2704         countLabels = 0;
2705         stackDepth -= 2;
2706         if (this.wideMode) {
2707                 generateWideRevertedConditionalBranch(OPC_if_icmple, lbl);
2708         } else {        
2709                 if (classFileOffset >= bCodeStream.length) {
2710                         resizeByteArray();
2711                 }
2712                 position++;
2713                 bCodeStream[classFileOffset++] = OPC_if_icmpgt;
2714                 lbl.branch();
2715         }
2716 }
2717 final public void if_icmple(Label lbl) {
2718         if (DEBUG) System.out.println(position + "\t\tif_iacmple:"+lbl); //$NON-NLS-1$
2719         countLabels = 0;
2720         stackDepth -= 2;
2721         if (this.wideMode) {
2722                 generateWideRevertedConditionalBranch(OPC_if_icmpgt, lbl);
2723         } else {        
2724                 if (classFileOffset >= bCodeStream.length) {
2725                         resizeByteArray();
2726                 }
2727                 position++;
2728                 bCodeStream[classFileOffset++] = OPC_if_icmple;
2729                 lbl.branch();
2730         }
2731 }
2732 final public void if_icmplt(Label lbl) {
2733         if (DEBUG) System.out.println(position + "\t\tif_iacmplt:"+lbl); //$NON-NLS-1$
2734         countLabels = 0;
2735         stackDepth -= 2;
2736         if (this.wideMode) {
2737                 generateWideRevertedConditionalBranch(OPC_if_icmpge, lbl);
2738         } else {
2739                 if (classFileOffset >= bCodeStream.length) {
2740                         resizeByteArray();
2741                 }
2742                 position++;
2743                 bCodeStream[classFileOffset++] = OPC_if_icmplt;
2744                 lbl.branch();
2745         }
2746 }
2747 final public void if_icmpne(Label lbl) {
2748         if (DEBUG) System.out.println(position + "\t\tif_iacmpne:"+lbl); //$NON-NLS-1$
2749         countLabels = 0;
2750         stackDepth -= 2;
2751         if (this.wideMode) {
2752                 generateWideRevertedConditionalBranch(OPC_if_icmpeq, lbl);
2753         } else {
2754                 if (classFileOffset >= bCodeStream.length) {
2755                         resizeByteArray();
2756                 }
2757                 position++;
2758                 bCodeStream[classFileOffset++] = OPC_if_icmpne;
2759                 lbl.branch();
2760         }
2761 }
2762 final public void ifeq(Label lbl) {
2763         if (DEBUG) System.out.println(position + "\t\tifeq:"+lbl); //$NON-NLS-1$
2764         countLabels = 0;
2765         stackDepth--;
2766         if (this.wideMode) {
2767                 generateWideRevertedConditionalBranch(OPC_ifne, lbl);
2768         } else {
2769                 if (classFileOffset >= bCodeStream.length) {
2770                         resizeByteArray();
2771                 }
2772                 position++;
2773                 bCodeStream[classFileOffset++] = OPC_ifeq;
2774                 lbl.branch();
2775         }
2776 }
2777 final public void ifge(Label lbl) {
2778         if (DEBUG) System.out.println(position + "\t\tifge:"+lbl); //$NON-NLS-1$
2779         countLabels = 0;
2780         stackDepth--;
2781         if (this.wideMode) {
2782                 generateWideRevertedConditionalBranch(OPC_iflt, lbl);
2783         } else {
2784                 if (classFileOffset >= bCodeStream.length) {
2785                         resizeByteArray();
2786                 }
2787                 position++;
2788                 bCodeStream[classFileOffset++] = OPC_ifge;
2789                 lbl.branch();
2790         }
2791 }
2792 final public void ifgt(Label lbl) {
2793         if (DEBUG) System.out.println(position + "\t\tifgt:"+lbl); //$NON-NLS-1$
2794         countLabels = 0;
2795         stackDepth--;
2796         if (this.wideMode) {
2797                 generateWideRevertedConditionalBranch(OPC_ifle, lbl);
2798         } else {
2799                 if (classFileOffset >= bCodeStream.length) {
2800                         resizeByteArray();
2801                 }
2802                 position++;
2803                 bCodeStream[classFileOffset++] = OPC_ifgt;
2804                 lbl.branch();
2805         }
2806 }
2807 final public void ifle(Label lbl) {
2808         if (DEBUG) System.out.println(position + "\t\tifle:"+lbl); //$NON-NLS-1$
2809         countLabels = 0;
2810         stackDepth--;
2811         if (this.wideMode) {
2812                 generateWideRevertedConditionalBranch(OPC_ifgt, lbl);
2813         } else {
2814                 if (classFileOffset >= bCodeStream.length) {
2815                         resizeByteArray();
2816                 }
2817                 position++;
2818                 bCodeStream[classFileOffset++] = OPC_ifle;
2819                 lbl.branch();
2820         }
2821 }
2822 final public void iflt(Label lbl) {
2823         if (DEBUG) System.out.println(position + "\t\tiflt:"+lbl); //$NON-NLS-1$
2824         countLabels = 0;
2825         stackDepth--;
2826         if (this.wideMode) {
2827                 generateWideRevertedConditionalBranch(OPC_ifge, lbl);
2828         } else {
2829                 if (classFileOffset >= bCodeStream.length) {
2830                         resizeByteArray();
2831                 }
2832                 position++;
2833                 bCodeStream[classFileOffset++] = OPC_iflt;
2834                 lbl.branch();
2835         }
2836 }
2837 final public void ifne(Label lbl) {
2838         if (DEBUG) System.out.println(position + "\t\tifne:"+lbl); //$NON-NLS-1$
2839         countLabels = 0;
2840         stackDepth--;
2841         if (this.wideMode) {
2842                 generateWideRevertedConditionalBranch(OPC_ifeq, lbl);
2843         } else {
2844                 if (classFileOffset >= bCodeStream.length) {
2845                         resizeByteArray();
2846                 }
2847                 position++;
2848                 bCodeStream[classFileOffset++] = OPC_ifne;
2849                 lbl.branch();
2850         }
2851 }
2852 final public void ifnonnull(Label lbl) {
2853         if (DEBUG) System.out.println(position + "\t\tifnonnull:"+lbl); //$NON-NLS-1$
2854         countLabels = 0;
2855         stackDepth--;
2856         if (this.wideMode) {
2857                 generateWideRevertedConditionalBranch(OPC_ifnull, lbl);
2858         } else {
2859                 if (classFileOffset >= bCodeStream.length) {
2860                         resizeByteArray();
2861                 }
2862                 position++;
2863                 bCodeStream[classFileOffset++] = OPC_ifnonnull;
2864                 lbl.branch();
2865         }
2866 }
2867 final public void ifnull(Label lbl) {
2868         if (DEBUG) System.out.println(position + "\t\tifnull:"+lbl); //$NON-NLS-1$
2869         countLabels = 0;
2870         stackDepth--;
2871         if (this.wideMode) {
2872                 generateWideRevertedConditionalBranch(OPC_ifnonnull, lbl);
2873         } else {
2874                 if (classFileOffset >= bCodeStream.length) {
2875                         resizeByteArray();
2876                 }
2877                 position++;
2878                 bCodeStream[classFileOffset++] = OPC_ifnull;
2879                 lbl.branch();
2880         }
2881 }
2882 final public void iinc(int index, int value) {
2883         if (DEBUG) System.out.println(position + "\t\tiinc:"+index+","+value); //$NON-NLS-1$ //$NON-NLS-2$
2884         countLabels = 0;
2885         if ((index > 255) || (value < -128 || value > 127)) { // have to widen
2886                 if (classFileOffset + 3 >= bCodeStream.length) {
2887                         resizeByteArray();
2888                 }
2889                 position += 2;
2890                 bCodeStream[classFileOffset++] = OPC_wide;
2891                 bCodeStream[classFileOffset++] = OPC_iinc;
2892                 writeUnsignedShort(index);
2893                 writeSignedShort(value);
2894         } else {
2895                 if (classFileOffset + 2 >= bCodeStream.length) {
2896                         resizeByteArray();
2897                 }
2898                 position += 3;
2899                 bCodeStream[classFileOffset++] = OPC_iinc;
2900                 bCodeStream[classFileOffset++] = (byte) index;
2901                 bCodeStream[classFileOffset++] = (byte) value;
2902         }
2903 }
2904 final public void iload(int iArg) {
2905         if (DEBUG) System.out.println(position + "\t\tiload:"+iArg); //$NON-NLS-1$
2906         countLabels = 0;
2907         stackDepth++;
2908         if (maxLocals <= iArg) {
2909                 maxLocals = iArg + 1;
2910         }
2911         if (stackDepth > stackMax)
2912                 stackMax = stackDepth;
2913         if (iArg > 255) { // Widen
2914                 if (classFileOffset + 3 >= bCodeStream.length) {
2915                         resizeByteArray();
2916                 }
2917                 position += 2;
2918                 bCodeStream[classFileOffset++] = OPC_wide;
2919                 bCodeStream[classFileOffset++] = OPC_iload;
2920                 writeUnsignedShort(iArg);
2921         } else {
2922                 if (classFileOffset + 1 >= bCodeStream.length) {
2923                         resizeByteArray();
2924                 }
2925                 position += 2;
2926                 bCodeStream[classFileOffset++] = OPC_iload;
2927                 bCodeStream[classFileOffset++] = (byte) iArg;
2928         }
2929 }
2930 final public void iload_0() {
2931         if (DEBUG) System.out.println(position + "\t\tiload_0"); //$NON-NLS-1$
2932         countLabels = 0;
2933         stackDepth++;
2934         if (maxLocals <= 0) {
2935                 maxLocals = 1;
2936         }
2937         if (stackDepth > stackMax)
2938                 stackMax = stackDepth;
2939         if (classFileOffset >= bCodeStream.length) {
2940                 resizeByteArray();
2941         }
2942         position++;
2943         bCodeStream[classFileOffset++] = OPC_iload_0;
2944 }
2945 final public void iload_1() {
2946         if (DEBUG) System.out.println(position + "\t\tiload_1"); //$NON-NLS-1$
2947         countLabels = 0;
2948         stackDepth++;
2949         if (maxLocals <= 1) {
2950                 maxLocals = 2;
2951         }
2952         if (stackDepth > stackMax)
2953                 stackMax = stackDepth;
2954         if (classFileOffset >= bCodeStream.length) {
2955                 resizeByteArray();
2956         }
2957         position++;
2958         bCodeStream[classFileOffset++] = OPC_iload_1;
2959 }
2960 final public void iload_2() {
2961         if (DEBUG) System.out.println(position + "\t\tiload_2"); //$NON-NLS-1$
2962         countLabels = 0;
2963         stackDepth++;
2964         if (maxLocals <= 2) {
2965                 maxLocals = 3;
2966         }
2967         if (stackDepth > stackMax)
2968                 stackMax = stackDepth;
2969         if (classFileOffset >= bCodeStream.length) {
2970                 resizeByteArray();
2971         }
2972         position++;
2973         bCodeStream[classFileOffset++] = OPC_iload_2;
2974 }
2975 final public void iload_3() {
2976         if (DEBUG) System.out.println(position + "\t\tiload_3"); //$NON-NLS-1$
2977         countLabels = 0;
2978         stackDepth++;
2979         if (maxLocals <= 3) {
2980                 maxLocals = 4;
2981         }
2982         if (stackDepth > stackMax)
2983                 stackMax = stackDepth;
2984         if (classFileOffset >= bCodeStream.length) {
2985                 resizeByteArray();
2986         }
2987         position++;
2988         bCodeStream[classFileOffset++] = OPC_iload_3;
2989 }
2990 final public void imul() {
2991         if (DEBUG) System.out.println(position + "\t\timul"); //$NON-NLS-1$
2992         countLabels = 0;
2993         stackDepth--;
2994         if (classFileOffset >= bCodeStream.length) {
2995                 resizeByteArray();
2996         }
2997         position++;
2998         bCodeStream[classFileOffset++] = OPC_imul;
2999 }
3000 public void incrementTemp(LocalVariableBinding localBinding, int value) {
3001         if (value == (short) value) {
3002                 this.iinc(localBinding.resolvedPosition, value);
3003                 return;
3004         }
3005         load(localBinding);
3006         this.ldc(value);
3007         this.iadd();
3008         store(localBinding, false);
3009 }
3010 public void incrStackSize(int offset) {
3011         if ((stackDepth += offset) > stackMax)
3012                 stackMax = stackDepth;
3013 }
3014 public int indexOfSameLineEntrySincePC(int pc, int line) {
3015         for (int index = pc, max = pcToSourceMapSize; index < max; index+=2) {
3016                 if (pcToSourceMap[index+1] == line)
3017                         return index;
3018         }
3019         return -1;
3020 }
3021 final public void ineg() {
3022         if (DEBUG) System.out.println(position + "\t\tineg"); //$NON-NLS-1$
3023         countLabels = 0;
3024         if (classFileOffset >= bCodeStream.length) {
3025                 resizeByteArray();
3026         }
3027         position++;
3028         bCodeStream[classFileOffset++] = OPC_ineg;
3029 }
3030 public void init(ClassFile targetClassFile) {
3031         this.classFile = targetClassFile;
3032         this.constantPool = targetClassFile.constantPool;
3033         this.bCodeStream = targetClassFile.contents;
3034         this.classFileOffset = targetClassFile.contentsOffset;
3035         this.startingClassFileOffset = this.classFileOffset;
3036         pcToSourceMapSize = 0;
3037         lastEntryPC = 0;
3038         int length = visibleLocals.length;
3039         if (noVisibleLocals.length < length) {
3040                 noVisibleLocals = new LocalVariableBinding[length];
3041         }
3042         System.arraycopy(noVisibleLocals, 0, visibleLocals, 0, length);
3043         visibleLocalsCount = 0;
3044         
3045         length = locals.length;
3046         if (noLocals.length < length) {
3047                 noLocals = new LocalVariableBinding[length];
3048         }
3049         System.arraycopy(noLocals, 0, locals, 0, length);
3050         allLocalsCounter = 0;
3051
3052         length = exceptionHandlers.length;
3053         if (noExceptionHandlers.length < length) {
3054                 noExceptionHandlers = new ExceptionLabel[length];
3055         }
3056         System.arraycopy(noExceptionHandlers, 0, exceptionHandlers, 0, length);
3057         exceptionHandlersIndex = 0;
3058         exceptionHandlersCounter = 0;
3059         
3060         length = labels.length;
3061         if (noLabels.length < length) {
3062                 noLabels = new Label[length];
3063         }
3064         System.arraycopy(noLabels, 0, labels, 0, length);
3065         countLabels = 0;
3066
3067         stackMax = 0;
3068         stackDepth = 0;
3069         maxLocals = 0;
3070         position = 0;
3071 }
3072 /**
3073  * @param methodBinding the given method binding to initialize the max locals
3074  */
3075 public void initializeMaxLocals(MethodBinding methodBinding) {
3076
3077         if (methodBinding == null) {
3078                 this.maxLocals = 0;
3079                 return;
3080         }
3081         
3082         this.maxLocals = methodBinding.isStatic() ? 0 : 1;
3083         
3084         // take into account enum constructor synthetic name+ordinal
3085         if (methodBinding.isConstructor() && methodBinding.declaringClass.isEnum()) {
3086                 this.maxLocals += 2; // String and int (enum constant name+ordinal)
3087         }
3088         
3089         // take into account the synthetic parameters
3090         if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
3091                 ReferenceBinding enclosingInstanceTypes[];
3092                 if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
3093                         for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
3094                                 this.maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be
3095                                 // LongBinding or DoubleBinding
3096                         }
3097                 }
3098                 SyntheticArgumentBinding syntheticArguments[];
3099                 if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
3100                         for (int i = 0, max = syntheticArguments.length; i < max; i++) {
3101                                 TypeBinding argType;
3102                                 if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) {
3103                                         this.maxLocals += 2;
3104                                 } else {
3105                                         this.maxLocals++;
3106                                 }
3107                         }
3108                 }
3109         }
3110         TypeBinding[] arguments;
3111         if ((arguments = methodBinding.parameters) != null) {
3112                 for (int i = 0, max = arguments.length; i < max; i++) {
3113                         TypeBinding argType;
3114                         if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) {
3115                                 this.maxLocals += 2;
3116                         } else {
3117                                 this.maxLocals++;
3118                         }
3119                 }
3120         }
3121 }
3122 /**
3123  * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
3124  * If there is an existing entry it returns -1 (no insertion required).
3125  * Otherwise it returns the index where the entry for the pc has to be inserted.
3126  * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
3127  *
3128  * @param pcToSourceMap the given pcToSourceMap array
3129  * @param length the given length
3130  * @param pc the given pc
3131  * @return int
3132  */
3133 public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
3134         int g = 0;
3135         int d = length - 2;
3136         int m = 0;
3137         while (g <= d) {
3138                 m = (g + d) / 2;
3139                 // we search only on even indexes
3140                 if ((m % 2) != 0)
3141                         m--;
3142                 int currentPC = pcToSourceMap[m];
3143                 if (pc < currentPC) {
3144                         d = m - 2;
3145                 } else
3146                         if (pc > currentPC) {
3147                                 g = m + 2;
3148                         } else {
3149                                 return -1;
3150                         }
3151         }
3152         if (pc < pcToSourceMap[m])
3153                 return m;
3154         return m + 2;
3155 }
3156 /**
3157  * We didn't call it instanceof because there is a conflit with the
3158  * instanceof keyword
3159  */
3160 final public void instance_of(TypeBinding typeBinding) {
3161         if (DEBUG) System.out.println(position + "\t\tinstance_of:"+typeBinding); //$NON-NLS-1$
3162         countLabels = 0;
3163         if (classFileOffset + 2 >= bCodeStream.length) {
3164                 resizeByteArray();
3165         }
3166         position++;
3167         bCodeStream[classFileOffset++] = OPC_instanceof;
3168         writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
3169 }
3170 public void invokeClassForName() {
3171         // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
3172         if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$
3173         this.invoke(
3174                 OPC_invokestatic,
3175                 1, // argCount
3176                 1, // return type size
3177                 ConstantPool.JavaLangClassConstantPoolName,
3178                 ConstantPool.ForName,
3179                 ConstantPool.ForNameSignature);
3180 }
3181 public void invokeJavaLangClassDesiredAssertionStatus() {
3182         // invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
3183         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$
3184         this.invoke(
3185                         OPC_invokevirtual,
3186                         0, // argCount
3187                         1, // return type size
3188                         ConstantPool.JavaLangClassConstantPoolName,
3189                         ConstantPool.DesiredAssertionStatus,
3190                         ConstantPool.DesiredAssertionStatusSignature);
3191 }
3192
3193 public void invokeJavaLangClassGetComponentType() {
3194         // invokevirtual: java.lang.Class.getComponentType()java.lang.Class;
3195         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.getComponentType()java.lang.Class;"); //$NON-NLS-1$
3196         this.invoke(
3197                         OPC_invokevirtual,
3198                         0, // argCount
3199                         1, // return type size
3200                         ConstantPool.JavaLangClassConstantPoolName,
3201                         ConstantPool.GetComponentType,
3202                         ConstantPool.GetComponentTypeSignature);
3203 }
3204 public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
3205         // invokevirtual: <enumConstantPoolName>.ordinal()
3206         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: "+new String(enumTypeConstantPoolName)+".ordinal()"); //$NON-NLS-1$ //$NON-NLS-2$
3207         this.invoke(
3208                         OPC_invokevirtual,
3209                         0, // argCount
3210                         1, // return type size
3211                         enumTypeConstantPoolName,
3212                         ConstantPool.Ordinal,
3213                         ConstantPool.OrdinalSignature);
3214 }
3215 final public void invokeinterface(MethodBinding methodBinding) {
3216         // initialized to 1 to take into account this  immediately
3217         if (DEBUG) System.out.println(position + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$
3218         countLabels = 0;
3219         int argCount = 1;
3220         int id;
3221         if (classFileOffset + 4 >= bCodeStream.length) {
3222                 resizeByteArray();
3223         }
3224         position += 3;
3225         bCodeStream[classFileOffset++] = OPC_invokeinterface;
3226         writeUnsignedShort(constantPool.literalIndex(methodBinding));
3227         for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3228                 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3229                         argCount += 2;
3230                 else
3231                         argCount += 1;
3232         bCodeStream[classFileOffset++] = (byte) argCount;
3233         // Generate a  0 into the byte array. Like the array is already fill with 0, we just need to increment
3234         // the number of bytes.
3235         bCodeStream[classFileOffset++] = 0;
3236         if (((id = methodBinding.returnType.id) == T_double) || (id == T_long)) {
3237                 stackDepth += (2 - argCount);
3238         } else {
3239                 if (id == T_void) {
3240                         stackDepth -= argCount;
3241                 } else {
3242                         stackDepth += (1 - argCount);
3243                 }
3244         }
3245         if (stackDepth > stackMax) {
3246                 stackMax = stackDepth;
3247         }
3248 }
3249 public void invokeJavaLangErrorConstructor() {
3250         // invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
3251         if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.Error<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3252         this.invoke(
3253                         OPC_invokespecial,
3254                         1, // argCount
3255                         0, // return type size
3256                         ConstantPool.JavaLangErrorConstantPoolName,
3257                         ConstantPool.Init,
3258                         ConstantPool.StringConstructorSignature);
3259 }
3260 public void invokeNoClassDefFoundErrorStringConstructor() {
3261         // invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
3262         if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3263         this.invoke(
3264                         OPC_invokespecial,
3265                         1, // argCount
3266                         0, // return type size
3267                         ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName,
3268                         ConstantPool.Init,
3269                         ConstantPool.StringConstructorSignature);
3270 }
3271 public void invokeObjectGetClass() {
3272         // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
3273         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$
3274         this.invoke(
3275                         OPC_invokevirtual,
3276                         0, // argCount
3277                         1, // return type size
3278                         ConstantPool.JavaLangObjectConstantPoolName,
3279                         ConstantPool.GetClass,
3280                         ConstantPool.GetClassSignature);
3281 }
3282
3283 final public void invokespecial(MethodBinding methodBinding) {
3284         if (DEBUG) System.out.println(position + "\t\tinvokespecial:"+methodBinding); //$NON-NLS-1$
3285         // initialized to 1 to take into account this  immediately
3286         countLabels = 0;
3287         int argCount = 1;
3288         int id;
3289         if (classFileOffset + 2 >= bCodeStream.length) {
3290                 resizeByteArray();
3291         }
3292         position++;
3293         bCodeStream[classFileOffset++] = OPC_invokespecial;
3294         writeUnsignedShort(constantPool.literalIndex(methodBinding));
3295         if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) {
3296                 // enclosing instances
3297                 TypeBinding[] syntheticArgumentTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes();
3298                 if (syntheticArgumentTypes != null) {
3299                         for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
3300                                 if (((id = syntheticArgumentTypes[i].id) == T_double) || (id == T_long)) {
3301                                         argCount += 2;
3302                                 } else {
3303                                         argCount++;
3304                                 }
3305                         }
3306                 }
3307                 // outer local variables
3308                 SyntheticArgumentBinding[] syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables();
3309                 if (syntheticArguments != null) {
3310                         for (int i = 0, max = syntheticArguments.length; i < max; i++) {
3311                                 if (((id = syntheticArguments[i].type.id) == T_double) || (id == T_long)) {
3312                                         argCount += 2;
3313                                 } else {
3314                                         argCount++;
3315                                 }
3316                         }
3317                 }
3318         }
3319         for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3320                 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3321                         argCount += 2;
3322                 else
3323                         argCount++;
3324         if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3325                 stackDepth += (2 - argCount);
3326         else
3327                 if (id == T_void)
3328                         stackDepth -= argCount;
3329                 else
3330                         stackDepth += (1 - argCount);
3331         if (stackDepth > stackMax)
3332                 stackMax = stackDepth;
3333 }
3334 final public void invokestatic(MethodBinding methodBinding) {
3335         if (DEBUG) System.out.println(position + "\t\tinvokestatic:"+methodBinding); //$NON-NLS-1$
3336         // initialized to 0 to take into account that there is no this for
3337         // a static method
3338         countLabels = 0;
3339         int argCount = 0;
3340         int id;
3341         if (classFileOffset + 2 >= bCodeStream.length) {
3342                 resizeByteArray();
3343         }
3344         position++;
3345         bCodeStream[classFileOffset++] = OPC_invokestatic;
3346         writeUnsignedShort(constantPool.literalIndex(methodBinding));
3347         for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3348                 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3349                         argCount += 2;
3350                 else
3351                         argCount += 1;
3352         if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3353                 stackDepth += (2 - argCount);
3354         else
3355                 if (id == T_void)
3356                         stackDepth -= argCount;
3357                 else
3358                         stackDepth += (1 - argCount);
3359         if (stackDepth > stackMax)
3360                 stackMax = stackDepth;
3361 }
3362 /**
3363  * The equivalent code performs a string conversion of the TOS
3364  * @param typeID <CODE>int</CODE>
3365  */
3366 public void invokeStringConcatenationAppendForType(int typeID) {
3367         if (DEBUG) {
3368                 if (this.targetLevel >= JDK1_5) {
3369                         System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuilder.append(...)"); //$NON-NLS-1$
3370                 } else {
3371                         System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$
3372                 }
3373         }
3374         int argCount = 1;
3375         int returnType = 1;
3376         char[] declarinClass = null;
3377         char[] selector = ConstantPool.Append;
3378         char[] signature = null;
3379         switch (typeID) {
3380                 case T_int :
3381                 case T_byte :
3382                 case T_short :
3383                         if (this.targetLevel >= JDK1_5) {
3384                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3385                                 signature = ConstantPool.StringBuilderAppendIntSignature;
3386                         } else {
3387                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3388                                 signature = ConstantPool.StringBufferAppendIntSignature;
3389                         }
3390                         break;
3391                 case T_long :
3392                         if (this.targetLevel >= JDK1_5) {
3393                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3394                                 signature = ConstantPool.StringBuilderAppendLongSignature;
3395                         } else {
3396                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3397                                 signature = ConstantPool.StringBufferAppendLongSignature;
3398                         }
3399                         argCount = 2;
3400                         break;
3401                 case T_float :
3402                         if (this.targetLevel >= JDK1_5) {
3403                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3404                                 signature = ConstantPool.StringBuilderAppendFloatSignature;
3405                         } else {
3406                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3407                                 signature = ConstantPool.StringBufferAppendFloatSignature;
3408                         }
3409                         break;
3410                 case T_double :
3411                         if (this.targetLevel >= JDK1_5) {
3412                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3413                                 signature = ConstantPool.StringBuilderAppendDoubleSignature;
3414                         } else {
3415                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3416                                 signature = ConstantPool.StringBufferAppendDoubleSignature;
3417                         }
3418                         argCount = 2;
3419                         break;
3420                 case T_char :
3421                         if (this.targetLevel >= JDK1_5) {
3422                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3423                                 signature = ConstantPool.StringBuilderAppendCharSignature;
3424                         } else {
3425                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3426                                 signature = ConstantPool.StringBufferAppendCharSignature;
3427                         }
3428                         break;
3429                 case T_boolean :
3430                         if (this.targetLevel >= JDK1_5) {
3431                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3432                                 signature = ConstantPool.StringBuilderAppendBooleanSignature;
3433                         } else {
3434                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3435                                 signature = ConstantPool.StringBufferAppendBooleanSignature;
3436                         }
3437                         break;
3438                 case T_undefined :
3439                 case T_JavaLangObject :
3440                 case T_null :
3441                         if (this.targetLevel >= JDK1_5) {
3442                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3443                                 signature = ConstantPool.StringBuilderAppendObjectSignature;
3444                         } else {
3445                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3446                                 signature = ConstantPool.StringBufferAppendObjectSignature;
3447                         }
3448                         break;
3449                 case T_JavaLangString :
3450                         if (this.targetLevel >= JDK1_5) {
3451                                 declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3452                                 signature = ConstantPool.StringBuilderAppendStringSignature;
3453                         } else {
3454                                 declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3455                                 signature = ConstantPool.StringBufferAppendStringSignature;
3456                         }
3457                         break;
3458         }
3459         this.invoke(
3460                         OPC_invokevirtual,
3461                         argCount, // argCount
3462                         returnType, // return type size
3463                         declarinClass,
3464                         selector,
3465                         signature);
3466 }
3467
3468 public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
3469         // invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
3470         if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>(typeBindingID)V"); //$NON-NLS-1$
3471         int argCount = 1;
3472         char[] signature = null;
3473         switch (typeBindingID) {
3474                 case T_int :
3475                 case T_byte :
3476                 case T_short :
3477                         signature = ConstantPool.IntConstrSignature;
3478                         break;
3479                 case T_long :
3480                         signature = ConstantPool.LongConstrSignature;
3481                         argCount = 2;
3482                         break;
3483                 case T_float :
3484                         signature = ConstantPool.FloatConstrSignature;
3485                         break;
3486                 case T_double :
3487                         signature = ConstantPool.DoubleConstrSignature;
3488                         argCount = 2;
3489                         break;
3490                 case T_char :
3491                         signature = ConstantPool.CharConstrSignature;
3492                         break;
3493                 case T_boolean :
3494                         signature = ConstantPool.BooleanConstrSignature;
3495                         break;
3496                 case T_JavaLangObject :
3497                 case T_JavaLangString :
3498                 case T_null :
3499                         signature = ConstantPool.ObjectConstrSignature;
3500                         break;
3501         }
3502         this.invoke(
3503                         OPC_invokespecial,
3504                         argCount, // argCount
3505                         0, // return type size
3506                         ConstantPool.JavaLangAssertionErrorConstantPoolName,
3507                         ConstantPool.Init,
3508                         signature);
3509 }
3510
3511 public void invokeJavaLangAssertionErrorDefaultConstructor() {
3512         // invokespecial: java.lang.AssertionError.<init>()V
3513         if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.<init>()V"); //$NON-NLS-1$
3514         this.invoke(
3515                         OPC_invokespecial,
3516                         0, // argCount
3517                         0, // return type size
3518                         ConstantPool.JavaLangAssertionErrorConstantPoolName,
3519                         ConstantPool.Init,
3520                         ConstantPool.DefaultConstructorSignature);
3521 }
3522 public void invokeJavaLangEnumname(TypeBinding typeBinding) {
3523         // invokevirtual: java.lang.Enum.name()String
3524         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Enum.name()Ljava/lang/String;"); //$NON-NLS-1$
3525         this.invoke(
3526                         OPC_invokevirtual,
3527                         0,
3528                         1,
3529                         typeBinding.constantPoolName(),
3530                         ConstantPool.Name,
3531                         ConstantPool.NameSignature);
3532 }
3533 public void invokeJavaLangIllegalArgumentExceptionStringConstructor() {
3534         // invokespecial: java.lang.IllegalArgumentException.<init>(String)V
3535         if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.IllegalArgumentException.<init>(java.lang.String)V"); //$NON-NLS-1$
3536         this.invoke(
3537                         OPC_invokespecial,
3538                         1, // argCount
3539                         0, // return type size
3540                         ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName,
3541                         ConstantPool.Init,
3542                         ConstantPool.StringConstructorSignature);
3543 }
3544
3545 public void invokeJavaUtilIteratorHasNext() {
3546         // invokeinterface java.util.Iterator.hasNext()Z
3547         if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.hasNext()Z"); //$NON-NLS-1$
3548         this.invoke(
3549                         OPC_invokeinterface,
3550                         0, // argCount
3551                         1, // return type size
3552                         ConstantPool.JavaUtilIteratorConstantPoolName,
3553                         ConstantPool.HasNext,
3554                         ConstantPool.HasNextSignature);
3555 }
3556 public void invokeJavaUtilIteratorNext() {
3557         // invokeinterface java.util.Iterator.next()java.lang.Object
3558         if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.next()java.lang.Object"); //$NON-NLS-1$
3559         this.invoke(
3560                         OPC_invokeinterface,
3561                         0, // argCount
3562                         1, // return type size
3563                         ConstantPool.JavaUtilIteratorConstantPoolName,
3564                         ConstantPool.Next,
3565                         ConstantPool.NextSignature);
3566 }
3567 public void invokeStringConcatenationDefaultConstructor() {
3568         // invokespecial: java.lang.StringBuffer.<init>()V
3569         if (DEBUG) {
3570                 if (this.targetLevel >= JDK1_5) {
3571                         System.out.println(position + "\t\tinvokespecial: java.lang.StringBuilder.<init>()V"); //$NON-NLS-1$
3572                 } else {
3573                         System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.<init>()V"); //$NON-NLS-1$
3574                 }
3575         }
3576         char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3577         if (this.targetLevel >= JDK1_5) {
3578                 declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3579         }
3580         this.invoke(
3581                         OPC_invokespecial,
3582                         0, // argCount
3583                         0, // return type size
3584                         declaringClass,
3585                         ConstantPool.Init,
3586                         ConstantPool.DefaultConstructorSignature);
3587 }
3588 public void invokeStringConcatenationStringConstructor() {
3589         if (DEBUG) {
3590                 if (this.targetLevel >= JDK1_5) {
3591                         System.out.println(position + "\t\tjava.lang.StringBuilder.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3592                 } else {
3593                         System.out.println(position + "\t\tjava.lang.StringBuffer.<init>(Ljava.lang.String;)V"); //$NON-NLS-1$
3594                 }
3595         }
3596         char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3597         if (this.targetLevel >= JDK1_5) {
3598                 declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3599         }
3600         this.invoke(
3601                         OPC_invokespecial,
3602                         1, // argCount
3603                         0, // return type size
3604                         declaringClass,
3605                         ConstantPool.Init,
3606                         ConstantPool.StringConstructorSignature);
3607 }
3608
3609 public void invokeStringConcatenationToString() {
3610         if (DEBUG) {
3611                 if (this.targetLevel >= JDK1_5) {
3612                         System.out.println(position + "\t\tinvokevirtual: StringBuilder.toString()Ljava.lang.String;"); //$NON-NLS-1$
3613                 } else {
3614                         System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$
3615                 }
3616         }
3617         char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
3618         if (this.targetLevel >= JDK1_5) {
3619                 declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
3620         }
3621         this.invoke(
3622                         OPC_invokevirtual,
3623                         0, // argCount
3624                         1, // return type size
3625                         declaringClass,
3626                         ConstantPool.ToString,
3627                         ConstantPool.ToStringSignature);
3628 }
3629 public void invokeStringEquals() {
3630         // invokevirtual: java.lang.String.equals(java.lang.Object)
3631         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.equals(...)"); //$NON-NLS-1$
3632         this.invoke(
3633                         OPC_invokevirtual,
3634                         1, // argCount
3635                         1, // return type size
3636                         ConstantPool.JavaLangStringConstantPoolName,
3637                         ConstantPool.Equals,
3638                         ConstantPool.EqualsSignature);
3639 }
3640 public void invokeStringIntern() {
3641         // invokevirtual: java.lang.String.intern()
3642         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$
3643         this.invoke(
3644                         OPC_invokevirtual,
3645                         0, // argCount
3646                         1, // return type size
3647                         ConstantPool.JavaLangStringConstantPoolName,
3648                         ConstantPool.Intern,
3649                         ConstantPool.InternSignature);
3650 }
3651 public void invokeStringValueOf(int typeID) {
3652         // invokestatic: java.lang.String.valueOf(argumentType)
3653         if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$
3654         int argCount = 1;
3655         char[] signature = null;
3656         switch (typeID) {
3657                 case T_int :
3658                 case T_byte :
3659                 case T_short :
3660                         signature = ConstantPool.ValueOfIntSignature;
3661                         break;
3662                 case T_long :
3663                         signature = ConstantPool.ValueOfLongSignature;
3664                         argCount = 2;
3665                         break;
3666                 case T_float :
3667                         signature = ConstantPool.ValueOfFloatSignature;
3668                         break;
3669                 case T_double :
3670                         signature = ConstantPool.ValueOfDoubleSignature;
3671                         argCount = 2;
3672                         break;
3673                 case T_char :
3674                         signature = ConstantPool.ValueOfCharSignature;
3675                         break;
3676                 case T_boolean :
3677                         signature = ConstantPool.ValueOfBooleanSignature;
3678                         break;
3679                 case T_JavaLangObject :
3680                 case T_JavaLangString :
3681                 case T_null :
3682                 case T_undefined :
3683                         signature = ConstantPool.ValueOfObjectSignature;
3684                         break;
3685         }
3686         this.invoke(
3687                         OPC_invokestatic,
3688                         argCount, // argCount
3689                         1, // return type size
3690                         ConstantPool.JavaLangStringConstantPoolName,
3691                         ConstantPool.ValueOf,
3692                         signature);
3693 }
3694 public void invokeSystemArraycopy() {
3695         // invokestatic #21 <Method java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>
3696         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V"); //$NON-NLS-1$
3697         this.invoke(
3698                         OPC_invokestatic,
3699                         5, // argCount
3700                         0, // return type size
3701                         ConstantPool.JavaLangSystemConstantPoolName,
3702                         ConstantPool.ArrayCopy,
3703                         ConstantPool.ArrayCopySignature);
3704 }
3705 public void invokeThrowableGetMessage() {
3706         // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
3707         if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$
3708         this.invoke(
3709                         OPC_invokevirtual,
3710                         0, // argCount
3711                         1, // return type size
3712                         ConstantPool.JavaLangThrowableConstantPoolName,
3713                         ConstantPool.GetMessage,
3714                         ConstantPool.GetMessageSignature);
3715 }
3716 final public void invoke(int opcode, int argsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
3717         countLabels = 0;
3718         int argCount = argsSize;
3719         switch(opcode) {
3720                 case OPC_invokeinterface :
3721                         if (classFileOffset + 4 >= bCodeStream.length) {
3722                                 resizeByteArray();
3723                         }
3724                         position +=3;
3725                         bCodeStream[classFileOffset++] = OPC_invokeinterface;
3726                         writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
3727                         argCount++;
3728                         bCodeStream[classFileOffset++] = (byte) argCount;
3729                         bCodeStream[classFileOffset++] = 0;
3730                         break;
3731                 case OPC_invokevirtual :
3732                 case OPC_invokespecial :
3733                         if (classFileOffset + 2 >= bCodeStream.length) {
3734                                 resizeByteArray();
3735                         }
3736                         position++;
3737                         bCodeStream[classFileOffset++] = (byte) opcode;
3738                         writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3739                         argCount++;
3740                         break;
3741                 case OPC_invokestatic :
3742                         if (classFileOffset + 2 >= bCodeStream.length) {
3743                                 resizeByteArray();
3744                         }
3745                         position++;
3746                         bCodeStream[classFileOffset++] = OPC_invokestatic;
3747                         writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
3748         }
3749         stackDepth += returnTypeSize - argCount;
3750         if (stackDepth > stackMax) {
3751                 stackMax = stackDepth;
3752         }
3753 }
3754 final public void invokevirtual(MethodBinding methodBinding) {
3755         if (DEBUG) System.out.println(position + "\t\tinvokevirtual:"+methodBinding); //$NON-NLS-1$
3756         // initialized to 1 to take into account this  immediately
3757         countLabels = 0;
3758         int argCount = 1;
3759         int id;
3760         if (classFileOffset + 2 >= bCodeStream.length) {
3761                 resizeByteArray();
3762         }
3763         position++;
3764         bCodeStream[classFileOffset++] = OPC_invokevirtual;
3765         writeUnsignedShort(constantPool.literalIndex(methodBinding));
3766         for (int i = methodBinding.parameters.length - 1; i >= 0; i--)
3767                 if (((id = methodBinding.parameters[i].id) == T_double) || (id == T_long))
3768                         argCount += 2;
3769                 else
3770                         argCount++;
3771         if (((id = methodBinding.returnType.id) == T_double) || (id == T_long))
3772                 stackDepth += (2 - argCount);
3773         else
3774                 if (id == T_void)
3775                         stackDepth -= argCount;
3776                 else
3777                         stackDepth += (1 - argCount);
3778         if (stackDepth > stackMax)
3779                 stackMax = stackDepth;
3780 }
3781 final public void ior() {
3782         if (DEBUG) System.out.println(position + "\t\tior"); //$NON-NLS-1$
3783         countLabels = 0;
3784         stackDepth--;
3785         if (classFileOffset >= bCodeStream.length) {
3786                 resizeByteArray();
3787         }
3788         position++;
3789         bCodeStream[classFileOffset++] = OPC_ior;
3790 }
3791 final public void irem() {
3792         if (DEBUG) System.out.println(position + "\t\tirem"); //$NON-NLS-1$
3793         countLabels = 0;
3794         stackDepth--;
3795         if (classFileOffset >= bCodeStream.length) {
3796                 resizeByteArray();
3797         }
3798         position++;
3799         bCodeStream[classFileOffset++] = OPC_irem;
3800 }
3801 final public void ireturn() {
3802         if (DEBUG) System.out.println(position + "\t\tireturn"); //$NON-NLS-1$
3803         countLabels = 0;
3804         stackDepth--;
3805         // the stackDepth should be equal to 0 
3806         if (classFileOffset >= bCodeStream.length) {
3807                 resizeByteArray();
3808         }
3809         position++;
3810         bCodeStream[classFileOffset++] = OPC_ireturn;
3811 }
3812 public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
3813         // Dependant of UnconditionalFlowInfo.isDefinitelyAssigned(..)
3814         if (initStateIndex == -1)
3815                 return false;
3816         if (local.isArgument) {
3817                 return true;
3818         }
3819         int localPosition = local.id + maxFieldCount;
3820         MethodScope methodScope = scope.methodScope();
3821         // id is zero-based
3822         if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
3823                 return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 0; // use bits
3824         }
3825         // use extra vector
3826         long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
3827         if (extraInits == null)
3828                 return false; // if vector not yet allocated, then not initialized
3829         int vectorIndex;
3830         if ((vectorIndex = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
3831                 return false; // if not enough room in vector, then not initialized 
3832         return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
3833 }
3834 final public void ishl() {
3835         if (DEBUG) System.out.println(position + "\t\tishl"); //$NON-NLS-1$
3836         countLabels = 0;
3837         stackDepth--;
3838         if (classFileOffset >= bCodeStream.length) {
3839                 resizeByteArray();
3840         }
3841         position++;
3842         bCodeStream[classFileOffset++] = OPC_ishl;
3843 }
3844 final public void ishr() {
3845         if (DEBUG) System.out.println(position + "\t\tishr"); //$NON-NLS-1$
3846         countLabels = 0;
3847         stackDepth--;
3848         if (classFileOffset >= bCodeStream.length) {
3849                 resizeByteArray();
3850         }
3851         position++;
3852         bCodeStream[classFileOffset++] = OPC_ishr;
3853 }
3854 final public void istore(int iArg) {
3855         if (DEBUG) System.out.println(position + "\t\tistore:"+iArg); //$NON-NLS-1$
3856         countLabels = 0;
3857         stackDepth--;
3858         if (maxLocals <= iArg) {
3859                 maxLocals = iArg + 1;
3860         }
3861         if (iArg > 255) { // Widen
3862                 if (classFileOffset + 3 >= bCodeStream.length) {
3863                         resizeByteArray();
3864                 }
3865                 position += 2;
3866                 bCodeStream[classFileOffset++] = OPC_wide;
3867                 bCodeStream[classFileOffset++] = OPC_istore;
3868                 writeUnsignedShort(iArg);
3869         } else {
3870                 if (classFileOffset + 1 >= bCodeStream.length) {
3871                         resizeByteArray();
3872                 }
3873                 position += 2;
3874                 bCodeStream[classFileOffset++] = OPC_istore;
3875                 bCodeStream[classFileOffset++] = (byte) iArg;
3876         }
3877 }
3878 final public void istore_0() {
3879         if (DEBUG) System.out.println(position + "\t\tistore_0"); //$NON-NLS-1$
3880         countLabels = 0;
3881         stackDepth--;
3882         if (maxLocals == 0) {
3883                 maxLocals = 1;
3884         }
3885         if (classFileOffset >= bCodeStream.length) {
3886                 resizeByteArray();
3887         }
3888         position++;
3889         bCodeStream[classFileOffset++] = OPC_istore_0;
3890 }
3891 final public void istore_1() {
3892         if (DEBUG) System.out.println(position + "\t\tistore_1"); //$NON-NLS-1$
3893         countLabels = 0;
3894         stackDepth--;
3895         if (maxLocals <= 1) {
3896                 maxLocals = 2;
3897         }
3898         if (classFileOffset >= bCodeStream.length) {
3899                 resizeByteArray();
3900         }
3901         position++;
3902         bCodeStream[classFileOffset++] = OPC_istore_1;
3903 }
3904 final public void istore_2() {
3905         if (DEBUG) System.out.println(position + "\t\tistore_2"); //$NON-NLS-1$
3906         countLabels = 0;
3907         stackDepth--;
3908         if (maxLocals <= 2) {
3909                 maxLocals = 3;
3910         }
3911         if (classFileOffset >= bCodeStream.length) {
3912                 resizeByteArray();
3913         }
3914         position++;
3915         bCodeStream[classFileOffset++] = OPC_istore_2;
3916 }
3917 final public void istore_3() {
3918         if (DEBUG) System.out.println(position + "\t\tistore_3"); //$NON-NLS-1$
3919         countLabels = 0;
3920         stackDepth--;
3921         if (maxLocals <= 3) {
3922                 maxLocals = 4;
3923         }
3924         if (classFileOffset >= bCodeStream.length) {
3925                 resizeByteArray();
3926         }
3927         position++;
3928         bCodeStream[classFileOffset++] = OPC_istore_3;
3929 }
3930 final public void isub() {
3931         if (DEBUG) System.out.println(position + "\t\tisub"); //$NON-NLS-1$
3932         countLabels = 0;
3933         stackDepth--;
3934         if (classFileOffset >= bCodeStream.length) {
3935                 resizeByteArray();
3936         }
3937         position++;
3938         bCodeStream[classFileOffset++] = OPC_isub;
3939 }
3940 final public void iushr() {
3941         if (DEBUG) System.out.println(position + "\t\tiushr"); //$NON-NLS-1$
3942         countLabels = 0;
3943         stackDepth--;
3944         if (classFileOffset >= bCodeStream.length) {
3945                 resizeByteArray();
3946         }
3947         position++;
3948         bCodeStream[classFileOffset++] = OPC_iushr;
3949 }
3950 final public void ixor() {
3951         if (DEBUG) System.out.println(position + "\t\tixor"); //$NON-NLS-1$
3952         countLabels = 0;
3953         stackDepth--;
3954         if (classFileOffset >= bCodeStream.length) {
3955                 resizeByteArray();
3956         }
3957         position++;
3958         bCodeStream[classFileOffset++] = OPC_ixor;
3959 }
3960 final public void jsr(Label lbl) {
3961         if (this.wideMode) {
3962                 this.jsr_w(lbl);
3963                 return;
3964         }
3965         if (DEBUG) System.out.println(position + "\t\tjsr"+lbl); //$NON-NLS-1$
3966         countLabels = 0;
3967         if (classFileOffset >= bCodeStream.length) {
3968                 resizeByteArray();
3969         }
3970         position++;
3971         bCodeStream[classFileOffset++] = OPC_jsr;
3972         lbl.branch();
3973 }
3974 final public void jsr_w(Label lbl) {
3975         if (DEBUG) System.out.println(position + "\t\tjsr_w"+lbl); //$NON-NLS-1$
3976         countLabels = 0;
3977         if (classFileOffset >= bCodeStream.length) {
3978                 resizeByteArray();
3979         }
3980         position++;
3981         bCodeStream[classFileOffset++] = OPC_jsr_w;
3982         lbl.branchWide();
3983 }
3984 final public void l2d() {
3985         if (DEBUG) System.out.println(position + "\t\tl2d"); //$NON-NLS-1$
3986         countLabels = 0;
3987         if (classFileOffset >= bCodeStream.length) {
3988                 resizeByteArray();
3989         }
3990         position++;
3991         bCodeStream[classFileOffset++] = OPC_l2d;
3992 }
3993 final public void l2f() {
3994         if (DEBUG) System.out.println(position + "\t\tl2f"); //$NON-NLS-1$
3995         countLabels = 0;
3996         stackDepth--;
3997         if (classFileOffset >= bCodeStream.length) {
3998                 resizeByteArray();
3999         }
4000         position++;
4001         bCodeStream[classFileOffset++] = OPC_l2f;
4002 }
4003 final public void l2i() {
4004         if (DEBUG) System.out.println(position + "\t\tl2i"); //$NON-NLS-1$
4005         countLabels = 0;
4006         stackDepth--;
4007         if (classFileOffset >= bCodeStream.length) {
4008                 resizeByteArray();
4009         }
4010         position++;
4011         bCodeStream[classFileOffset++] = OPC_l2i;
4012 }
4013 final public void ladd() {
4014         if (DEBUG) System.out.println(position + "\t\tladd"); //$NON-NLS-1$
4015         countLabels = 0;
4016         stackDepth -= 2;
4017         if (classFileOffset >= bCodeStream.length) {
4018                 resizeByteArray();
4019         }
4020         position++;
4021         bCodeStream[classFileOffset++] = OPC_ladd;
4022 }
4023 final public void laload() {
4024         if (DEBUG) System.out.println(position + "\t\tlaload"); //$NON-NLS-1$
4025         countLabels = 0;
4026         if (classFileOffset >= bCodeStream.length) {
4027                 resizeByteArray();
4028         }
4029         position++;
4030         bCodeStream[classFileOffset++] = OPC_laload;
4031 }
4032 final public void land() {
4033         if (DEBUG) System.out.println(position + "\t\tland"); //$NON-NLS-1$
4034         countLabels = 0;
4035         stackDepth -= 2;
4036         if (classFileOffset >= bCodeStream.length) {
4037                 resizeByteArray();
4038         }
4039         position++;
4040         bCodeStream[classFileOffset++] = OPC_land;
4041 }
4042 final public void lastore() {
4043         if (DEBUG) System.out.println(position + "\t\tlastore"); //$NON-NLS-1$
4044         countLabels = 0;
4045         stackDepth -= 4;
4046         if (classFileOffset >= bCodeStream.length) {
4047                 resizeByteArray();
4048         }
4049         position++;
4050         bCodeStream[classFileOffset++] = OPC_lastore;
4051 }
4052 final public void lcmp() {
4053         if (DEBUG) System.out.println(position + "\t\tlcmp"); //$NON-NLS-1$
4054         countLabels = 0;
4055         stackDepth -= 3;
4056         if (classFileOffset >= bCodeStream.length) {
4057                 resizeByteArray();
4058         }
4059         position++;
4060         bCodeStream[classFileOffset++] = OPC_lcmp;
4061 }
4062 final public void lconst_0() {
4063         if (DEBUG) System.out.println(position + "\t\tlconst_0"); //$NON-NLS-1$
4064         countLabels = 0;
4065         stackDepth += 2;
4066         if (stackDepth > stackMax)
4067                 stackMax = stackDepth;
4068         if (classFileOffset >= bCodeStream.length) {
4069                 resizeByteArray();
4070         }
4071         position++;
4072         bCodeStream[classFileOffset++] = OPC_lconst_0;
4073 }
4074 final public void lconst_1() {
4075         if (DEBUG) System.out.println(position + "\t\tlconst_1"); //$NON-NLS-1$
4076         countLabels = 0;
4077         stackDepth += 2;
4078         if (stackDepth > stackMax)
4079                 stackMax = stackDepth;
4080         if (classFileOffset >= bCodeStream.length) {
4081                 resizeByteArray();
4082         }
4083         position++;
4084         bCodeStream[classFileOffset++] = OPC_lconst_1;
4085 }
4086 final public void ldc(float constant) {
4087         countLabels = 0;
4088         int index = constantPool.literalIndex(constant);
4089         stackDepth++;
4090         if (stackDepth > stackMax)
4091                 stackMax = stackDepth;
4092         if (index > 255) {
4093                 if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4094                 // Generate a ldc_w
4095                 if (classFileOffset + 2 >= bCodeStream.length) {
4096                         resizeByteArray();
4097                 }
4098                 position++;
4099                 bCodeStream[classFileOffset++] = OPC_ldc_w;
4100                 writeUnsignedShort(index);
4101         } else {
4102                 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4103                 // Generate a ldc
4104                 if (classFileOffset + 1 >= bCodeStream.length) {
4105                         resizeByteArray();
4106                 }
4107                 position += 2;
4108                 bCodeStream[classFileOffset++] = OPC_ldc;
4109                 bCodeStream[classFileOffset++] = (byte) index;
4110         }
4111 }
4112 final public void ldc(int constant) {
4113         countLabels = 0;
4114         int index = constantPool.literalIndex(constant);
4115         stackDepth++;
4116         if (stackDepth > stackMax)
4117                 stackMax = stackDepth;
4118         if (index > 255) {
4119                 if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4120                 // Generate a ldc_w
4121                 if (classFileOffset + 2 >= bCodeStream.length) {
4122                         resizeByteArray();
4123                 }
4124                 position++;
4125                 bCodeStream[classFileOffset++] = OPC_ldc_w;
4126                 writeUnsignedShort(index);
4127         } else {
4128                 if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4129                 // Generate a ldc
4130                 if (classFileOffset + 1 >= bCodeStream.length) {
4131                         resizeByteArray();
4132                 }
4133                 position += 2;
4134                 bCodeStream[classFileOffset++] = OPC_ldc;
4135                 bCodeStream[classFileOffset++] = (byte) index;
4136         }
4137 }
4138 final public void ldc(String constant) {
4139         countLabels = 0;
4140         int currentConstantPoolIndex = constantPool.currentIndex;
4141         int currentConstantPoolOffset = constantPool.currentOffset;
4142         int currentCodeStreamPosition = position;
4143         int index = constantPool.literalIndexForLdc(constant.toCharArray());
4144         if (index > 0) {
4145                 // the string already exists inside the constant pool
4146                 // we reuse the same index
4147                 stackDepth++;
4148                 if (stackDepth > stackMax)
4149                         stackMax = stackDepth;
4150                 if (index > 255) {
4151                         if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$
4152                         // Generate a ldc_w
4153                         if (classFileOffset + 2 >= bCodeStream.length) {
4154                                 resizeByteArray();
4155                         }
4156                         position++;
4157                         bCodeStream[classFileOffset++] = OPC_ldc_w;
4158                         writeUnsignedShort(index);
4159                 } else {
4160                         if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$
4161                         // Generate a ldc
4162                         if (classFileOffset + 1 >= bCodeStream.length) {
4163                                 resizeByteArray();
4164                         }
4165                         position += 2;
4166                         bCodeStream[classFileOffset++] = OPC_ldc;
4167                         bCodeStream[classFileOffset++] = (byte) index;
4168                 }
4169         } else {
4170                 // the string is too big to be utf8-encoded in one pass.
4171                 // we have to split it into different pieces.
4172                 // first we clean all side-effects due to the code above
4173                 // this case is very rare, so we can afford to lose time to handle it
4174                 char[] constantChars = constant.toCharArray();
4175                 position = currentCodeStreamPosition;
4176                 constantPool.currentIndex = currentConstantPoolIndex;
4177                 constantPool.currentOffset = currentConstantPoolOffset;
4178                 constantPool.stringCache.remove(constantChars);
4179                 constantPool.UTF8Cache.remove(constantChars);
4180                 int i = 0;
4181                 int length = 0;
4182                 int constantLength = constant.length();
4183                 byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
4184                 int utf8encodingLength = 0;
4185                 while ((length < 65532) && (i < constantLength)) {
4186                         char current = constantChars[i];
4187                         // we resize the byte array immediately if necessary
4188                         if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
4189                                 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
4190                         }
4191                         if ((current >= 0x0001) && (current <= 0x007F)) {
4192                                 // we only need one byte: ASCII table
4193                                 utf8encoding[length++] = (byte) current;
4194                         } else {
4195                                 if (current > 0x07FF) {
4196                                         // we need 3 bytes
4197                                         utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
4198                                         utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
4199                                         utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4200                                 } else {
4201                                         // we can be 0 or between 0x0080 and 0x07FF
4202                                         // In that case we only need 2 bytes
4203                                         utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
4204                                         utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4205                                 }
4206                         }
4207                         i++;
4208                 }
4209                 // check if all the string is encoded (PR 1PR2DWJ)
4210                 // the string is too big to be encoded in one pass
4211                 newStringContatenation();
4212                 dup();
4213                 // write the first part
4214                 char[] subChars = new char[i];
4215                 System.arraycopy(constantChars, 0, subChars, 0, i);
4216                 System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
4217                 index = constantPool.literalIndex(subChars, utf8encoding);
4218                 stackDepth++;
4219                 if (stackDepth > stackMax)
4220                         stackMax = stackDepth;
4221                 if (index > 255) {
4222                         // Generate a ldc_w
4223                         if (classFileOffset + 2 >= bCodeStream.length) {
4224                                 resizeByteArray();
4225                         }
4226                         position++;
4227                         bCodeStream[classFileOffset++] = OPC_ldc_w;
4228                         writeUnsignedShort(index);
4229                 } else {
4230                         // Generate a ldc
4231                         if (classFileOffset + 1 >= bCodeStream.length) {
4232                                 resizeByteArray();
4233                         }
4234                         position += 2;
4235                         bCodeStream[classFileOffset++] = OPC_ldc;
4236                         bCodeStream[classFileOffset++] = (byte) index;
4237                 }
4238                 // write the remaining part
4239                 invokeStringConcatenationStringConstructor();
4240                 while (i < constantLength) {
4241                         length = 0;
4242                         utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
4243                         int startIndex = i;
4244                         while ((length < 65532) && (i < constantLength)) {
4245                                 char current = constantChars[i];
4246                                 // we resize the byte array immediately if necessary
4247                                 if (constantLength + 2 > (utf8encodingLength = utf8encoding.length)) {
4248                                         System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
4249                                 }
4250                                 if ((current >= 0x0001) && (current <= 0x007F)) {
4251                                         // we only need one byte: ASCII table
4252                                         utf8encoding[length++] = (byte) current;
4253                                 } else {
4254                                         if (current > 0x07FF) {
4255                                                 // we need 3 bytes
4256                                                 utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
4257                                                 utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
4258                                                 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4259                                         } else {
4260                                                 // we can be 0 or between 0x0080 and 0x07FF
4261                                                 // In that case we only need 2 bytes
4262                                                 utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
4263                                                 utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
4264                                         }
4265                                 }
4266                                 i++;
4267                         }
4268                         // the next part is done
4269                         subChars = new char[i - startIndex];
4270                         System.arraycopy(constantChars, startIndex, subChars, 0, i - startIndex);
4271                         System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
4272                         index = constantPool.literalIndex(subChars, utf8encoding);
4273                         stackDepth++;
4274                         if (stackDepth > stackMax)
4275                                 stackMax = stackDepth;
4276                         if (index > 255) {
4277                                 // Generate a ldc_w
4278                                 if (classFileOffset + 2 >= bCodeStream.length) {
4279                                         resizeByteArray();
4280                                 }
4281                                 position++;
4282                                 bCodeStream[classFileOffset++] = OPC_ldc_w;
4283                                 writeUnsignedShort(index);
4284                         } else {
4285                                 // Generate a ldc
4286                                 if (classFileOffset + 1 >= bCodeStream.length) {
4287                                         resizeByteArray();
4288                                 }
4289                                 position += 2;
4290                                 bCodeStream[classFileOffset++] = OPC_ldc;
4291                                 bCodeStream[classFileOffset++] = (byte) index;
4292                         }
4293                         // now on the stack it should be a StringBuffer and a string.
4294                         invokeStringConcatenationAppendForType(T_JavaLangString);
4295                 }
4296                 invokeStringConcatenationToString();
4297                 invokeStringIntern();
4298         }
4299 }
4300 final public void ldc(TypeBinding typeBinding) {
4301         countLabels = 0;
4302         int index = constantPool.literalIndexForType(typeBinding.constantPoolName());
4303         stackDepth++;
4304         if (stackDepth > stackMax)
4305                 stackMax = stackDepth;
4306         if (index > 255) {
4307                 if (DEBUG) System.out.println(position + "\t\tldc_w:"+ typeBinding); //$NON-NLS-1$
4308                 // Generate a ldc_w
4309                 if (classFileOffset + 2 >= bCodeStream.length) {
4310                         resizeByteArray();
4311                 }
4312                 position++;
4313                 bCodeStream[classFileOffset++] = OPC_ldc_w;
4314                 writeUnsignedShort(index);
4315         } else {
4316                 if (DEBUG) System.out.println(position + "\t\tldw:"+ typeBinding); //$NON-NLS-1$
4317                 // Generate a ldc
4318                 if (classFileOffset + 1 >= bCodeStream.length) {
4319                         resizeByteArray();
4320                 }
4321                 position += 2;
4322                 bCodeStream[classFileOffset++] = OPC_ldc;
4323                 bCodeStream[classFileOffset++] = (byte) index;
4324         }
4325 }
4326 final public void ldc2_w(double constant) {
4327         if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
4328         countLabels = 0;
4329         int index = constantPool.literalIndex(constant);
4330         stackDepth += 2;
4331         if (stackDepth > stackMax)
4332                 stackMax = stackDepth;
4333         // Generate a ldc2_w
4334         if (classFileOffset + 2 >= bCodeStream.length) {
4335                 resizeByteArray();
4336         }
4337         position++;
4338         bCodeStream[classFileOffset++] = OPC_ldc2_w;
4339         writeUnsignedShort(index);
4340 }
4341 final public void ldc2_w(long constant) {
4342         if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$
4343         countLabels = 0;
4344         int index = constantPool.literalIndex(constant);
4345         stackDepth += 2;
4346         if (stackDepth > stackMax)
4347                 stackMax = stackDepth;
4348         // Generate a ldc2_w
4349         if (classFileOffset + 2 >= bCodeStream.length) {
4350                 resizeByteArray();
4351         }
4352         position++;
4353         bCodeStream[classFileOffset++] = OPC_ldc2_w;
4354         writeUnsignedShort(index);
4355 }
4356 final public void ldiv() {
4357         if (DEBUG) System.out.println(position + "\t\tldiv"); //$NON-NLS-1$
4358         countLabels = 0;
4359         stackDepth -= 2;
4360         if (classFileOffset >= bCodeStream.length) {
4361                 resizeByteArray();
4362         }
4363         position++;
4364         bCodeStream[classFileOffset++] = OPC_ldiv;
4365 }
4366 final public void lload(int iArg) {
4367         if (DEBUG) System.out.println(position + "\t\tlload:"+iArg); //$NON-NLS-1$
4368         countLabels = 0;
4369         stackDepth += 2;
4370         if (maxLocals <= iArg + 1) {
4371                 maxLocals = iArg + 2;
4372         }
4373         if (stackDepth > stackMax)
4374                 stackMax = stackDepth;
4375         if (iArg > 255) { // Widen
4376                 if (classFileOffset + 3 >= bCodeStream.length) {
4377                         resizeByteArray();
4378                 }
4379                 position += 2;
4380                 bCodeStream[classFileOffset++] = OPC_wide;
4381                 bCodeStream[classFileOffset++] = OPC_lload;
4382                 writeUnsignedShort(iArg);
4383         } else {
4384                 if (classFileOffset + 1 >= bCodeStream.length) {
4385                         resizeByteArray();
4386                 }
4387                 position += 2;
4388                 bCodeStream[classFileOffset++] = OPC_lload;
4389                 bCodeStream[classFileOffset++] = (byte) iArg;
4390         }
4391 }
4392 final public void lload_0() {
4393         if (DEBUG) System.out.println(position + "\t\tlload_0"); //$NON-NLS-1$
4394         countLabels = 0;
4395         stackDepth += 2;
4396         if (maxLocals < 2) {
4397                 maxLocals = 2;
4398         }
4399         if (stackDepth > stackMax)
4400                 stackMax = stackDepth;
4401         if (classFileOffset >= bCodeStream.length) {
4402                 resizeByteArray();
4403         }
4404         position++;
4405         bCodeStream[classFileOffset++] = OPC_lload_0;
4406 }
4407 final public void lload_1() {
4408         if (DEBUG) System.out.println(position + "\t\tlload_1"); //$NON-NLS-1$
4409         countLabels = 0;
4410         stackDepth += 2;
4411         if (maxLocals < 3) {
4412                 maxLocals = 3;
4413         }
4414         if (stackDepth > stackMax)
4415                 stackMax = stackDepth;
4416         if (classFileOffset >= bCodeStream.length) {
4417                 resizeByteArray();
4418         }
4419         position++;
4420         bCodeStream[classFileOffset++] = OPC_lload_1;
4421 }
4422 final public void lload_2() {
4423         if (DEBUG) System.out.println(position + "\t\tlload_2"); //$NON-NLS-1$
4424         countLabels = 0;
4425         stackDepth += 2;
4426         if (maxLocals < 4) {
4427                 maxLocals = 4;
4428         }
4429         if (stackDepth > stackMax)
4430                 stackMax = stackDepth;
4431         if (classFileOffset >= bCodeStream.length) {
4432                 resizeByteArray();
4433         }
4434         position++;
4435         bCodeStream[classFileOffset++] = OPC_lload_2;
4436 }
4437 final public void lload_3() {
4438         if (DEBUG) System.out.println(position + "\t\tlload_3"); //$NON-NLS-1$
4439         countLabels = 0;
4440         stackDepth += 2;
4441         if (maxLocals < 5) {
4442                 maxLocals = 5;
4443         }
4444         if (stackDepth > stackMax)
4445                 stackMax = stackDepth;
4446         if (classFileOffset >= bCodeStream.length) {
4447                 resizeByteArray();
4448         }
4449         position++;
4450         bCodeStream[classFileOffset++] = OPC_lload_3;
4451 }
4452 final public void lmul() {
4453         if (DEBUG) System.out.println(position + "\t\tlmul"); //$NON-NLS-1$
4454         countLabels = 0;
4455         stackDepth -= 2;
4456         if (classFileOffset >= bCodeStream.length) {
4457                 resizeByteArray();
4458         }
4459         position++;
4460         bCodeStream[classFileOffset++] = OPC_lmul;
4461 }
4462 final public void lneg() {
4463         if (DEBUG) System.out.println(position + "\t\tlneg"); //$NON-NLS-1$
4464         countLabels = 0;
4465         if (classFileOffset >= bCodeStream.length) {
4466                 resizeByteArray();
4467         }
4468         position++;
4469         bCodeStream[classFileOffset++] = OPC_lneg;
4470 }
4471 public final void load(LocalVariableBinding localBinding) {
4472         countLabels = 0;
4473         TypeBinding typeBinding = localBinding.type;
4474         int resolvedPosition = localBinding.resolvedPosition;
4475         // Using dedicated int bytecode
4476         if (typeBinding == IntBinding) {
4477                 switch (resolvedPosition) {
4478                         case 0 :
4479                                 this.iload_0();
4480                                 break;
4481                         case 1 :
4482                                 this.iload_1();
4483                                 break;
4484                         case 2 :
4485                                 this.iload_2();
4486                                 break;
4487                         case 3 :
4488                                 this.iload_3();
4489                                 break;
4490                         //case -1 :
4491                         // internal failure: trying to load variable not supposed to be generated
4492                         //      break;
4493                         default :
4494                                 this.iload(resolvedPosition);
4495                 }
4496                 return;
4497         }
4498         // Using dedicated float bytecode
4499         if (typeBinding == FloatBinding) {
4500                 switch (resolvedPosition) {
4501                         case 0 :
4502                                 this.fload_0();
4503                                 break;
4504                         case 1 :
4505                                 this.fload_1();
4506                                 break;
4507                         case 2 :
4508                                 this.fload_2();
4509                                 break;
4510                         case 3 :
4511                                 this.fload_3();
4512                                 break;
4513                         default :
4514                                 this.fload(resolvedPosition);
4515                 }
4516                 return;
4517         }
4518         // Using dedicated long bytecode
4519         if (typeBinding == LongBinding) {
4520                 switch (resolvedPosition) {
4521                         case 0 :
4522                                 this.lload_0();
4523                                 break;
4524                         case 1 :
4525                                 this.lload_1();
4526                                 break;
4527                         case 2 :
4528                                 this.lload_2();
4529                                 break;
4530                         case 3 :
4531                                 this.lload_3();
4532                                 break;
4533                         default :
4534                                 this.lload(resolvedPosition);
4535                 }
4536                 return;
4537         }
4538         // Using dedicated double bytecode
4539         if (typeBinding == DoubleBinding) {
4540                 switch (resolvedPosition) {
4541                         case 0 :
4542                                 this.dload_0();
4543                                 break;
4544                         case 1 :
4545                                 this.dload_1();
4546                                 break;
4547                         case 2 :
4548                                 this.dload_2();
4549                                 break;
4550                         case 3 :
4551                                 this.dload_3();
4552                                 break;
4553                         default :
4554                                 this.dload(resolvedPosition);
4555                 }
4556                 return;
4557         }
4558         // boolean, byte, char and short are handled as int
4559         if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
4560                 switch (resolvedPosition) {
4561                         case 0 :
4562                                 this.iload_0();
4563                                 break;
4564                         case 1 :
4565                                 this.iload_1();
4566                                 break;
4567                         case 2 :
4568                                 this.iload_2();
4569                                 break;
4570                         case 3 :
4571                                 this.iload_3();
4572                                 break;
4573                         default :
4574                                 this.iload(resolvedPosition);
4575                 }
4576                 return;
4577         }
4578
4579         // Reference object
4580         switch (resolvedPosition) {
4581                 case 0 :
4582                         this.aload_0();
4583                         break;
4584                 case 1 :
4585                         this.aload_1();
4586                         break;
4587                 case 2 :
4588                         this.aload_2();
4589                         break;
4590                 case 3 :
4591                         this.aload_3();
4592                         break;
4593                 default :
4594                         this.aload(resolvedPosition);
4595         }
4596 }
4597 public final void load(TypeBinding typeBinding, int resolvedPosition) {
4598         countLabels = 0;
4599         // Using dedicated int bytecode
4600         if (typeBinding == IntBinding) {
4601                 switch (resolvedPosition) {
4602                         case 0 :
4603                                 this.iload_0();
4604                                 break;
4605                         case 1 :
4606                                 this.iload_1();
4607                                 break;
4608                         case 2 :
4609                                 this.iload_2();
4610                                 break;
4611                         case 3 :
4612                                 this.iload_3();
4613                                 break;
4614                         default :
4615                                 this.iload(resolvedPosition);
4616                 }
4617                 return;
4618         }
4619         // Using dedicated float bytecode
4620         if (typeBinding == FloatBinding) {
4621                 switch (resolvedPosition) {
4622                         case 0 :
4623                                 this.fload_0();
4624                                 break;
4625                         case 1 :
4626                                 this.fload_1();
4627                                 break;
4628                         case 2 :
4629                                 this.fload_2();
4630                                 break;
4631                         case 3 :
4632                                 this.fload_3();
4633                                 break;
4634                         default :
4635                                 this.fload(resolvedPosition);
4636                 }
4637                 return;
4638         }
4639         // Using dedicated long bytecode
4640         if (typeBinding == LongBinding) {
4641                 switch (resolvedPosition) {
4642                         case 0 :
4643                                 this.lload_0();
4644                                 break;
4645                         case 1 :
4646                                 this.lload_1();
4647                                 break;
4648                         case 2 :
4649                                 this.lload_2();
4650                                 break;
4651                         case 3 :
4652                                 this.lload_3();
4653                                 break;
4654                         default :
4655                                 this.lload(resolvedPosition);
4656                 }
4657                 return;
4658         }
4659         // Using dedicated double bytecode
4660         if (typeBinding == DoubleBinding) {
4661                 switch (resolvedPosition) {
4662                         case 0 :
4663                                 this.dload_0();
4664                                 break;
4665                         case 1 :
4666                                 this.dload_1();
4667                                 break;
4668                         case 2 :
4669                                 this.dload_2();
4670                                 break;
4671                         case 3 :
4672                                 this.dload_3();
4673                                 break;
4674                         default :
4675                                 this.dload(resolvedPosition);
4676                 }
4677                 return;
4678         }
4679         // boolean, byte, char and short are handled as int
4680         if ((typeBinding == ByteBinding) || (typeBinding == CharBinding) || (typeBinding == BooleanBinding) || (typeBinding == ShortBinding)) {
4681                 switch (resolvedPosition) {
4682                         case 0 :
4683                                 this.iload_0();
4684                                 break;
4685                         case 1 :
4686                                 this.iload_1();
4687                                 break;
4688                         case 2 :
4689                                 this.iload_2();
4690                                 break;
4691                         case 3 :
4692                                 this.iload_3();
4693                                 break;
4694                         default :
4695                                 this.iload(resolvedPosition);
4696                 }
4697                 return;
4698         }
4699
4700         // Reference object
4701         switch (resolvedPosition) {
4702                 case 0 :
4703                         this.aload_0();
4704                         break;
4705                 case 1 :
4706                         this.aload_1();
4707                         break;
4708                 case 2 :
4709                         this.aload_2();
4710                         break;
4711                 case 3 :
4712                         this.aload_3();
4713                         break;
4714                 default :
4715                         this.aload(resolvedPosition);
4716         }
4717 }
4718 public final void loadInt(int resolvedPosition) {
4719         // Using dedicated int bytecode
4720         switch (resolvedPosition) {
4721                 case 0 :
4722                         this.iload_0();
4723                         break;
4724                 case 1 :
4725                         this.iload_1();
4726                         break;
4727                 case 2 :
4728                         this.iload_2();
4729                         break;
4730                 case 3 :
4731                         this.iload_3();
4732                         break;
4733                 default :
4734                         this.iload(resolvedPosition);
4735         }
4736 }
4737 public final void loadObject(int resolvedPosition) {
4738         switch (resolvedPosition) {
4739                 case 0 :
4740                         this.aload_0();
4741                         break;
4742                 case 1 :
4743                         this.aload_1();
4744                         break;
4745                 case 2 :
4746                         this.aload_2();
4747                         break;
4748                 case 3 :
4749                         this.aload_3();
4750                         break;
4751                 default :
4752                         this.aload(resolvedPosition);
4753         }
4754 }
4755 final public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
4756         if (DEBUG) System.out.println(position + "\t\tlookupswitch"); //$NON-NLS-1$
4757         countLabels = 0;
4758         stackDepth--;
4759         int length = keys.length;
4760         int pos = position;
4761         defaultLabel.placeInstruction();
4762         for (int i = 0; i < length; i++) {
4763                 casesLabel[i].placeInstruction();
4764         }
4765         if (classFileOffset >= bCodeStream.length) {
4766                 resizeByteArray();
4767         }
4768         position++;
4769         bCodeStream[classFileOffset++] = OPC_lookupswitch;
4770         for (int i = (3 - (pos % 4)); i > 0; i--) {
4771                 if (classFileOffset >= bCodeStream.length) {
4772                         resizeByteArray();
4773                 }
4774                 position++;
4775                 bCodeStream[classFileOffset++] = 0;
4776         }
4777         defaultLabel.branch();
4778         writeSignedWord(length);
4779         for (int i = 0; i < length; i++) {
4780                 writeSignedWord(keys[sortedIndexes[i]]);
4781                 casesLabel[sortedIndexes[i]].branch();
4782         }
4783 }
4784 final public void lor() {
4785         if (DEBUG) System.out.println(position + "\t\tlor"); //$NON-NLS-1$
4786         countLabels = 0;
4787         stackDepth -= 2;
4788         if (classFileOffset >= bCodeStream.length) {
4789                 resizeByteArray();
4790         }
4791         position++;
4792         bCodeStream[classFileOffset++] = OPC_lor;
4793 }
4794 final public void lrem() {
4795         if (DEBUG) System.out.println(position + "\t\tlrem"); //$NON-NLS-1$
4796         countLabels = 0;
4797         stackDepth -= 2;
4798         if (classFileOffset >= bCodeStream.length) {
4799                 resizeByteArray();
4800         }
4801         position++;
4802         bCodeStream[classFileOffset++] = OPC_lrem;
4803 }
4804 final public void lreturn() {
4805         if (DEBUG) System.out.println(position + "\t\tlreturn"); //$NON-NLS-1$
4806         countLabels = 0;
4807         stackDepth -= 2;
4808         // the stackDepth should be equal to 0 
4809         if (classFileOffset >= bCodeStream.length) {
4810                 resizeByteArray();
4811         }
4812         position++;
4813         bCodeStream[classFileOffset++] = OPC_lreturn;
4814 }
4815 final public void lshl() {
4816         if (DEBUG) System.out.println(position + "\t\tlshl"); //$NON-NLS-1$
4817         countLabels = 0;
4818         stackDepth--;
4819         if (classFileOffset >= bCodeStream.length) {
4820                 resizeByteArray();
4821         }
4822         position++;
4823         bCodeStream[classFileOffset++] = OPC_lshl;
4824 }
4825 final public void lshr() {
4826         if (DEBUG) System.out.println(position + "\t\tlshr"); //$NON-NLS-1$
4827         countLabels = 0;
4828         stackDepth--;
4829         if (classFileOffset >= bCodeStream.length) {
4830                 resizeByteArray();
4831         }
4832         position++;
4833         bCodeStream[classFileOffset++] = OPC_lshr;
4834 }
4835 final public void lstore(int iArg) {
4836         if (DEBUG) System.out.println(position + "\t\tlstore:"+iArg); //$NON-NLS-1$
4837         countLabels = 0;
4838         stackDepth -= 2;
4839         if (maxLocals <= iArg + 1) {
4840                 maxLocals = iArg + 2;
4841         }
4842         if (iArg > 255) { // Widen
4843                 if (classFileOffset + 3 >= bCodeStream.length) {
4844                         resizeByteArray();
4845                 }
4846                 position += 2;
4847                 bCodeStream[classFileOffset++] = OPC_wide;
4848                 bCodeStream[classFileOffset++] = OPC_lstore;
4849                 writeUnsignedShort(iArg);
4850         } else {
4851                 if (classFileOffset + 1 >= bCodeStream.length) {
4852                         resizeByteArray();
4853                 }
4854                 position += 2;
4855                 bCodeStream[classFileOffset++] = OPC_lstore;
4856                 bCodeStream[classFileOffset++] = (byte) iArg;
4857         }
4858 }
4859 final public void lstore_0() {
4860         if (DEBUG) System.out.println(position + "\t\tlstore_0"); //$NON-NLS-1$
4861         countLabels = 0;
4862         stackDepth -= 2;
4863         if (maxLocals < 2) {
4864                 maxLocals = 2;
4865         }
4866         if (classFileOffset >= bCodeStream.length) {
4867                 resizeByteArray();
4868         }
4869         position++;
4870         bCodeStream[classFileOffset++] = OPC_lstore_0;
4871 }
4872 final public void lstore_1() {
4873         if (DEBUG) System.out.println(position + "\t\tlstore_1"); //$NON-NLS-1$
4874         countLabels = 0;
4875         stackDepth -= 2;
4876         if (maxLocals < 3) {
4877                 maxLocals = 3;
4878         }
4879         if (classFileOffset >= bCodeStream.length) {
4880                 resizeByteArray();
4881         }
4882         position++;
4883         bCodeStream[classFileOffset++] = OPC_lstore_1;
4884 }
4885 final public void lstore_2() {
4886         if (DEBUG) System.out.println(position + "\t\tlstore_2"); //$NON-NLS-1$
4887         countLabels = 0;
4888         stackDepth -= 2;
4889         if (maxLocals < 4) {
4890                 maxLocals = 4;
4891         }
4892         if (classFileOffset >= bCodeStream.length) {
4893                 resizeByteArray();
4894         }
4895         position++;
4896         bCodeStream[classFileOffset++] = OPC_lstore_2;
4897 }
4898 final public void lstore_3() {
4899         if (DEBUG) System.out.println(position + "\t\tlstore_3"); //$NON-NLS-1$
4900         countLabels = 0;
4901         stackDepth -= 2;
4902         if (maxLocals < 5) {
4903                 maxLocals = 5;
4904         }
4905         if (classFileOffset >= bCodeStream.length) {
4906                 resizeByteArray();
4907         }
4908         position++;
4909         bCodeStream[classFileOffset++] = OPC_lstore_3;
4910 }
4911 final public void lsub() {
4912         if (DEBUG) System.out.println(position + "\t\tlsub"); //$NON-NLS-1$
4913         countLabels = 0;
4914         stackDepth -= 2;
4915         if (classFileOffset >= bCodeStream.length) {
4916                 resizeByteArray();
4917         }
4918         position++;
4919         bCodeStream[classFileOffset++] = OPC_lsub;
4920 }
4921 final public void lushr() {
4922         if (DEBUG) System.out.println(position + "\t\tlushr"); //$NON-NLS-1$
4923         countLabels = 0;
4924         stackDepth--;
4925         if (classFileOffset >= bCodeStream.length) {
4926                 resizeByteArray();
4927         }
4928         position++;
4929         bCodeStream[classFileOffset++] = OPC_lushr;
4930 }
4931 final public void lxor() {
4932         if (DEBUG) System.out.println(position + "\t\tlxor"); //$NON-NLS-1$
4933         countLabels = 0;
4934         stackDepth -= 2;
4935         if (classFileOffset >= bCodeStream.length) {
4936                 resizeByteArray();
4937         }
4938         position++;
4939         bCodeStream[classFileOffset++] = OPC_lxor;
4940 }
4941 final public void monitorenter() {
4942         if (DEBUG) System.out.println(position + "\t\tmonitorenter"); //$NON-NLS-1$
4943         countLabels = 0;
4944         stackDepth--;
4945         if (classFileOffset >= bCodeStream.length) {
4946                 resizeByteArray();
4947         }
4948         position++;
4949         bCodeStream[classFileOffset++] = OPC_monitorenter;
4950 }
4951 final public void monitorexit() {
4952         if (DEBUG) System.out.println(position + "\t\tmonitorexit"); //$NON-NLS-1$
4953         countLabels = 0;
4954         stackDepth--;
4955         if (classFileOffset >= bCodeStream.length) {
4956                 resizeByteArray();
4957         }
4958         position++;
4959         bCodeStream[classFileOffset++] = OPC_monitorexit;
4960 }
4961 final public void multianewarray(TypeBinding typeBinding, int dimensions) {
4962         if (DEBUG) System.out.println(position + "\t\tmultinewarray:"+typeBinding+","+dimensions); //$NON-NLS-1$ //$NON-NLS-2$
4963         countLabels = 0;
4964         stackDepth += (1 - dimensions);
4965         if (classFileOffset + 3 >= bCodeStream.length) {
4966                 resizeByteArray();
4967         }
4968         position += 2;
4969         bCodeStream[classFileOffset++] = OPC_multianewarray;
4970         writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
4971         bCodeStream[classFileOffset++] = (byte) dimensions;
4972 }
4973 /**
4974  * We didn't call it new, because there is a conflit with the new keyword
4975  */
4976 final public void new_(TypeBinding typeBinding) {
4977         if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding.debugName()); //$NON-NLS-1$
4978         countLabels = 0;
4979         stackDepth++;
4980         if (stackDepth > stackMax)
4981                 stackMax = stackDepth;
4982         if (classFileOffset + 2 >= bCodeStream.length) {
4983                 resizeByteArray();
4984         }
4985         position++;
4986         bCodeStream[classFileOffset++] = OPC_new;
4987         writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName()));
4988 }
4989 final public void newarray(int array_Type) {
4990         if (DEBUG) System.out.println(position + "\t\tnewarray:"+array_Type); //$NON-NLS-1$
4991         countLabels = 0;
4992         if (classFileOffset + 1 >= bCodeStream.length) {
4993                 resizeByteArray();
4994         }
4995         position += 2;
4996         bCodeStream[classFileOffset++] = OPC_newarray;
4997         bCodeStream[classFileOffset++] = (byte) array_Type;
4998 }
4999 public void newArray(ArrayBinding arrayBinding) {
5000         TypeBinding component = arrayBinding.elementsType();
5001         switch (component.id) {
5002                 case T_int :
5003                         this.newarray(INT_ARRAY);
5004                         break;
5005                 case T_byte :
5006                         this.newarray(BYTE_ARRAY);
5007                         break;
5008                 case T_boolean :
5009                         this.newarray(BOOLEAN_ARRAY);
5010                         break;
5011                 case T_short :
5012                         this.newarray(SHORT_ARRAY);
5013                         break;
5014                 case T_char :
5015                         this.newarray(CHAR_ARRAY);
5016                         break;
5017                 case T_long :
5018                         this.newarray(LONG_ARRAY);
5019                         break;
5020                 case T_float :
5021                         this.newarray(FLOAT_ARRAY);
5022                         break;
5023                 case T_double :
5024                         this.newarray(DOUBLE_ARRAY);
5025                         break;
5026                 default :
5027                         this.anewarray(component);
5028         }
5029 }
5030 public void newJavaLangError() {
5031         // new: java.lang.Error
5032         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Error"); //$NON-NLS-1$
5033         countLabels = 0;
5034         stackDepth++;
5035         if (stackDepth > stackMax)
5036                 stackMax = stackDepth;
5037         if (classFileOffset + 2 >= bCodeStream.length) {
5038                 resizeByteArray();
5039         }
5040         position++;
5041         bCodeStream[classFileOffset++] = OPC_new;
5042         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
5043 }
5044
5045 public void newJavaLangAssertionError() {
5046         // new: java.lang.AssertionError
5047         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.AssertionError"); //$NON-NLS-1$
5048         countLabels = 0;
5049         stackDepth++;
5050         if (stackDepth > stackMax)
5051                 stackMax = stackDepth;
5052         if (classFileOffset + 2 >= bCodeStream.length) {
5053                 resizeByteArray();
5054         }
5055         position++;
5056         bCodeStream[classFileOffset++] = OPC_new;
5057         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName));
5058 }
5059 public void newJavaLangIllegalArgumentException() {
5060         // new: java.lang.IllegalArgumentException
5061         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.IllegalArgumentException"); //$NON-NLS-1$
5062         countLabels = 0;
5063         stackDepth++;
5064         if (stackDepth > stackMax)
5065                 stackMax = stackDepth;
5066         if (classFileOffset + 2 >= bCodeStream.length) {
5067                 resizeByteArray();
5068         }
5069         position++;
5070         bCodeStream[classFileOffset++] = OPC_new;
5071         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName));
5072 }
5073 public void newNoClassDefFoundError() {
5074         // new: java.lang.NoClassDefFoundError
5075         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$
5076         countLabels = 0;
5077         stackDepth++;
5078         if (stackDepth > stackMax)
5079                 stackMax = stackDepth;
5080         if (classFileOffset + 2 >= bCodeStream.length) {
5081                 resizeByteArray();
5082         }
5083         position++;
5084         bCodeStream[classFileOffset++] = OPC_new;
5085         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName));
5086 }
5087 public void newStringContatenation() {
5088         // new: java.lang.StringBuffer
5089         // new: java.lang.StringBuilder
5090         if (DEBUG) {
5091                 if (this.targetLevel >= JDK1_5) {
5092                         System.out.println(position + "\t\tnew: java.lang.StringBuilder"); //$NON-NLS-1$
5093                 } else {
5094                         System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$
5095                 }
5096         }
5097         countLabels = 0;
5098         stackDepth++;
5099         if (stackDepth > stackMax) {
5100                 stackMax = stackDepth;
5101         }
5102         if (classFileOffset + 2 >= bCodeStream.length) {
5103                 resizeByteArray();
5104         }
5105         position++;
5106         bCodeStream[classFileOffset++] = OPC_new;
5107         if (this.targetLevel >= JDK1_5) {
5108                 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName));
5109         } else {
5110                 writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName));
5111         }
5112 }
5113 public void newWrapperFor(int typeID) {
5114         countLabels = 0;
5115         stackDepth++;
5116         if (stackDepth > stackMax)
5117                 stackMax = stackDepth;
5118         if (classFileOffset + 2 >= bCodeStream.length) {
5119                 resizeByteArray();
5120         }
5121         position++;
5122         bCodeStream[classFileOffset++] = OPC_new;
5123         switch (typeID) {
5124                 case T_int : // new: java.lang.Integer
5125                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$
5126                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
5127                         break;
5128                 case T_boolean : // new: java.lang.Boolean
5129                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$
5130                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
5131                         break;
5132                 case T_byte : // new: java.lang.Byte
5133                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$
5134                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
5135                         break;
5136                 case T_char : // new: java.lang.Character
5137                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Character"); //$NON-NLS-1$
5138                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
5139                         break;
5140                 case T_float : // new: java.lang.Float
5141                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Float"); //$NON-NLS-1$
5142                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
5143                         break;
5144                 case T_double : // new: java.lang.Double
5145                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Double"); //$NON-NLS-1$
5146                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
5147                         break;
5148                 case T_short : // new: java.lang.Short
5149                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Short"); //$NON-NLS-1$
5150                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
5151                         break;
5152                 case T_long : // new: java.lang.Long
5153                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$
5154                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
5155                         break;
5156                 case T_void : // new: java.lang.Void
5157                         if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$
5158                         writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName));
5159         }
5160 }
5161 final public void nop() {
5162         if (DEBUG) System.out.println(position + "\t\tnop"); //$NON-NLS-1$
5163         countLabels = 0;
5164         if (classFileOffset >= bCodeStream.length) {
5165                 resizeByteArray();
5166         }
5167         position++;
5168         bCodeStream[classFileOffset++] = OPC_nop;
5169 }
5170 final public void pop() {
5171         if (DEBUG) System.out.println(position + "\t\tpop"); //$NON-NLS-1$
5172         countLabels = 0;
5173         stackDepth--;
5174         if (classFileOffset >= bCodeStream.length) {
5175                 resizeByteArray();
5176         }
5177         position++;
5178         bCodeStream[classFileOffset++] = OPC_pop;
5179 }
5180 final public void pop2() {
5181         if (DEBUG) System.out.println(position + "\t\tpop2"); //$NON-NLS-1$
5182         countLabels = 0;
5183         stackDepth -= 2;
5184         if (classFileOffset >= bCodeStream.length) {
5185                 resizeByteArray();
5186         }
5187         position++;
5188         bCodeStream[classFileOffset++] = OPC_pop2;
5189 }
5190 final public void putfield(FieldBinding fieldBinding) {
5191         if (DEBUG) System.out.println(position + "\t\tputfield:"+fieldBinding); //$NON-NLS-1$
5192         int returnTypeSize = 1;
5193         if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
5194                 returnTypeSize = 2;
5195         }
5196         generateFieldAccess(
5197                         OPC_putfield,
5198                         returnTypeSize,
5199                         fieldBinding.declaringClass.constantPoolName(),
5200                         fieldBinding.name,
5201                         fieldBinding.type.signature());
5202 }
5203 final public void putstatic(FieldBinding fieldBinding) {
5204         if (DEBUG) System.out.println(position + "\t\tputstatic:"+fieldBinding); //$NON-NLS-1$
5205         int returnTypeSize = 1;
5206         if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) {
5207                 returnTypeSize = 2;
5208         }
5209         generateFieldAccess(
5210                         OPC_putstatic,
5211                         returnTypeSize,
5212                         fieldBinding.declaringClass.constantPoolName(),
5213                         fieldBinding.name,
5214                         fieldBinding.type.signature());
5215 }
5216 public void record(LocalVariableBinding local) {
5217         if (!generateLocalVariableTableAttributes)
5218                 return;
5219         if (allLocalsCounter == locals.length) {
5220                 // resize the collection
5221                 System.arraycopy(locals, 0, locals = new LocalVariableBinding[allLocalsCounter + LOCALS_INCREMENT], 0, allLocalsCounter);
5222         }
5223         locals[allLocalsCounter++] = local;
5224         local.initializationPCs = new int[4];
5225         local.initializationCount = 0;
5226 }
5227 public void recordPositionsFrom(int startPC, int sourcePos) {
5228
5229         /* Record positions in the table, only if nothing has 
5230          * already been recorded. Since we output them on the way 
5231          * up (children first for more specific info)
5232          * The pcToSourceMap table is always sorted.
5233          */
5234
5235         if (!generateLineNumberAttributes)
5236                 return;
5237         if (sourcePos == 0)
5238                 return;
5239
5240         // no code generated for this node. e.g. field without any initialization
5241         if (position == startPC)
5242                 return;
5243
5244         // Widening an existing entry that already has the same source positions
5245         if (pcToSourceMapSize + 4 > pcToSourceMap.length) {
5246                 // resize the array pcToSourceMap
5247                 System.arraycopy(pcToSourceMap, 0, pcToSourceMap = new int[pcToSourceMapSize << 1], 0, pcToSourceMapSize);
5248         }
5249         int newLine = ClassFile.searchLineNumber(lineSeparatorPositions, sourcePos);
5250         // lastEntryPC represents the endPC of the lastEntry.
5251         if (pcToSourceMapSize > 0) {
5252                 // in this case there is already an entry in the table
5253                 if (pcToSourceMap[pcToSourceMapSize - 1] != newLine) {
5254                         if (startPC < lastEntryPC) {
5255                                 // we forgot to add an entry.
5256                                 // search if an existing entry exists for startPC
5257                                 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5258                                 if (insertionIndex != -1) {
5259                                         // there is no existing entry starting with startPC.
5260                                         int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, newLine); // index for PC
5261                                         /* the existingEntryIndex corresponds to en entry with the same line and a PC >= startPC.
5262                                                 in this case it is relevant to widen this entry instead of creating a new one.
5263                                                 line1: this(a,
5264                                                   b,
5265                                                   c);
5266                                                 with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
5267                                                 aload0 bytecode. The first entry is the one for the argument a.
5268                                                 But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
5269                                                 So we widen the existing entry (if there is one) or we create a new entry with the startPC.
5270                                         */
5271                                         if (existingEntryIndex != -1) {
5272                                                 // widen existing entry
5273                                                 pcToSourceMap[existingEntryIndex] = startPC;
5274                                         } else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != newLine) {
5275                                                 // we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
5276                                                 System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex);
5277                                                 pcToSourceMap[insertionIndex++] = startPC;
5278                                                 pcToSourceMap[insertionIndex] = newLine;
5279                                                 pcToSourceMapSize += 2;
5280                                         }
5281                                 } else if (position != lastEntryPC) { // no bytecode since last entry pc
5282                                         pcToSourceMap[pcToSourceMapSize++] = lastEntryPC;
5283                                         pcToSourceMap[pcToSourceMapSize++] = newLine;
5284                                 }
5285                         } else {
5286                                 // we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
5287                                 pcToSourceMap[pcToSourceMapSize++] = startPC;
5288                                 pcToSourceMap[pcToSourceMapSize++] = newLine;
5289                         }
5290                 } else {
5291                         /* the last recorded entry is on the same line. But it could be relevant to widen this entry.
5292                            we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
5293                         */      
5294                         if (startPC < pcToSourceMap[pcToSourceMapSize - 2]) {
5295                                 int insertionIndex = insertionIndex(pcToSourceMap, pcToSourceMapSize, startPC);
5296                                 if (insertionIndex != -1) {
5297                                         // widen the existing entry
5298                                         // we have to figure out if we need to move the last entry at another location to keep a sorted table
5299                                         /* First we need to check if at the insertion position there is not an existing entry
5300                                          * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
5301                                          * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
5302                                          * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
5303                                          */
5304                                         if (!((insertionIndex > 1) && (pcToSourceMap[insertionIndex - 1] == newLine))) {
5305                                                 if ((pcToSourceMapSize > 4) && (pcToSourceMap[pcToSourceMapSize - 4] > startPC)) {
5306                                                         System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - 2 - insertionIndex);
5307                                                         pcToSourceMap[insertionIndex++] = startPC;
5308                                                         pcToSourceMap[insertionIndex] = newLine;                                                
5309                                                 } else {
5310                                                         pcToSourceMap[pcToSourceMapSize - 2] = startPC;
5311                                                 }
5312                                         }
5313                                 }
5314                         }
5315                 }
5316                 lastEntryPC = position;
5317         } else {
5318                 // record the first entry
5319                 pcToSourceMap[pcToSourceMapSize++] = startPC;
5320                 pcToSourceMap[pcToSourceMapSize++] = newLine;
5321                 lastEntryPC = position;
5322         }
5323 }
5324 /**
5325  * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
5326  */
5327 public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
5328         int length;
5329         if (exceptionHandlersIndex >= (length = exceptionHandlers.length)) {
5330                 // resize the exception handlers table
5331                 System.arraycopy(exceptionHandlers, 0, exceptionHandlers = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
5332         }
5333         // no need to resize. So just add the new exception label
5334         exceptionHandlers[exceptionHandlersIndex++] = anExceptionLabel;
5335         exceptionHandlersCounter++;
5336 }
5337 public void removeExceptionHandler(ExceptionLabel exceptionLabel) {
5338         for (int i = 0; i < exceptionHandlersIndex; i++) {
5339                 if (exceptionHandlers[i] == exceptionLabel) {
5340                         exceptionHandlers[i] = null;
5341                         exceptionHandlersCounter--;
5342                         return;
5343                 }
5344         }
5345 }
5346 public final void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
5347         // given some flow info, make sure we did not loose some variables initialization
5348         // if this happens, then we must update their pc entries to reflect it in debug attributes
5349         if (!generateLocalVariableTableAttributes)
5350                 return;
5351 /*      if (initStateIndex == lastInitStateIndexWhenRemovingInits)
5352                 return;
5353                 
5354         lastInitStateIndexWhenRemovingInits = initStateIndex;
5355         if (lastInitStateIndexWhenAddingInits != initStateIndex){
5356                 lastInitStateIndexWhenAddingInits = -2;// reinitialize add index 
5357                 // add(1)-remove(1)-add(1) -> ignore second add
5358                 // add(1)-remove(2)-add(1) -> perform second add
5359         }*/
5360         for (int i = 0; i < visibleLocalsCount; i++) {
5361                 LocalVariableBinding localBinding = visibleLocals[i];
5362                 if (localBinding != null) {
5363                         if (initStateIndex == -1 || !isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
5364                                 if (localBinding.initializationCount > 0) {
5365                                         localBinding.recordInitializationEndPC(position);
5366                                 }
5367                         }
5368                 }
5369         }
5370 }
5371 /**
5372  * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
5373  * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
5374  */
5375 public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
5376         init(targetClassFile);
5377         this.methodDeclaration = referenceMethod;
5378         preserveUnusedLocals = referenceMethod.scope.problemReporter().options.preserveAllLocalVariables;
5379         initializeMaxLocals(referenceMethod.binding);
5380 }
5381 /**
5382  * @param targetClassFile The given classfile to reset the code stream
5383  */
5384 public void resetForProblemClinit(ClassFile targetClassFile) {
5385         init(targetClassFile);
5386         maxLocals = 0;
5387 }
5388 private final void resizeByteArray() {
5389         int length = bCodeStream.length;
5390         int requiredSize = length + length;
5391         if (classFileOffset > requiredSize) {
5392                 // must be sure to grow by enough
5393                 requiredSize = classFileOffset + length;
5394         }
5395         System.arraycopy(bCodeStream, 0, bCodeStream = new byte[requiredSize], 0, length);
5396 }
5397 final public void ret(int index) {
5398         if (DEBUG) System.out.println(position + "\t\tret:"+index); //$NON-NLS-1$
5399         countLabels = 0;
5400         if (index > 255) { // Widen
5401                 if (classFileOffset + 3 >= bCodeStream.length) {
5402                         resizeByteArray();
5403                 }
5404                 position += 2;
5405                 bCodeStream[classFileOffset++] = OPC_wide;
5406                 bCodeStream[classFileOffset++] = OPC_ret;
5407                 writeUnsignedShort(index);
5408         } else { // Don't Widen
5409                 if (classFileOffset + 1 >= bCodeStream.length) {
5410                         resizeByteArray();
5411                 }
5412                 position += 2;
5413                 bCodeStream[classFileOffset++] = OPC_ret;
5414                 bCodeStream[classFileOffset++] = (byte) index;
5415         }
5416 }
5417 final public void return_() {
5418         if (DEBUG) System.out.println(position + "\t\treturn"); //$NON-NLS-1$
5419         countLabels = 0;
5420         // the stackDepth should be equal to 0 
5421         if (classFileOffset >= bCodeStream.length) {
5422                 resizeByteArray();
5423         }
5424         position++;
5425         bCodeStream[classFileOffset++] = OPC_return;
5426 }
5427 final public void saload() {
5428         if (DEBUG) System.out.println(position + "\t\tsaload"); //$NON-NLS-1$
5429         countLabels = 0;
5430         stackDepth--;
5431         if (classFileOffset >= bCodeStream.length) {
5432                 resizeByteArray();
5433         }
5434         position++;
5435         bCodeStream[classFileOffset++] = OPC_saload;
5436 }
5437 final public void sastore() {
5438         if (DEBUG) System.out.println(position + "\t\tsastore"); //$NON-NLS-1$
5439         countLabels = 0;
5440         stackDepth -= 3;
5441         if (classFileOffset >= bCodeStream.length) {
5442                 resizeByteArray();
5443         }
5444         position++;
5445         bCodeStream[classFileOffset++] = OPC_sastore;
5446 }
5447 /**
5448  * @param operatorConstant int
5449  * @param type_ID int
5450  */
5451 public void sendOperator(int operatorConstant, int type_ID) {
5452         switch (type_ID) {
5453                 case T_int :
5454                 case T_boolean :
5455                 case T_char :
5456                 case T_byte :
5457                 case T_short :
5458                         switch (operatorConstant) {
5459                                 case PLUS :
5460                                         this.iadd();
5461                                         break;
5462                                 case MINUS :
5463                                         this.isub();
5464                                         break;
5465                                 case MULTIPLY :
5466                                         this.imul();
5467                                         break;
5468                                 case DIVIDE :
5469                                         this.idiv();
5470                                         break;
5471                                 case REMAINDER :
5472                                         this.irem();
5473                                         break;
5474                                 case LEFT_SHIFT :
5475                                         this.ishl();
5476                                         break;
5477                                 case RIGHT_SHIFT :
5478                                         this.ishr();
5479                                         break;
5480                                 case UNSIGNED_RIGHT_SHIFT :
5481                                         this.iushr();
5482                                         break;
5483                                 case AND :
5484                                         this.iand();
5485                                         break;
5486                                 case OR :
5487                                         this.ior();
5488                                         break;
5489                                 case XOR :
5490                                         this.ixor();
5491                                         break;
5492                         }
5493                         break;
5494                 case T_long :
5495                         switch (operatorConstant) {
5496                                 case PLUS :
5497                                         this.ladd();
5498                                         break;
5499                                 case MINUS :
5500                                         this.lsub();
5501                                         break;
5502                                 case MULTIPLY :
5503                                         this.lmul();
5504                                         break;
5505                                 case DIVIDE :
5506                                         this.ldiv();
5507                                         break;
5508                                 case REMAINDER :
5509                                         this.lrem();
5510                                         break;
5511                                 case LEFT_SHIFT :
5512                                         this.lshl();
5513                                         break;
5514                                 case RIGHT_SHIFT :
5515                                         this.lshr();
5516                                         break;
5517                                 case UNSIGNED_RIGHT_SHIFT :
5518                                         this.lushr();
5519                                         break;
5520                                 case AND :
5521                                         this.land();
5522                                         break;
5523                                 case OR :
5524                                         this.lor();
5525                                         break;
5526                                 case XOR :
5527                                         this.lxor();
5528                                         break;
5529                         }
5530                         break;
5531                 case T_float :
5532                         switch (operatorConstant) {
5533                                 case PLUS :
5534                                         this.fadd();
5535                                         break;
5536                                 case MINUS :
5537                                         this.fsub();
5538                                         break;
5539                                 case MULTIPLY :
5540                                         this.fmul();
5541                                         break;
5542                                 case DIVIDE :
5543                                         this.fdiv();
5544                                         break;
5545                                 case REMAINDER :
5546                                         this.frem();
5547                         }
5548                         break;
5549                 case T_double :
5550                         switch (operatorConstant) {
5551                                 case PLUS :
5552                                         this.dadd();
5553                                         break;
5554                                 case MINUS :
5555                                         this.dsub();
5556                                         break;
5557                                 case MULTIPLY :
5558                                         this.dmul();
5559                                         break;
5560                                 case DIVIDE :
5561                                         this.ddiv();
5562                                         break;
5563                                 case REMAINDER :
5564                                         this.drem();
5565                         }
5566         }
5567 }
5568 final public void sipush(int s) {
5569         if (DEBUG) System.out.println(position + "\t\tsipush:"+s); //$NON-NLS-1$
5570         countLabels = 0;
5571         stackDepth++;
5572         if (stackDepth > stackMax)
5573                 stackMax = stackDepth;
5574         if (classFileOffset >= bCodeStream.length) {
5575                 resizeByteArray();
5576         }
5577         position++;
5578         bCodeStream[classFileOffset++] = OPC_sipush;
5579         writeSignedShort(s);
5580 }
5581 public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
5582         int lo = lo0;
5583         int hi = hi0;
5584         int mid;
5585         if (hi0 > lo0) {
5586                 /* Arbitrarily establishing partition element as the midpoint of
5587                   * the array.
5588                   */
5589                 mid = tab[ (lo0 + hi0) / 2];
5590                 // loop through the array until indices cross
5591                 while (lo <= hi) {
5592                         /* find the first element that is greater than or equal to 
5593                          * the partition element starting from the left Index.
5594                          */
5595                         while ((lo < hi0) && (tab[lo] < mid))
5596                                 ++lo;
5597                         /* find an element that is smaller than or equal to 
5598                          * the partition element starting from the right Index.
5599                          */
5600                         while ((hi > lo0) && (tab[hi] > mid))
5601                                 --hi;
5602                         // if the indexes have not crossed, swap
5603                         if (lo <= hi) {
5604                                 swap(tab, lo, hi, result);
5605                                 ++lo;
5606                                 --hi;
5607                         }
5608                 }
5609                 /* If the right index has not reached the left side of array
5610                   * must now sort the left partition.
5611                   */
5612                 if (lo0 < hi)
5613                         sort(tab, lo0, hi, result);
5614                 /* If the left index has not reached the right side of array
5615                   * must now sort the right partition.
5616                   */
5617                 if (lo < hi0)
5618                         sort(tab, lo, hi0, result);
5619         }
5620 }
5621
5622 public final void store(LocalVariableBinding localBinding, boolean valueRequired) {
5623         int localPosition = localBinding.resolvedPosition;
5624         // Using dedicated int bytecode
5625         switch(localBinding.type.id) {
5626                 case TypeIds.T_int :
5627                 case TypeIds.T_char :
5628                 case TypeIds.T_byte :
5629                 case TypeIds.T_short :
5630                 case TypeIds.T_boolean :
5631                         if (valueRequired)
5632                                 this.dup();
5633                         switch (localPosition) {
5634                                 case 0 :
5635                                         this.istore_0();
5636                                         break;
5637                                 case 1 :
5638                                         this.istore_1();
5639                                         break;
5640                                 case 2 :
5641                                         this.istore_2();
5642                                         break;
5643                                 case 3 :
5644                                         this.istore_3();
5645                                         break;
5646                                 //case -1 :
5647                                 // internal failure: trying to store into variable not supposed to be generated
5648                                 //      break;
5649                                 default :
5650                                         this.istore(localPosition);
5651                         }
5652                         break;
5653                 case TypeIds.T_float :
5654                         if (valueRequired)
5655                                 this.dup();
5656                         switch (localPosition) {
5657                                 case 0 :
5658                                         this.fstore_0();
5659                                         break;
5660                                 case 1 :
5661                                         this.fstore_1();
5662                                         break;
5663                                 case 2 :
5664                                         this.fstore_2();
5665                                         break;
5666                                 case 3 :
5667                                         this.fstore_3();
5668                                         break;
5669                                 default :
5670                                         this.fstore(localPosition);
5671                         }
5672                         break;
5673                 case TypeIds.T_double :
5674                         if (valueRequired)
5675                                 this.dup2();
5676                         switch (localPosition) {
5677                                 case 0 :
5678                                         this.dstore_0();
5679                                         break;
5680                                 case 1 :
5681                                         this.dstore_1();
5682                                         break;
5683                                 case 2 :
5684                                         this.dstore_2();
5685                                         break;
5686                                 case 3 :
5687                                         this.dstore_3();
5688                                         break;
5689                                 default :
5690                                         this.dstore(localPosition);
5691                         }
5692                         break;
5693                 case TypeIds.T_long :
5694                         if (valueRequired)
5695                                 this.dup2();
5696                         switch (localPosition) {
5697                                 case 0 :
5698                                         this.lstore_0();
5699                                         break;
5700                                 case 1 :
5701                                         this.lstore_1();
5702                                         break;
5703                                 case 2 :
5704                                         this.lstore_2();
5705                                         break;
5706                                 case 3 :
5707                                         this.lstore_3();
5708                                         break;
5709                                 default :
5710                                         this.lstore(localPosition);
5711                         }
5712                         break;
5713                 default:
5714                         // Reference object
5715                         if (valueRequired)
5716                                 this.dup();
5717                         switch (localPosition) {
5718                                 case 0 :
5719                                         this.astore_0();
5720                                         break;
5721                                 case 1 :
5722                                         this.astore_1();
5723                                         break;
5724                                 case 2 :
5725                                         this.astore_2();
5726                                         break;
5727                                 case 3 :
5728                                         this.astore_3();
5729                                         break;
5730                                 default :
5731                                         this.astore(localPosition);
5732                         }
5733         }
5734 }
5735 public final void store(TypeBinding type, int localPosition) {
5736         // Using dedicated int bytecode
5737         if ((type == IntBinding) || (type == CharBinding) || (type == ByteBinding) || (type == ShortBinding) || (type == BooleanBinding)) {
5738                 switch (localPosition) {
5739                         case 0 :
5740                                 this.istore_0();
5741                                 break;
5742                         case 1 :
5743                                 this.istore_1();
5744                                 break;
5745                         case 2 :
5746                                 this.istore_2();
5747                                 break;
5748                         case 3 :
5749                                 this.istore_3();
5750                                 break;
5751                         default :
5752                                 this.istore(localPosition);
5753                 }
5754                 return;
5755         }
5756         // Using dedicated float bytecode
5757         if (type == FloatBinding) {
5758                 switch (localPosition) {
5759                         case 0 :
5760                                 this.fstore_0();
5761                                 break;
5762                         case 1 :
5763                                 this.fstore_1();
5764                                 break;
5765                         case 2 :
5766                                 this.fstore_2();
5767                                 break;
5768                         case 3 :
5769                                 this.fstore_3();
5770                                 break;
5771                         default :
5772                                 this.fstore(localPosition);
5773                 }
5774                 return;
5775         }
5776         // Using dedicated long bytecode
5777         if (type == LongBinding) {
5778                 switch (localPosition) {
5779                         case 0 :
5780                                 this.lstore_0();
5781                                 break;
5782                         case 1 :
5783                                 this.lstore_1();
5784                                 break;
5785                         case 2 :
5786                                 this.lstore_2();
5787                                 break;
5788                         case 3 :
5789                                 this.lstore_3();
5790                                 break;
5791                         default :
5792                                 this.lstore(localPosition);
5793                 }
5794                 return;
5795         }
5796         // Using dedicated double bytecode
5797         if (type == DoubleBinding) {
5798                 switch (localPosition) {
5799                         case 0 :
5800                                 this.dstore_0();
5801                                 break;
5802                         case 1 :
5803                                 this.dstore_1();
5804                                 break;
5805                         case 2 :
5806                                 this.dstore_2();
5807                                 break;
5808                         case 3 :
5809                                 this.dstore_3();
5810                                 break;
5811                         default :
5812                                 this.dstore(localPosition);
5813                 }
5814                 return;
5815         }
5816         // Reference object
5817         switch (localPosition) {
5818                 case 0 :
5819                         this.astore_0();
5820                         break;
5821                 case 1 :
5822                         this.astore_1();
5823                         break;
5824                 case 2 :
5825                         this.astore_2();
5826                         break;
5827                 case 3 :
5828                         this.astore_3();
5829                         break;
5830                 default :
5831                         this.astore(localPosition);
5832         }
5833 }
5834 public final void storeInt(int localPosition) {
5835         switch (localPosition) {
5836                 case 0 :
5837                         this.istore_0();
5838                         break;
5839                 case 1 :
5840                         this.istore_1();
5841                         break;
5842                 case 2 :
5843                         this.istore_2();
5844                         break;
5845                 case 3 :
5846                         this.istore_3();
5847                         break;
5848                 default :
5849                         this.istore(localPosition);
5850         }
5851 }
5852 public final void storeObject(int localPosition) {
5853         switch (localPosition) {
5854                 case 0 :
5855                         this.astore_0();
5856                         break;
5857                 case 1 :
5858                         this.astore_1();
5859                         break;
5860                 case 2 :
5861                         this.astore_2();
5862                         break;
5863                 case 3 :
5864                         this.astore_3();
5865                         break;
5866                 default :
5867                         this.astore(localPosition);
5868         }
5869 }
5870 final public void swap() {
5871         if (DEBUG) System.out.println(position + "\t\tswap"); //$NON-NLS-1$
5872         countLabels = 0;
5873         if (classFileOffset >= bCodeStream.length) {
5874                 resizeByteArray();
5875         }
5876         position++;
5877         bCodeStream[classFileOffset++] = OPC_swap;
5878 }
5879 private static final void swap(int a[], int i, int j, int result[]) {
5880         int T;
5881         T = a[i];
5882         a[i] = a[j];
5883         a[j] = T;
5884         T = result[j];
5885         result[j] = result[i];
5886         result[i] = T;
5887 }
5888 final public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
5889         if (DEBUG) System.out.println(position + "\t\ttableswitch"); //$NON-NLS-1$
5890         countLabels = 0;
5891         stackDepth--;
5892         int length = casesLabel.length;
5893         int pos = position;
5894         defaultLabel.placeInstruction();
5895         for (int i = 0; i < length; i++)
5896                 casesLabel[i].placeInstruction();
5897         if (classFileOffset >= bCodeStream.length) {
5898                 resizeByteArray();
5899         }
5900         position++;
5901         bCodeStream[classFileOffset++] = OPC_tableswitch;
5902         for (int i = (3 - (pos % 4)); i > 0; i--) {
5903                 if (classFileOffset >= bCodeStream.length) {
5904                         resizeByteArray();
5905                 }
5906                 position++;
5907                 bCodeStream[classFileOffset++] = 0;
5908         }
5909         defaultLabel.branch();
5910         writeSignedWord(low);
5911         writeSignedWord(high);
5912         int i = low, j = low;
5913         // the index j is used to know if the index i is one of the missing entries in case of an 
5914         // optimized tableswitch
5915         while (true) {
5916                 int index;
5917                 int key = keys[index = sortedIndexes[j - low]];
5918                 if (key == i) {
5919                         casesLabel[index].branch();
5920                         j++;
5921                         if (i == high) break; // if high is maxint, then avoids wrapping to minint.
5922                 } else {
5923                         defaultLabel.branch();
5924                 }
5925                 i++;
5926         }
5927 }
5928 public String toString() {
5929         StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
5930         buffer.append(position);
5931         buffer.append(",\nstackDepth:"); //$NON-NLS-1$
5932         buffer.append(stackDepth);
5933         buffer.append(",\nmaxStack:"); //$NON-NLS-1$
5934         buffer.append(stackMax);
5935         buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
5936         buffer.append(maxLocals);
5937         buffer.append(")"); //$NON-NLS-1$
5938         return buffer.toString();
5939 }
5940 public void updateLastRecordedEndPC(int pos) {
5941
5942         /* Tune positions in the table, this is due to some 
5943          * extra bytecodes being
5944          * added to some user code (jumps). */
5945         /** OLD CODE
5946                 if (!generateLineNumberAttributes)
5947                         return;
5948                 pcToSourceMap[pcToSourceMapSize - 1][1] = position;
5949                 // need to update the initialization endPC in case of generation of local variable attributes.
5950                 updateLocalVariablesAttribute(pos);     
5951         */      
5952
5953         if (!generateLineNumberAttributes)
5954                 return;
5955         this.lastEntryPC = pos;
5956         // need to update the initialization endPC in case of generation of local variable attributes.
5957         updateLocalVariablesAttribute(pos);
5958 }
5959 public void updateLocalVariablesAttribute(int pos) {
5960         // need to update the initialization endPC in case of generation of local variable attributes.
5961         if (generateLocalVariableTableAttributes) {
5962                 for (int i = 0, max = locals.length; i < max; i++) {
5963                         LocalVariableBinding local = locals[i];
5964                         if ((local != null) && (local.initializationCount > 0)) {
5965                                 if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
5966                                         local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position;
5967                                 }
5968                         }
5969                 }
5970         }
5971 }
5972 /**
5973  * Write a signed 16 bits value into the byte array
5974  * @param value the signed short
5975  */
5976 public final void writeSignedShort(int value) {
5977         // we keep the resize in here because it is used outside the code stream
5978         if (classFileOffset + 1 >= bCodeStream.length) {
5979                 resizeByteArray();
5980         }
5981         position += 2;
5982         bCodeStream[classFileOffset++] = (byte) (value >> 8);
5983         bCodeStream[classFileOffset++] = (byte) value;
5984 }
5985 public final void writeSignedShort(int pos, int value) {
5986         int currentOffset = startingClassFileOffset + pos;
5987         if (currentOffset + 1 >= bCodeStream.length) {
5988                 resizeByteArray();
5989         }
5990         bCodeStream[currentOffset] = (byte) (value >> 8);
5991         bCodeStream[currentOffset + 1] = (byte) value;
5992 }
5993 public final void writeSignedWord(int value) {
5994         // we keep the resize in here because it is used outside the code stream
5995         if (classFileOffset + 3 >= bCodeStream.length) {
5996                 resizeByteArray();
5997         }
5998         position += 4;
5999         bCodeStream[classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
6000         bCodeStream[classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
6001         bCodeStream[classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
6002         bCodeStream[classFileOffset++] = (byte) (value & 0xFF);
6003 }
6004 public final void writeSignedWord(int pos, int value) {
6005         int currentOffset = startingClassFileOffset + pos;
6006         if (currentOffset + 4 >= bCodeStream.length) {
6007                 resizeByteArray();
6008         }
6009         bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
6010         bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
6011         bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
6012         bCodeStream[currentOffset++] = (byte) (value & 0xFF);
6013 }
6014 /**
6015  * Write a unsigned 16 bits value into the byte array
6016  * @param value the unsigned short
6017  */
6018 protected final void writeUnsignedShort(int value) {
6019         position += 2;
6020         bCodeStream[classFileOffset++] = (byte) (value >>> 8);
6021         bCodeStream[classFileOffset++] = (byte) value;
6022 }
6023 /*
6024  * Wide conditional branch compare, improved by swapping comparison opcode
6025  *   ifeq WideTarget
6026  * becomes
6027  *    ifne Intermediate
6028  *    gotow WideTarget
6029  *    Intermediate:
6030  */
6031 public void generateWideRevertedConditionalBranch(byte revertedOpcode, Label wideTarget) {
6032                 Label intermediate = new Label(this);
6033                 if (classFileOffset >= bCodeStream.length) {
6034                         resizeByteArray();
6035                 }
6036                 position++;
6037                 bCodeStream[classFileOffset++] = revertedOpcode;
6038                 intermediate.branch();
6039                 this.goto_w(wideTarget);
6040                 intermediate.place();
6041 }
6042 }