001    /*
002     * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    package com.sun.tools.javac.jvm;
027    
028    import com.sun.tools.javac.code.*;
029    import com.sun.tools.javac.code.Symbol.*;
030    import com.sun.tools.javac.util.*;
031    import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
032    
033    import static com.sun.tools.javac.code.TypeTags.*;
034    import static com.sun.tools.javac.jvm.ByteCodes.*;
035    import static com.sun.tools.javac.jvm.UninitializedType.*;
036    import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
037    
038    /** An internal structure that corresponds to the code attribute of
039     *  methods in a classfile. The class also provides some utility operations to
040     *  generate bytecode instructions.
041     *
042     *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
043     *  you write code that depends on this, you do so at your own risk.
044     *  This code and its internal interfaces are subject to change or
045     *  deletion without notice.</b>
046     */
047    public class Code {
048    
049        public final boolean debugCode;
050        public final boolean needStackMap;
051    
052        public enum StackMapFormat {
053            NONE,
054            CLDC {
055                Name getAttributeName(Names names) {
056                    return names.StackMap;
057                }
058            },
059            JSR202 {
060                Name getAttributeName(Names names) {
061                    return names.StackMapTable;
062                }
063            };
064            Name getAttributeName(Names names) {
065                return names.empty;
066            }
067        }
068    
069        final Types types;
070        final Symtab syms;
071    
072    /*---------- classfile fields: --------------- */
073    
074        /** The maximum stack size.
075         */
076        public int max_stack = 0;
077    
078        /** The maximum number of local variable slots.
079         */
080        public int max_locals = 0;
081    
082        /** The code buffer.
083         */
084        public byte[] code = new byte[64];
085    
086        /** the current code pointer.
087         */
088        public int cp = 0;
089    
090        /** Check the code against VM spec limits; if
091         *  problems report them and return true.
092         */
093        public boolean checkLimits(DiagnosticPosition pos, Log log) {
094            if (cp > ClassFile.MAX_CODE) {
095                log.error(pos, "limit.code");
096                return true;
097            }
098            if (max_locals > ClassFile.MAX_LOCALS) {
099                log.error(pos, "limit.locals");
100                return true;
101            }
102            if (max_stack > ClassFile.MAX_STACK) {
103                log.error(pos, "limit.stack");
104                return true;
105            }
106            return false;
107        }
108    
109        /** A buffer for expression catch data. Each enter is a vector
110         *  of four unsigned shorts.
111         */
112        ListBuffer<char[]> catchInfo = new ListBuffer<char[]>();
113    
114        /** A buffer for line number information. Each entry is a vector
115         *  of two unsigned shorts.
116         */
117        List<char[]> lineInfo = List.nil(); // handled in stack fashion
118    
119        /** The CharacterRangeTable
120         */
121        public CRTable crt;
122    
123    /*---------- internal fields: --------------- */
124    
125        /** Are we generating code with jumps >= 32K?
126         */
127        public boolean fatcode;
128    
129        /** Code generation enabled?
130         */
131        private boolean alive = true;
132    
133        /** The current machine state (registers and stack).
134         */
135        State state;
136    
137        /** Is it forbidden to compactify code, because something is
138         *  pointing to current location?
139         */
140        private boolean fixedPc = false;
141    
142        /** The next available register.
143         */
144        public int nextreg = 0;
145    
146        /** A chain for jumps to be resolved before the next opcode is emitted.
147         *  We do this lazily to avoid jumps to jumps.
148         */
149        Chain pendingJumps = null;
150    
151        /** The position of the currently statement, if we are at the
152         *  start of this statement, NOPOS otherwise.
153         *  We need this to emit line numbers lazily, which we need to do
154         *  because of jump-to-jump optimization.
155         */
156        int pendingStatPos = Position.NOPOS;
157    
158        /** Set true when a stackMap is needed at the current PC. */
159        boolean pendingStackMap = false;
160    
161        /** The stack map format to be generated. */
162        StackMapFormat stackMap;
163    
164        /** Switch: emit variable debug info.
165         */
166        boolean varDebugInfo;
167    
168        /** Switch: emit line number info.
169         */
170        boolean lineDebugInfo;
171    
172        /** Emit line number info if map supplied
173         */
174        Position.LineMap lineMap;
175    
176        /** The constant pool of the current class.
177         */
178        final Pool pool;
179    
180        final MethodSymbol meth;
181    
182        /** Construct a code object, given the settings of the fatcode,
183         *  debugging info switches and the CharacterRangeTable.
184         */
185        public Code(MethodSymbol meth,
186                    boolean fatcode,
187                    Position.LineMap lineMap,
188                    boolean varDebugInfo,
189                    StackMapFormat stackMap,
190                    boolean debugCode,
191                    CRTable crt,
192                    Symtab syms,
193                    Types types,
194                    Pool pool) {
195            this.meth = meth;
196            this.fatcode = fatcode;
197            this.lineMap = lineMap;
198            this.lineDebugInfo = lineMap != null;
199            this.varDebugInfo = varDebugInfo;
200            this.crt = crt;
201            this.syms = syms;
202            this.types = types;
203            this.debugCode = debugCode;
204            this.stackMap = stackMap;
205            switch (stackMap) {
206            case CLDC:
207            case JSR202:
208                this.needStackMap = true;
209                break;
210            default:
211                this.needStackMap = false;
212            }
213            state = new State();
214            lvar = new LocalVar[20];
215            this.pool = pool;
216        }
217    
218    
219    /* **************************************************************************
220     * Typecodes & related stuff
221     ****************************************************************************/
222    
223        /** Given a type, return its type code (used implicitly in the
224         *  JVM architecture).
225         */
226        public static int typecode(Type type) {
227            switch (type.tag) {
228            case BYTE: return BYTEcode;
229            case SHORT: return SHORTcode;
230            case CHAR: return CHARcode;
231            case INT: return INTcode;
232            case LONG: return LONGcode;
233            case FLOAT: return FLOATcode;
234            case DOUBLE: return DOUBLEcode;
235            case BOOLEAN: return BYTEcode;
236            case VOID: return VOIDcode;
237            case CLASS:
238            case ARRAY:
239            case METHOD:
240            case BOT:
241            case TYPEVAR:
242            case UNINITIALIZED_THIS:
243            case UNINITIALIZED_OBJECT:
244                return OBJECTcode;
245            default: throw new AssertionError("typecode " + type.tag);
246            }
247        }
248    
249        /** Collapse type code for subtypes of int to INTcode.
250         */
251        public static int truncate(int tc) {
252            switch (tc) {
253            case BYTEcode: case SHORTcode: case CHARcode: return INTcode;
254            default: return tc;
255            }
256        }
257    
258        /** The width in bytes of objects of the type.
259         */
260        public static int width(int typecode) {
261            switch (typecode) {
262            case LONGcode: case DOUBLEcode: return 2;
263            case VOIDcode: return 0;
264            default: return 1;
265            }
266        }
267    
268        public static int width(Type type) {
269            return type == null ? 1 : width(typecode(type));
270        }
271    
272        /** The total width taken up by a vector of objects.
273         */
274        public static int width(List<Type> types) {
275            int w = 0;
276            for (List<Type> l = types; l.nonEmpty(); l = l.tail)
277                w = w + width(l.head);
278            return w;
279        }
280    
281        /** Given a type, return its code for allocating arrays of that type.
282         */
283        public static int arraycode(Type type) {
284            switch (type.tag) {
285            case BYTE: return 8;
286            case BOOLEAN: return 4;
287            case SHORT: return 9;
288            case CHAR: return 5;
289            case INT: return 10;
290            case LONG: return 11;
291            case FLOAT: return 6;
292            case DOUBLE: return 7;
293            case CLASS: return 0;
294            case ARRAY: return 1;
295            default: throw new AssertionError("arraycode " + type);
296            }
297        }
298    
299    
300    /* **************************************************************************
301     * Emit code
302     ****************************************************************************/
303    
304        /** The current output code pointer.
305         */
306        public int curPc() {
307            if (pendingJumps != null) resolvePending();
308            if (pendingStatPos != Position.NOPOS) markStatBegin();
309            fixedPc = true;
310            return cp;
311        }
312    
313        /** Emit a byte of code.
314         */
315        private  void emit1(int od) {
316            if (!alive) return;
317            if (cp == code.length) {
318                byte[] newcode = new byte[cp * 2];
319                System.arraycopy(code, 0, newcode, 0, cp);
320                code = newcode;
321            }
322            code[cp++] = (byte)od;
323        }
324    
325        /** Emit two bytes of code.
326         */
327        private void emit2(int od) {
328            if (!alive) return;
329            if (cp + 2 > code.length) {
330                emit1(od >> 8);
331                emit1(od);
332            } else {
333                code[cp++] = (byte)(od >> 8);
334                code[cp++] = (byte)od;
335            }
336        }
337    
338        /** Emit four bytes of code.
339         */
340        public void emit4(int od) {
341            if (!alive) return;
342            if (cp + 4 > code.length) {
343                emit1(od >> 24);
344                emit1(od >> 16);
345                emit1(od >> 8);
346                emit1(od);
347            } else {
348                code[cp++] = (byte)(od >> 24);
349                code[cp++] = (byte)(od >> 16);
350                code[cp++] = (byte)(od >> 8);
351                code[cp++] = (byte)od;
352            }
353        }
354    
355        /** Emit an opcode.
356         */
357        private void emitop(int op) {
358            if (pendingJumps != null) resolvePending();
359            if (alive) {
360                if (pendingStatPos != Position.NOPOS)
361                    markStatBegin();
362                if (pendingStackMap) {
363                    pendingStackMap = false;
364                    emitStackMap();
365                }
366                if (debugCode)
367                    System.err.println("emit@" + cp + " stack=" +
368                                       state.stacksize + ": " +
369                                       mnem(op));
370                emit1(op);
371            }
372        }
373    
374        void postop() {
375            assert alive || state.stacksize == 0;
376        }
377    
378        /** Emit a multinewarray instruction.
379         */
380        public void emitMultianewarray(int ndims, int type, Type arrayType) {
381            emitop(multianewarray);
382            if (!alive) return;
383            emit2(type);
384            emit1(ndims);
385            state.pop(ndims);
386            state.push(arrayType);
387        }
388    
389        /** Emit newarray.
390         */
391        public void emitNewarray(int elemcode, Type arrayType) {
392            emitop(newarray);
393            if (!alive) return;
394            emit1(elemcode);
395            state.pop(1); // count
396            state.push(arrayType);
397        }
398    
399        /** Emit anewarray.
400         */
401        public void emitAnewarray(int od, Type arrayType) {
402            emitop(anewarray);
403            if (!alive) return;
404            emit2(od);
405            state.pop(1);
406            state.push(arrayType);
407        }
408    
409        /** Emit an invokeinterface instruction.
410         */
411        public void emitInvokeinterface(int meth, Type mtype) {
412            int argsize = width(mtype.getParameterTypes());
413            emitop(invokeinterface);
414            if (!alive) return;
415            emit2(meth);
416            emit1(argsize + 1);
417            emit1(0);
418            state.pop(argsize + 1);
419            state.push(mtype.getReturnType());
420        }
421    
422        /** Emit an invokespecial instruction.
423         */
424        public void emitInvokespecial(int meth, Type mtype) {
425            int argsize = width(mtype.getParameterTypes());
426            emitop(invokespecial);
427            if (!alive) return;
428            emit2(meth);
429            Symbol sym = (Symbol)pool.pool[meth];
430            state.pop(argsize);
431            if (sym.isConstructor())
432                state.markInitialized((UninitializedType)state.peek());
433            state.pop(1);
434            state.push(mtype.getReturnType());
435        }
436    
437        /** Emit an invokestatic instruction.
438         */
439        public void emitInvokestatic(int meth, Type mtype) {
440            int argsize = width(mtype.getParameterTypes());
441            emitop(invokestatic);
442            if (!alive) return;
443            emit2(meth);
444            state.pop(argsize);
445            state.push(mtype.getReturnType());
446        }
447    
448        /** Emit an invokevirtual instruction.
449         */
450        public void emitInvokevirtual(int meth, Type mtype) {
451            int argsize = width(mtype.getParameterTypes());
452            emitop(invokevirtual);
453            if (!alive) return;
454            emit2(meth);
455            state.pop(argsize + 1);
456            state.push(mtype.getReturnType());
457        }
458    
459        /** Emit an opcode with no operand field.
460         */
461        public void emitop0(int op) {
462            emitop(op);
463            if (!alive) return;
464            switch (op) {
465            case aaload: {
466                state.pop(1);// index
467                Type a = state.stack[state.stacksize-1];
468                state.pop(1);
469                state.push(types.erasure(types.elemtype(a))); }
470                break;
471            case goto_:
472                markDead();
473                break;
474            case nop:
475            case ineg:
476            case lneg:
477            case fneg:
478            case dneg:
479                break;
480            case aconst_null:
481                state.push(syms.botType);
482                break;
483            case iconst_m1:
484            case iconst_0:
485            case iconst_1:
486            case iconst_2:
487            case iconst_3:
488            case iconst_4:
489            case iconst_5:
490            case iload_0:
491            case iload_1:
492            case iload_2:
493            case iload_3:
494                state.push(syms.intType);
495                break;
496            case lconst_0:
497            case lconst_1:
498            case lload_0:
499            case lload_1:
500            case lload_2:
501            case lload_3:
502                state.push(syms.longType);
503                break;
504            case fconst_0:
505            case fconst_1:
506            case fconst_2:
507            case fload_0:
508            case fload_1:
509            case fload_2:
510            case fload_3:
511                state.push(syms.floatType);
512                break;
513            case dconst_0:
514            case dconst_1:
515            case dload_0:
516            case dload_1:
517            case dload_2:
518            case dload_3:
519                state.push(syms.doubleType);
520                break;
521            case aload_0:
522                state.push(lvar[0].sym.type);
523                break;
524            case aload_1:
525                state.push(lvar[1].sym.type);
526                break;
527            case aload_2:
528                state.push(lvar[2].sym.type);
529                break;
530            case aload_3:
531                state.push(lvar[3].sym.type);
532                break;
533            case iaload:
534            case baload:
535            case caload:
536            case saload:
537                state.pop(2);
538                state.push(syms.intType);
539                break;
540            case laload:
541                state.pop(2);
542                state.push(syms.longType);
543                break;
544            case faload:
545                state.pop(2);
546                state.push(syms.floatType);
547                break;
548            case daload:
549                state.pop(2);
550                state.push(syms.doubleType);
551                break;
552            case istore_0:
553            case istore_1:
554            case istore_2:
555            case istore_3:
556            case fstore_0:
557            case fstore_1:
558            case fstore_2:
559            case fstore_3:
560            case astore_0:
561            case astore_1:
562            case astore_2:
563            case astore_3:
564            case pop:
565            case lshr:
566            case lshl:
567            case lushr:
568                state.pop(1);
569                break;
570            case areturn:
571            case ireturn:
572            case freturn:
573                assert state.nlocks == 0;
574                state.pop(1);
575                markDead();
576                break;
577            case athrow:
578                state.pop(1);
579                markDead();
580                break;
581            case lstore_0:
582            case lstore_1:
583            case lstore_2:
584            case lstore_3:
585            case dstore_0:
586            case dstore_1:
587            case dstore_2:
588            case dstore_3:
589            case pop2:
590                state.pop(2);
591                break;
592            case lreturn:
593            case dreturn:
594                assert state.nlocks == 0;
595                state.pop(2);
596                markDead();
597                break;
598            case dup:
599                state.push(state.stack[state.stacksize-1]);
600                break;
601            case return_:
602                assert state.nlocks == 0;
603                markDead();
604                break;
605            case arraylength:
606                state.pop(1);
607                state.push(syms.intType);
608                break;
609            case isub:
610            case iadd:
611            case imul:
612            case idiv:
613            case imod:
614            case ishl:
615            case ishr:
616            case iushr:
617            case iand:
618            case ior:
619            case ixor:
620                state.pop(1);
621                // state.pop(1);
622                // state.push(syms.intType);
623                break;
624            case aastore:
625                state.pop(3);
626                break;
627            case land:
628            case lor:
629            case lxor:
630            case lmod:
631            case ldiv:
632            case lmul:
633            case lsub:
634            case ladd:
635                state.pop(2);
636                break;
637            case lcmp:
638                state.pop(4);
639                state.push(syms.intType);
640                break;
641            case l2i:
642                state.pop(2);
643                state.push(syms.intType);
644                break;
645            case i2l:
646                state.pop(1);
647                state.push(syms.longType);
648                break;
649            case i2f:
650                state.pop(1);
651                state.push(syms.floatType);
652                break;
653            case i2d:
654                state.pop(1);
655                state.push(syms.doubleType);
656                break;
657            case l2f:
658                state.pop(2);
659                state.push(syms.floatType);
660                break;
661            case l2d:
662                state.pop(2);
663                state.push(syms.doubleType);
664                break;
665            case f2i:
666                state.pop(1);
667                state.push(syms.intType);
668                break;
669            case f2l:
670                state.pop(1);
671                state.push(syms.longType);
672                break;
673            case f2d:
674                state.pop(1);
675                state.push(syms.doubleType);
676                break;
677            case d2i:
678                state.pop(2);
679                state.push(syms.intType);
680                break;
681            case d2l:
682                state.pop(2);
683                state.push(syms.longType);
684                break;
685            case d2f:
686                state.pop(2);
687                state.push(syms.floatType);
688                break;
689            case tableswitch:
690            case lookupswitch:
691                state.pop(1);
692                // the caller is responsible for patching up the state
693                break;
694            case dup_x1: {
695                Type val1 = state.pop1();
696                Type val2 = state.pop1();
697                state.push(val1);
698                state.push(val2);
699                state.push(val1);
700                break;
701            }
702            case bastore:
703                state.pop(3);
704                break;
705            case int2byte:
706            case int2char:
707            case int2short:
708                break;
709            case fmul:
710            case fadd:
711            case fsub:
712            case fdiv:
713            case fmod:
714                state.pop(1);
715                break;
716            case castore:
717            case iastore:
718            case fastore:
719            case sastore:
720                state.pop(3);
721                break;
722            case lastore:
723            case dastore:
724                state.pop(4);
725                break;
726            case dup2:
727                if (state.stack[state.stacksize-1] != null) {
728                    Type value1 = state.pop1();
729                    Type value2 = state.pop1();
730                    state.push(value2);
731                    state.push(value1);
732                    state.push(value2);
733                    state.push(value1);
734                } else {
735                    Type value = state.pop2();
736                    state.push(value);
737                    state.push(value);
738                }
739                break;
740            case dup2_x1:
741                if (state.stack[state.stacksize-1] != null) {
742                    Type value1 = state.pop1();
743                    Type value2 = state.pop1();
744                    Type value3 = state.pop1();
745                    state.push(value2);
746                    state.push(value1);
747                    state.push(value3);
748                    state.push(value2);
749                    state.push(value1);
750                } else {
751                    Type value1 = state.pop2();
752                    Type value2 = state.pop1();
753                    state.push(value1);
754                    state.push(value2);
755                    state.push(value1);
756                }
757                break;
758            case dup2_x2:
759                if (state.stack[state.stacksize-1] != null) {
760                    Type value1 = state.pop1();
761                    Type value2 = state.pop1();
762                    if (state.stack[state.stacksize-1] != null) {
763                        // form 1
764                        Type value3 = state.pop1();
765                        Type value4 = state.pop1();
766                        state.push(value2);
767                        state.push(value1);
768                        state.push(value4);
769                        state.push(value3);
770                        state.push(value2);
771                        state.push(value1);
772                    } else {
773                        // form 3
774                        Type value3 = state.pop2();
775                        state.push(value2);
776                        state.push(value1);
777                        state.push(value3);
778                        state.push(value2);
779                        state.push(value1);
780                    }
781                } else {
782                    Type value1 = state.pop2();
783                    if (state.stack[state.stacksize-1] != null) {
784                        // form 2
785                        Type value2 = state.pop1();
786                        Type value3 = state.pop1();
787                        state.push(value1);
788                        state.push(value3);
789                        state.push(value2);
790                        state.push(value1);
791                    } else {
792                        // form 4
793                        Type value2 = state.pop2();
794                        state.push(value1);
795                        state.push(value2);
796                        state.push(value1);
797                    }
798                }
799                break;
800            case dup_x2: {
801                Type value1 = state.pop1();
802                if (state.stack[state.stacksize-1] != null) {
803                    // form 1
804                    Type value2 = state.pop1();
805                    Type value3 = state.pop1();
806                    state.push(value1);
807                    state.push(value3);
808                    state.push(value2);
809                    state.push(value1);
810                } else {
811                    // form 2
812                    Type value2 = state.pop2();
813                    state.push(value1);
814                    state.push(value2);
815                    state.push(value1);
816                }
817            }
818                break;
819            case fcmpl:
820            case fcmpg:
821                state.pop(2);
822                state.push(syms.intType);
823                break;
824            case dcmpl:
825            case dcmpg:
826                state.pop(4);
827                state.push(syms.intType);
828                break;
829            case swap: {
830                Type value1 = state.pop1();
831                Type value2 = state.pop1();
832                state.push(value1);
833                state.push(value2);
834                break;
835            }
836            case dadd:
837            case dsub:
838            case dmul:
839            case ddiv:
840            case dmod:
841                state.pop(2);
842                break;
843            case ret:
844                markDead();
845                break;
846            case wide:
847                // must be handled by the caller.
848                return;
849            case monitorenter:
850            case monitorexit:
851                state.pop(1);
852                break;
853    
854            default:
855                throw new AssertionError(mnem(op));
856            }
857            postop();
858        }
859    
860        /** Emit an opcode with a one-byte operand field.
861         */
862        public void emitop1(int op, int od) {
863            emitop(op);
864            if (!alive) return;
865            emit1(od);
866            switch (op) {
867            case bipush:
868                state.push(syms.intType);
869                break;
870            case ldc1:
871                state.push(typeForPool(pool.pool[od]));
872                break;
873            default:
874                throw new AssertionError(mnem(op));
875            }
876            postop();
877        }
878    
879        /** The type of a constant pool entry. */
880        private Type typeForPool(Object o) {
881            if (o instanceof Integer) return syms.intType;
882            if (o instanceof Float) return syms.floatType;
883            if (o instanceof String) return syms.stringType;
884            if (o instanceof Long) return syms.longType;
885            if (o instanceof Double) return syms.doubleType;
886            if (o instanceof ClassSymbol) return syms.classType;
887            if (o instanceof Type.ArrayType) return syms.classType;
888            throw new AssertionError(o);
889        }
890    
891        /** Emit an opcode with a one-byte operand field;
892         *  widen if field does not fit in a byte.
893         */
894        public void emitop1w(int op, int od) {
895            if (od > 0xFF) {
896                emitop(wide);
897                emitop(op);
898                emit2(od);
899            } else {
900                emitop(op);
901                emit1(od);
902            }
903            if (!alive) return;
904            switch (op) {
905            case iload:
906                state.push(syms.intType);
907                break;
908            case lload:
909                state.push(syms.longType);
910                break;
911            case fload:
912                state.push(syms.floatType);
913                break;
914            case dload:
915                state.push(syms.doubleType);
916                break;
917            case aload:
918                state.push(lvar[od].sym.type);
919                break;
920            case lstore:
921            case dstore:
922                state.pop(2);
923                break;
924            case istore:
925            case fstore:
926            case astore:
927                state.pop(1);
928                break;
929            case ret:
930                markDead();
931                break;
932            default:
933                throw new AssertionError(mnem(op));
934            }
935            postop();
936        }
937    
938        /** Emit an opcode with two one-byte operand fields;
939         *  widen if either field does not fit in a byte.
940         */
941        public void emitop1w(int op, int od1, int od2) {
942            if (od1 > 0xFF || od2 < -128 || od2 > 127) {
943                emitop(wide);
944                emitop(op);
945                emit2(od1);
946                emit2(od2);
947            } else {
948                emitop(op);
949                emit1(od1);
950                emit1(od2);
951            }
952            if (!alive) return;
953            switch (op) {
954            case iinc:
955                break;
956            default:
957                throw new AssertionError(mnem(op));
958            }
959        }
960    
961        /** Emit an opcode with a two-byte operand field.
962         */
963        public void emitop2(int op, int od) {
964            emitop(op);
965            if (!alive) return;
966            emit2(od);
967            switch (op) {
968            case getstatic:
969                state.push(((Symbol)(pool.pool[od])).erasure(types));
970                break;
971            case putstatic:
972                state.pop(((Symbol)(pool.pool[od])).erasure(types));
973                break;
974            case new_:
975                state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
976                break;
977            case sipush:
978                state.push(syms.intType);
979                break;
980            case if_acmp_null:
981            case if_acmp_nonnull:
982            case ifeq:
983            case ifne:
984            case iflt:
985            case ifge:
986            case ifgt:
987            case ifle:
988                state.pop(1);
989                break;
990            case if_icmpeq:
991            case if_icmpne:
992            case if_icmplt:
993            case if_icmpge:
994            case if_icmpgt:
995            case if_icmple:
996            case if_acmpeq:
997            case if_acmpne:
998                state.pop(2);
999                break;
1000            case goto_:
1001                markDead();
1002                break;
1003            case putfield:
1004                state.pop(((Symbol)(pool.pool[od])).erasure(types));
1005                state.pop(1); // object ref
1006                break;
1007            case getfield:
1008                state.pop(1); // object ref
1009                state.push(((Symbol)(pool.pool[od])).erasure(types));
1010                break;
1011            case checkcast: {
1012                state.pop(1); // object ref
1013                Object o = pool.pool[od];
1014                Type t = (o instanceof Symbol)
1015                    ? ((Symbol)o).erasure(types)
1016                    : types.erasure(((Type)o));
1017                state.push(t);
1018                break; }
1019            case ldc2w:
1020                state.push(typeForPool(pool.pool[od]));
1021                break;
1022            case instanceof_:
1023                state.pop(1);
1024                state.push(syms.intType);
1025                break;
1026            case ldc2:
1027                state.push(typeForPool(pool.pool[od]));
1028                break;
1029            case jsr:
1030                break;
1031            default:
1032                throw new AssertionError(mnem(op));
1033            }
1034            // postop();
1035        }
1036    
1037        /** Emit an opcode with a four-byte operand field.
1038         */
1039        public void emitop4(int op, int od) {
1040            emitop(op);
1041            if (!alive) return;
1042            emit4(od);
1043            switch (op) {
1044            case goto_w:
1045                markDead();
1046                break;
1047            case jsr_w:
1048                break;
1049            default:
1050                throw new AssertionError(mnem(op));
1051            }
1052            // postop();
1053        }
1054    
1055        /** Align code pointer to next `incr' boundary.
1056         */
1057        public void align(int incr) {
1058            if (alive)
1059                while (cp % incr != 0) emitop0(nop);
1060        }
1061    
1062        /** Place a byte into code at address pc. Pre: pc + 1 <= cp.
1063         */
1064        private void put1(int pc, int op) {
1065            code[pc] = (byte)op;
1066        }
1067    
1068        /** Place two bytes into code at address pc. Pre: pc + 2 <= cp.
1069         */
1070        private void put2(int pc, int od) {
1071            // pre: pc + 2 <= cp
1072            put1(pc, od >> 8);
1073            put1(pc+1, od);
1074        }
1075    
1076        /** Place four  bytes into code at address pc. Pre: pc + 4 <= cp.
1077         */
1078        public void put4(int pc, int od) {
1079            // pre: pc + 4 <= cp
1080            put1(pc  , od >> 24);
1081            put1(pc+1, od >> 16);
1082            put1(pc+2, od >> 8);
1083            put1(pc+3, od);
1084        }
1085    
1086        /** Return code byte at position pc as an unsigned int.
1087         */
1088        private int get1(int pc) {
1089            return code[pc] & 0xFF;
1090        }
1091    
1092        /** Return two code bytes at position pc as an unsigned int.
1093         */
1094        private int get2(int pc) {
1095            return (get1(pc) << 8) | get1(pc+1);
1096        }
1097    
1098        /** Return four code bytes at position pc as an int.
1099         */
1100        public int get4(int pc) {
1101            // pre: pc + 4 <= cp
1102            return
1103                (get1(pc) << 24) |
1104                (get1(pc+1) << 16) |
1105                (get1(pc+2) << 8) |
1106                (get1(pc+3));
1107        }
1108    
1109        /** Is code generation currently enabled?
1110         */
1111        public boolean isAlive() {
1112            return alive || pendingJumps != null;
1113        }
1114    
1115        /** Switch code generation on/off.
1116         */
1117        public void markDead() {
1118            alive = false;
1119        }
1120    
1121        /** Declare an entry point; return current code pointer
1122         */
1123        public int entryPoint() {
1124            int pc = curPc();
1125            alive = true;
1126            pendingStackMap = needStackMap;
1127            return pc;
1128        }
1129    
1130        /** Declare an entry point with initial state;
1131         *  return current code pointer
1132         */
1133        public int entryPoint(State state) {
1134            int pc = curPc();
1135            alive = true;
1136            this.state = state.dup();
1137            assert state.stacksize <= max_stack;
1138            if (debugCode) System.err.println("entry point " + state);
1139            pendingStackMap = needStackMap;
1140            return pc;
1141        }
1142    
1143        /** Declare an entry point with initial state plus a pushed value;
1144         *  return current code pointer
1145         */
1146        public int entryPoint(State state, Type pushed) {
1147            int pc = curPc();
1148            alive = true;
1149            this.state = state.dup();
1150            assert state.stacksize <= max_stack;
1151            this.state.push(pushed);
1152            if (debugCode) System.err.println("entry point " + state);
1153            pendingStackMap = needStackMap;
1154            return pc;
1155        }
1156    
1157    
1158    /**************************************************************************
1159     * Stack map generation
1160     *************************************************************************/
1161    
1162        /** An entry in the stack map. */
1163        static class StackMapFrame {
1164            int pc;
1165            Type[] locals;
1166            Type[] stack;
1167        }
1168    
1169        /** A buffer of cldc stack map entries. */
1170        StackMapFrame[] stackMapBuffer = null;
1171    
1172        /** A buffer of compressed StackMapTable entries. */
1173        StackMapTableFrame[] stackMapTableBuffer = null;
1174        int stackMapBufferSize = 0;
1175    
1176        /** The last PC at which we generated a stack map. */
1177        int lastStackMapPC = -1;
1178    
1179        /** The last stack map frame in StackMapTable. */
1180        StackMapFrame lastFrame = null;
1181    
1182        /** The stack map frame before the last one. */
1183        StackMapFrame frameBeforeLast = null;
1184    
1185        /** Emit a stack map entry.  */
1186        public void emitStackMap() {
1187            int pc = curPc();
1188            if (!needStackMap) return;
1189    
1190    
1191    
1192            switch (stackMap) {
1193                case CLDC:
1194                    emitCLDCStackMap(pc, getLocalsSize());
1195                    break;
1196                case JSR202:
1197                    emitStackMapFrame(pc, getLocalsSize());
1198                    break;
1199                default:
1200                    throw new AssertionError("Should have chosen a stackmap format");
1201            }
1202            // DEBUG code follows
1203            if (debugCode) state.dump(pc);
1204        }
1205    
1206        private int getLocalsSize() {
1207            int nextLocal = 0;
1208            for (int i=max_locals-1; i>=0; i--) {
1209                if (state.defined.isMember(i) && lvar[i] != null) {
1210                    nextLocal = i + width(lvar[i].sym.erasure(types));
1211                    break;
1212                }
1213            }
1214            return nextLocal;
1215        }
1216    
1217        /** Emit a CLDC stack map frame. */
1218        void emitCLDCStackMap(int pc, int localsSize) {
1219            if (lastStackMapPC == pc) {
1220                // drop existing stackmap at this offset
1221                stackMapBuffer[--stackMapBufferSize] = null;
1222            }
1223            lastStackMapPC = pc;
1224    
1225            if (stackMapBuffer == null) {
1226                stackMapBuffer = new StackMapFrame[20];
1227            } else if (stackMapBuffer.length == stackMapBufferSize) {
1228                StackMapFrame[] newStackMapBuffer =
1229                    new StackMapFrame[stackMapBufferSize << 1];
1230                System.arraycopy(stackMapBuffer, 0, newStackMapBuffer,
1231                                 0, stackMapBufferSize);
1232                stackMapBuffer = newStackMapBuffer;
1233            }
1234            StackMapFrame frame =
1235                stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
1236            frame.pc = pc;
1237    
1238            frame.locals = new Type[localsSize];
1239            for (int i=0; i<localsSize; i++) {
1240                if (state.defined.isMember(i) && lvar[i] != null) {
1241                    Type vtype = lvar[i].sym.type;
1242                    if (!(vtype instanceof UninitializedType))
1243                        vtype = types.erasure(vtype);
1244                    frame.locals[i] = vtype;
1245                }
1246            }
1247            frame.stack = new Type[state.stacksize];
1248            for (int i=0; i<state.stacksize; i++)
1249                frame.stack[i] = state.stack[i];
1250        }
1251    
1252        void emitStackMapFrame(int pc, int localsSize) {
1253            if (lastFrame == null) {
1254                // first frame
1255                lastFrame = getInitialFrame();
1256            } else if (lastFrame.pc == pc) {
1257                // drop existing stackmap at this offset
1258                stackMapTableBuffer[--stackMapBufferSize] = null;
1259                lastFrame = frameBeforeLast;
1260                frameBeforeLast = null;
1261            }
1262    
1263            StackMapFrame frame = new StackMapFrame();
1264            frame.pc = pc;
1265    
1266            int localCount = 0;
1267            Type[] locals = new Type[localsSize];
1268            for (int i=0; i<localsSize; i++, localCount++) {
1269                if (state.defined.isMember(i) && lvar[i] != null) {
1270                    Type vtype = lvar[i].sym.type;
1271                    if (!(vtype instanceof UninitializedType))
1272                        vtype = types.erasure(vtype);
1273                    locals[i] = vtype;
1274                    if (width(vtype) > 1) i++;
1275                }
1276            }
1277            frame.locals = new Type[localCount];
1278            for (int i=0, j=0; i<localsSize; i++, j++) {
1279                assert(j < localCount);
1280                frame.locals[j] = locals[i];
1281                if (width(locals[i]) > 1) i++;
1282            }
1283    
1284            int stackCount = 0;
1285            for (int i=0; i<state.stacksize; i++) {
1286                if (state.stack[i] != null) {
1287                    stackCount++;
1288                }
1289            }
1290            frame.stack = new Type[stackCount];
1291            stackCount = 0;
1292            for (int i=0; i<state.stacksize; i++) {
1293                if (state.stack[i] != null) {
1294                    frame.stack[stackCount++] = state.stack[i];
1295                }
1296            }
1297    
1298            if (stackMapTableBuffer == null) {
1299                stackMapTableBuffer = new StackMapTableFrame[20];
1300            } else if (stackMapTableBuffer.length == stackMapBufferSize) {
1301                StackMapTableFrame[] newStackMapTableBuffer =
1302                    new StackMapTableFrame[stackMapBufferSize << 1];
1303                System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer,
1304                                 0, stackMapBufferSize);
1305                stackMapTableBuffer = newStackMapTableBuffer;
1306            }
1307            stackMapTableBuffer[stackMapBufferSize++] =
1308                    StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1309    
1310            frameBeforeLast = lastFrame;
1311            lastFrame = frame;
1312        }
1313    
1314        StackMapFrame getInitialFrame() {
1315            StackMapFrame frame = new StackMapFrame();
1316            List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1317            int len = arg_types.length();
1318            int count = 0;
1319            if (!meth.isStatic()) {
1320                Type thisType = meth.owner.type;
1321                frame.locals = new Type[len+1];
1322                if (meth.isConstructor() && thisType != syms.objectType) {
1323                    frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1324                } else {
1325                    frame.locals[count++] = types.erasure(thisType);
1326                }
1327            } else {
1328                frame.locals = new Type[len];
1329            }
1330            for (Type arg_type : arg_types) {
1331                frame.locals[count++] = types.erasure(arg_type);
1332            }
1333            frame.pc = -1;
1334            frame.stack = null;
1335            return frame;
1336        }
1337    
1338    
1339    /**************************************************************************
1340     * Operations having to do with jumps
1341     *************************************************************************/
1342    
1343        /** A chain represents a list of unresolved jumps. Jump locations
1344         *  are sorted in decreasing order.
1345         */
1346        public static class Chain {
1347    
1348            /** The position of the jump instruction.
1349             */
1350            public final int pc;
1351    
1352            /** The machine state after the jump instruction.
1353             *  Invariant: all elements of a chain list have the same stacksize
1354             *  and compatible stack and register contents.
1355             */
1356            Code.State state;
1357    
1358            /** The next jump in the list.
1359             */
1360            public final Chain next;
1361    
1362            /** Construct a chain from its jump position, stacksize, previous
1363             *  chain, and machine state.
1364             */
1365            public Chain(int pc, Chain next, Code.State state) {
1366                this.pc = pc;
1367                this.next = next;
1368                this.state = state;
1369            }
1370        }
1371    
1372        /** Negate a branch opcode.
1373         */
1374        public static int negate(int opcode) {
1375            if (opcode == if_acmp_null) return if_acmp_nonnull;
1376            else if (opcode == if_acmp_nonnull) return if_acmp_null;
1377            else return ((opcode + 1) ^ 1) - 1;
1378        }
1379    
1380        /** Emit a jump instruction.
1381         *  Return code pointer of instruction to be patched.
1382         */
1383        public int emitJump(int opcode) {
1384            if (fatcode) {
1385                if (opcode == goto_ || opcode == jsr) {
1386                    emitop4(opcode + goto_w - goto_, 0);
1387                } else {
1388                    emitop2(negate(opcode), 8);
1389                    emitop4(goto_w, 0);
1390                    alive = true;
1391                    pendingStackMap = needStackMap;
1392                }
1393                return cp - 5;
1394            } else {
1395                emitop2(opcode, 0);
1396                return cp - 3;
1397            }
1398        }
1399    
1400        /** Emit a branch with given opcode; return its chain.
1401         *  branch differs from jump in that jsr is treated as no-op.
1402         */
1403        public Chain branch(int opcode) {
1404            Chain result = null;
1405            if (opcode == goto_) {
1406                result = pendingJumps;
1407                pendingJumps = null;
1408            }
1409            if (opcode != dontgoto && isAlive()) {
1410                result = new Chain(emitJump(opcode),
1411                                   result,
1412                                   state.dup());
1413                fixedPc = fatcode;
1414                if (opcode == goto_) alive = false;
1415            }
1416            return result;
1417        }
1418    
1419        /** Resolve chain to point to given target.
1420         */
1421        public void resolve(Chain chain, int target) {
1422            boolean changed = false;
1423            State newState = state;
1424            for (; chain != null; chain = chain.next) {
1425                assert state != chain.state;
1426                assert target > chain.pc || state.stacksize == 0;
1427                if (target >= cp) {
1428                    target = cp;
1429                } else if (get1(target) == goto_) {
1430                    if (fatcode) target = target + get4(target + 1);
1431                    else target = target + get2(target + 1);
1432                }
1433                if (get1(chain.pc) == goto_ &&
1434                    chain.pc + 3 == target && target == cp && !fixedPc) {
1435                    // If goto the next instruction, the jump is not needed:
1436                    // compact the code.
1437                    cp = cp - 3;
1438                    target = target - 3;
1439                    if (chain.next == null) {
1440                        // This is the only jump to the target. Exit the loop
1441                        // without setting new state. The code is reachable
1442                        // from the instruction before goto_.
1443                        alive = true;
1444                        break;
1445                    }
1446                } else {
1447                    if (fatcode)
1448                        put4(chain.pc + 1, target - chain.pc);
1449                    else if (target - chain.pc < Short.MIN_VALUE ||
1450                             target - chain.pc > Short.MAX_VALUE)
1451                        fatcode = true;
1452                    else
1453                        put2(chain.pc + 1, target - chain.pc);
1454                    assert !alive ||
1455                        chain.state.stacksize == newState.stacksize &&
1456                        chain.state.nlocks == newState.nlocks;
1457                }
1458                fixedPc = true;
1459                if (cp == target) {
1460                    changed = true;
1461                    if (debugCode)
1462                        System.err.println("resolving chain state=" + chain.state);
1463                    if (alive) {
1464                        newState = chain.state.join(newState);
1465                    } else {
1466                        newState = chain.state;
1467                        alive = true;
1468                    }
1469                }
1470            }
1471            assert !changed || state != newState;
1472            if (state != newState) {
1473                setDefined(newState.defined);
1474                state = newState;
1475                pendingStackMap = needStackMap;
1476            }
1477        }
1478    
1479        /** Resolve chain to point to current code pointer.
1480         */
1481        public void resolve(Chain chain) {
1482            assert
1483                !alive ||
1484                chain==null ||
1485                state.stacksize == chain.state.stacksize &&
1486                state.nlocks == chain.state.nlocks;
1487            pendingJumps = mergeChains(chain, pendingJumps);
1488        }
1489    
1490        /** Resolve any pending jumps.
1491         */
1492        public void resolvePending() {
1493            Chain x = pendingJumps;
1494            pendingJumps = null;
1495            resolve(x, cp);
1496        }
1497    
1498        /** Merge the jumps in of two chains into one.
1499         */
1500        public static Chain mergeChains(Chain chain1, Chain chain2) {
1501            // recursive merge sort
1502            if (chain2 == null) return chain1;
1503            if (chain1 == null) return chain2;
1504            assert
1505                chain1.state.stacksize == chain2.state.stacksize &&
1506                chain1.state.nlocks == chain2.state.nlocks;
1507            if (chain1.pc < chain2.pc)
1508                return new Chain(
1509                    chain2.pc,
1510                    mergeChains(chain1, chain2.next),
1511                    chain2.state);
1512            return new Chain(
1513                    chain1.pc,
1514                    mergeChains(chain1.next, chain2),
1515                    chain1.state);
1516        }
1517    
1518    
1519    /* **************************************************************************
1520     * Catch clauses
1521     ****************************************************************************/
1522    
1523        /** Add a catch clause to code.
1524         */
1525        public void addCatch(
1526            char startPc, char endPc, char handlerPc, char catchType) {
1527            catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
1528        }
1529    
1530    
1531    /* **************************************************************************
1532     * Line numbers
1533     ****************************************************************************/
1534    
1535        /** Add a line number entry.
1536         */
1537        public void addLineNumber(char startPc, char lineNumber) {
1538            if (lineDebugInfo) {
1539                if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
1540                    lineInfo = lineInfo.tail;
1541                if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
1542                    lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
1543            }
1544        }
1545    
1546        /** Mark beginning of statement.
1547         */
1548        public void statBegin(int pos) {
1549            if (pos != Position.NOPOS) {
1550                pendingStatPos = pos;
1551            }
1552        }
1553    
1554        /** Force stat begin eagerly
1555         */
1556        public void markStatBegin() {
1557            if (alive && lineDebugInfo) {
1558                int line = lineMap.getLineNumber(pendingStatPos);
1559                char cp1 = (char)cp;
1560                char line1 = (char)line;
1561                if (cp1 == cp && line1 == line)
1562                    addLineNumber(cp1, line1);
1563            }
1564            pendingStatPos = Position.NOPOS;
1565        }
1566    
1567    
1568    /* **************************************************************************
1569     * Simulated VM machine state
1570     ****************************************************************************/
1571    
1572        class State implements Cloneable {
1573            /** The set of registers containing values. */
1574            Bits defined;
1575    
1576            /** The (types of the) contents of the machine stack. */
1577            Type[] stack;
1578    
1579            /** The first stack position currently unused. */
1580            int stacksize;
1581    
1582            /** The numbers of registers containing locked monitors. */
1583            int[] locks;
1584            int nlocks;
1585    
1586            State() {
1587                defined = new Bits();
1588                stack = new Type[16];
1589            }
1590    
1591            State dup() {
1592                try {
1593                    State state = (State)super.clone();
1594                    state.defined = defined.dup();
1595                    state.stack = stack.clone();
1596                    if (locks != null) state.locks = locks.clone();
1597                    if (debugCode) {
1598                        System.err.println("duping state " + this);
1599                        dump();
1600                    }
1601                    return state;
1602                } catch (CloneNotSupportedException ex) {
1603                    throw new AssertionError(ex);
1604                }
1605            }
1606    
1607            void lock(int register) {
1608                if (locks == null) {
1609                    locks = new int[20];
1610                } else if (locks.length == nlocks) {
1611                    int[] newLocks = new int[locks.length << 1];
1612                    System.arraycopy(locks, 0, newLocks, 0, locks.length);
1613                    locks = newLocks;
1614                }
1615                locks[nlocks] = register;
1616                nlocks++;
1617            }
1618    
1619            void unlock(int register) {
1620                nlocks--;
1621                assert locks[nlocks] == register;
1622                locks[nlocks] = -1;
1623            }
1624    
1625            void push(Type t) {
1626                if (debugCode) System.err.println("   pushing " + t);
1627                switch (t.tag) {
1628                case TypeTags.VOID:
1629                    return;
1630                case TypeTags.BYTE:
1631                case TypeTags.CHAR:
1632                case TypeTags.SHORT:
1633                case TypeTags.BOOLEAN:
1634                    t = syms.intType;
1635                    break;
1636                default:
1637                    break;
1638                }
1639                if (stacksize+2 >= stack.length) {
1640                    Type[] newstack = new Type[2*stack.length];
1641                    System.arraycopy(stack, 0, newstack, 0, stack.length);
1642                    stack = newstack;
1643                }
1644                stack[stacksize++] = t;
1645                switch (width(t)) {
1646                case 1:
1647                    break;
1648                case 2:
1649                    stack[stacksize++] = null;
1650                    break;
1651                default:
1652                    throw new AssertionError(t);
1653                }
1654                if (stacksize > max_stack)
1655                    max_stack = stacksize;
1656            }
1657    
1658            Type pop1() {
1659                if (debugCode) System.err.println("   popping " + 1);
1660                stacksize--;
1661                Type result = stack[stacksize];
1662                stack[stacksize] = null;
1663                assert result != null && width(result) == 1;
1664                return result;
1665            }
1666    
1667            Type peek() {
1668                return stack[stacksize-1];
1669            }
1670    
1671            Type pop2() {
1672                if (debugCode) System.err.println("   popping " + 2);
1673                stacksize -= 2;
1674                Type result = stack[stacksize];
1675                stack[stacksize] = null;
1676                assert stack[stacksize+1] == null;
1677                assert result != null && width(result) == 2;
1678                return result;
1679            }
1680    
1681            void pop(int n) {
1682                if (debugCode) System.err.println("   popping " + n);
1683                while (n > 0) {
1684                    stack[--stacksize] = null;
1685                    n--;
1686                }
1687            }
1688    
1689            void pop(Type t) {
1690                pop(width(t));
1691            }
1692    
1693            /** Force the top of the stack to be treated as this supertype
1694             *  of its current type. */
1695            void forceStackTop(Type t) {
1696                if (!alive) return;
1697                switch (t.tag) {
1698                case CLASS:
1699                case ARRAY:
1700                    int width = width(t);
1701                    Type old = stack[stacksize-width];
1702                    assert types.isSubtype(types.erasure(old),
1703                                           types.erasure(t));
1704                    stack[stacksize-width] = t;
1705                    break;
1706                default:
1707                }
1708            }
1709    
1710            void markInitialized(UninitializedType old) {
1711                Type newtype = old.initializedType();
1712                for (int i=0; i<stacksize; i++)
1713                    if (stack[i] == old) stack[i] = newtype;
1714                for (int i=0; i<lvar.length; i++) {
1715                    LocalVar lv = lvar[i];
1716                    if (lv != null && lv.sym.type == old) {
1717                        VarSymbol sym = lv.sym;
1718                        sym = sym.clone(sym.owner);
1719                        sym.type = newtype;
1720                        LocalVar newlv = lvar[i] = new LocalVar(sym);
1721                        // should the following be initialized to cp?
1722                        newlv.start_pc = lv.start_pc;
1723                    }
1724                }
1725            }
1726    
1727            State join(State other) {
1728                defined = defined.andSet(other.defined);
1729                assert stacksize == other.stacksize;
1730                assert nlocks == other.nlocks;
1731                for (int i=0; i<stacksize; ) {
1732                    Type t = stack[i];
1733                    Type tother = other.stack[i];
1734                    Type result =
1735                        t==tother ? t :
1736                        types.isSubtype(t, tother) ? tother :
1737                        types.isSubtype(tother, t) ? t :
1738                        error();
1739                    int w = width(result);
1740                    stack[i] = result;
1741                    if (w == 2) assert stack[i+1] == null;
1742                    i += w;
1743                }
1744                return this;
1745            }
1746    
1747            Type error() {
1748                throw new AssertionError("inconsistent stack types at join point");
1749            }
1750    
1751            void dump() {
1752                dump(-1);
1753            }
1754    
1755            void dump(int pc) {
1756                System.err.print("stackMap for " + meth.owner + "." + meth);
1757                if (pc == -1)
1758                    System.out.println();
1759                else
1760                    System.out.println(" at " + pc);
1761                System.err.println(" stack (from bottom):");
1762                for (int i=0; i<stacksize; i++)
1763                    System.err.println("  " + i + ": " + stack[i]);
1764    
1765                int lastLocal = 0;
1766                for (int i=max_locals-1; i>=0; i--) {
1767                    if (defined.isMember(i)) {
1768                        lastLocal = i;
1769                        break;
1770                    }
1771                }
1772                if (lastLocal >= 0)
1773                    System.err.println(" locals:");
1774                for (int i=0; i<=lastLocal; i++) {
1775                    System.err.print("  " + i + ": ");
1776                    if (defined.isMember(i)) {
1777                        LocalVar var = lvar[i];
1778                        if (var == null) {
1779                            System.err.println("(none)");
1780                        } else if (var.sym == null)
1781                            System.err.println("UNKNOWN!");
1782                        else
1783                            System.err.println("" + var.sym + " of type " +
1784                                               var.sym.erasure(types));
1785                    } else {
1786                        System.err.println("undefined");
1787                    }
1788                }
1789                if (nlocks != 0) {
1790                    System.err.print(" locks:");
1791                    for (int i=0; i<nlocks; i++) {
1792                        System.err.print(" " + locks[i]);
1793                    }
1794                    System.err.println();
1795                }
1796            }
1797        }
1798    
1799        static Type jsrReturnValue = new Type(TypeTags.INT, null);
1800    
1801    
1802    /* **************************************************************************
1803     * Local variables
1804     ****************************************************************************/
1805    
1806        /** A live range of a local variable. */
1807        static class LocalVar {
1808            final VarSymbol sym;
1809            final char reg;
1810            char start_pc = Character.MAX_VALUE;
1811            char length = Character.MAX_VALUE;
1812            LocalVar(VarSymbol v) {
1813                this.sym = v;
1814                this.reg = (char)v.adr;
1815            }
1816            public LocalVar dup() {
1817                return new LocalVar(sym);
1818            }
1819            public String toString() {
1820                return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
1821            }
1822        };
1823    
1824        /** Local variables, indexed by register. */
1825        LocalVar[] lvar;
1826    
1827        /** Add a new local variable. */
1828        private void addLocalVar(VarSymbol v) {
1829            int adr = v.adr;
1830            if (adr+1 >= lvar.length) {
1831                int newlength = lvar.length << 1;
1832                if (newlength <= adr) newlength = adr + 10;
1833                LocalVar[] new_lvar = new LocalVar[newlength];
1834                System.arraycopy(lvar, 0, new_lvar, 0, lvar.length);
1835                lvar = new_lvar;
1836            }
1837            assert lvar[adr] == null;
1838            if (pendingJumps != null) resolvePending();
1839            lvar[adr] = new LocalVar(v);
1840            state.defined.excl(adr);
1841        }
1842    
1843        /** Set the current variable defined state. */
1844        public void setDefined(Bits newDefined) {
1845            if (alive && newDefined != state.defined) {
1846                Bits diff = state.defined.dup().xorSet(newDefined);
1847                for (int adr = diff.nextBit(0);
1848                     adr >= 0;
1849                     adr = diff.nextBit(adr+1)) {
1850                    if (adr >= nextreg)
1851                        state.defined.excl(adr);
1852                    else if (state.defined.isMember(adr))
1853                        setUndefined(adr);
1854                    else
1855                        setDefined(adr);
1856                }
1857            }
1858        }
1859    
1860        /** Mark a register as being (possibly) defined. */
1861        public void setDefined(int adr) {
1862            LocalVar v = lvar[adr];
1863            if (v == null) {
1864                state.defined.excl(adr);
1865            } else {
1866                state.defined.incl(adr);
1867                if (cp < Character.MAX_VALUE) {
1868                    if (v.start_pc == Character.MAX_VALUE)
1869                        v.start_pc = (char)cp;
1870                }
1871            }
1872        }
1873    
1874        /** Mark a register as being undefined. */
1875        public void setUndefined(int adr) {
1876            state.defined.excl(adr);
1877            if (adr < lvar.length &&
1878                lvar[adr] != null &&
1879                lvar[adr].start_pc != Character.MAX_VALUE) {
1880                LocalVar v = lvar[adr];
1881                char length = (char)(curPc() - v.start_pc);
1882                if (length > 0 && length < Character.MAX_VALUE) {
1883                    lvar[adr] = v.dup();
1884                    v.length = length;
1885                    putVar(v);
1886                } else {
1887                    v.start_pc = Character.MAX_VALUE;
1888                }
1889            }
1890        }
1891    
1892        /** End the scope of a variable. */
1893        private void endScope(int adr) {
1894            LocalVar v = lvar[adr];
1895            if (v != null) {
1896                lvar[adr] = null;
1897                if (v.start_pc != Character.MAX_VALUE) {
1898                    char length = (char)(curPc() - v.start_pc);
1899                    if (length < Character.MAX_VALUE) {
1900                        v.length = length;
1901                        putVar(v);
1902                    }
1903                }
1904            }
1905            state.defined.excl(adr);
1906        }
1907    
1908        /** Put a live variable range into the buffer to be output to the
1909         *  class file.
1910         */
1911        void putVar(LocalVar var) {
1912            if (!varDebugInfo) return;
1913            if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
1914            if (varBuffer == null)
1915                varBuffer = new LocalVar[20];
1916            else if (varBufferSize >= varBuffer.length) {
1917                LocalVar[] newVarBuffer = new LocalVar[varBufferSize*2];
1918                System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length);
1919                varBuffer = newVarBuffer;
1920            }
1921            varBuffer[varBufferSize++] = var;
1922        }
1923    
1924        /** Previously live local variables, to be put into the variable table. */
1925        LocalVar[] varBuffer;
1926        int varBufferSize;
1927    
1928        /** Create a new local variable address and return it.
1929         */
1930        private int newLocal(int typecode) {
1931            int reg = nextreg;
1932            int w = width(typecode);
1933            nextreg = reg + w;
1934            if (nextreg > max_locals) max_locals = nextreg;
1935            return reg;
1936        }
1937    
1938        private int newLocal(Type type) {
1939            return newLocal(typecode(type));
1940        }
1941    
1942        public int newLocal(VarSymbol v) {
1943            int reg = v.adr = newLocal(v.erasure(types));
1944            addLocalVar(v);
1945            return reg;
1946        }
1947    
1948        /** Start a set of fresh registers.
1949         */
1950        public void newRegSegment() {
1951            nextreg = max_locals;
1952        }
1953    
1954        /** End scopes of all variables with registers >= first.
1955         */
1956        public void endScopes(int first) {
1957            int prevNextReg = nextreg;
1958            nextreg = first;
1959            for (int i = nextreg; i < prevNextReg; i++) endScope(i);
1960        }
1961    
1962    /**************************************************************************
1963     * static tables
1964     *************************************************************************/
1965    
1966        public static String mnem(int opcode) {
1967            return Mneumonics.mnem[opcode];
1968        }
1969    
1970        private static class Mneumonics {
1971            private final static String[] mnem = new String[ByteCodeCount];
1972            static {
1973                mnem[nop] = "nop";
1974                mnem[aconst_null] = "aconst_null";
1975                mnem[iconst_m1] = "iconst_m1";
1976                mnem[iconst_0] = "iconst_0";
1977                mnem[iconst_1] = "iconst_1";
1978                mnem[iconst_2] = "iconst_2";
1979                mnem[iconst_3] = "iconst_3";
1980                mnem[iconst_4] = "iconst_4";
1981                mnem[iconst_5] = "iconst_5";
1982                mnem[lconst_0] = "lconst_0";
1983                mnem[lconst_1] = "lconst_1";
1984                mnem[fconst_0] = "fconst_0";
1985                mnem[fconst_1] = "fconst_1";
1986                mnem[fconst_2] = "fconst_2";
1987                mnem[dconst_0] = "dconst_0";
1988                mnem[dconst_1] = "dconst_1";
1989                mnem[bipush] = "bipush";
1990                mnem[sipush] = "sipush";
1991                mnem[ldc1] = "ldc1";
1992                mnem[ldc2] = "ldc2";
1993                mnem[ldc2w] = "ldc2w";
1994                mnem[iload] = "iload";
1995                mnem[lload] = "lload";
1996                mnem[fload] = "fload";
1997                mnem[dload] = "dload";
1998                mnem[aload] = "aload";
1999                mnem[iload_0] = "iload_0";
2000                mnem[lload_0] = "lload_0";
2001                mnem[fload_0] = "fload_0";
2002                mnem[dload_0] = "dload_0";
2003                mnem[aload_0] = "aload_0";
2004                mnem[iload_1] = "iload_1";
2005                mnem[lload_1] = "lload_1";
2006                mnem[fload_1] = "fload_1";
2007                mnem[dload_1] = "dload_1";
2008                mnem[aload_1] = "aload_1";
2009                mnem[iload_2] = "iload_2";
2010                mnem[lload_2] = "lload_2";
2011                mnem[fload_2] = "fload_2";
2012                mnem[dload_2] = "dload_2";
2013                mnem[aload_2] = "aload_2";
2014                mnem[iload_3] = "iload_3";
2015                mnem[lload_3] = "lload_3";
2016                mnem[fload_3] = "fload_3";
2017                mnem[dload_3] = "dload_3";
2018                mnem[aload_3] = "aload_3";
2019                mnem[iaload] = "iaload";
2020                mnem[laload] = "laload";
2021                mnem[faload] = "faload";
2022                mnem[daload] = "daload";
2023                mnem[aaload] = "aaload";
2024                mnem[baload] = "baload";
2025                mnem[caload] = "caload";
2026                mnem[saload] = "saload";
2027                mnem[istore] = "istore";
2028                mnem[lstore] = "lstore";
2029                mnem[fstore] = "fstore";
2030                mnem[dstore] = "dstore";
2031                mnem[astore] = "astore";
2032                mnem[istore_0] = "istore_0";
2033                mnem[lstore_0] = "lstore_0";
2034                mnem[fstore_0] = "fstore_0";
2035                mnem[dstore_0] = "dstore_0";
2036                mnem[astore_0] = "astore_0";
2037                mnem[istore_1] = "istore_1";
2038                mnem[lstore_1] = "lstore_1";
2039                mnem[fstore_1] = "fstore_1";
2040                mnem[dstore_1] = "dstore_1";
2041                mnem[astore_1] = "astore_1";
2042                mnem[istore_2] = "istore_2";
2043                mnem[lstore_2] = "lstore_2";
2044                mnem[fstore_2] = "fstore_2";
2045                mnem[dstore_2] = "dstore_2";
2046                mnem[astore_2] = "astore_2";
2047                mnem[istore_3] = "istore_3";
2048                mnem[lstore_3] = "lstore_3";
2049                mnem[fstore_3] = "fstore_3";
2050                mnem[dstore_3] = "dstore_3";
2051                mnem[astore_3] = "astore_3";
2052                mnem[iastore] = "iastore";
2053                mnem[lastore] = "lastore";
2054                mnem[fastore] = "fastore";
2055                mnem[dastore] = "dastore";
2056                mnem[aastore] = "aastore";
2057                mnem[bastore] = "bastore";
2058                mnem[castore] = "castore";
2059                mnem[sastore] = "sastore";
2060                mnem[pop] = "pop";
2061                mnem[pop2] = "pop2";
2062                mnem[dup] = "dup";
2063                mnem[dup_x1] = "dup_x1";
2064                mnem[dup_x2] = "dup_x2";
2065                mnem[dup2] = "dup2";
2066                mnem[dup2_x1] = "dup2_x1";
2067                mnem[dup2_x2] = "dup2_x2";
2068                mnem[swap] = "swap";
2069                mnem[iadd] = "iadd";
2070                mnem[ladd] = "ladd";
2071                mnem[fadd] = "fadd";
2072                mnem[dadd] = "dadd";
2073                mnem[isub] = "isub";
2074                mnem[lsub] = "lsub";
2075                mnem[fsub] = "fsub";
2076                mnem[dsub] = "dsub";
2077                mnem[imul] = "imul";
2078                mnem[lmul] = "lmul";
2079                mnem[fmul] = "fmul";
2080                mnem[dmul] = "dmul";
2081                mnem[idiv] = "idiv";
2082                mnem[ldiv] = "ldiv";
2083                mnem[fdiv] = "fdiv";
2084                mnem[ddiv] = "ddiv";
2085                mnem[imod] = "imod";
2086                mnem[lmod] = "lmod";
2087                mnem[fmod] = "fmod";
2088                mnem[dmod] = "dmod";
2089                mnem[ineg] = "ineg";
2090                mnem[lneg] = "lneg";
2091                mnem[fneg] = "fneg";
2092                mnem[dneg] = "dneg";
2093                mnem[ishl] = "ishl";
2094                mnem[lshl] = "lshl";
2095                mnem[ishr] = "ishr";
2096                mnem[lshr] = "lshr";
2097                mnem[iushr] = "iushr";
2098                mnem[lushr] = "lushr";
2099                mnem[iand] = "iand";
2100                mnem[land] = "land";
2101                mnem[ior] = "ior";
2102                mnem[lor] = "lor";
2103                mnem[ixor] = "ixor";
2104                mnem[lxor] = "lxor";
2105                mnem[iinc] = "iinc";
2106                mnem[i2l] = "i2l";
2107                mnem[i2f] = "i2f";
2108                mnem[i2d] = "i2d";
2109                mnem[l2i] = "l2i";
2110                mnem[l2f] = "l2f";
2111                mnem[l2d] = "l2d";
2112                mnem[f2i] = "f2i";
2113                mnem[f2l] = "f2l";
2114                mnem[f2d] = "f2d";
2115                mnem[d2i] = "d2i";
2116                mnem[d2l] = "d2l";
2117                mnem[d2f] = "d2f";
2118                mnem[int2byte] = "int2byte";
2119                mnem[int2char] = "int2char";
2120                mnem[int2short] = "int2short";
2121                mnem[lcmp] = "lcmp";
2122                mnem[fcmpl] = "fcmpl";
2123                mnem[fcmpg] = "fcmpg";
2124                mnem[dcmpl] = "dcmpl";
2125                mnem[dcmpg] = "dcmpg";
2126                mnem[ifeq] = "ifeq";
2127                mnem[ifne] = "ifne";
2128                mnem[iflt] = "iflt";
2129                mnem[ifge] = "ifge";
2130                mnem[ifgt] = "ifgt";
2131                mnem[ifle] = "ifle";
2132                mnem[if_icmpeq] = "if_icmpeq";
2133                mnem[if_icmpne] = "if_icmpne";
2134                mnem[if_icmplt] = "if_icmplt";
2135                mnem[if_icmpge] = "if_icmpge";
2136                mnem[if_icmpgt] = "if_icmpgt";
2137                mnem[if_icmple] = "if_icmple";
2138                mnem[if_acmpeq] = "if_acmpeq";
2139                mnem[if_acmpne] = "if_acmpne";
2140                mnem[goto_] = "goto_";
2141                mnem[jsr] = "jsr";
2142                mnem[ret] = "ret";
2143                mnem[tableswitch] = "tableswitch";
2144                mnem[lookupswitch] = "lookupswitch";
2145                mnem[ireturn] = "ireturn";
2146                mnem[lreturn] = "lreturn";
2147                mnem[freturn] = "freturn";
2148                mnem[dreturn] = "dreturn";
2149                mnem[areturn] = "areturn";
2150                mnem[return_] = "return_";
2151                mnem[getstatic] = "getstatic";
2152                mnem[putstatic] = "putstatic";
2153                mnem[getfield] = "getfield";
2154                mnem[putfield] = "putfield";
2155                mnem[invokevirtual] = "invokevirtual";
2156                mnem[invokespecial] = "invokespecial";
2157                mnem[invokestatic] = "invokestatic";
2158                mnem[invokeinterface] = "invokeinterface";
2159                // mnem[___unused___] = "___unused___";
2160                mnem[new_] = "new_";
2161                mnem[newarray] = "newarray";
2162                mnem[anewarray] = "anewarray";
2163                mnem[arraylength] = "arraylength";
2164                mnem[athrow] = "athrow";
2165                mnem[checkcast] = "checkcast";
2166                mnem[instanceof_] = "instanceof_";
2167                mnem[monitorenter] = "monitorenter";
2168                mnem[monitorexit] = "monitorexit";
2169                mnem[wide] = "wide";
2170                mnem[multianewarray] = "multianewarray";
2171                mnem[if_acmp_null] = "if_acmp_null";
2172                mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2173                mnem[goto_w] = "goto_w";
2174                mnem[jsr_w] = "jsr_w";
2175                mnem[breakpoint] = "breakpoint";
2176            }
2177        }
2178    }