Fri, 29 Apr 2011 16:05:02 +0100
7040104: javac NPE on Object a[]; Object o = (a=null)[0];
Summary: When a null literal is found on top of stack, if expected type is 1-dimension array no checkcast is emitted
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.jvm;
28 import com.sun.tools.javac.code.*;
29 import com.sun.tools.javac.code.Symbol.*;
30 import com.sun.tools.javac.util.*;
31 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
33 import static com.sun.tools.javac.code.TypeTags.*;
34 import static com.sun.tools.javac.jvm.ByteCodes.*;
35 import static com.sun.tools.javac.jvm.UninitializedType.*;
36 import static com.sun.tools.javac.jvm.ClassWriter.StackMapTableFrame;
38 /** An internal structure that corresponds to the code attribute of
39 * methods in a classfile. The class also provides some utility operations to
40 * generate bytecode instructions.
41 *
42 * <p><b>This is NOT part of any supported API.
43 * If you write code that depends on this, you do so at your own risk.
44 * This code and its internal interfaces are subject to change or
45 * deletion without notice.</b>
46 */
47 public class Code {
49 public final boolean debugCode;
50 public final boolean needStackMap;
52 public enum StackMapFormat {
53 NONE,
54 CLDC {
55 Name getAttributeName(Names names) {
56 return names.StackMap;
57 }
58 },
59 JSR202 {
60 Name getAttributeName(Names names) {
61 return names.StackMapTable;
62 }
63 };
64 Name getAttributeName(Names names) {
65 return names.empty;
66 }
67 }
69 final Types types;
70 final Symtab syms;
72 /*---------- classfile fields: --------------- */
74 /** The maximum stack size.
75 */
76 public int max_stack = 0;
78 /** The maximum number of local variable slots.
79 */
80 public int max_locals = 0;
82 /** The code buffer.
83 */
84 public byte[] code = new byte[64];
86 /** the current code pointer.
87 */
88 public int cp = 0;
90 /** Check the code against VM spec limits; if
91 * problems report them and return true.
92 */
93 public boolean checkLimits(DiagnosticPosition pos, Log log) {
94 if (cp > ClassFile.MAX_CODE) {
95 log.error(pos, "limit.code");
96 return true;
97 }
98 if (max_locals > ClassFile.MAX_LOCALS) {
99 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 }
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[]>();
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
119 /** The CharacterRangeTable
120 */
121 public CRTable crt;
123 /*---------- internal fields: --------------- */
125 /** Are we generating code with jumps >= 32K?
126 */
127 public boolean fatcode;
129 /** Code generation enabled?
130 */
131 private boolean alive = true;
133 /** The current machine state (registers and stack).
134 */
135 State state;
137 /** Is it forbidden to compactify code, because something is
138 * pointing to current location?
139 */
140 private boolean fixedPc = false;
142 /** The next available register.
143 */
144 public int nextreg = 0;
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;
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;
158 /** Set true when a stackMap is needed at the current PC. */
159 boolean pendingStackMap = false;
161 /** The stack map format to be generated. */
162 StackMapFormat stackMap;
164 /** Switch: emit variable debug info.
165 */
166 boolean varDebugInfo;
168 /** Switch: emit line number info.
169 */
170 boolean lineDebugInfo;
172 /** Emit line number info if map supplied
173 */
174 Position.LineMap lineMap;
176 /** The constant pool of the current class.
177 */
178 final Pool pool;
180 final MethodSymbol meth;
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 }
219 /* **************************************************************************
220 * Typecodes & related stuff
221 ****************************************************************************/
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 }
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 }
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 }
268 public static int width(Type type) {
269 return type == null ? 1 : width(typecode(type));
270 }
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 }
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 }
300 /* **************************************************************************
301 * Emit code
302 ****************************************************************************/
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 }
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 }
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 }
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 }
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 }
374 void postop() {
375 Assert.check(alive || state.stacksize == 0);
376 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
459 /** Emit an invokedynamic instruction.
460 */
461 public void emitInvokedynamic(int desc, Type mtype) {
462 // N.B. this format is under consideration by the JSR 292 EG
463 int argsize = width(mtype.getParameterTypes());
464 emitop(invokedynamic);
465 if (!alive) return;
466 emit2(desc);
467 emit2(0);
468 state.pop(argsize);
469 state.push(mtype.getReturnType());
470 }
472 /** Emit an opcode with no operand field.
473 */
474 public void emitop0(int op) {
475 emitop(op);
476 if (!alive) return;
477 switch (op) {
478 case aaload: {
479 state.pop(1);// index
480 Type a = state.stack[state.stacksize-1];
481 state.pop(1);
482 //sometimes 'null type' is treated as a one-dimensional array type
483 //see Gen.visitLiteral - we should handle this case accordingly
484 Type stackType = a.tag == BOT ?
485 syms.objectType :
486 types.erasure(types.elemtype(a));
487 state.push(stackType); }
488 break;
489 case goto_:
490 markDead();
491 break;
492 case nop:
493 case ineg:
494 case lneg:
495 case fneg:
496 case dneg:
497 break;
498 case aconst_null:
499 state.push(syms.botType);
500 break;
501 case iconst_m1:
502 case iconst_0:
503 case iconst_1:
504 case iconst_2:
505 case iconst_3:
506 case iconst_4:
507 case iconst_5:
508 case iload_0:
509 case iload_1:
510 case iload_2:
511 case iload_3:
512 state.push(syms.intType);
513 break;
514 case lconst_0:
515 case lconst_1:
516 case lload_0:
517 case lload_1:
518 case lload_2:
519 case lload_3:
520 state.push(syms.longType);
521 break;
522 case fconst_0:
523 case fconst_1:
524 case fconst_2:
525 case fload_0:
526 case fload_1:
527 case fload_2:
528 case fload_3:
529 state.push(syms.floatType);
530 break;
531 case dconst_0:
532 case dconst_1:
533 case dload_0:
534 case dload_1:
535 case dload_2:
536 case dload_3:
537 state.push(syms.doubleType);
538 break;
539 case aload_0:
540 state.push(lvar[0].sym.type);
541 break;
542 case aload_1:
543 state.push(lvar[1].sym.type);
544 break;
545 case aload_2:
546 state.push(lvar[2].sym.type);
547 break;
548 case aload_3:
549 state.push(lvar[3].sym.type);
550 break;
551 case iaload:
552 case baload:
553 case caload:
554 case saload:
555 state.pop(2);
556 state.push(syms.intType);
557 break;
558 case laload:
559 state.pop(2);
560 state.push(syms.longType);
561 break;
562 case faload:
563 state.pop(2);
564 state.push(syms.floatType);
565 break;
566 case daload:
567 state.pop(2);
568 state.push(syms.doubleType);
569 break;
570 case istore_0:
571 case istore_1:
572 case istore_2:
573 case istore_3:
574 case fstore_0:
575 case fstore_1:
576 case fstore_2:
577 case fstore_3:
578 case astore_0:
579 case astore_1:
580 case astore_2:
581 case astore_3:
582 case pop:
583 case lshr:
584 case lshl:
585 case lushr:
586 state.pop(1);
587 break;
588 case areturn:
589 case ireturn:
590 case freturn:
591 Assert.check(state.nlocks == 0);
592 state.pop(1);
593 markDead();
594 break;
595 case athrow:
596 state.pop(1);
597 markDead();
598 break;
599 case lstore_0:
600 case lstore_1:
601 case lstore_2:
602 case lstore_3:
603 case dstore_0:
604 case dstore_1:
605 case dstore_2:
606 case dstore_3:
607 case pop2:
608 state.pop(2);
609 break;
610 case lreturn:
611 case dreturn:
612 Assert.check(state.nlocks == 0);
613 state.pop(2);
614 markDead();
615 break;
616 case dup:
617 state.push(state.stack[state.stacksize-1]);
618 break;
619 case return_:
620 Assert.check(state.nlocks == 0);
621 markDead();
622 break;
623 case arraylength:
624 state.pop(1);
625 state.push(syms.intType);
626 break;
627 case isub:
628 case iadd:
629 case imul:
630 case idiv:
631 case imod:
632 case ishl:
633 case ishr:
634 case iushr:
635 case iand:
636 case ior:
637 case ixor:
638 state.pop(1);
639 // state.pop(1);
640 // state.push(syms.intType);
641 break;
642 case aastore:
643 state.pop(3);
644 break;
645 case land:
646 case lor:
647 case lxor:
648 case lmod:
649 case ldiv:
650 case lmul:
651 case lsub:
652 case ladd:
653 state.pop(2);
654 break;
655 case lcmp:
656 state.pop(4);
657 state.push(syms.intType);
658 break;
659 case l2i:
660 state.pop(2);
661 state.push(syms.intType);
662 break;
663 case i2l:
664 state.pop(1);
665 state.push(syms.longType);
666 break;
667 case i2f:
668 state.pop(1);
669 state.push(syms.floatType);
670 break;
671 case i2d:
672 state.pop(1);
673 state.push(syms.doubleType);
674 break;
675 case l2f:
676 state.pop(2);
677 state.push(syms.floatType);
678 break;
679 case l2d:
680 state.pop(2);
681 state.push(syms.doubleType);
682 break;
683 case f2i:
684 state.pop(1);
685 state.push(syms.intType);
686 break;
687 case f2l:
688 state.pop(1);
689 state.push(syms.longType);
690 break;
691 case f2d:
692 state.pop(1);
693 state.push(syms.doubleType);
694 break;
695 case d2i:
696 state.pop(2);
697 state.push(syms.intType);
698 break;
699 case d2l:
700 state.pop(2);
701 state.push(syms.longType);
702 break;
703 case d2f:
704 state.pop(2);
705 state.push(syms.floatType);
706 break;
707 case tableswitch:
708 case lookupswitch:
709 state.pop(1);
710 // the caller is responsible for patching up the state
711 break;
712 case dup_x1: {
713 Type val1 = state.pop1();
714 Type val2 = state.pop1();
715 state.push(val1);
716 state.push(val2);
717 state.push(val1);
718 break;
719 }
720 case bastore:
721 state.pop(3);
722 break;
723 case int2byte:
724 case int2char:
725 case int2short:
726 break;
727 case fmul:
728 case fadd:
729 case fsub:
730 case fdiv:
731 case fmod:
732 state.pop(1);
733 break;
734 case castore:
735 case iastore:
736 case fastore:
737 case sastore:
738 state.pop(3);
739 break;
740 case lastore:
741 case dastore:
742 state.pop(4);
743 break;
744 case dup2:
745 if (state.stack[state.stacksize-1] != null) {
746 Type value1 = state.pop1();
747 Type value2 = state.pop1();
748 state.push(value2);
749 state.push(value1);
750 state.push(value2);
751 state.push(value1);
752 } else {
753 Type value = state.pop2();
754 state.push(value);
755 state.push(value);
756 }
757 break;
758 case dup2_x1:
759 if (state.stack[state.stacksize-1] != null) {
760 Type value1 = state.pop1();
761 Type value2 = state.pop1();
762 Type value3 = state.pop1();
763 state.push(value2);
764 state.push(value1);
765 state.push(value3);
766 state.push(value2);
767 state.push(value1);
768 } else {
769 Type value1 = state.pop2();
770 Type value2 = state.pop1();
771 state.push(value1);
772 state.push(value2);
773 state.push(value1);
774 }
775 break;
776 case dup2_x2:
777 if (state.stack[state.stacksize-1] != null) {
778 Type value1 = state.pop1();
779 Type value2 = state.pop1();
780 if (state.stack[state.stacksize-1] != null) {
781 // form 1
782 Type value3 = state.pop1();
783 Type value4 = state.pop1();
784 state.push(value2);
785 state.push(value1);
786 state.push(value4);
787 state.push(value3);
788 state.push(value2);
789 state.push(value1);
790 } else {
791 // form 3
792 Type value3 = state.pop2();
793 state.push(value2);
794 state.push(value1);
795 state.push(value3);
796 state.push(value2);
797 state.push(value1);
798 }
799 } else {
800 Type value1 = state.pop2();
801 if (state.stack[state.stacksize-1] != null) {
802 // form 2
803 Type value2 = state.pop1();
804 Type value3 = state.pop1();
805 state.push(value1);
806 state.push(value3);
807 state.push(value2);
808 state.push(value1);
809 } else {
810 // form 4
811 Type value2 = state.pop2();
812 state.push(value1);
813 state.push(value2);
814 state.push(value1);
815 }
816 }
817 break;
818 case dup_x2: {
819 Type value1 = state.pop1();
820 if (state.stack[state.stacksize-1] != null) {
821 // form 1
822 Type value2 = state.pop1();
823 Type value3 = state.pop1();
824 state.push(value1);
825 state.push(value3);
826 state.push(value2);
827 state.push(value1);
828 } else {
829 // form 2
830 Type value2 = state.pop2();
831 state.push(value1);
832 state.push(value2);
833 state.push(value1);
834 }
835 }
836 break;
837 case fcmpl:
838 case fcmpg:
839 state.pop(2);
840 state.push(syms.intType);
841 break;
842 case dcmpl:
843 case dcmpg:
844 state.pop(4);
845 state.push(syms.intType);
846 break;
847 case swap: {
848 Type value1 = state.pop1();
849 Type value2 = state.pop1();
850 state.push(value1);
851 state.push(value2);
852 break;
853 }
854 case dadd:
855 case dsub:
856 case dmul:
857 case ddiv:
858 case dmod:
859 state.pop(2);
860 break;
861 case ret:
862 markDead();
863 break;
864 case wide:
865 // must be handled by the caller.
866 return;
867 case monitorenter:
868 case monitorexit:
869 state.pop(1);
870 break;
872 default:
873 throw new AssertionError(mnem(op));
874 }
875 postop();
876 }
878 /** Emit an opcode with a one-byte operand field.
879 */
880 public void emitop1(int op, int od) {
881 emitop(op);
882 if (!alive) return;
883 emit1(od);
884 switch (op) {
885 case bipush:
886 state.push(syms.intType);
887 break;
888 case ldc1:
889 state.push(typeForPool(pool.pool[od]));
890 break;
891 default:
892 throw new AssertionError(mnem(op));
893 }
894 postop();
895 }
897 /** The type of a constant pool entry. */
898 private Type typeForPool(Object o) {
899 if (o instanceof Integer) return syms.intType;
900 if (o instanceof Float) return syms.floatType;
901 if (o instanceof String) return syms.stringType;
902 if (o instanceof Long) return syms.longType;
903 if (o instanceof Double) return syms.doubleType;
904 if (o instanceof ClassSymbol) return syms.classType;
905 if (o instanceof Type.ArrayType) return syms.classType;
906 throw new AssertionError(o);
907 }
909 /** Emit an opcode with a one-byte operand field;
910 * widen if field does not fit in a byte.
911 */
912 public void emitop1w(int op, int od) {
913 if (od > 0xFF) {
914 emitop(wide);
915 emitop(op);
916 emit2(od);
917 } else {
918 emitop(op);
919 emit1(od);
920 }
921 if (!alive) return;
922 switch (op) {
923 case iload:
924 state.push(syms.intType);
925 break;
926 case lload:
927 state.push(syms.longType);
928 break;
929 case fload:
930 state.push(syms.floatType);
931 break;
932 case dload:
933 state.push(syms.doubleType);
934 break;
935 case aload:
936 state.push(lvar[od].sym.type);
937 break;
938 case lstore:
939 case dstore:
940 state.pop(2);
941 break;
942 case istore:
943 case fstore:
944 case astore:
945 state.pop(1);
946 break;
947 case ret:
948 markDead();
949 break;
950 default:
951 throw new AssertionError(mnem(op));
952 }
953 postop();
954 }
956 /** Emit an opcode with two one-byte operand fields;
957 * widen if either field does not fit in a byte.
958 */
959 public void emitop1w(int op, int od1, int od2) {
960 if (od1 > 0xFF || od2 < -128 || od2 > 127) {
961 emitop(wide);
962 emitop(op);
963 emit2(od1);
964 emit2(od2);
965 } else {
966 emitop(op);
967 emit1(od1);
968 emit1(od2);
969 }
970 if (!alive) return;
971 switch (op) {
972 case iinc:
973 break;
974 default:
975 throw new AssertionError(mnem(op));
976 }
977 }
979 /** Emit an opcode with a two-byte operand field.
980 */
981 public void emitop2(int op, int od) {
982 emitop(op);
983 if (!alive) return;
984 emit2(od);
985 switch (op) {
986 case getstatic:
987 state.push(((Symbol)(pool.pool[od])).erasure(types));
988 break;
989 case putstatic:
990 state.pop(((Symbol)(pool.pool[od])).erasure(types));
991 break;
992 case new_:
993 state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
994 break;
995 case sipush:
996 state.push(syms.intType);
997 break;
998 case if_acmp_null:
999 case if_acmp_nonnull:
1000 case ifeq:
1001 case ifne:
1002 case iflt:
1003 case ifge:
1004 case ifgt:
1005 case ifle:
1006 state.pop(1);
1007 break;
1008 case if_icmpeq:
1009 case if_icmpne:
1010 case if_icmplt:
1011 case if_icmpge:
1012 case if_icmpgt:
1013 case if_icmple:
1014 case if_acmpeq:
1015 case if_acmpne:
1016 state.pop(2);
1017 break;
1018 case goto_:
1019 markDead();
1020 break;
1021 case putfield:
1022 state.pop(((Symbol)(pool.pool[od])).erasure(types));
1023 state.pop(1); // object ref
1024 break;
1025 case getfield:
1026 state.pop(1); // object ref
1027 state.push(((Symbol)(pool.pool[od])).erasure(types));
1028 break;
1029 case checkcast: {
1030 state.pop(1); // object ref
1031 Object o = pool.pool[od];
1032 Type t = (o instanceof Symbol)
1033 ? ((Symbol)o).erasure(types)
1034 : types.erasure(((Type)o));
1035 state.push(t);
1036 break; }
1037 case ldc2w:
1038 state.push(typeForPool(pool.pool[od]));
1039 break;
1040 case instanceof_:
1041 state.pop(1);
1042 state.push(syms.intType);
1043 break;
1044 case ldc2:
1045 state.push(typeForPool(pool.pool[od]));
1046 break;
1047 case jsr:
1048 break;
1049 default:
1050 throw new AssertionError(mnem(op));
1051 }
1052 // postop();
1053 }
1055 /** Emit an opcode with a four-byte operand field.
1056 */
1057 public void emitop4(int op, int od) {
1058 emitop(op);
1059 if (!alive) return;
1060 emit4(od);
1061 switch (op) {
1062 case goto_w:
1063 markDead();
1064 break;
1065 case jsr_w:
1066 break;
1067 default:
1068 throw new AssertionError(mnem(op));
1069 }
1070 // postop();
1071 }
1073 /** Align code pointer to next `incr' boundary.
1074 */
1075 public void align(int incr) {
1076 if (alive)
1077 while (cp % incr != 0) emitop0(nop);
1078 }
1080 /** Place a byte into code at address pc. Pre: pc + 1 <= cp.
1081 */
1082 private void put1(int pc, int op) {
1083 code[pc] = (byte)op;
1084 }
1086 /** Place two bytes into code at address pc. Pre: pc + 2 <= cp.
1087 */
1088 private void put2(int pc, int od) {
1089 // pre: pc + 2 <= cp
1090 put1(pc, od >> 8);
1091 put1(pc+1, od);
1092 }
1094 /** Place four bytes into code at address pc. Pre: pc + 4 <= cp.
1095 */
1096 public void put4(int pc, int od) {
1097 // pre: pc + 4 <= cp
1098 put1(pc , od >> 24);
1099 put1(pc+1, od >> 16);
1100 put1(pc+2, od >> 8);
1101 put1(pc+3, od);
1102 }
1104 /** Return code byte at position pc as an unsigned int.
1105 */
1106 private int get1(int pc) {
1107 return code[pc] & 0xFF;
1108 }
1110 /** Return two code bytes at position pc as an unsigned int.
1111 */
1112 private int get2(int pc) {
1113 return (get1(pc) << 8) | get1(pc+1);
1114 }
1116 /** Return four code bytes at position pc as an int.
1117 */
1118 public int get4(int pc) {
1119 // pre: pc + 4 <= cp
1120 return
1121 (get1(pc) << 24) |
1122 (get1(pc+1) << 16) |
1123 (get1(pc+2) << 8) |
1124 (get1(pc+3));
1125 }
1127 /** Is code generation currently enabled?
1128 */
1129 public boolean isAlive() {
1130 return alive || pendingJumps != null;
1131 }
1133 /** Switch code generation on/off.
1134 */
1135 public void markDead() {
1136 alive = false;
1137 }
1139 /** Declare an entry point; return current code pointer
1140 */
1141 public int entryPoint() {
1142 int pc = curPc();
1143 alive = true;
1144 pendingStackMap = needStackMap;
1145 return pc;
1146 }
1148 /** Declare an entry point with initial state;
1149 * return current code pointer
1150 */
1151 public int entryPoint(State state) {
1152 int pc = curPc();
1153 alive = true;
1154 this.state = state.dup();
1155 Assert.check(state.stacksize <= max_stack);
1156 if (debugCode) System.err.println("entry point " + state);
1157 pendingStackMap = needStackMap;
1158 return pc;
1159 }
1161 /** Declare an entry point with initial state plus a pushed value;
1162 * return current code pointer
1163 */
1164 public int entryPoint(State state, Type pushed) {
1165 int pc = curPc();
1166 alive = true;
1167 this.state = state.dup();
1168 Assert.check(state.stacksize <= max_stack);
1169 this.state.push(pushed);
1170 if (debugCode) System.err.println("entry point " + state);
1171 pendingStackMap = needStackMap;
1172 return pc;
1173 }
1176 /**************************************************************************
1177 * Stack map generation
1178 *************************************************************************/
1180 /** An entry in the stack map. */
1181 static class StackMapFrame {
1182 int pc;
1183 Type[] locals;
1184 Type[] stack;
1185 }
1187 /** A buffer of cldc stack map entries. */
1188 StackMapFrame[] stackMapBuffer = null;
1190 /** A buffer of compressed StackMapTable entries. */
1191 StackMapTableFrame[] stackMapTableBuffer = null;
1192 int stackMapBufferSize = 0;
1194 /** The last PC at which we generated a stack map. */
1195 int lastStackMapPC = -1;
1197 /** The last stack map frame in StackMapTable. */
1198 StackMapFrame lastFrame = null;
1200 /** The stack map frame before the last one. */
1201 StackMapFrame frameBeforeLast = null;
1203 /** Emit a stack map entry. */
1204 public void emitStackMap() {
1205 int pc = curPc();
1206 if (!needStackMap) return;
1210 switch (stackMap) {
1211 case CLDC:
1212 emitCLDCStackMap(pc, getLocalsSize());
1213 break;
1214 case JSR202:
1215 emitStackMapFrame(pc, getLocalsSize());
1216 break;
1217 default:
1218 throw new AssertionError("Should have chosen a stackmap format");
1219 }
1220 // DEBUG code follows
1221 if (debugCode) state.dump(pc);
1222 }
1224 private int getLocalsSize() {
1225 int nextLocal = 0;
1226 for (int i=max_locals-1; i>=0; i--) {
1227 if (state.defined.isMember(i) && lvar[i] != null) {
1228 nextLocal = i + width(lvar[i].sym.erasure(types));
1229 break;
1230 }
1231 }
1232 return nextLocal;
1233 }
1235 /** Emit a CLDC stack map frame. */
1236 void emitCLDCStackMap(int pc, int localsSize) {
1237 if (lastStackMapPC == pc) {
1238 // drop existing stackmap at this offset
1239 stackMapBuffer[--stackMapBufferSize] = null;
1240 }
1241 lastStackMapPC = pc;
1243 if (stackMapBuffer == null) {
1244 stackMapBuffer = new StackMapFrame[20];
1245 } else if (stackMapBuffer.length == stackMapBufferSize) {
1246 StackMapFrame[] newStackMapBuffer =
1247 new StackMapFrame[stackMapBufferSize << 1];
1248 System.arraycopy(stackMapBuffer, 0, newStackMapBuffer,
1249 0, stackMapBufferSize);
1250 stackMapBuffer = newStackMapBuffer;
1251 }
1252 StackMapFrame frame =
1253 stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
1254 frame.pc = pc;
1256 frame.locals = new Type[localsSize];
1257 for (int i=0; i<localsSize; i++) {
1258 if (state.defined.isMember(i) && lvar[i] != null) {
1259 Type vtype = lvar[i].sym.type;
1260 if (!(vtype instanceof UninitializedType))
1261 vtype = types.erasure(vtype);
1262 frame.locals[i] = vtype;
1263 }
1264 }
1265 frame.stack = new Type[state.stacksize];
1266 for (int i=0; i<state.stacksize; i++)
1267 frame.stack[i] = state.stack[i];
1268 }
1270 void emitStackMapFrame(int pc, int localsSize) {
1271 if (lastFrame == null) {
1272 // first frame
1273 lastFrame = getInitialFrame();
1274 } else if (lastFrame.pc == pc) {
1275 // drop existing stackmap at this offset
1276 stackMapTableBuffer[--stackMapBufferSize] = null;
1277 lastFrame = frameBeforeLast;
1278 frameBeforeLast = null;
1279 }
1281 StackMapFrame frame = new StackMapFrame();
1282 frame.pc = pc;
1284 int localCount = 0;
1285 Type[] locals = new Type[localsSize];
1286 for (int i=0; i<localsSize; i++, localCount++) {
1287 if (state.defined.isMember(i) && lvar[i] != null) {
1288 Type vtype = lvar[i].sym.type;
1289 if (!(vtype instanceof UninitializedType))
1290 vtype = types.erasure(vtype);
1291 locals[i] = vtype;
1292 if (width(vtype) > 1) i++;
1293 }
1294 }
1295 frame.locals = new Type[localCount];
1296 for (int i=0, j=0; i<localsSize; i++, j++) {
1297 Assert.check(j < localCount);
1298 frame.locals[j] = locals[i];
1299 if (width(locals[i]) > 1) i++;
1300 }
1302 int stackCount = 0;
1303 for (int i=0; i<state.stacksize; i++) {
1304 if (state.stack[i] != null) {
1305 stackCount++;
1306 }
1307 }
1308 frame.stack = new Type[stackCount];
1309 stackCount = 0;
1310 for (int i=0; i<state.stacksize; i++) {
1311 if (state.stack[i] != null) {
1312 frame.stack[stackCount++] = types.erasure(state.stack[i]);
1313 }
1314 }
1316 if (stackMapTableBuffer == null) {
1317 stackMapTableBuffer = new StackMapTableFrame[20];
1318 } else if (stackMapTableBuffer.length == stackMapBufferSize) {
1319 StackMapTableFrame[] newStackMapTableBuffer =
1320 new StackMapTableFrame[stackMapBufferSize << 1];
1321 System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer,
1322 0, stackMapBufferSize);
1323 stackMapTableBuffer = newStackMapTableBuffer;
1324 }
1325 stackMapTableBuffer[stackMapBufferSize++] =
1326 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1328 frameBeforeLast = lastFrame;
1329 lastFrame = frame;
1330 }
1332 StackMapFrame getInitialFrame() {
1333 StackMapFrame frame = new StackMapFrame();
1334 List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1335 int len = arg_types.length();
1336 int count = 0;
1337 if (!meth.isStatic()) {
1338 Type thisType = meth.owner.type;
1339 frame.locals = new Type[len+1];
1340 if (meth.isConstructor() && thisType != syms.objectType) {
1341 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1342 } else {
1343 frame.locals[count++] = types.erasure(thisType);
1344 }
1345 } else {
1346 frame.locals = new Type[len];
1347 }
1348 for (Type arg_type : arg_types) {
1349 frame.locals[count++] = types.erasure(arg_type);
1350 }
1351 frame.pc = -1;
1352 frame.stack = null;
1353 return frame;
1354 }
1357 /**************************************************************************
1358 * Operations having to do with jumps
1359 *************************************************************************/
1361 /** A chain represents a list of unresolved jumps. Jump locations
1362 * are sorted in decreasing order.
1363 */
1364 public static class Chain {
1366 /** The position of the jump instruction.
1367 */
1368 public final int pc;
1370 /** The machine state after the jump instruction.
1371 * Invariant: all elements of a chain list have the same stacksize
1372 * and compatible stack and register contents.
1373 */
1374 Code.State state;
1376 /** The next jump in the list.
1377 */
1378 public final Chain next;
1380 /** Construct a chain from its jump position, stacksize, previous
1381 * chain, and machine state.
1382 */
1383 public Chain(int pc, Chain next, Code.State state) {
1384 this.pc = pc;
1385 this.next = next;
1386 this.state = state;
1387 }
1388 }
1390 /** Negate a branch opcode.
1391 */
1392 public static int negate(int opcode) {
1393 if (opcode == if_acmp_null) return if_acmp_nonnull;
1394 else if (opcode == if_acmp_nonnull) return if_acmp_null;
1395 else return ((opcode + 1) ^ 1) - 1;
1396 }
1398 /** Emit a jump instruction.
1399 * Return code pointer of instruction to be patched.
1400 */
1401 public int emitJump(int opcode) {
1402 if (fatcode) {
1403 if (opcode == goto_ || opcode == jsr) {
1404 emitop4(opcode + goto_w - goto_, 0);
1405 } else {
1406 emitop2(negate(opcode), 8);
1407 emitop4(goto_w, 0);
1408 alive = true;
1409 pendingStackMap = needStackMap;
1410 }
1411 return cp - 5;
1412 } else {
1413 emitop2(opcode, 0);
1414 return cp - 3;
1415 }
1416 }
1418 /** Emit a branch with given opcode; return its chain.
1419 * branch differs from jump in that jsr is treated as no-op.
1420 */
1421 public Chain branch(int opcode) {
1422 Chain result = null;
1423 if (opcode == goto_) {
1424 result = pendingJumps;
1425 pendingJumps = null;
1426 }
1427 if (opcode != dontgoto && isAlive()) {
1428 result = new Chain(emitJump(opcode),
1429 result,
1430 state.dup());
1431 fixedPc = fatcode;
1432 if (opcode == goto_) alive = false;
1433 }
1434 return result;
1435 }
1437 /** Resolve chain to point to given target.
1438 */
1439 public void resolve(Chain chain, int target) {
1440 boolean changed = false;
1441 State newState = state;
1442 for (; chain != null; chain = chain.next) {
1443 Assert.check(state != chain.state
1444 && (target > chain.pc || state.stacksize == 0));
1445 if (target >= cp) {
1446 target = cp;
1447 } else if (get1(target) == goto_) {
1448 if (fatcode) target = target + get4(target + 1);
1449 else target = target + get2(target + 1);
1450 }
1451 if (get1(chain.pc) == goto_ &&
1452 chain.pc + 3 == target && target == cp && !fixedPc) {
1453 // If goto the next instruction, the jump is not needed:
1454 // compact the code.
1455 cp = cp - 3;
1456 target = target - 3;
1457 if (chain.next == null) {
1458 // This is the only jump to the target. Exit the loop
1459 // without setting new state. The code is reachable
1460 // from the instruction before goto_.
1461 alive = true;
1462 break;
1463 }
1464 } else {
1465 if (fatcode)
1466 put4(chain.pc + 1, target - chain.pc);
1467 else if (target - chain.pc < Short.MIN_VALUE ||
1468 target - chain.pc > Short.MAX_VALUE)
1469 fatcode = true;
1470 else
1471 put2(chain.pc + 1, target - chain.pc);
1472 Assert.check(!alive ||
1473 chain.state.stacksize == newState.stacksize &&
1474 chain.state.nlocks == newState.nlocks);
1475 }
1476 fixedPc = true;
1477 if (cp == target) {
1478 changed = true;
1479 if (debugCode)
1480 System.err.println("resolving chain state=" + chain.state);
1481 if (alive) {
1482 newState = chain.state.join(newState);
1483 } else {
1484 newState = chain.state;
1485 alive = true;
1486 }
1487 }
1488 }
1489 Assert.check(!changed || state != newState);
1490 if (state != newState) {
1491 setDefined(newState.defined);
1492 state = newState;
1493 pendingStackMap = needStackMap;
1494 }
1495 }
1497 /** Resolve chain to point to current code pointer.
1498 */
1499 public void resolve(Chain chain) {
1500 Assert.check(
1501 !alive ||
1502 chain==null ||
1503 state.stacksize == chain.state.stacksize &&
1504 state.nlocks == chain.state.nlocks);
1505 pendingJumps = mergeChains(chain, pendingJumps);
1506 }
1508 /** Resolve any pending jumps.
1509 */
1510 public void resolvePending() {
1511 Chain x = pendingJumps;
1512 pendingJumps = null;
1513 resolve(x, cp);
1514 }
1516 /** Merge the jumps in of two chains into one.
1517 */
1518 public static Chain mergeChains(Chain chain1, Chain chain2) {
1519 // recursive merge sort
1520 if (chain2 == null) return chain1;
1521 if (chain1 == null) return chain2;
1522 Assert.check(
1523 chain1.state.stacksize == chain2.state.stacksize &&
1524 chain1.state.nlocks == chain2.state.nlocks);
1525 if (chain1.pc < chain2.pc)
1526 return new Chain(
1527 chain2.pc,
1528 mergeChains(chain1, chain2.next),
1529 chain2.state);
1530 return new Chain(
1531 chain1.pc,
1532 mergeChains(chain1.next, chain2),
1533 chain1.state);
1534 }
1537 /* **************************************************************************
1538 * Catch clauses
1539 ****************************************************************************/
1541 /** Add a catch clause to code.
1542 */
1543 public void addCatch(
1544 char startPc, char endPc, char handlerPc, char catchType) {
1545 catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
1546 }
1549 /* **************************************************************************
1550 * Line numbers
1551 ****************************************************************************/
1553 /** Add a line number entry.
1554 */
1555 public void addLineNumber(char startPc, char lineNumber) {
1556 if (lineDebugInfo) {
1557 if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
1558 lineInfo = lineInfo.tail;
1559 if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
1560 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
1561 }
1562 }
1564 /** Mark beginning of statement.
1565 */
1566 public void statBegin(int pos) {
1567 if (pos != Position.NOPOS) {
1568 pendingStatPos = pos;
1569 }
1570 }
1572 /** Force stat begin eagerly
1573 */
1574 public void markStatBegin() {
1575 if (alive && lineDebugInfo) {
1576 int line = lineMap.getLineNumber(pendingStatPos);
1577 char cp1 = (char)cp;
1578 char line1 = (char)line;
1579 if (cp1 == cp && line1 == line)
1580 addLineNumber(cp1, line1);
1581 }
1582 pendingStatPos = Position.NOPOS;
1583 }
1586 /* **************************************************************************
1587 * Simulated VM machine state
1588 ****************************************************************************/
1590 class State implements Cloneable {
1591 /** The set of registers containing values. */
1592 Bits defined;
1594 /** The (types of the) contents of the machine stack. */
1595 Type[] stack;
1597 /** The first stack position currently unused. */
1598 int stacksize;
1600 /** The numbers of registers containing locked monitors. */
1601 int[] locks;
1602 int nlocks;
1604 State() {
1605 defined = new Bits();
1606 stack = new Type[16];
1607 }
1609 State dup() {
1610 try {
1611 State state = (State)super.clone();
1612 state.defined = defined.dup();
1613 state.stack = stack.clone();
1614 if (locks != null) state.locks = locks.clone();
1615 if (debugCode) {
1616 System.err.println("duping state " + this);
1617 dump();
1618 }
1619 return state;
1620 } catch (CloneNotSupportedException ex) {
1621 throw new AssertionError(ex);
1622 }
1623 }
1625 void lock(int register) {
1626 if (locks == null) {
1627 locks = new int[20];
1628 } else if (locks.length == nlocks) {
1629 int[] newLocks = new int[locks.length << 1];
1630 System.arraycopy(locks, 0, newLocks, 0, locks.length);
1631 locks = newLocks;
1632 }
1633 locks[nlocks] = register;
1634 nlocks++;
1635 }
1637 void unlock(int register) {
1638 nlocks--;
1639 Assert.check(locks[nlocks] == register);
1640 locks[nlocks] = -1;
1641 }
1643 void push(Type t) {
1644 if (debugCode) System.err.println(" pushing " + t);
1645 switch (t.tag) {
1646 case TypeTags.VOID:
1647 return;
1648 case TypeTags.BYTE:
1649 case TypeTags.CHAR:
1650 case TypeTags.SHORT:
1651 case TypeTags.BOOLEAN:
1652 t = syms.intType;
1653 break;
1654 default:
1655 break;
1656 }
1657 if (stacksize+2 >= stack.length) {
1658 Type[] newstack = new Type[2*stack.length];
1659 System.arraycopy(stack, 0, newstack, 0, stack.length);
1660 stack = newstack;
1661 }
1662 stack[stacksize++] = t;
1663 switch (width(t)) {
1664 case 1:
1665 break;
1666 case 2:
1667 stack[stacksize++] = null;
1668 break;
1669 default:
1670 throw new AssertionError(t);
1671 }
1672 if (stacksize > max_stack)
1673 max_stack = stacksize;
1674 }
1676 Type pop1() {
1677 if (debugCode) System.err.println(" popping " + 1);
1678 stacksize--;
1679 Type result = stack[stacksize];
1680 stack[stacksize] = null;
1681 Assert.check(result != null && width(result) == 1);
1682 return result;
1683 }
1685 Type peek() {
1686 return stack[stacksize-1];
1687 }
1689 Type pop2() {
1690 if (debugCode) System.err.println(" popping " + 2);
1691 stacksize -= 2;
1692 Type result = stack[stacksize];
1693 stack[stacksize] = null;
1694 Assert.check(stack[stacksize+1] == null
1695 && result != null && width(result) == 2);
1696 return result;
1697 }
1699 void pop(int n) {
1700 if (debugCode) System.err.println(" popping " + n);
1701 while (n > 0) {
1702 stack[--stacksize] = null;
1703 n--;
1704 }
1705 }
1707 void pop(Type t) {
1708 pop(width(t));
1709 }
1711 /** Force the top of the stack to be treated as this supertype
1712 * of its current type. */
1713 void forceStackTop(Type t) {
1714 if (!alive) return;
1715 switch (t.tag) {
1716 case CLASS:
1717 case ARRAY:
1718 int width = width(t);
1719 Type old = stack[stacksize-width];
1720 Assert.check(types.isSubtype(types.erasure(old),
1721 types.erasure(t)));
1722 stack[stacksize-width] = t;
1723 break;
1724 default:
1725 }
1726 }
1728 void markInitialized(UninitializedType old) {
1729 Type newtype = old.initializedType();
1730 for (int i=0; i<stacksize; i++)
1731 if (stack[i] == old) stack[i] = newtype;
1732 for (int i=0; i<lvar.length; i++) {
1733 LocalVar lv = lvar[i];
1734 if (lv != null && lv.sym.type == old) {
1735 VarSymbol sym = lv.sym;
1736 sym = sym.clone(sym.owner);
1737 sym.type = newtype;
1738 LocalVar newlv = lvar[i] = new LocalVar(sym);
1739 // should the following be initialized to cp?
1740 newlv.start_pc = lv.start_pc;
1741 }
1742 }
1743 }
1745 State join(State other) {
1746 defined = defined.andSet(other.defined);
1747 Assert.check(stacksize == other.stacksize
1748 && nlocks == other.nlocks);
1749 for (int i=0; i<stacksize; ) {
1750 Type t = stack[i];
1751 Type tother = other.stack[i];
1752 Type result =
1753 t==tother ? t :
1754 types.isSubtype(t, tother) ? tother :
1755 types.isSubtype(tother, t) ? t :
1756 error();
1757 int w = width(result);
1758 stack[i] = result;
1759 if (w == 2) Assert.checkNull(stack[i+1]);
1760 i += w;
1761 }
1762 return this;
1763 }
1765 Type error() {
1766 throw new AssertionError("inconsistent stack types at join point");
1767 }
1769 void dump() {
1770 dump(-1);
1771 }
1773 void dump(int pc) {
1774 System.err.print("stackMap for " + meth.owner + "." + meth);
1775 if (pc == -1)
1776 System.out.println();
1777 else
1778 System.out.println(" at " + pc);
1779 System.err.println(" stack (from bottom):");
1780 for (int i=0; i<stacksize; i++)
1781 System.err.println(" " + i + ": " + stack[i]);
1783 int lastLocal = 0;
1784 for (int i=max_locals-1; i>=0; i--) {
1785 if (defined.isMember(i)) {
1786 lastLocal = i;
1787 break;
1788 }
1789 }
1790 if (lastLocal >= 0)
1791 System.err.println(" locals:");
1792 for (int i=0; i<=lastLocal; i++) {
1793 System.err.print(" " + i + ": ");
1794 if (defined.isMember(i)) {
1795 LocalVar var = lvar[i];
1796 if (var == null) {
1797 System.err.println("(none)");
1798 } else if (var.sym == null)
1799 System.err.println("UNKNOWN!");
1800 else
1801 System.err.println("" + var.sym + " of type " +
1802 var.sym.erasure(types));
1803 } else {
1804 System.err.println("undefined");
1805 }
1806 }
1807 if (nlocks != 0) {
1808 System.err.print(" locks:");
1809 for (int i=0; i<nlocks; i++) {
1810 System.err.print(" " + locks[i]);
1811 }
1812 System.err.println();
1813 }
1814 }
1815 }
1817 static Type jsrReturnValue = new Type(TypeTags.INT, null);
1820 /* **************************************************************************
1821 * Local variables
1822 ****************************************************************************/
1824 /** A live range of a local variable. */
1825 static class LocalVar {
1826 final VarSymbol sym;
1827 final char reg;
1828 char start_pc = Character.MAX_VALUE;
1829 char length = Character.MAX_VALUE;
1830 LocalVar(VarSymbol v) {
1831 this.sym = v;
1832 this.reg = (char)v.adr;
1833 }
1834 public LocalVar dup() {
1835 return new LocalVar(sym);
1836 }
1837 public String toString() {
1838 return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
1839 }
1840 };
1842 /** Local variables, indexed by register. */
1843 LocalVar[] lvar;
1845 /** Add a new local variable. */
1846 private void addLocalVar(VarSymbol v) {
1847 int adr = v.adr;
1848 if (adr+1 >= lvar.length) {
1849 int newlength = lvar.length << 1;
1850 if (newlength <= adr) newlength = adr + 10;
1851 LocalVar[] new_lvar = new LocalVar[newlength];
1852 System.arraycopy(lvar, 0, new_lvar, 0, lvar.length);
1853 lvar = new_lvar;
1854 }
1855 Assert.checkNull(lvar[adr]);
1856 if (pendingJumps != null) resolvePending();
1857 lvar[adr] = new LocalVar(v);
1858 state.defined.excl(adr);
1859 }
1861 /** Set the current variable defined state. */
1862 public void setDefined(Bits newDefined) {
1863 if (alive && newDefined != state.defined) {
1864 Bits diff = state.defined.dup().xorSet(newDefined);
1865 for (int adr = diff.nextBit(0);
1866 adr >= 0;
1867 adr = diff.nextBit(adr+1)) {
1868 if (adr >= nextreg)
1869 state.defined.excl(adr);
1870 else if (state.defined.isMember(adr))
1871 setUndefined(adr);
1872 else
1873 setDefined(adr);
1874 }
1875 }
1876 }
1878 /** Mark a register as being (possibly) defined. */
1879 public void setDefined(int adr) {
1880 LocalVar v = lvar[adr];
1881 if (v == null) {
1882 state.defined.excl(adr);
1883 } else {
1884 state.defined.incl(adr);
1885 if (cp < Character.MAX_VALUE) {
1886 if (v.start_pc == Character.MAX_VALUE)
1887 v.start_pc = (char)cp;
1888 }
1889 }
1890 }
1892 /** Mark a register as being undefined. */
1893 public void setUndefined(int adr) {
1894 state.defined.excl(adr);
1895 if (adr < lvar.length &&
1896 lvar[adr] != null &&
1897 lvar[adr].start_pc != Character.MAX_VALUE) {
1898 LocalVar v = lvar[adr];
1899 char length = (char)(curPc() - v.start_pc);
1900 if (length > 0 && length < Character.MAX_VALUE) {
1901 lvar[adr] = v.dup();
1902 v.length = length;
1903 putVar(v);
1904 } else {
1905 v.start_pc = Character.MAX_VALUE;
1906 }
1907 }
1908 }
1910 /** End the scope of a variable. */
1911 private void endScope(int adr) {
1912 LocalVar v = lvar[adr];
1913 if (v != null) {
1914 lvar[adr] = null;
1915 if (v.start_pc != Character.MAX_VALUE) {
1916 char length = (char)(curPc() - v.start_pc);
1917 if (length < Character.MAX_VALUE) {
1918 v.length = length;
1919 putVar(v);
1920 }
1921 }
1922 }
1923 state.defined.excl(adr);
1924 }
1926 /** Put a live variable range into the buffer to be output to the
1927 * class file.
1928 */
1929 void putVar(LocalVar var) {
1930 if (!varDebugInfo) return;
1931 if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
1932 if (varBuffer == null)
1933 varBuffer = new LocalVar[20];
1934 else if (varBufferSize >= varBuffer.length) {
1935 LocalVar[] newVarBuffer = new LocalVar[varBufferSize*2];
1936 System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length);
1937 varBuffer = newVarBuffer;
1938 }
1939 varBuffer[varBufferSize++] = var;
1940 }
1942 /** Previously live local variables, to be put into the variable table. */
1943 LocalVar[] varBuffer;
1944 int varBufferSize;
1946 /** Create a new local variable address and return it.
1947 */
1948 private int newLocal(int typecode) {
1949 int reg = nextreg;
1950 int w = width(typecode);
1951 nextreg = reg + w;
1952 if (nextreg > max_locals) max_locals = nextreg;
1953 return reg;
1954 }
1956 private int newLocal(Type type) {
1957 return newLocal(typecode(type));
1958 }
1960 public int newLocal(VarSymbol v) {
1961 int reg = v.adr = newLocal(v.erasure(types));
1962 addLocalVar(v);
1963 return reg;
1964 }
1966 /** Start a set of fresh registers.
1967 */
1968 public void newRegSegment() {
1969 nextreg = max_locals;
1970 }
1972 /** End scopes of all variables with registers >= first.
1973 */
1974 public void endScopes(int first) {
1975 int prevNextReg = nextreg;
1976 nextreg = first;
1977 for (int i = nextreg; i < prevNextReg; i++) endScope(i);
1978 }
1980 /**************************************************************************
1981 * static tables
1982 *************************************************************************/
1984 public static String mnem(int opcode) {
1985 return Mneumonics.mnem[opcode];
1986 }
1988 private static class Mneumonics {
1989 private final static String[] mnem = new String[ByteCodeCount];
1990 static {
1991 mnem[nop] = "nop";
1992 mnem[aconst_null] = "aconst_null";
1993 mnem[iconst_m1] = "iconst_m1";
1994 mnem[iconst_0] = "iconst_0";
1995 mnem[iconst_1] = "iconst_1";
1996 mnem[iconst_2] = "iconst_2";
1997 mnem[iconst_3] = "iconst_3";
1998 mnem[iconst_4] = "iconst_4";
1999 mnem[iconst_5] = "iconst_5";
2000 mnem[lconst_0] = "lconst_0";
2001 mnem[lconst_1] = "lconst_1";
2002 mnem[fconst_0] = "fconst_0";
2003 mnem[fconst_1] = "fconst_1";
2004 mnem[fconst_2] = "fconst_2";
2005 mnem[dconst_0] = "dconst_0";
2006 mnem[dconst_1] = "dconst_1";
2007 mnem[bipush] = "bipush";
2008 mnem[sipush] = "sipush";
2009 mnem[ldc1] = "ldc1";
2010 mnem[ldc2] = "ldc2";
2011 mnem[ldc2w] = "ldc2w";
2012 mnem[iload] = "iload";
2013 mnem[lload] = "lload";
2014 mnem[fload] = "fload";
2015 mnem[dload] = "dload";
2016 mnem[aload] = "aload";
2017 mnem[iload_0] = "iload_0";
2018 mnem[lload_0] = "lload_0";
2019 mnem[fload_0] = "fload_0";
2020 mnem[dload_0] = "dload_0";
2021 mnem[aload_0] = "aload_0";
2022 mnem[iload_1] = "iload_1";
2023 mnem[lload_1] = "lload_1";
2024 mnem[fload_1] = "fload_1";
2025 mnem[dload_1] = "dload_1";
2026 mnem[aload_1] = "aload_1";
2027 mnem[iload_2] = "iload_2";
2028 mnem[lload_2] = "lload_2";
2029 mnem[fload_2] = "fload_2";
2030 mnem[dload_2] = "dload_2";
2031 mnem[aload_2] = "aload_2";
2032 mnem[iload_3] = "iload_3";
2033 mnem[lload_3] = "lload_3";
2034 mnem[fload_3] = "fload_3";
2035 mnem[dload_3] = "dload_3";
2036 mnem[aload_3] = "aload_3";
2037 mnem[iaload] = "iaload";
2038 mnem[laload] = "laload";
2039 mnem[faload] = "faload";
2040 mnem[daload] = "daload";
2041 mnem[aaload] = "aaload";
2042 mnem[baload] = "baload";
2043 mnem[caload] = "caload";
2044 mnem[saload] = "saload";
2045 mnem[istore] = "istore";
2046 mnem[lstore] = "lstore";
2047 mnem[fstore] = "fstore";
2048 mnem[dstore] = "dstore";
2049 mnem[astore] = "astore";
2050 mnem[istore_0] = "istore_0";
2051 mnem[lstore_0] = "lstore_0";
2052 mnem[fstore_0] = "fstore_0";
2053 mnem[dstore_0] = "dstore_0";
2054 mnem[astore_0] = "astore_0";
2055 mnem[istore_1] = "istore_1";
2056 mnem[lstore_1] = "lstore_1";
2057 mnem[fstore_1] = "fstore_1";
2058 mnem[dstore_1] = "dstore_1";
2059 mnem[astore_1] = "astore_1";
2060 mnem[istore_2] = "istore_2";
2061 mnem[lstore_2] = "lstore_2";
2062 mnem[fstore_2] = "fstore_2";
2063 mnem[dstore_2] = "dstore_2";
2064 mnem[astore_2] = "astore_2";
2065 mnem[istore_3] = "istore_3";
2066 mnem[lstore_3] = "lstore_3";
2067 mnem[fstore_3] = "fstore_3";
2068 mnem[dstore_3] = "dstore_3";
2069 mnem[astore_3] = "astore_3";
2070 mnem[iastore] = "iastore";
2071 mnem[lastore] = "lastore";
2072 mnem[fastore] = "fastore";
2073 mnem[dastore] = "dastore";
2074 mnem[aastore] = "aastore";
2075 mnem[bastore] = "bastore";
2076 mnem[castore] = "castore";
2077 mnem[sastore] = "sastore";
2078 mnem[pop] = "pop";
2079 mnem[pop2] = "pop2";
2080 mnem[dup] = "dup";
2081 mnem[dup_x1] = "dup_x1";
2082 mnem[dup_x2] = "dup_x2";
2083 mnem[dup2] = "dup2";
2084 mnem[dup2_x1] = "dup2_x1";
2085 mnem[dup2_x2] = "dup2_x2";
2086 mnem[swap] = "swap";
2087 mnem[iadd] = "iadd";
2088 mnem[ladd] = "ladd";
2089 mnem[fadd] = "fadd";
2090 mnem[dadd] = "dadd";
2091 mnem[isub] = "isub";
2092 mnem[lsub] = "lsub";
2093 mnem[fsub] = "fsub";
2094 mnem[dsub] = "dsub";
2095 mnem[imul] = "imul";
2096 mnem[lmul] = "lmul";
2097 mnem[fmul] = "fmul";
2098 mnem[dmul] = "dmul";
2099 mnem[idiv] = "idiv";
2100 mnem[ldiv] = "ldiv";
2101 mnem[fdiv] = "fdiv";
2102 mnem[ddiv] = "ddiv";
2103 mnem[imod] = "imod";
2104 mnem[lmod] = "lmod";
2105 mnem[fmod] = "fmod";
2106 mnem[dmod] = "dmod";
2107 mnem[ineg] = "ineg";
2108 mnem[lneg] = "lneg";
2109 mnem[fneg] = "fneg";
2110 mnem[dneg] = "dneg";
2111 mnem[ishl] = "ishl";
2112 mnem[lshl] = "lshl";
2113 mnem[ishr] = "ishr";
2114 mnem[lshr] = "lshr";
2115 mnem[iushr] = "iushr";
2116 mnem[lushr] = "lushr";
2117 mnem[iand] = "iand";
2118 mnem[land] = "land";
2119 mnem[ior] = "ior";
2120 mnem[lor] = "lor";
2121 mnem[ixor] = "ixor";
2122 mnem[lxor] = "lxor";
2123 mnem[iinc] = "iinc";
2124 mnem[i2l] = "i2l";
2125 mnem[i2f] = "i2f";
2126 mnem[i2d] = "i2d";
2127 mnem[l2i] = "l2i";
2128 mnem[l2f] = "l2f";
2129 mnem[l2d] = "l2d";
2130 mnem[f2i] = "f2i";
2131 mnem[f2l] = "f2l";
2132 mnem[f2d] = "f2d";
2133 mnem[d2i] = "d2i";
2134 mnem[d2l] = "d2l";
2135 mnem[d2f] = "d2f";
2136 mnem[int2byte] = "int2byte";
2137 mnem[int2char] = "int2char";
2138 mnem[int2short] = "int2short";
2139 mnem[lcmp] = "lcmp";
2140 mnem[fcmpl] = "fcmpl";
2141 mnem[fcmpg] = "fcmpg";
2142 mnem[dcmpl] = "dcmpl";
2143 mnem[dcmpg] = "dcmpg";
2144 mnem[ifeq] = "ifeq";
2145 mnem[ifne] = "ifne";
2146 mnem[iflt] = "iflt";
2147 mnem[ifge] = "ifge";
2148 mnem[ifgt] = "ifgt";
2149 mnem[ifle] = "ifle";
2150 mnem[if_icmpeq] = "if_icmpeq";
2151 mnem[if_icmpne] = "if_icmpne";
2152 mnem[if_icmplt] = "if_icmplt";
2153 mnem[if_icmpge] = "if_icmpge";
2154 mnem[if_icmpgt] = "if_icmpgt";
2155 mnem[if_icmple] = "if_icmple";
2156 mnem[if_acmpeq] = "if_acmpeq";
2157 mnem[if_acmpne] = "if_acmpne";
2158 mnem[goto_] = "goto_";
2159 mnem[jsr] = "jsr";
2160 mnem[ret] = "ret";
2161 mnem[tableswitch] = "tableswitch";
2162 mnem[lookupswitch] = "lookupswitch";
2163 mnem[ireturn] = "ireturn";
2164 mnem[lreturn] = "lreturn";
2165 mnem[freturn] = "freturn";
2166 mnem[dreturn] = "dreturn";
2167 mnem[areturn] = "areturn";
2168 mnem[return_] = "return_";
2169 mnem[getstatic] = "getstatic";
2170 mnem[putstatic] = "putstatic";
2171 mnem[getfield] = "getfield";
2172 mnem[putfield] = "putfield";
2173 mnem[invokevirtual] = "invokevirtual";
2174 mnem[invokespecial] = "invokespecial";
2175 mnem[invokestatic] = "invokestatic";
2176 mnem[invokeinterface] = "invokeinterface";
2177 mnem[invokedynamic] = "invokedynamic";
2178 mnem[new_] = "new_";
2179 mnem[newarray] = "newarray";
2180 mnem[anewarray] = "anewarray";
2181 mnem[arraylength] = "arraylength";
2182 mnem[athrow] = "athrow";
2183 mnem[checkcast] = "checkcast";
2184 mnem[instanceof_] = "instanceof_";
2185 mnem[monitorenter] = "monitorenter";
2186 mnem[monitorexit] = "monitorexit";
2187 mnem[wide] = "wide";
2188 mnem[multianewarray] = "multianewarray";
2189 mnem[if_acmp_null] = "if_acmp_null";
2190 mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2191 mnem[goto_w] = "goto_w";
2192 mnem[jsr_w] = "jsr_w";
2193 mnem[breakpoint] = "breakpoint";
2194 }
2195 }
2196 }