src/share/classes/jdk/internal/org/objectweb/asm/Frame.java

Print this page




  92      * This explains the rather complicated type format used in output frames.
  93      *
  94      * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
  95      * signed number of array dimensions (from -8 to 7). KIND is either BASE,
  96      * LOCAL or STACK. BASE is used for types that are not relative to the input
  97      * frame. LOCAL is used for types that are relative to the input local
  98      * variable types. STACK is used for types that are relative to the input
  99      * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
 100      * the input local variable types. For STACK types, it is a position
 101      * relatively to the top of input frame stack. For BASE types, it is either
 102      * one of the constants defined in FrameVisitor, or for OBJECT and
 103      * UNINITIALIZED types, a tag and an index in the type table.
 104      *
 105      * Output frames can contain types of any kind and with a positive or
 106      * negative dimension (and even unassigned types, represented by 0 - which
 107      * does not correspond to any valid type value). Input frames can only
 108      * contain BASE types of positive or null dimension. In all cases the type
 109      * table contains only internal type names (array type descriptors are
 110      * forbidden - dimensions must be represented through the DIM field).
 111      *
 112      * The LONG and DOUBLE types are always represented by using two slots (LONG +
 113      * TOP or DOUBLE + TOP), for local variable types as well as in the operand
 114      * stack. This is necessary to be able to simulate DUPx_y instructions,
 115      * whose effect would be dependent on the actual type values if types were
 116      * always represented by a single slot in the stack (and this is not
 117      * possible, since actual type values are not always known - cf LOCAL and
 118      * STACK type kinds).
 119      */
 120 
 121     /**
 122      * Mask to get the dimension of a frame type. This dimension is a signed
 123      * integer between -8 and 7.
 124      */
 125     static final int DIM = 0xF0000000;
 126 
 127     /**
 128      * Constant to be added to a type to get a type with one more dimension.
 129      */
 130     static final int ARRAY_OF = 0x10000000;
 131 
 132     /**
 133      * Constant to be added to a type to get a type with one less dimension.
 134      */
 135     static final int ELEMENT_OF = 0xF0000000;
 136 
 137     /**
 138      * Mask to get the kind of a frame type.
 139      *
 140      * @see #BASE
 141      * @see #LOCAL
 142      * @see #STACK
 143      */
 144     static final int KIND = 0xF000000;
 145 
 146     /**
 147      * Flag used for LOCAL and STACK types. Indicates that if this type happens
 148      * to be a long or double type (during the computations of input frames),
 149      * then it must be set to TOP because the second word of this value has
 150      * been reused to store other data in the basic block. Hence the first word
 151      * no longer stores a valid long or double value.
 152      */
 153     static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
 154 
 155     /**
 156      * Mask to get the value of a frame type.
 157      */
 158     static final int VALUE = 0x7FFFFF;
 159 
 160     /**
 161      * Mask to get the kind of base types.
 162      */
 163     static final int BASE_KIND = 0xFF00000;
 164 
 165     /**
 166      * Mask to get the value of base types.
 167      */
 168     static final int BASE_VALUE = 0xFFFFF;
 169 
 170     /**
 171      * Kind of the types that are not relative to an input stack map frame.


 535     private int initializationCount;
 536 
 537     /**
 538      * The types that are initialized in the basic block. A constructor
 539      * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
 540      * <i>every occurence</i> of this type in the local variables and in the
 541      * operand stack. This cannot be done during the first phase of the
 542      * algorithm since, during this phase, the local variables and the operand
 543      * stack are not completely computed. It is therefore necessary to store the
 544      * types on which constructors are invoked in the basic block, in order to
 545      * do this replacement during the second phase of the algorithm, where the
 546      * frames are fully computed. Note that this array can contain types that
 547      * are relative to input locals or to the input stack (see below for the
 548      * description of the algorithm).
 549      */
 550     private int[] initializations;
 551 
 552     /**
 553      * Returns the output frame local variable type at the given index.
 554      *
 555      * @param local the index of the local that must be returned.

 556      * @return the output frame local variable type at the given index.
 557      */
 558     private int get(final int local) {
 559         if (outputLocals == null || local >= outputLocals.length) {
 560             // this local has never been assigned in this basic block,
 561             // so it is still equal to its value in the input frame
 562             return LOCAL | local;
 563         } else {
 564             int type = outputLocals[local];
 565             if (type == 0) {
 566                 // this local has never been assigned in this basic block,
 567                 // so it is still equal to its value in the input frame
 568                 type = outputLocals[local] = LOCAL | local;
 569             }
 570             return type;
 571         }
 572     }
 573 
 574     /**
 575      * Sets the output frame local variable type at the given index.
 576      *
 577      * @param local the index of the local that must be set.
 578      * @param type the value of the local that must be set.


 579      */
 580     private void set(final int local, final int type) {
 581         // creates and/or resizes the output local variables array if necessary
 582         if (outputLocals == null) {
 583             outputLocals = new int[10];
 584         }
 585         int n = outputLocals.length;
 586         if (local >= n) {
 587             int[] t = new int[Math.max(local + 1, 2 * n)];
 588             System.arraycopy(outputLocals, 0, t, 0, n);
 589             outputLocals = t;
 590         }
 591         // sets the local variable
 592         outputLocals[local] = type;
 593     }
 594 
 595     /**
 596      * Pushes a new type onto the output frame stack.
 597      *
 598      * @param type the type that must be pushed.

 599      */
 600     private void push(final int type) {
 601         // creates and/or resizes the output stack array if necessary
 602         if (outputStack == null) {
 603             outputStack = new int[10];
 604         }
 605         int n = outputStack.length;
 606         if (outputStackTop >= n) {
 607             int[] t = new int[Math.max(outputStackTop + 1, 2 * n)];
 608             System.arraycopy(outputStack, 0, t, 0, n);
 609             outputStack = t;
 610         }
 611         // pushes the type on the output stack
 612         outputStack[outputStackTop++] = type;
 613         // updates the maximun height reached by the output stack, if needed
 614         int top = owner.inputStackTop + outputStackTop;
 615         if (top > owner.outputStackMax) {
 616             owner.outputStackMax = top;
 617         }
 618     }
 619 
 620     /**
 621      * Pushes a new type onto the output frame stack.
 622      *
 623      * @param cw the ClassWriter to which this label belongs.
 624      * @param desc the descriptor of the type to be pushed. Can also be a method
 625      *        descriptor (in this case this method pushes its return type onto
 626      *        the output frame stack).


 627      */
 628     private void push(final ClassWriter cw, final String desc) {
 629         int type = type(cw, desc);
 630         if (type != 0) {
 631             push(type);
 632             if (type == LONG || type == DOUBLE) {
 633                 push(TOP);
 634             }
 635         }
 636     }
 637 
 638     /**
 639      * Returns the int encoding of the given type.
 640      *
 641      * @param cw the ClassWriter to which this label belongs.
 642      * @param desc a type descriptor.


 643      * @return the int encoding of the given type.
 644      */
 645     private static int type(final ClassWriter cw, final String desc) {
 646         String t;
 647         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
 648         switch (desc.charAt(index)) {
 649             case 'V':
 650                 return 0;
 651             case 'Z':
 652             case 'C':
 653             case 'B':
 654             case 'S':
 655             case 'I':
 656                 return INTEGER;
 657             case 'F':
 658                 return FLOAT;
 659             case 'J':
 660                 return LONG;
 661             case 'D':
 662                 return DOUBLE;


 707         }
 708     }
 709 
 710     /**
 711      * Pops a type from the output frame stack and returns its value.
 712      *
 713      * @return the type that has been popped from the output frame stack.
 714      */
 715     private int pop() {
 716         if (outputStackTop > 0) {
 717             return outputStack[--outputStackTop];
 718         } else {
 719             // if the output frame stack is empty, pops from the input stack
 720             return STACK | -(--owner.inputStackTop);
 721         }
 722     }
 723 
 724     /**
 725      * Pops the given number of types from the output frame stack.
 726      *
 727      * @param elements the number of types that must be popped.

 728      */
 729     private void pop(final int elements) {
 730         if (outputStackTop >= elements) {
 731             outputStackTop -= elements;
 732         } else {
 733             // if the number of elements to be popped is greater than the number
 734             // of elements in the output stack, clear it, and pops the remaining
 735             // elements from the input stack.
 736             owner.inputStackTop -= elements - outputStackTop;
 737             outputStackTop = 0;
 738         }
 739     }
 740 
 741     /**
 742      * Pops a type from the output frame stack.
 743      *
 744      * @param desc the descriptor of the type to be popped. Can also be a method
 745      *        descriptor (in this case this method pops the types corresponding
 746      *        to the method arguments).

 747      */
 748     private void pop(final String desc) {
 749         char c = desc.charAt(0);
 750         if (c == '(') {
 751             pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
 752         } else if (c == 'J' || c == 'D') {
 753             pop(2);
 754         } else {
 755             pop(1);
 756         }
 757     }
 758 
 759     /**
 760      * Adds a new type to the list of types on which a constructor is invoked in
 761      * the basic block.
 762      *
 763      * @param var a type on a which a constructor is invoked.

 764      */
 765     private void init(final int var) {
 766         // creates and/or resizes the initializations array if necessary
 767         if (initializations == null) {
 768             initializations = new int[2];
 769         }
 770         int n = initializations.length;
 771         if (initializationCount >= n) {
 772             int[] t = new int[Math.max(initializationCount + 1, 2 * n)];
 773             System.arraycopy(initializations, 0, t, 0, n);
 774             initializations = t;
 775         }
 776         // stores the type to be initialized
 777         initializations[initializationCount++] = var;
 778     }
 779 
 780     /**
 781      * Replaces the given type with the appropriate type if it is one of the
 782      * types on which a constructor is invoked in the basic block.
 783      *
 784      * @param cw the ClassWriter to which this label belongs.
 785      * @param t a type


 786      * @return t or, if t is one of the types on which a constructor is invoked
 787      *         in the basic block, the type corresponding to this constructor.
 788      */
 789     private int init(final ClassWriter cw, final int t) {
 790         int s;
 791         if (t == UNINITIALIZED_THIS) {
 792             s = OBJECT | cw.addType(cw.thisName);
 793         } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) {
 794             String type = cw.typeTable[t & BASE_VALUE].strVal1;
 795             s = OBJECT | cw.addType(type);
 796         } else {
 797             return t;
 798         }
 799         for (int j = 0; j < initializationCount; ++j) {
 800             int u = initializations[j];
 801             int dim = u & DIM;
 802             int kind = u & KIND;
 803             if (kind == LOCAL) {
 804                 u = dim + inputLocals[u & VALUE];
 805             } else if (kind == STACK) {
 806                 u = dim + inputStack[inputStack.length - (u & VALUE)];
 807             }
 808             if (t == u) {
 809                 return s;
 810             }
 811         }
 812         return t;
 813     }
 814 
 815     /**
 816      * Initializes the input frame of the first basic block from the method
 817      * descriptor.
 818      *
 819      * @param cw the ClassWriter to which this label belongs.
 820      * @param access the access flags of the method to which this label belongs.
 821      * @param args the formal parameter types of this method.
 822      * @param maxLocals the maximum number of local variables of this method.




 823      */
 824     void initInputFrame(
 825         final ClassWriter cw,
 826         final int access,
 827         final Type[] args,
 828         final int maxLocals)
 829     {
 830         inputLocals = new int[maxLocals];
 831         inputStack = new int[0];
 832         int i = 0;
 833         if ((access & Opcodes.ACC_STATIC) == 0) {
 834             if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) {
 835                 inputLocals[i++] = OBJECT | cw.addType(cw.thisName);
 836             } else {
 837                 inputLocals[i++] = UNINITIALIZED_THIS;
 838             }
 839         }
 840         for (int j = 0; j < args.length; ++j) {
 841             int t = type(cw, args[j].getDescriptor());
 842             inputLocals[i++] = t;
 843             if (t == LONG || t == DOUBLE) {
 844                 inputLocals[i++] = TOP;
 845             }
 846         }
 847         while (i < maxLocals) {
 848             inputLocals[i++] = TOP;
 849         }
 850     }
 851 
 852     /**
 853      * Simulates the action of the given instruction on the output stack frame.
 854      *
 855      * @param opcode the opcode of the instruction.
 856      * @param arg the operand of the instruction, if any.
 857      * @param cw the class writer to which this label belongs.
 858      * @param item the operand of the instructions, if any.




 859      */
 860     void execute(
 861         final int opcode,
 862         final int arg,
 863         final ClassWriter cw,
 864         final Item item)
 865     {
 866         int t1, t2, t3, t4;
 867         switch (opcode) {
 868             case Opcodes.NOP:
 869             case Opcodes.INEG:
 870             case Opcodes.LNEG:
 871             case Opcodes.FNEG:
 872             case Opcodes.DNEG:
 873             case Opcodes.I2B:
 874             case Opcodes.I2C:
 875             case Opcodes.I2S:
 876             case Opcodes.GOTO:
 877             case Opcodes.RETURN:
 878                 break;
 879             case Opcodes.ACONST_NULL:
 880                 push(NULL);
 881                 break;
 882             case Opcodes.ICONST_M1:
 883             case Opcodes.ICONST_0:
 884             case Opcodes.ICONST_1:
 885             case Opcodes.ICONST_2:


1174             case Opcodes.I2D:
1175             case Opcodes.F2D:
1176                 pop(1);
1177                 push(DOUBLE);
1178                 push(TOP);
1179                 break;
1180             case Opcodes.F2I:
1181             case Opcodes.ARRAYLENGTH:
1182             case Opcodes.INSTANCEOF:
1183                 pop(1);
1184                 push(INTEGER);
1185                 break;
1186             case Opcodes.LCMP:
1187             case Opcodes.DCMPL:
1188             case Opcodes.DCMPG:
1189                 pop(4);
1190                 push(INTEGER);
1191                 break;
1192             case Opcodes.JSR:
1193             case Opcodes.RET:
1194                 throw new RuntimeException("JSR/RET are not supported with computeFrames option");

1195             case Opcodes.GETSTATIC:
1196                 push(cw, item.strVal3);
1197                 break;
1198             case Opcodes.PUTSTATIC:
1199                 pop(item.strVal3);
1200                 break;
1201             case Opcodes.GETFIELD:
1202                 pop(1);
1203                 push(cw, item.strVal3);
1204                 break;
1205             case Opcodes.PUTFIELD:
1206                 pop(item.strVal3);
1207                 pop();
1208                 break;
1209             case Opcodes.INVOKEVIRTUAL:
1210             case Opcodes.INVOKESPECIAL:
1211             case Opcodes.INVOKESTATIC:
1212             case Opcodes.INVOKEINTERFACE:
1213                 pop(item.strVal3);
1214                 if (opcode != Opcodes.INVOKESTATIC) {
1215                     t1 = pop();
1216                     if (opcode == Opcodes.INVOKESPECIAL
1217                             && item.strVal2.charAt(0) == '<')
1218                     {
1219                         init(t1);
1220                     }
1221                 }
1222                 push(cw, item.strVal3);
1223                 break;
1224             case Opcodes.INVOKEDYNAMIC:
1225                 pop(item.strVal2);
1226                 push(cw, item.strVal2);
1227                 break;
1228             case Opcodes.NEW:
1229                 push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
1230                 break;
1231             case Opcodes.NEWARRAY:
1232                 pop();
1233                 switch (arg) {
1234                     case Opcodes.T_BOOLEAN:
1235                         push(ARRAY_OF | BOOLEAN);
1236                         break;
1237                     case Opcodes.T_CHAR:
1238                         push(ARRAY_OF | CHAR);


1272                 pop();
1273                 if (s.charAt(0) == '[') {
1274                     push(cw, s);
1275                 } else {
1276                     push(OBJECT | cw.addType(s));
1277                 }
1278                 break;
1279             // case Opcodes.MULTIANEWARRAY:
1280             default:
1281                 pop(arg);
1282                 push(cw, item.strVal1);
1283                 break;
1284         }
1285     }
1286 
1287     /**
1288      * Merges the input frame of the given basic block with the input and output
1289      * frames of this basic block. Returns <tt>true</tt> if the input frame of
1290      * the given label has been changed by this operation.
1291      *
1292      * @param cw the ClassWriter to which this label belongs.
1293      * @param frame the basic block whose input frame must be updated.
1294      * @param edge the kind of the {@link Edge} between this label and 'label'.



1295      *        See {@link Edge#info}.
1296      * @return <tt>true</tt> if the input frame of the given label has been
1297      *         changed by this operation.
1298      */
1299     boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
1300         boolean changed = false;
1301         int i, s, dim, kind, t;
1302 
1303         int nLocal = inputLocals.length;
1304         int nStack = inputStack.length;
1305         if (frame.inputLocals == null) {
1306             frame.inputLocals = new int[nLocal];
1307             changed = true;
1308         }
1309 
1310         for (i = 0; i < nLocal; ++i) {
1311             if (outputLocals != null && i < outputLocals.length) {
1312                 s = outputLocals[i];
1313                 if (s == 0) {
1314                     t = inputLocals[i];
1315                 } else {
1316                     dim = s & DIM;
1317                     kind = s & KIND;
1318                     if (kind == BASE) {
1319                         t = s;
1320                     } else {
1321                         if (kind == LOCAL) {
1322                             t = dim + inputLocals[s & VALUE];
1323                         } else {
1324                             t = dim + inputStack[nStack - (s & VALUE)];
1325                         }
1326                         if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {

1327                             t = TOP;
1328                         }
1329                     }
1330                 }
1331             } else {
1332                 t = inputLocals[i];
1333             }
1334             if (initializations != null) {
1335                 t = init(cw, t);
1336             }
1337             changed |= merge(cw, t, frame.inputLocals, i);
1338         }
1339 
1340         if (edge > 0) {
1341             for (i = 0; i < nLocal; ++i) {
1342                 t = inputLocals[i];
1343                 changed |= merge(cw, t, frame.inputLocals, i);
1344             }
1345             if (frame.inputStack == null) {
1346                 frame.inputStack = new int[1];


1358 
1359         for (i = 0; i < nInputStack; ++i) {
1360             t = inputStack[i];
1361             if (initializations != null) {
1362                 t = init(cw, t);
1363             }
1364             changed |= merge(cw, t, frame.inputStack, i);
1365         }
1366         for (i = 0; i < outputStackTop; ++i) {
1367             s = outputStack[i];
1368             dim = s & DIM;
1369             kind = s & KIND;
1370             if (kind == BASE) {
1371                 t = s;
1372             } else {
1373                 if (kind == LOCAL) {
1374                     t = dim + inputLocals[s & VALUE];
1375                 } else {
1376                     t = dim + inputStack[nStack - (s & VALUE)];
1377                 }
1378                 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {

1379                     t = TOP;
1380                 }
1381             }
1382             if (initializations != null) {
1383                 t = init(cw, t);
1384             }
1385             changed |= merge(cw, t, frame.inputStack, nInputStack + i);
1386         }
1387         return changed;
1388     }
1389 
1390     /**
1391      * Merges the type at the given index in the given type array with the given
1392      * type. Returns <tt>true</tt> if the type array has been modified by this
1393      * operation.
1394      *
1395      * @param cw the ClassWriter to which this label belongs.
1396      * @param t the type with which the type array element must be merged.
1397      * @param types an array of types.
1398      * @param index the index of the type that must be merged in 'types'.




1399      * @return <tt>true</tt> if the type array has been modified by this
1400      *         operation.
1401      */
1402     private static boolean merge(
1403         final ClassWriter cw,
1404         int t,
1405         final int[] types,
1406         final int index)
1407     {
1408         int u = types[index];
1409         if (u == t) {
1410             // if the types are equal, merge(u,t)=u, so there is no change
1411             return false;
1412         }
1413         if ((t & ~DIM) == NULL) {
1414             if (u == NULL) {
1415                 return false;
1416             }
1417             t = NULL;
1418         }
1419         if (u == 0) {
1420             // if types[index] has never been assigned, merge(u,t)=t
1421             types[index] = t;
1422             return true;
1423         }
1424         int v;
1425         if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) {
1426             // if u is a reference type of any dimension
1427             if (t == NULL) {




  92      * This explains the rather complicated type format used in output frames.
  93      *
  94      * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
  95      * signed number of array dimensions (from -8 to 7). KIND is either BASE,
  96      * LOCAL or STACK. BASE is used for types that are not relative to the input
  97      * frame. LOCAL is used for types that are relative to the input local
  98      * variable types. STACK is used for types that are relative to the input
  99      * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
 100      * the input local variable types. For STACK types, it is a position
 101      * relatively to the top of input frame stack. For BASE types, it is either
 102      * one of the constants defined in FrameVisitor, or for OBJECT and
 103      * UNINITIALIZED types, a tag and an index in the type table.
 104      *
 105      * Output frames can contain types of any kind and with a positive or
 106      * negative dimension (and even unassigned types, represented by 0 - which
 107      * does not correspond to any valid type value). Input frames can only
 108      * contain BASE types of positive or null dimension. In all cases the type
 109      * table contains only internal type names (array type descriptors are
 110      * forbidden - dimensions must be represented through the DIM field).
 111      *
 112      * The LONG and DOUBLE types are always represented by using two slots (LONG
 113      * + TOP or DOUBLE + TOP), for local variable types as well as in the
 114      * operand stack. This is necessary to be able to simulate DUPx_y
 115      * instructions, whose effect would be dependent on the actual type values
 116      * if types were always represented by a single slot in the stack (and this
 117      * is not possible, since actual type values are not always known - cf LOCAL
 118      * and STACK type kinds).
 119      */
 120 
 121     /**
 122      * Mask to get the dimension of a frame type. This dimension is a signed
 123      * integer between -8 and 7.
 124      */
 125     static final int DIM = 0xF0000000;
 126 
 127     /**
 128      * Constant to be added to a type to get a type with one more dimension.
 129      */
 130     static final int ARRAY_OF = 0x10000000;
 131 
 132     /**
 133      * Constant to be added to a type to get a type with one less dimension.
 134      */
 135     static final int ELEMENT_OF = 0xF0000000;
 136 
 137     /**
 138      * Mask to get the kind of a frame type.
 139      *
 140      * @see #BASE
 141      * @see #LOCAL
 142      * @see #STACK
 143      */
 144     static final int KIND = 0xF000000;
 145 
 146     /**
 147      * Flag used for LOCAL and STACK types. Indicates that if this type happens
 148      * to be a long or double type (during the computations of input frames),
 149      * then it must be set to TOP because the second word of this value has been
 150      * reused to store other data in the basic block. Hence the first word no
 151      * longer stores a valid long or double value.
 152      */
 153     static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
 154 
 155     /**
 156      * Mask to get the value of a frame type.
 157      */
 158     static final int VALUE = 0x7FFFFF;
 159 
 160     /**
 161      * Mask to get the kind of base types.
 162      */
 163     static final int BASE_KIND = 0xFF00000;
 164 
 165     /**
 166      * Mask to get the value of base types.
 167      */
 168     static final int BASE_VALUE = 0xFFFFF;
 169 
 170     /**
 171      * Kind of the types that are not relative to an input stack map frame.


 535     private int initializationCount;
 536 
 537     /**
 538      * The types that are initialized in the basic block. A constructor
 539      * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
 540      * <i>every occurence</i> of this type in the local variables and in the
 541      * operand stack. This cannot be done during the first phase of the
 542      * algorithm since, during this phase, the local variables and the operand
 543      * stack are not completely computed. It is therefore necessary to store the
 544      * types on which constructors are invoked in the basic block, in order to
 545      * do this replacement during the second phase of the algorithm, where the
 546      * frames are fully computed. Note that this array can contain types that
 547      * are relative to input locals or to the input stack (see below for the
 548      * description of the algorithm).
 549      */
 550     private int[] initializations;
 551 
 552     /**
 553      * Returns the output frame local variable type at the given index.
 554      *
 555      * @param local
 556      *            the index of the local that must be returned.
 557      * @return the output frame local variable type at the given index.
 558      */
 559     private int get(final int local) {
 560         if (outputLocals == null || local >= outputLocals.length) {
 561             // this local has never been assigned in this basic block,
 562             // so it is still equal to its value in the input frame
 563             return LOCAL | local;
 564         } else {
 565             int type = outputLocals[local];
 566             if (type == 0) {
 567                 // this local has never been assigned in this basic block,
 568                 // so it is still equal to its value in the input frame
 569                 type = outputLocals[local] = LOCAL | local;
 570             }
 571             return type;
 572         }
 573     }
 574 
 575     /**
 576      * Sets the output frame local variable type at the given index.
 577      *
 578      * @param local
 579      *            the index of the local that must be set.
 580      * @param type
 581      *            the value of the local that must be set.
 582      */
 583     private void set(final int local, final int type) {
 584         // creates and/or resizes the output local variables array if necessary
 585         if (outputLocals == null) {
 586             outputLocals = new int[10];
 587         }
 588         int n = outputLocals.length;
 589         if (local >= n) {
 590             int[] t = new int[Math.max(local + 1, 2 * n)];
 591             System.arraycopy(outputLocals, 0, t, 0, n);
 592             outputLocals = t;
 593         }
 594         // sets the local variable
 595         outputLocals[local] = type;
 596     }
 597 
 598     /**
 599      * Pushes a new type onto the output frame stack.
 600      *
 601      * @param type
 602      *            the type that must be pushed.
 603      */
 604     private void push(final int type) {
 605         // creates and/or resizes the output stack array if necessary
 606         if (outputStack == null) {
 607             outputStack = new int[10];
 608         }
 609         int n = outputStack.length;
 610         if (outputStackTop >= n) {
 611             int[] t = new int[Math.max(outputStackTop + 1, 2 * n)];
 612             System.arraycopy(outputStack, 0, t, 0, n);
 613             outputStack = t;
 614         }
 615         // pushes the type on the output stack
 616         outputStack[outputStackTop++] = type;
 617         // updates the maximun height reached by the output stack, if needed
 618         int top = owner.inputStackTop + outputStackTop;
 619         if (top > owner.outputStackMax) {
 620             owner.outputStackMax = top;
 621         }
 622     }
 623 
 624     /**
 625      * Pushes a new type onto the output frame stack.
 626      *
 627      * @param cw
 628      *            the ClassWriter to which this label belongs.
 629      * @param desc
 630      *            the descriptor of the type to be pushed. Can also be a method
 631      *            descriptor (in this case this method pushes its return type
 632      *            onto the output frame stack).
 633      */
 634     private void push(final ClassWriter cw, final String desc) {
 635         int type = type(cw, desc);
 636         if (type != 0) {
 637             push(type);
 638             if (type == LONG || type == DOUBLE) {
 639                 push(TOP);
 640             }
 641         }
 642     }
 643 
 644     /**
 645      * Returns the int encoding of the given type.
 646      *
 647      * @param cw
 648      *            the ClassWriter to which this label belongs.
 649      * @param desc
 650      *            a type descriptor.
 651      * @return the int encoding of the given type.
 652      */
 653     private static int type(final ClassWriter cw, final String desc) {
 654         String t;
 655         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
 656         switch (desc.charAt(index)) {
 657         case 'V':
 658             return 0;
 659         case 'Z':
 660         case 'C':
 661         case 'B':
 662         case 'S':
 663         case 'I':
 664             return INTEGER;
 665         case 'F':
 666             return FLOAT;
 667         case 'J':
 668             return LONG;
 669         case 'D':
 670             return DOUBLE;


 715         }
 716     }
 717 
 718     /**
 719      * Pops a type from the output frame stack and returns its value.
 720      *
 721      * @return the type that has been popped from the output frame stack.
 722      */
 723     private int pop() {
 724         if (outputStackTop > 0) {
 725             return outputStack[--outputStackTop];
 726         } else {
 727             // if the output frame stack is empty, pops from the input stack
 728             return STACK | -(--owner.inputStackTop);
 729         }
 730     }
 731 
 732     /**
 733      * Pops the given number of types from the output frame stack.
 734      *
 735      * @param elements
 736      *            the number of types that must be popped.
 737      */
 738     private void pop(final int elements) {
 739         if (outputStackTop >= elements) {
 740             outputStackTop -= elements;
 741         } else {
 742             // if the number of elements to be popped is greater than the number
 743             // of elements in the output stack, clear it, and pops the remaining
 744             // elements from the input stack.
 745             owner.inputStackTop -= elements - outputStackTop;
 746             outputStackTop = 0;
 747         }
 748     }
 749 
 750     /**
 751      * Pops a type from the output frame stack.
 752      *
 753      * @param desc
 754      *            the descriptor of the type to be popped. Can also be a method
 755      *            descriptor (in this case this method pops the types
 756      *            corresponding to the method arguments).
 757      */
 758     private void pop(final String desc) {
 759         char c = desc.charAt(0);
 760         if (c == '(') {
 761             pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
 762         } else if (c == 'J' || c == 'D') {
 763             pop(2);
 764         } else {
 765             pop(1);
 766         }
 767     }
 768 
 769     /**
 770      * Adds a new type to the list of types on which a constructor is invoked in
 771      * the basic block.
 772      *
 773      * @param var
 774      *            a type on a which a constructor is invoked.
 775      */
 776     private void init(final int var) {
 777         // creates and/or resizes the initializations array if necessary
 778         if (initializations == null) {
 779             initializations = new int[2];
 780         }
 781         int n = initializations.length;
 782         if (initializationCount >= n) {
 783             int[] t = new int[Math.max(initializationCount + 1, 2 * n)];
 784             System.arraycopy(initializations, 0, t, 0, n);
 785             initializations = t;
 786         }
 787         // stores the type to be initialized
 788         initializations[initializationCount++] = var;
 789     }
 790 
 791     /**
 792      * Replaces the given type with the appropriate type if it is one of the
 793      * types on which a constructor is invoked in the basic block.
 794      *
 795      * @param cw
 796      *            the ClassWriter to which this label belongs.
 797      * @param t
 798      *            a type
 799      * @return t or, if t is one of the types on which a constructor is invoked
 800      *         in the basic block, the type corresponding to this constructor.
 801      */
 802     private int init(final ClassWriter cw, final int t) {
 803         int s;
 804         if (t == UNINITIALIZED_THIS) {
 805             s = OBJECT | cw.addType(cw.thisName);
 806         } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) {
 807             String type = cw.typeTable[t & BASE_VALUE].strVal1;
 808             s = OBJECT | cw.addType(type);
 809         } else {
 810             return t;
 811         }
 812         for (int j = 0; j < initializationCount; ++j) {
 813             int u = initializations[j];
 814             int dim = u & DIM;
 815             int kind = u & KIND;
 816             if (kind == LOCAL) {
 817                 u = dim + inputLocals[u & VALUE];
 818             } else if (kind == STACK) {
 819                 u = dim + inputStack[inputStack.length - (u & VALUE)];
 820             }
 821             if (t == u) {
 822                 return s;
 823             }
 824         }
 825         return t;
 826     }
 827 
 828     /**
 829      * Initializes the input frame of the first basic block from the method
 830      * descriptor.
 831      *
 832      * @param cw
 833      *            the ClassWriter to which this label belongs.
 834      * @param access
 835      *            the access flags of the method to which this label belongs.
 836      * @param args
 837      *            the formal parameter types of this method.
 838      * @param maxLocals
 839      *            the maximum number of local variables of this method.
 840      */
 841     void initInputFrame(final ClassWriter cw, final int access,
 842             final Type[] args, final int maxLocals) {




 843         inputLocals = new int[maxLocals];
 844         inputStack = new int[0];
 845         int i = 0;
 846         if ((access & Opcodes.ACC_STATIC) == 0) {
 847             if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) {
 848                 inputLocals[i++] = OBJECT | cw.addType(cw.thisName);
 849             } else {
 850                 inputLocals[i++] = UNINITIALIZED_THIS;
 851             }
 852         }
 853         for (int j = 0; j < args.length; ++j) {
 854             int t = type(cw, args[j].getDescriptor());
 855             inputLocals[i++] = t;
 856             if (t == LONG || t == DOUBLE) {
 857                 inputLocals[i++] = TOP;
 858             }
 859         }
 860         while (i < maxLocals) {
 861             inputLocals[i++] = TOP;
 862         }
 863     }
 864 
 865     /**
 866      * Simulates the action of the given instruction on the output stack frame.
 867      *
 868      * @param opcode
 869      *            the opcode of the instruction.
 870      * @param arg
 871      *            the operand of the instruction, if any.
 872      * @param cw
 873      *            the class writer to which this label belongs.
 874      * @param item
 875      *            the operand of the instructions, if any.
 876      */
 877     void execute(final int opcode, final int arg, final ClassWriter cw,
 878             final Item item) {




 879         int t1, t2, t3, t4;
 880         switch (opcode) {
 881         case Opcodes.NOP:
 882         case Opcodes.INEG:
 883         case Opcodes.LNEG:
 884         case Opcodes.FNEG:
 885         case Opcodes.DNEG:
 886         case Opcodes.I2B:
 887         case Opcodes.I2C:
 888         case Opcodes.I2S:
 889         case Opcodes.GOTO:
 890         case Opcodes.RETURN:
 891             break;
 892         case Opcodes.ACONST_NULL:
 893             push(NULL);
 894             break;
 895         case Opcodes.ICONST_M1:
 896         case Opcodes.ICONST_0:
 897         case Opcodes.ICONST_1:
 898         case Opcodes.ICONST_2:


1187         case Opcodes.I2D:
1188         case Opcodes.F2D:
1189             pop(1);
1190             push(DOUBLE);
1191             push(TOP);
1192             break;
1193         case Opcodes.F2I:
1194         case Opcodes.ARRAYLENGTH:
1195         case Opcodes.INSTANCEOF:
1196             pop(1);
1197             push(INTEGER);
1198             break;
1199         case Opcodes.LCMP:
1200         case Opcodes.DCMPL:
1201         case Opcodes.DCMPG:
1202             pop(4);
1203             push(INTEGER);
1204             break;
1205         case Opcodes.JSR:
1206         case Opcodes.RET:
1207             throw new RuntimeException(
1208                     "JSR/RET are not supported with computeFrames option");
1209         case Opcodes.GETSTATIC:
1210             push(cw, item.strVal3);
1211             break;
1212         case Opcodes.PUTSTATIC:
1213             pop(item.strVal3);
1214             break;
1215         case Opcodes.GETFIELD:
1216             pop(1);
1217             push(cw, item.strVal3);
1218             break;
1219         case Opcodes.PUTFIELD:
1220             pop(item.strVal3);
1221             pop();
1222             break;
1223         case Opcodes.INVOKEVIRTUAL:
1224         case Opcodes.INVOKESPECIAL:
1225         case Opcodes.INVOKESTATIC:
1226         case Opcodes.INVOKEINTERFACE:
1227             pop(item.strVal3);
1228             if (opcode != Opcodes.INVOKESTATIC) {
1229                 t1 = pop();
1230                 if (opcode == Opcodes.INVOKESPECIAL
1231                         && item.strVal2.charAt(0) == '<') {

1232                     init(t1);
1233                 }
1234             }
1235             push(cw, item.strVal3);
1236             break;
1237         case Opcodes.INVOKEDYNAMIC:
1238             pop(item.strVal2);
1239             push(cw, item.strVal2);
1240             break;
1241         case Opcodes.NEW:
1242             push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
1243             break;
1244         case Opcodes.NEWARRAY:
1245             pop();
1246             switch (arg) {
1247             case Opcodes.T_BOOLEAN:
1248                 push(ARRAY_OF | BOOLEAN);
1249                 break;
1250             case Opcodes.T_CHAR:
1251                 push(ARRAY_OF | CHAR);


1285             pop();
1286             if (s.charAt(0) == '[') {
1287                 push(cw, s);
1288             } else {
1289                 push(OBJECT | cw.addType(s));
1290             }
1291             break;
1292         // case Opcodes.MULTIANEWARRAY:
1293         default:
1294             pop(arg);
1295             push(cw, item.strVal1);
1296             break;
1297         }
1298     }
1299 
1300     /**
1301      * Merges the input frame of the given basic block with the input and output
1302      * frames of this basic block. Returns <tt>true</tt> if the input frame of
1303      * the given label has been changed by this operation.
1304      *
1305      * @param cw
1306      *            the ClassWriter to which this label belongs.
1307      * @param frame
1308      *            the basic block whose input frame must be updated.
1309      * @param edge
1310      *            the kind of the {@link Edge} between this label and 'label'.
1311      *            See {@link Edge#info}.
1312      * @return <tt>true</tt> if the input frame of the given label has been
1313      *         changed by this operation.
1314      */
1315     boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
1316         boolean changed = false;
1317         int i, s, dim, kind, t;
1318 
1319         int nLocal = inputLocals.length;
1320         int nStack = inputStack.length;
1321         if (frame.inputLocals == null) {
1322             frame.inputLocals = new int[nLocal];
1323             changed = true;
1324         }
1325 
1326         for (i = 0; i < nLocal; ++i) {
1327             if (outputLocals != null && i < outputLocals.length) {
1328                 s = outputLocals[i];
1329                 if (s == 0) {
1330                     t = inputLocals[i];
1331                 } else {
1332                     dim = s & DIM;
1333                     kind = s & KIND;
1334                     if (kind == BASE) {
1335                         t = s;
1336                     } else {
1337                         if (kind == LOCAL) {
1338                             t = dim + inputLocals[s & VALUE];
1339                         } else {
1340                             t = dim + inputStack[nStack - (s & VALUE)];
1341                         }
1342                         if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
1343                                 && (t == LONG || t == DOUBLE)) {
1344                             t = TOP;
1345                         }
1346                     }
1347                 }
1348             } else {
1349                 t = inputLocals[i];
1350             }
1351             if (initializations != null) {
1352                 t = init(cw, t);
1353             }
1354             changed |= merge(cw, t, frame.inputLocals, i);
1355         }
1356 
1357         if (edge > 0) {
1358             for (i = 0; i < nLocal; ++i) {
1359                 t = inputLocals[i];
1360                 changed |= merge(cw, t, frame.inputLocals, i);
1361             }
1362             if (frame.inputStack == null) {
1363                 frame.inputStack = new int[1];


1375 
1376         for (i = 0; i < nInputStack; ++i) {
1377             t = inputStack[i];
1378             if (initializations != null) {
1379                 t = init(cw, t);
1380             }
1381             changed |= merge(cw, t, frame.inputStack, i);
1382         }
1383         for (i = 0; i < outputStackTop; ++i) {
1384             s = outputStack[i];
1385             dim = s & DIM;
1386             kind = s & KIND;
1387             if (kind == BASE) {
1388                 t = s;
1389             } else {
1390                 if (kind == LOCAL) {
1391                     t = dim + inputLocals[s & VALUE];
1392                 } else {
1393                     t = dim + inputStack[nStack - (s & VALUE)];
1394                 }
1395                 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
1396                         && (t == LONG || t == DOUBLE)) {
1397                     t = TOP;
1398                 }
1399             }
1400             if (initializations != null) {
1401                 t = init(cw, t);
1402             }
1403             changed |= merge(cw, t, frame.inputStack, nInputStack + i);
1404         }
1405         return changed;
1406     }
1407 
1408     /**
1409      * Merges the type at the given index in the given type array with the given
1410      * type. Returns <tt>true</tt> if the type array has been modified by this
1411      * operation.
1412      *
1413      * @param cw
1414      *            the ClassWriter to which this label belongs.
1415      * @param t
1416      *            the type with which the type array element must be merged.
1417      * @param types
1418      *            an array of types.
1419      * @param index
1420      *            the index of the type that must be merged in 'types'.
1421      * @return <tt>true</tt> if the type array has been modified by this
1422      *         operation.
1423      */
1424     private static boolean merge(final ClassWriter cw, int t,
1425             final int[] types, final int index) {




1426         int u = types[index];
1427         if (u == t) {
1428             // if the types are equal, merge(u,t)=u, so there is no change
1429             return false;
1430         }
1431         if ((t & ~DIM) == NULL) {
1432             if (u == NULL) {
1433                 return false;
1434             }
1435             t = NULL;
1436         }
1437         if (u == 0) {
1438             // if types[index] has never been assigned, merge(u,t)=t
1439             types[index] = t;
1440             return true;
1441         }
1442         int v;
1443         if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) {
1444             // if u is a reference type of any dimension
1445             if (t == NULL) {