Mon, 23 Aug 2010 15:13:33 -0700
6976747: JCDiagnostic: replace "boolean mandatory" with new "Set<JCDiagnostic.Flag>"
Reviewed-by: mcimadamore
1 /*
2 * Copyright (c) 1999, 2009, 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 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 state.push(types.erasure(types.elemtype(a))); }
483 break;
484 case goto_:
485 markDead();
486 break;
487 case nop:
488 case ineg:
489 case lneg:
490 case fneg:
491 case dneg:
492 break;
493 case aconst_null:
494 state.push(syms.botType);
495 break;
496 case iconst_m1:
497 case iconst_0:
498 case iconst_1:
499 case iconst_2:
500 case iconst_3:
501 case iconst_4:
502 case iconst_5:
503 case iload_0:
504 case iload_1:
505 case iload_2:
506 case iload_3:
507 state.push(syms.intType);
508 break;
509 case lconst_0:
510 case lconst_1:
511 case lload_0:
512 case lload_1:
513 case lload_2:
514 case lload_3:
515 state.push(syms.longType);
516 break;
517 case fconst_0:
518 case fconst_1:
519 case fconst_2:
520 case fload_0:
521 case fload_1:
522 case fload_2:
523 case fload_3:
524 state.push(syms.floatType);
525 break;
526 case dconst_0:
527 case dconst_1:
528 case dload_0:
529 case dload_1:
530 case dload_2:
531 case dload_3:
532 state.push(syms.doubleType);
533 break;
534 case aload_0:
535 state.push(lvar[0].sym.type);
536 break;
537 case aload_1:
538 state.push(lvar[1].sym.type);
539 break;
540 case aload_2:
541 state.push(lvar[2].sym.type);
542 break;
543 case aload_3:
544 state.push(lvar[3].sym.type);
545 break;
546 case iaload:
547 case baload:
548 case caload:
549 case saload:
550 state.pop(2);
551 state.push(syms.intType);
552 break;
553 case laload:
554 state.pop(2);
555 state.push(syms.longType);
556 break;
557 case faload:
558 state.pop(2);
559 state.push(syms.floatType);
560 break;
561 case daload:
562 state.pop(2);
563 state.push(syms.doubleType);
564 break;
565 case istore_0:
566 case istore_1:
567 case istore_2:
568 case istore_3:
569 case fstore_0:
570 case fstore_1:
571 case fstore_2:
572 case fstore_3:
573 case astore_0:
574 case astore_1:
575 case astore_2:
576 case astore_3:
577 case pop:
578 case lshr:
579 case lshl:
580 case lushr:
581 state.pop(1);
582 break;
583 case areturn:
584 case ireturn:
585 case freturn:
586 assert state.nlocks == 0;
587 state.pop(1);
588 markDead();
589 break;
590 case athrow:
591 state.pop(1);
592 markDead();
593 break;
594 case lstore_0:
595 case lstore_1:
596 case lstore_2:
597 case lstore_3:
598 case dstore_0:
599 case dstore_1:
600 case dstore_2:
601 case dstore_3:
602 case pop2:
603 state.pop(2);
604 break;
605 case lreturn:
606 case dreturn:
607 assert state.nlocks == 0;
608 state.pop(2);
609 markDead();
610 break;
611 case dup:
612 state.push(state.stack[state.stacksize-1]);
613 break;
614 case return_:
615 assert state.nlocks == 0;
616 markDead();
617 break;
618 case arraylength:
619 state.pop(1);
620 state.push(syms.intType);
621 break;
622 case isub:
623 case iadd:
624 case imul:
625 case idiv:
626 case imod:
627 case ishl:
628 case ishr:
629 case iushr:
630 case iand:
631 case ior:
632 case ixor:
633 state.pop(1);
634 // state.pop(1);
635 // state.push(syms.intType);
636 break;
637 case aastore:
638 state.pop(3);
639 break;
640 case land:
641 case lor:
642 case lxor:
643 case lmod:
644 case ldiv:
645 case lmul:
646 case lsub:
647 case ladd:
648 state.pop(2);
649 break;
650 case lcmp:
651 state.pop(4);
652 state.push(syms.intType);
653 break;
654 case l2i:
655 state.pop(2);
656 state.push(syms.intType);
657 break;
658 case i2l:
659 state.pop(1);
660 state.push(syms.longType);
661 break;
662 case i2f:
663 state.pop(1);
664 state.push(syms.floatType);
665 break;
666 case i2d:
667 state.pop(1);
668 state.push(syms.doubleType);
669 break;
670 case l2f:
671 state.pop(2);
672 state.push(syms.floatType);
673 break;
674 case l2d:
675 state.pop(2);
676 state.push(syms.doubleType);
677 break;
678 case f2i:
679 state.pop(1);
680 state.push(syms.intType);
681 break;
682 case f2l:
683 state.pop(1);
684 state.push(syms.longType);
685 break;
686 case f2d:
687 state.pop(1);
688 state.push(syms.doubleType);
689 break;
690 case d2i:
691 state.pop(2);
692 state.push(syms.intType);
693 break;
694 case d2l:
695 state.pop(2);
696 state.push(syms.longType);
697 break;
698 case d2f:
699 state.pop(2);
700 state.push(syms.floatType);
701 break;
702 case tableswitch:
703 case lookupswitch:
704 state.pop(1);
705 // the caller is responsible for patching up the state
706 break;
707 case dup_x1: {
708 Type val1 = state.pop1();
709 Type val2 = state.pop1();
710 state.push(val1);
711 state.push(val2);
712 state.push(val1);
713 break;
714 }
715 case bastore:
716 state.pop(3);
717 break;
718 case int2byte:
719 case int2char:
720 case int2short:
721 break;
722 case fmul:
723 case fadd:
724 case fsub:
725 case fdiv:
726 case fmod:
727 state.pop(1);
728 break;
729 case castore:
730 case iastore:
731 case fastore:
732 case sastore:
733 state.pop(3);
734 break;
735 case lastore:
736 case dastore:
737 state.pop(4);
738 break;
739 case dup2:
740 if (state.stack[state.stacksize-1] != null) {
741 Type value1 = state.pop1();
742 Type value2 = state.pop1();
743 state.push(value2);
744 state.push(value1);
745 state.push(value2);
746 state.push(value1);
747 } else {
748 Type value = state.pop2();
749 state.push(value);
750 state.push(value);
751 }
752 break;
753 case dup2_x1:
754 if (state.stack[state.stacksize-1] != null) {
755 Type value1 = state.pop1();
756 Type value2 = state.pop1();
757 Type value3 = state.pop1();
758 state.push(value2);
759 state.push(value1);
760 state.push(value3);
761 state.push(value2);
762 state.push(value1);
763 } else {
764 Type value1 = state.pop2();
765 Type value2 = state.pop1();
766 state.push(value1);
767 state.push(value2);
768 state.push(value1);
769 }
770 break;
771 case dup2_x2:
772 if (state.stack[state.stacksize-1] != null) {
773 Type value1 = state.pop1();
774 Type value2 = state.pop1();
775 if (state.stack[state.stacksize-1] != null) {
776 // form 1
777 Type value3 = state.pop1();
778 Type value4 = state.pop1();
779 state.push(value2);
780 state.push(value1);
781 state.push(value4);
782 state.push(value3);
783 state.push(value2);
784 state.push(value1);
785 } else {
786 // form 3
787 Type value3 = state.pop2();
788 state.push(value2);
789 state.push(value1);
790 state.push(value3);
791 state.push(value2);
792 state.push(value1);
793 }
794 } else {
795 Type value1 = state.pop2();
796 if (state.stack[state.stacksize-1] != null) {
797 // form 2
798 Type value2 = state.pop1();
799 Type value3 = state.pop1();
800 state.push(value1);
801 state.push(value3);
802 state.push(value2);
803 state.push(value1);
804 } else {
805 // form 4
806 Type value2 = state.pop2();
807 state.push(value1);
808 state.push(value2);
809 state.push(value1);
810 }
811 }
812 break;
813 case dup_x2: {
814 Type value1 = state.pop1();
815 if (state.stack[state.stacksize-1] != null) {
816 // form 1
817 Type value2 = state.pop1();
818 Type value3 = state.pop1();
819 state.push(value1);
820 state.push(value3);
821 state.push(value2);
822 state.push(value1);
823 } else {
824 // form 2
825 Type value2 = state.pop2();
826 state.push(value1);
827 state.push(value2);
828 state.push(value1);
829 }
830 }
831 break;
832 case fcmpl:
833 case fcmpg:
834 state.pop(2);
835 state.push(syms.intType);
836 break;
837 case dcmpl:
838 case dcmpg:
839 state.pop(4);
840 state.push(syms.intType);
841 break;
842 case swap: {
843 Type value1 = state.pop1();
844 Type value2 = state.pop1();
845 state.push(value1);
846 state.push(value2);
847 break;
848 }
849 case dadd:
850 case dsub:
851 case dmul:
852 case ddiv:
853 case dmod:
854 state.pop(2);
855 break;
856 case ret:
857 markDead();
858 break;
859 case wide:
860 // must be handled by the caller.
861 return;
862 case monitorenter:
863 case monitorexit:
864 state.pop(1);
865 break;
867 default:
868 throw new AssertionError(mnem(op));
869 }
870 postop();
871 }
873 /** Emit an opcode with a one-byte operand field.
874 */
875 public void emitop1(int op, int od) {
876 emitop(op);
877 if (!alive) return;
878 emit1(od);
879 switch (op) {
880 case bipush:
881 state.push(syms.intType);
882 break;
883 case ldc1:
884 state.push(typeForPool(pool.pool[od]));
885 break;
886 default:
887 throw new AssertionError(mnem(op));
888 }
889 postop();
890 }
892 /** The type of a constant pool entry. */
893 private Type typeForPool(Object o) {
894 if (o instanceof Integer) return syms.intType;
895 if (o instanceof Float) return syms.floatType;
896 if (o instanceof String) return syms.stringType;
897 if (o instanceof Long) return syms.longType;
898 if (o instanceof Double) return syms.doubleType;
899 if (o instanceof ClassSymbol) return syms.classType;
900 if (o instanceof Type.ArrayType) return syms.classType;
901 throw new AssertionError(o);
902 }
904 /** Emit an opcode with a one-byte operand field;
905 * widen if field does not fit in a byte.
906 */
907 public void emitop1w(int op, int od) {
908 if (od > 0xFF) {
909 emitop(wide);
910 emitop(op);
911 emit2(od);
912 } else {
913 emitop(op);
914 emit1(od);
915 }
916 if (!alive) return;
917 switch (op) {
918 case iload:
919 state.push(syms.intType);
920 break;
921 case lload:
922 state.push(syms.longType);
923 break;
924 case fload:
925 state.push(syms.floatType);
926 break;
927 case dload:
928 state.push(syms.doubleType);
929 break;
930 case aload:
931 state.push(lvar[od].sym.type);
932 break;
933 case lstore:
934 case dstore:
935 state.pop(2);
936 break;
937 case istore:
938 case fstore:
939 case astore:
940 state.pop(1);
941 break;
942 case ret:
943 markDead();
944 break;
945 default:
946 throw new AssertionError(mnem(op));
947 }
948 postop();
949 }
951 /** Emit an opcode with two one-byte operand fields;
952 * widen if either field does not fit in a byte.
953 */
954 public void emitop1w(int op, int od1, int od2) {
955 if (od1 > 0xFF || od2 < -128 || od2 > 127) {
956 emitop(wide);
957 emitop(op);
958 emit2(od1);
959 emit2(od2);
960 } else {
961 emitop(op);
962 emit1(od1);
963 emit1(od2);
964 }
965 if (!alive) return;
966 switch (op) {
967 case iinc:
968 break;
969 default:
970 throw new AssertionError(mnem(op));
971 }
972 }
974 /** Emit an opcode with a two-byte operand field.
975 */
976 public void emitop2(int op, int od) {
977 emitop(op);
978 if (!alive) return;
979 emit2(od);
980 switch (op) {
981 case getstatic:
982 state.push(((Symbol)(pool.pool[od])).erasure(types));
983 break;
984 case putstatic:
985 state.pop(((Symbol)(pool.pool[od])).erasure(types));
986 break;
987 case new_:
988 state.push(uninitializedObject(((Symbol)(pool.pool[od])).erasure(types), cp-3));
989 break;
990 case sipush:
991 state.push(syms.intType);
992 break;
993 case if_acmp_null:
994 case if_acmp_nonnull:
995 case ifeq:
996 case ifne:
997 case iflt:
998 case ifge:
999 case ifgt:
1000 case ifle:
1001 state.pop(1);
1002 break;
1003 case if_icmpeq:
1004 case if_icmpne:
1005 case if_icmplt:
1006 case if_icmpge:
1007 case if_icmpgt:
1008 case if_icmple:
1009 case if_acmpeq:
1010 case if_acmpne:
1011 state.pop(2);
1012 break;
1013 case goto_:
1014 markDead();
1015 break;
1016 case putfield:
1017 state.pop(((Symbol)(pool.pool[od])).erasure(types));
1018 state.pop(1); // object ref
1019 break;
1020 case getfield:
1021 state.pop(1); // object ref
1022 state.push(((Symbol)(pool.pool[od])).erasure(types));
1023 break;
1024 case checkcast: {
1025 state.pop(1); // object ref
1026 Object o = pool.pool[od];
1027 Type t = (o instanceof Symbol)
1028 ? ((Symbol)o).erasure(types)
1029 : types.erasure(((Type)o));
1030 state.push(t);
1031 break; }
1032 case ldc2w:
1033 state.push(typeForPool(pool.pool[od]));
1034 break;
1035 case instanceof_:
1036 state.pop(1);
1037 state.push(syms.intType);
1038 break;
1039 case ldc2:
1040 state.push(typeForPool(pool.pool[od]));
1041 break;
1042 case jsr:
1043 break;
1044 default:
1045 throw new AssertionError(mnem(op));
1046 }
1047 // postop();
1048 }
1050 /** Emit an opcode with a four-byte operand field.
1051 */
1052 public void emitop4(int op, int od) {
1053 emitop(op);
1054 if (!alive) return;
1055 emit4(od);
1056 switch (op) {
1057 case goto_w:
1058 markDead();
1059 break;
1060 case jsr_w:
1061 break;
1062 default:
1063 throw new AssertionError(mnem(op));
1064 }
1065 // postop();
1066 }
1068 /** Align code pointer to next `incr' boundary.
1069 */
1070 public void align(int incr) {
1071 if (alive)
1072 while (cp % incr != 0) emitop0(nop);
1073 }
1075 /** Place a byte into code at address pc. Pre: pc + 1 <= cp.
1076 */
1077 private void put1(int pc, int op) {
1078 code[pc] = (byte)op;
1079 }
1081 /** Place two bytes into code at address pc. Pre: pc + 2 <= cp.
1082 */
1083 private void put2(int pc, int od) {
1084 // pre: pc + 2 <= cp
1085 put1(pc, od >> 8);
1086 put1(pc+1, od);
1087 }
1089 /** Place four bytes into code at address pc. Pre: pc + 4 <= cp.
1090 */
1091 public void put4(int pc, int od) {
1092 // pre: pc + 4 <= cp
1093 put1(pc , od >> 24);
1094 put1(pc+1, od >> 16);
1095 put1(pc+2, od >> 8);
1096 put1(pc+3, od);
1097 }
1099 /** Return code byte at position pc as an unsigned int.
1100 */
1101 private int get1(int pc) {
1102 return code[pc] & 0xFF;
1103 }
1105 /** Return two code bytes at position pc as an unsigned int.
1106 */
1107 private int get2(int pc) {
1108 return (get1(pc) << 8) | get1(pc+1);
1109 }
1111 /** Return four code bytes at position pc as an int.
1112 */
1113 public int get4(int pc) {
1114 // pre: pc + 4 <= cp
1115 return
1116 (get1(pc) << 24) |
1117 (get1(pc+1) << 16) |
1118 (get1(pc+2) << 8) |
1119 (get1(pc+3));
1120 }
1122 /** Is code generation currently enabled?
1123 */
1124 public boolean isAlive() {
1125 return alive || pendingJumps != null;
1126 }
1128 /** Switch code generation on/off.
1129 */
1130 public void markDead() {
1131 alive = false;
1132 }
1134 /** Declare an entry point; return current code pointer
1135 */
1136 public int entryPoint() {
1137 int pc = curPc();
1138 alive = true;
1139 pendingStackMap = needStackMap;
1140 return pc;
1141 }
1143 /** Declare an entry point with initial state;
1144 * return current code pointer
1145 */
1146 public int entryPoint(State state) {
1147 int pc = curPc();
1148 alive = true;
1149 this.state = state.dup();
1150 assert state.stacksize <= max_stack;
1151 if (debugCode) System.err.println("entry point " + state);
1152 pendingStackMap = needStackMap;
1153 return pc;
1154 }
1156 /** Declare an entry point with initial state plus a pushed value;
1157 * return current code pointer
1158 */
1159 public int entryPoint(State state, Type pushed) {
1160 int pc = curPc();
1161 alive = true;
1162 this.state = state.dup();
1163 assert state.stacksize <= max_stack;
1164 this.state.push(pushed);
1165 if (debugCode) System.err.println("entry point " + state);
1166 pendingStackMap = needStackMap;
1167 return pc;
1168 }
1171 /**************************************************************************
1172 * Stack map generation
1173 *************************************************************************/
1175 /** An entry in the stack map. */
1176 static class StackMapFrame {
1177 int pc;
1178 Type[] locals;
1179 Type[] stack;
1180 }
1182 /** A buffer of cldc stack map entries. */
1183 StackMapFrame[] stackMapBuffer = null;
1185 /** A buffer of compressed StackMapTable entries. */
1186 StackMapTableFrame[] stackMapTableBuffer = null;
1187 int stackMapBufferSize = 0;
1189 /** The last PC at which we generated a stack map. */
1190 int lastStackMapPC = -1;
1192 /** The last stack map frame in StackMapTable. */
1193 StackMapFrame lastFrame = null;
1195 /** The stack map frame before the last one. */
1196 StackMapFrame frameBeforeLast = null;
1198 /** Emit a stack map entry. */
1199 public void emitStackMap() {
1200 int pc = curPc();
1201 if (!needStackMap) return;
1205 switch (stackMap) {
1206 case CLDC:
1207 emitCLDCStackMap(pc, getLocalsSize());
1208 break;
1209 case JSR202:
1210 emitStackMapFrame(pc, getLocalsSize());
1211 break;
1212 default:
1213 throw new AssertionError("Should have chosen a stackmap format");
1214 }
1215 // DEBUG code follows
1216 if (debugCode) state.dump(pc);
1217 }
1219 private int getLocalsSize() {
1220 int nextLocal = 0;
1221 for (int i=max_locals-1; i>=0; i--) {
1222 if (state.defined.isMember(i) && lvar[i] != null) {
1223 nextLocal = i + width(lvar[i].sym.erasure(types));
1224 break;
1225 }
1226 }
1227 return nextLocal;
1228 }
1230 /** Emit a CLDC stack map frame. */
1231 void emitCLDCStackMap(int pc, int localsSize) {
1232 if (lastStackMapPC == pc) {
1233 // drop existing stackmap at this offset
1234 stackMapBuffer[--stackMapBufferSize] = null;
1235 }
1236 lastStackMapPC = pc;
1238 if (stackMapBuffer == null) {
1239 stackMapBuffer = new StackMapFrame[20];
1240 } else if (stackMapBuffer.length == stackMapBufferSize) {
1241 StackMapFrame[] newStackMapBuffer =
1242 new StackMapFrame[stackMapBufferSize << 1];
1243 System.arraycopy(stackMapBuffer, 0, newStackMapBuffer,
1244 0, stackMapBufferSize);
1245 stackMapBuffer = newStackMapBuffer;
1246 }
1247 StackMapFrame frame =
1248 stackMapBuffer[stackMapBufferSize++] = new StackMapFrame();
1249 frame.pc = pc;
1251 frame.locals = new Type[localsSize];
1252 for (int i=0; i<localsSize; i++) {
1253 if (state.defined.isMember(i) && lvar[i] != null) {
1254 Type vtype = lvar[i].sym.type;
1255 if (!(vtype instanceof UninitializedType))
1256 vtype = types.erasure(vtype);
1257 frame.locals[i] = vtype;
1258 }
1259 }
1260 frame.stack = new Type[state.stacksize];
1261 for (int i=0; i<state.stacksize; i++)
1262 frame.stack[i] = state.stack[i];
1263 }
1265 void emitStackMapFrame(int pc, int localsSize) {
1266 if (lastFrame == null) {
1267 // first frame
1268 lastFrame = getInitialFrame();
1269 } else if (lastFrame.pc == pc) {
1270 // drop existing stackmap at this offset
1271 stackMapTableBuffer[--stackMapBufferSize] = null;
1272 lastFrame = frameBeforeLast;
1273 frameBeforeLast = null;
1274 }
1276 StackMapFrame frame = new StackMapFrame();
1277 frame.pc = pc;
1279 int localCount = 0;
1280 Type[] locals = new Type[localsSize];
1281 for (int i=0; i<localsSize; i++, localCount++) {
1282 if (state.defined.isMember(i) && lvar[i] != null) {
1283 Type vtype = lvar[i].sym.type;
1284 if (!(vtype instanceof UninitializedType))
1285 vtype = types.erasure(vtype);
1286 locals[i] = vtype;
1287 if (width(vtype) > 1) i++;
1288 }
1289 }
1290 frame.locals = new Type[localCount];
1291 for (int i=0, j=0; i<localsSize; i++, j++) {
1292 assert(j < localCount);
1293 frame.locals[j] = locals[i];
1294 if (width(locals[i]) > 1) i++;
1295 }
1297 int stackCount = 0;
1298 for (int i=0; i<state.stacksize; i++) {
1299 if (state.stack[i] != null) {
1300 stackCount++;
1301 }
1302 }
1303 frame.stack = new Type[stackCount];
1304 stackCount = 0;
1305 for (int i=0; i<state.stacksize; i++) {
1306 if (state.stack[i] != null) {
1307 frame.stack[stackCount++] = state.stack[i];
1308 }
1309 }
1311 if (stackMapTableBuffer == null) {
1312 stackMapTableBuffer = new StackMapTableFrame[20];
1313 } else if (stackMapTableBuffer.length == stackMapBufferSize) {
1314 StackMapTableFrame[] newStackMapTableBuffer =
1315 new StackMapTableFrame[stackMapBufferSize << 1];
1316 System.arraycopy(stackMapTableBuffer, 0, newStackMapTableBuffer,
1317 0, stackMapBufferSize);
1318 stackMapTableBuffer = newStackMapTableBuffer;
1319 }
1320 stackMapTableBuffer[stackMapBufferSize++] =
1321 StackMapTableFrame.getInstance(frame, lastFrame.pc, lastFrame.locals, types);
1323 frameBeforeLast = lastFrame;
1324 lastFrame = frame;
1325 }
1327 StackMapFrame getInitialFrame() {
1328 StackMapFrame frame = new StackMapFrame();
1329 List<Type> arg_types = ((MethodType)meth.externalType(types)).argtypes;
1330 int len = arg_types.length();
1331 int count = 0;
1332 if (!meth.isStatic()) {
1333 Type thisType = meth.owner.type;
1334 frame.locals = new Type[len+1];
1335 if (meth.isConstructor() && thisType != syms.objectType) {
1336 frame.locals[count++] = UninitializedType.uninitializedThis(thisType);
1337 } else {
1338 frame.locals[count++] = types.erasure(thisType);
1339 }
1340 } else {
1341 frame.locals = new Type[len];
1342 }
1343 for (Type arg_type : arg_types) {
1344 frame.locals[count++] = types.erasure(arg_type);
1345 }
1346 frame.pc = -1;
1347 frame.stack = null;
1348 return frame;
1349 }
1352 /**************************************************************************
1353 * Operations having to do with jumps
1354 *************************************************************************/
1356 /** A chain represents a list of unresolved jumps. Jump locations
1357 * are sorted in decreasing order.
1358 */
1359 public static class Chain {
1361 /** The position of the jump instruction.
1362 */
1363 public final int pc;
1365 /** The machine state after the jump instruction.
1366 * Invariant: all elements of a chain list have the same stacksize
1367 * and compatible stack and register contents.
1368 */
1369 Code.State state;
1371 /** The next jump in the list.
1372 */
1373 public final Chain next;
1375 /** Construct a chain from its jump position, stacksize, previous
1376 * chain, and machine state.
1377 */
1378 public Chain(int pc, Chain next, Code.State state) {
1379 this.pc = pc;
1380 this.next = next;
1381 this.state = state;
1382 }
1383 }
1385 /** Negate a branch opcode.
1386 */
1387 public static int negate(int opcode) {
1388 if (opcode == if_acmp_null) return if_acmp_nonnull;
1389 else if (opcode == if_acmp_nonnull) return if_acmp_null;
1390 else return ((opcode + 1) ^ 1) - 1;
1391 }
1393 /** Emit a jump instruction.
1394 * Return code pointer of instruction to be patched.
1395 */
1396 public int emitJump(int opcode) {
1397 if (fatcode) {
1398 if (opcode == goto_ || opcode == jsr) {
1399 emitop4(opcode + goto_w - goto_, 0);
1400 } else {
1401 emitop2(negate(opcode), 8);
1402 emitop4(goto_w, 0);
1403 alive = true;
1404 pendingStackMap = needStackMap;
1405 }
1406 return cp - 5;
1407 } else {
1408 emitop2(opcode, 0);
1409 return cp - 3;
1410 }
1411 }
1413 /** Emit a branch with given opcode; return its chain.
1414 * branch differs from jump in that jsr is treated as no-op.
1415 */
1416 public Chain branch(int opcode) {
1417 Chain result = null;
1418 if (opcode == goto_) {
1419 result = pendingJumps;
1420 pendingJumps = null;
1421 }
1422 if (opcode != dontgoto && isAlive()) {
1423 result = new Chain(emitJump(opcode),
1424 result,
1425 state.dup());
1426 fixedPc = fatcode;
1427 if (opcode == goto_) alive = false;
1428 }
1429 return result;
1430 }
1432 /** Resolve chain to point to given target.
1433 */
1434 public void resolve(Chain chain, int target) {
1435 boolean changed = false;
1436 State newState = state;
1437 for (; chain != null; chain = chain.next) {
1438 assert state != chain.state;
1439 assert target > chain.pc || state.stacksize == 0;
1440 if (target >= cp) {
1441 target = cp;
1442 } else if (get1(target) == goto_) {
1443 if (fatcode) target = target + get4(target + 1);
1444 else target = target + get2(target + 1);
1445 }
1446 if (get1(chain.pc) == goto_ &&
1447 chain.pc + 3 == target && target == cp && !fixedPc) {
1448 // If goto the next instruction, the jump is not needed:
1449 // compact the code.
1450 cp = cp - 3;
1451 target = target - 3;
1452 if (chain.next == null) {
1453 // This is the only jump to the target. Exit the loop
1454 // without setting new state. The code is reachable
1455 // from the instruction before goto_.
1456 alive = true;
1457 break;
1458 }
1459 } else {
1460 if (fatcode)
1461 put4(chain.pc + 1, target - chain.pc);
1462 else if (target - chain.pc < Short.MIN_VALUE ||
1463 target - chain.pc > Short.MAX_VALUE)
1464 fatcode = true;
1465 else
1466 put2(chain.pc + 1, target - chain.pc);
1467 assert !alive ||
1468 chain.state.stacksize == newState.stacksize &&
1469 chain.state.nlocks == newState.nlocks;
1470 }
1471 fixedPc = true;
1472 if (cp == target) {
1473 changed = true;
1474 if (debugCode)
1475 System.err.println("resolving chain state=" + chain.state);
1476 if (alive) {
1477 newState = chain.state.join(newState);
1478 } else {
1479 newState = chain.state;
1480 alive = true;
1481 }
1482 }
1483 }
1484 assert !changed || state != newState;
1485 if (state != newState) {
1486 setDefined(newState.defined);
1487 state = newState;
1488 pendingStackMap = needStackMap;
1489 }
1490 }
1492 /** Resolve chain to point to current code pointer.
1493 */
1494 public void resolve(Chain chain) {
1495 assert
1496 !alive ||
1497 chain==null ||
1498 state.stacksize == chain.state.stacksize &&
1499 state.nlocks == chain.state.nlocks;
1500 pendingJumps = mergeChains(chain, pendingJumps);
1501 }
1503 /** Resolve any pending jumps.
1504 */
1505 public void resolvePending() {
1506 Chain x = pendingJumps;
1507 pendingJumps = null;
1508 resolve(x, cp);
1509 }
1511 /** Merge the jumps in of two chains into one.
1512 */
1513 public static Chain mergeChains(Chain chain1, Chain chain2) {
1514 // recursive merge sort
1515 if (chain2 == null) return chain1;
1516 if (chain1 == null) return chain2;
1517 assert
1518 chain1.state.stacksize == chain2.state.stacksize &&
1519 chain1.state.nlocks == chain2.state.nlocks;
1520 if (chain1.pc < chain2.pc)
1521 return new Chain(
1522 chain2.pc,
1523 mergeChains(chain1, chain2.next),
1524 chain2.state);
1525 return new Chain(
1526 chain1.pc,
1527 mergeChains(chain1.next, chain2),
1528 chain1.state);
1529 }
1532 /* **************************************************************************
1533 * Catch clauses
1534 ****************************************************************************/
1536 /** Add a catch clause to code.
1537 */
1538 public void addCatch(
1539 char startPc, char endPc, char handlerPc, char catchType) {
1540 catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
1541 }
1544 /* **************************************************************************
1545 * Line numbers
1546 ****************************************************************************/
1548 /** Add a line number entry.
1549 */
1550 public void addLineNumber(char startPc, char lineNumber) {
1551 if (lineDebugInfo) {
1552 if (lineInfo.nonEmpty() && lineInfo.head[0] == startPc)
1553 lineInfo = lineInfo.tail;
1554 if (lineInfo.isEmpty() || lineInfo.head[1] != lineNumber)
1555 lineInfo = lineInfo.prepend(new char[]{startPc, lineNumber});
1556 }
1557 }
1559 /** Mark beginning of statement.
1560 */
1561 public void statBegin(int pos) {
1562 if (pos != Position.NOPOS) {
1563 pendingStatPos = pos;
1564 }
1565 }
1567 /** Force stat begin eagerly
1568 */
1569 public void markStatBegin() {
1570 if (alive && lineDebugInfo) {
1571 int line = lineMap.getLineNumber(pendingStatPos);
1572 char cp1 = (char)cp;
1573 char line1 = (char)line;
1574 if (cp1 == cp && line1 == line)
1575 addLineNumber(cp1, line1);
1576 }
1577 pendingStatPos = Position.NOPOS;
1578 }
1581 /* **************************************************************************
1582 * Simulated VM machine state
1583 ****************************************************************************/
1585 class State implements Cloneable {
1586 /** The set of registers containing values. */
1587 Bits defined;
1589 /** The (types of the) contents of the machine stack. */
1590 Type[] stack;
1592 /** The first stack position currently unused. */
1593 int stacksize;
1595 /** The numbers of registers containing locked monitors. */
1596 int[] locks;
1597 int nlocks;
1599 State() {
1600 defined = new Bits();
1601 stack = new Type[16];
1602 }
1604 State dup() {
1605 try {
1606 State state = (State)super.clone();
1607 state.defined = defined.dup();
1608 state.stack = stack.clone();
1609 if (locks != null) state.locks = locks.clone();
1610 if (debugCode) {
1611 System.err.println("duping state " + this);
1612 dump();
1613 }
1614 return state;
1615 } catch (CloneNotSupportedException ex) {
1616 throw new AssertionError(ex);
1617 }
1618 }
1620 void lock(int register) {
1621 if (locks == null) {
1622 locks = new int[20];
1623 } else if (locks.length == nlocks) {
1624 int[] newLocks = new int[locks.length << 1];
1625 System.arraycopy(locks, 0, newLocks, 0, locks.length);
1626 locks = newLocks;
1627 }
1628 locks[nlocks] = register;
1629 nlocks++;
1630 }
1632 void unlock(int register) {
1633 nlocks--;
1634 assert locks[nlocks] == register;
1635 locks[nlocks] = -1;
1636 }
1638 void push(Type t) {
1639 if (debugCode) System.err.println(" pushing " + t);
1640 switch (t.tag) {
1641 case TypeTags.VOID:
1642 return;
1643 case TypeTags.BYTE:
1644 case TypeTags.CHAR:
1645 case TypeTags.SHORT:
1646 case TypeTags.BOOLEAN:
1647 t = syms.intType;
1648 break;
1649 default:
1650 break;
1651 }
1652 if (stacksize+2 >= stack.length) {
1653 Type[] newstack = new Type[2*stack.length];
1654 System.arraycopy(stack, 0, newstack, 0, stack.length);
1655 stack = newstack;
1656 }
1657 stack[stacksize++] = t;
1658 switch (width(t)) {
1659 case 1:
1660 break;
1661 case 2:
1662 stack[stacksize++] = null;
1663 break;
1664 default:
1665 throw new AssertionError(t);
1666 }
1667 if (stacksize > max_stack)
1668 max_stack = stacksize;
1669 }
1671 Type pop1() {
1672 if (debugCode) System.err.println(" popping " + 1);
1673 stacksize--;
1674 Type result = stack[stacksize];
1675 stack[stacksize] = null;
1676 assert result != null && width(result) == 1;
1677 return result;
1678 }
1680 Type peek() {
1681 return stack[stacksize-1];
1682 }
1684 Type pop2() {
1685 if (debugCode) System.err.println(" popping " + 2);
1686 stacksize -= 2;
1687 Type result = stack[stacksize];
1688 stack[stacksize] = null;
1689 assert stack[stacksize+1] == null;
1690 assert result != null && width(result) == 2;
1691 return result;
1692 }
1694 void pop(int n) {
1695 if (debugCode) System.err.println(" popping " + n);
1696 while (n > 0) {
1697 stack[--stacksize] = null;
1698 n--;
1699 }
1700 }
1702 void pop(Type t) {
1703 pop(width(t));
1704 }
1706 /** Force the top of the stack to be treated as this supertype
1707 * of its current type. */
1708 void forceStackTop(Type t) {
1709 if (!alive) return;
1710 switch (t.tag) {
1711 case CLASS:
1712 case ARRAY:
1713 int width = width(t);
1714 Type old = stack[stacksize-width];
1715 assert types.isSubtype(types.erasure(old),
1716 types.erasure(t));
1717 stack[stacksize-width] = t;
1718 break;
1719 default:
1720 }
1721 }
1723 void markInitialized(UninitializedType old) {
1724 Type newtype = old.initializedType();
1725 for (int i=0; i<stacksize; i++)
1726 if (stack[i] == old) stack[i] = newtype;
1727 for (int i=0; i<lvar.length; i++) {
1728 LocalVar lv = lvar[i];
1729 if (lv != null && lv.sym.type == old) {
1730 VarSymbol sym = lv.sym;
1731 sym = sym.clone(sym.owner);
1732 sym.type = newtype;
1733 LocalVar newlv = lvar[i] = new LocalVar(sym);
1734 // should the following be initialized to cp?
1735 newlv.start_pc = lv.start_pc;
1736 }
1737 }
1738 }
1740 State join(State other) {
1741 defined = defined.andSet(other.defined);
1742 assert stacksize == other.stacksize;
1743 assert nlocks == other.nlocks;
1744 for (int i=0; i<stacksize; ) {
1745 Type t = stack[i];
1746 Type tother = other.stack[i];
1747 Type result =
1748 t==tother ? t :
1749 types.isSubtype(t, tother) ? tother :
1750 types.isSubtype(tother, t) ? t :
1751 error();
1752 int w = width(result);
1753 stack[i] = result;
1754 if (w == 2) assert stack[i+1] == null;
1755 i += w;
1756 }
1757 return this;
1758 }
1760 Type error() {
1761 throw new AssertionError("inconsistent stack types at join point");
1762 }
1764 void dump() {
1765 dump(-1);
1766 }
1768 void dump(int pc) {
1769 System.err.print("stackMap for " + meth.owner + "." + meth);
1770 if (pc == -1)
1771 System.out.println();
1772 else
1773 System.out.println(" at " + pc);
1774 System.err.println(" stack (from bottom):");
1775 for (int i=0; i<stacksize; i++)
1776 System.err.println(" " + i + ": " + stack[i]);
1778 int lastLocal = 0;
1779 for (int i=max_locals-1; i>=0; i--) {
1780 if (defined.isMember(i)) {
1781 lastLocal = i;
1782 break;
1783 }
1784 }
1785 if (lastLocal >= 0)
1786 System.err.println(" locals:");
1787 for (int i=0; i<=lastLocal; i++) {
1788 System.err.print(" " + i + ": ");
1789 if (defined.isMember(i)) {
1790 LocalVar var = lvar[i];
1791 if (var == null) {
1792 System.err.println("(none)");
1793 } else if (var.sym == null)
1794 System.err.println("UNKNOWN!");
1795 else
1796 System.err.println("" + var.sym + " of type " +
1797 var.sym.erasure(types));
1798 } else {
1799 System.err.println("undefined");
1800 }
1801 }
1802 if (nlocks != 0) {
1803 System.err.print(" locks:");
1804 for (int i=0; i<nlocks; i++) {
1805 System.err.print(" " + locks[i]);
1806 }
1807 System.err.println();
1808 }
1809 }
1810 }
1812 static Type jsrReturnValue = new Type(TypeTags.INT, null);
1815 /* **************************************************************************
1816 * Local variables
1817 ****************************************************************************/
1819 /** A live range of a local variable. */
1820 static class LocalVar {
1821 final VarSymbol sym;
1822 final char reg;
1823 char start_pc = Character.MAX_VALUE;
1824 char length = Character.MAX_VALUE;
1825 LocalVar(VarSymbol v) {
1826 this.sym = v;
1827 this.reg = (char)v.adr;
1828 }
1829 public LocalVar dup() {
1830 return new LocalVar(sym);
1831 }
1832 public String toString() {
1833 return "" + sym + " in register " + ((int)reg) + " starts at pc=" + ((int)start_pc) + " length=" + ((int)length);
1834 }
1835 };
1837 /** Local variables, indexed by register. */
1838 LocalVar[] lvar;
1840 /** Add a new local variable. */
1841 private void addLocalVar(VarSymbol v) {
1842 int adr = v.adr;
1843 if (adr+1 >= lvar.length) {
1844 int newlength = lvar.length << 1;
1845 if (newlength <= adr) newlength = adr + 10;
1846 LocalVar[] new_lvar = new LocalVar[newlength];
1847 System.arraycopy(lvar, 0, new_lvar, 0, lvar.length);
1848 lvar = new_lvar;
1849 }
1850 assert lvar[adr] == null;
1851 if (pendingJumps != null) resolvePending();
1852 lvar[adr] = new LocalVar(v);
1853 state.defined.excl(adr);
1854 }
1856 /** Set the current variable defined state. */
1857 public void setDefined(Bits newDefined) {
1858 if (alive && newDefined != state.defined) {
1859 Bits diff = state.defined.dup().xorSet(newDefined);
1860 for (int adr = diff.nextBit(0);
1861 adr >= 0;
1862 adr = diff.nextBit(adr+1)) {
1863 if (adr >= nextreg)
1864 state.defined.excl(adr);
1865 else if (state.defined.isMember(adr))
1866 setUndefined(adr);
1867 else
1868 setDefined(adr);
1869 }
1870 }
1871 }
1873 /** Mark a register as being (possibly) defined. */
1874 public void setDefined(int adr) {
1875 LocalVar v = lvar[adr];
1876 if (v == null) {
1877 state.defined.excl(adr);
1878 } else {
1879 state.defined.incl(adr);
1880 if (cp < Character.MAX_VALUE) {
1881 if (v.start_pc == Character.MAX_VALUE)
1882 v.start_pc = (char)cp;
1883 }
1884 }
1885 }
1887 /** Mark a register as being undefined. */
1888 public void setUndefined(int adr) {
1889 state.defined.excl(adr);
1890 if (adr < lvar.length &&
1891 lvar[adr] != null &&
1892 lvar[adr].start_pc != Character.MAX_VALUE) {
1893 LocalVar v = lvar[adr];
1894 char length = (char)(curPc() - v.start_pc);
1895 if (length > 0 && length < Character.MAX_VALUE) {
1896 lvar[adr] = v.dup();
1897 v.length = length;
1898 putVar(v);
1899 } else {
1900 v.start_pc = Character.MAX_VALUE;
1901 }
1902 }
1903 }
1905 /** End the scope of a variable. */
1906 private void endScope(int adr) {
1907 LocalVar v = lvar[adr];
1908 if (v != null) {
1909 lvar[adr] = null;
1910 if (v.start_pc != Character.MAX_VALUE) {
1911 char length = (char)(curPc() - v.start_pc);
1912 if (length < Character.MAX_VALUE) {
1913 v.length = length;
1914 putVar(v);
1915 fillLocalVarPosition(v);
1916 }
1917 }
1918 }
1919 state.defined.excl(adr);
1920 }
1922 private void fillLocalVarPosition(LocalVar lv) {
1923 if (lv == null || lv.sym == null
1924 || lv.sym.typeAnnotations == null)
1925 return;
1926 for (Attribute.TypeCompound ta : lv.sym.typeAnnotations) {
1927 TypeAnnotationPosition p = ta.position;
1928 while (p != null) {
1929 p.lvarOffset = new int[] { (int)lv.start_pc };
1930 p.lvarLength = new int[] { (int)lv.length };
1931 p.lvarIndex = new int[] { (int)lv.reg };
1932 p.isValidOffset = true;
1933 p = p.wildcard_position;
1934 }
1935 }
1936 }
1938 /** Put a live variable range into the buffer to be output to the
1939 * class file.
1940 */
1941 void putVar(LocalVar var) {
1942 if (!varDebugInfo) return;
1943 if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
1944 if (varBuffer == null)
1945 varBuffer = new LocalVar[20];
1946 else if (varBufferSize >= varBuffer.length) {
1947 LocalVar[] newVarBuffer = new LocalVar[varBufferSize*2];
1948 System.arraycopy(varBuffer, 0, newVarBuffer, 0, varBuffer.length);
1949 varBuffer = newVarBuffer;
1950 }
1951 varBuffer[varBufferSize++] = var;
1952 }
1954 /** Previously live local variables, to be put into the variable table. */
1955 LocalVar[] varBuffer;
1956 int varBufferSize;
1958 /** Create a new local variable address and return it.
1959 */
1960 private int newLocal(int typecode) {
1961 int reg = nextreg;
1962 int w = width(typecode);
1963 nextreg = reg + w;
1964 if (nextreg > max_locals) max_locals = nextreg;
1965 return reg;
1966 }
1968 private int newLocal(Type type) {
1969 return newLocal(typecode(type));
1970 }
1972 public int newLocal(VarSymbol v) {
1973 int reg = v.adr = newLocal(v.erasure(types));
1974 addLocalVar(v);
1975 return reg;
1976 }
1978 /** Start a set of fresh registers.
1979 */
1980 public void newRegSegment() {
1981 nextreg = max_locals;
1982 }
1984 /** End scopes of all variables with registers >= first.
1985 */
1986 public void endScopes(int first) {
1987 int prevNextReg = nextreg;
1988 nextreg = first;
1989 for (int i = nextreg; i < prevNextReg; i++) endScope(i);
1990 }
1992 /**************************************************************************
1993 * static tables
1994 *************************************************************************/
1996 public static String mnem(int opcode) {
1997 return Mneumonics.mnem[opcode];
1998 }
2000 private static class Mneumonics {
2001 private final static String[] mnem = new String[ByteCodeCount];
2002 static {
2003 mnem[nop] = "nop";
2004 mnem[aconst_null] = "aconst_null";
2005 mnem[iconst_m1] = "iconst_m1";
2006 mnem[iconst_0] = "iconst_0";
2007 mnem[iconst_1] = "iconst_1";
2008 mnem[iconst_2] = "iconst_2";
2009 mnem[iconst_3] = "iconst_3";
2010 mnem[iconst_4] = "iconst_4";
2011 mnem[iconst_5] = "iconst_5";
2012 mnem[lconst_0] = "lconst_0";
2013 mnem[lconst_1] = "lconst_1";
2014 mnem[fconst_0] = "fconst_0";
2015 mnem[fconst_1] = "fconst_1";
2016 mnem[fconst_2] = "fconst_2";
2017 mnem[dconst_0] = "dconst_0";
2018 mnem[dconst_1] = "dconst_1";
2019 mnem[bipush] = "bipush";
2020 mnem[sipush] = "sipush";
2021 mnem[ldc1] = "ldc1";
2022 mnem[ldc2] = "ldc2";
2023 mnem[ldc2w] = "ldc2w";
2024 mnem[iload] = "iload";
2025 mnem[lload] = "lload";
2026 mnem[fload] = "fload";
2027 mnem[dload] = "dload";
2028 mnem[aload] = "aload";
2029 mnem[iload_0] = "iload_0";
2030 mnem[lload_0] = "lload_0";
2031 mnem[fload_0] = "fload_0";
2032 mnem[dload_0] = "dload_0";
2033 mnem[aload_0] = "aload_0";
2034 mnem[iload_1] = "iload_1";
2035 mnem[lload_1] = "lload_1";
2036 mnem[fload_1] = "fload_1";
2037 mnem[dload_1] = "dload_1";
2038 mnem[aload_1] = "aload_1";
2039 mnem[iload_2] = "iload_2";
2040 mnem[lload_2] = "lload_2";
2041 mnem[fload_2] = "fload_2";
2042 mnem[dload_2] = "dload_2";
2043 mnem[aload_2] = "aload_2";
2044 mnem[iload_3] = "iload_3";
2045 mnem[lload_3] = "lload_3";
2046 mnem[fload_3] = "fload_3";
2047 mnem[dload_3] = "dload_3";
2048 mnem[aload_3] = "aload_3";
2049 mnem[iaload] = "iaload";
2050 mnem[laload] = "laload";
2051 mnem[faload] = "faload";
2052 mnem[daload] = "daload";
2053 mnem[aaload] = "aaload";
2054 mnem[baload] = "baload";
2055 mnem[caload] = "caload";
2056 mnem[saload] = "saload";
2057 mnem[istore] = "istore";
2058 mnem[lstore] = "lstore";
2059 mnem[fstore] = "fstore";
2060 mnem[dstore] = "dstore";
2061 mnem[astore] = "astore";
2062 mnem[istore_0] = "istore_0";
2063 mnem[lstore_0] = "lstore_0";
2064 mnem[fstore_0] = "fstore_0";
2065 mnem[dstore_0] = "dstore_0";
2066 mnem[astore_0] = "astore_0";
2067 mnem[istore_1] = "istore_1";
2068 mnem[lstore_1] = "lstore_1";
2069 mnem[fstore_1] = "fstore_1";
2070 mnem[dstore_1] = "dstore_1";
2071 mnem[astore_1] = "astore_1";
2072 mnem[istore_2] = "istore_2";
2073 mnem[lstore_2] = "lstore_2";
2074 mnem[fstore_2] = "fstore_2";
2075 mnem[dstore_2] = "dstore_2";
2076 mnem[astore_2] = "astore_2";
2077 mnem[istore_3] = "istore_3";
2078 mnem[lstore_3] = "lstore_3";
2079 mnem[fstore_3] = "fstore_3";
2080 mnem[dstore_3] = "dstore_3";
2081 mnem[astore_3] = "astore_3";
2082 mnem[iastore] = "iastore";
2083 mnem[lastore] = "lastore";
2084 mnem[fastore] = "fastore";
2085 mnem[dastore] = "dastore";
2086 mnem[aastore] = "aastore";
2087 mnem[bastore] = "bastore";
2088 mnem[castore] = "castore";
2089 mnem[sastore] = "sastore";
2090 mnem[pop] = "pop";
2091 mnem[pop2] = "pop2";
2092 mnem[dup] = "dup";
2093 mnem[dup_x1] = "dup_x1";
2094 mnem[dup_x2] = "dup_x2";
2095 mnem[dup2] = "dup2";
2096 mnem[dup2_x1] = "dup2_x1";
2097 mnem[dup2_x2] = "dup2_x2";
2098 mnem[swap] = "swap";
2099 mnem[iadd] = "iadd";
2100 mnem[ladd] = "ladd";
2101 mnem[fadd] = "fadd";
2102 mnem[dadd] = "dadd";
2103 mnem[isub] = "isub";
2104 mnem[lsub] = "lsub";
2105 mnem[fsub] = "fsub";
2106 mnem[dsub] = "dsub";
2107 mnem[imul] = "imul";
2108 mnem[lmul] = "lmul";
2109 mnem[fmul] = "fmul";
2110 mnem[dmul] = "dmul";
2111 mnem[idiv] = "idiv";
2112 mnem[ldiv] = "ldiv";
2113 mnem[fdiv] = "fdiv";
2114 mnem[ddiv] = "ddiv";
2115 mnem[imod] = "imod";
2116 mnem[lmod] = "lmod";
2117 mnem[fmod] = "fmod";
2118 mnem[dmod] = "dmod";
2119 mnem[ineg] = "ineg";
2120 mnem[lneg] = "lneg";
2121 mnem[fneg] = "fneg";
2122 mnem[dneg] = "dneg";
2123 mnem[ishl] = "ishl";
2124 mnem[lshl] = "lshl";
2125 mnem[ishr] = "ishr";
2126 mnem[lshr] = "lshr";
2127 mnem[iushr] = "iushr";
2128 mnem[lushr] = "lushr";
2129 mnem[iand] = "iand";
2130 mnem[land] = "land";
2131 mnem[ior] = "ior";
2132 mnem[lor] = "lor";
2133 mnem[ixor] = "ixor";
2134 mnem[lxor] = "lxor";
2135 mnem[iinc] = "iinc";
2136 mnem[i2l] = "i2l";
2137 mnem[i2f] = "i2f";
2138 mnem[i2d] = "i2d";
2139 mnem[l2i] = "l2i";
2140 mnem[l2f] = "l2f";
2141 mnem[l2d] = "l2d";
2142 mnem[f2i] = "f2i";
2143 mnem[f2l] = "f2l";
2144 mnem[f2d] = "f2d";
2145 mnem[d2i] = "d2i";
2146 mnem[d2l] = "d2l";
2147 mnem[d2f] = "d2f";
2148 mnem[int2byte] = "int2byte";
2149 mnem[int2char] = "int2char";
2150 mnem[int2short] = "int2short";
2151 mnem[lcmp] = "lcmp";
2152 mnem[fcmpl] = "fcmpl";
2153 mnem[fcmpg] = "fcmpg";
2154 mnem[dcmpl] = "dcmpl";
2155 mnem[dcmpg] = "dcmpg";
2156 mnem[ifeq] = "ifeq";
2157 mnem[ifne] = "ifne";
2158 mnem[iflt] = "iflt";
2159 mnem[ifge] = "ifge";
2160 mnem[ifgt] = "ifgt";
2161 mnem[ifle] = "ifle";
2162 mnem[if_icmpeq] = "if_icmpeq";
2163 mnem[if_icmpne] = "if_icmpne";
2164 mnem[if_icmplt] = "if_icmplt";
2165 mnem[if_icmpge] = "if_icmpge";
2166 mnem[if_icmpgt] = "if_icmpgt";
2167 mnem[if_icmple] = "if_icmple";
2168 mnem[if_acmpeq] = "if_acmpeq";
2169 mnem[if_acmpne] = "if_acmpne";
2170 mnem[goto_] = "goto_";
2171 mnem[jsr] = "jsr";
2172 mnem[ret] = "ret";
2173 mnem[tableswitch] = "tableswitch";
2174 mnem[lookupswitch] = "lookupswitch";
2175 mnem[ireturn] = "ireturn";
2176 mnem[lreturn] = "lreturn";
2177 mnem[freturn] = "freturn";
2178 mnem[dreturn] = "dreturn";
2179 mnem[areturn] = "areturn";
2180 mnem[return_] = "return_";
2181 mnem[getstatic] = "getstatic";
2182 mnem[putstatic] = "putstatic";
2183 mnem[getfield] = "getfield";
2184 mnem[putfield] = "putfield";
2185 mnem[invokevirtual] = "invokevirtual";
2186 mnem[invokespecial] = "invokespecial";
2187 mnem[invokestatic] = "invokestatic";
2188 mnem[invokeinterface] = "invokeinterface";
2189 mnem[invokedynamic] = "invokedynamic";
2190 mnem[new_] = "new_";
2191 mnem[newarray] = "newarray";
2192 mnem[anewarray] = "anewarray";
2193 mnem[arraylength] = "arraylength";
2194 mnem[athrow] = "athrow";
2195 mnem[checkcast] = "checkcast";
2196 mnem[instanceof_] = "instanceof_";
2197 mnem[monitorenter] = "monitorenter";
2198 mnem[monitorexit] = "monitorexit";
2199 mnem[wide] = "wide";
2200 mnem[multianewarray] = "multianewarray";
2201 mnem[if_acmp_null] = "if_acmp_null";
2202 mnem[if_acmp_nonnull] = "if_acmp_nonnull";
2203 mnem[goto_w] = "goto_w";
2204 mnem[jsr_w] = "jsr_w";
2205 mnem[breakpoint] = "breakpoint";
2206 }
2207 }
2208 }