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