< prev index next >

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

Print this page
rev 47452 : imported patch jdk-new-asmv6.patch


  46  *
  47  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  48  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  51  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  52  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  56  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  57  * THE POSSIBILITY OF SUCH DAMAGE.
  58  */
  59 package jdk.internal.org.objectweb.asm;
  60 
  61 /**
  62  * Information about the input and output stack map frames of a basic block.
  63  *
  64  * @author Eric Bruneton
  65  */
  66 final class Frame {
  67 
  68     /*
  69      * Frames are computed in a two steps process: during the visit of each
  70      * instruction, the state of the frame at the end of current basic block is
  71      * updated by simulating the action of the instruction on the previous state
  72      * of this so called "output frame". In visitMaxs, a fix point algorithm is
  73      * used to compute the "input frame" of each basic block, i.e. the stack map
  74      * frame at the beginning of the basic block, starting from the input frame
  75      * of the first basic block (which is computed from the method descriptor),
  76      * and by using the previously computed output frames to compute the input
  77      * state of the other blocks.
  78      *
  79      * All output and input frames are stored as arrays of integers. Reference
  80      * and array types are represented by an index into a type table (which is
  81      * not the same as the constant pool of the class, in order to avoid adding
  82      * unnecessary constants in the pool - not all computed frames will end up
  83      * being stored in the stack map table). This allows very fast type
  84      * comparisons.
  85      *
  86      * Output stack map frames are computed relatively to the input frame of the


 508     /**
 509      * The output stack map frame locals.
 510      */
 511     private int[] outputLocals;
 512 
 513     /**
 514      * The output stack map frame stack.
 515      */
 516     private int[] outputStack;
 517 
 518     /**
 519      * Relative size of the output stack. The exact semantics of this field
 520      * depends on the algorithm that is used.
 521      *
 522      * When only the maximum stack size is computed, this field is the size of
 523      * the output stack relatively to the top of the input stack.
 524      *
 525      * When the stack map frames are completely computed, this field is the
 526      * actual number of types in {@link #outputStack}.
 527      */
 528     private int outputStackTop;
 529 
 530     /**
 531      * Number of types that are initialized in the basic block.
 532      *
 533      * @see #initializations
 534      */
 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         }


 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;
 671         case 'L':
 672             // stores the internal name, not the descriptor!
 673             t = desc.substring(index + 1, desc.length() - 1);


 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;


 964             break;
 965         case Opcodes.LALOAD:
 966         case Opcodes.D2L:
 967             pop(2);
 968             push(LONG);
 969             push(TOP);
 970             break;
 971         case Opcodes.FALOAD:
 972             pop(2);
 973             push(FLOAT);
 974             break;
 975         case Opcodes.DALOAD:
 976         case Opcodes.L2D:
 977             pop(2);
 978             push(DOUBLE);
 979             push(TOP);
 980             break;
 981         case Opcodes.AALOAD:
 982             pop(1);
 983             t1 = pop();
 984             push(ELEMENT_OF + t1);
 985             break;
 986         case Opcodes.ISTORE:
 987         case Opcodes.FSTORE:
 988         case Opcodes.ASTORE:
 989             t1 = pop();
 990             set(arg, t1);
 991             if (arg > 0) {
 992                 t2 = get(arg - 1);
 993                 // if t2 is of kind STACK or LOCAL we cannot know its size!
 994                 if (t2 == LONG || t2 == DOUBLE) {
 995                     set(arg - 1, TOP);
 996                 } else if ((t2 & KIND) != BASE) {
 997                     set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
 998                 }
 999             }
1000             break;
1001         case Opcodes.LSTORE:
1002         case Opcodes.DSTORE:
1003             pop(1);
1004             t1 = pop();


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;




  46  *
  47  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  48  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  51  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  52  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  56  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  57  * THE POSSIBILITY OF SUCH DAMAGE.
  58  */
  59 package jdk.internal.org.objectweb.asm;
  60 
  61 /**
  62  * Information about the input and output stack map frames of a basic block.
  63  *
  64  * @author Eric Bruneton
  65  */
  66 class Frame {
  67 
  68     /*
  69      * Frames are computed in a two steps process: during the visit of each
  70      * instruction, the state of the frame at the end of current basic block is
  71      * updated by simulating the action of the instruction on the previous state
  72      * of this so called "output frame". In visitMaxs, a fix point algorithm is
  73      * used to compute the "input frame" of each basic block, i.e. the stack map
  74      * frame at the beginning of the basic block, starting from the input frame
  75      * of the first basic block (which is computed from the method descriptor),
  76      * and by using the previously computed output frames to compute the input
  77      * state of the other blocks.
  78      *
  79      * All output and input frames are stored as arrays of integers. Reference
  80      * and array types are represented by an index into a type table (which is
  81      * not the same as the constant pool of the class, in order to avoid adding
  82      * unnecessary constants in the pool - not all computed frames will end up
  83      * being stored in the stack map table). This allows very fast type
  84      * comparisons.
  85      *
  86      * Output stack map frames are computed relatively to the input frame of the


 508     /**
 509      * The output stack map frame locals.
 510      */
 511     private int[] outputLocals;
 512 
 513     /**
 514      * The output stack map frame stack.
 515      */
 516     private int[] outputStack;
 517 
 518     /**
 519      * Relative size of the output stack. The exact semantics of this field
 520      * depends on the algorithm that is used.
 521      *
 522      * When only the maximum stack size is computed, this field is the size of
 523      * the output stack relatively to the top of the input stack.
 524      *
 525      * When the stack map frames are completely computed, this field is the
 526      * actual number of types in {@link #outputStack}.
 527      */
 528     int outputStackTop;
 529 
 530     /**
 531      * Number of types that are initialized in the basic block.
 532      *
 533      * @see #initializations
 534      */
 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      * Sets this frame to the given value.
 554      *
 555      * @param cw
 556      *            the ClassWriter to which this label belongs.
 557      * @param nLocal
 558      *            the number of local variables.
 559      * @param local
 560      *            the local variable types. Primitive types are represented by
 561      *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
 562      *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
 563      *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
 564      *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
 565      *            represented by a single element). Reference types are
 566      *            represented by String objects (representing internal names),
 567      *            and uninitialized types by Label objects (this label
 568      *            designates the NEW instruction that created this uninitialized
 569      *            value).
 570      * @param nStack
 571      *            the number of operand stack elements.
 572      * @param stack
 573      *            the operand stack types (same format as the "local" array).
 574      */
 575     final void set(ClassWriter cw, final int nLocal, final Object[] local,
 576             final int nStack, final Object[] stack) {
 577         int i = convert(cw, nLocal, local, inputLocals);
 578         while (i < local.length) {
 579             inputLocals[i++] = TOP;
 580         }
 581         int nStackTop = 0;
 582         for (int j = 0; j < nStack; ++j) {
 583             if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) {
 584                 ++nStackTop;
 585             }
 586         }
 587         inputStack = new int[nStack + nStackTop];
 588         convert(cw, nStack, stack, inputStack);
 589         outputStackTop = 0;
 590         initializationCount = 0;
 591     }
 592 
 593     /**
 594      * Converts types from the MethodWriter.visitFrame() format to the Frame
 595      * format.
 596      *
 597      * @param cw
 598      *            the ClassWriter to which this label belongs.
 599      * @param nInput
 600      *            the number of types to convert.
 601      * @param input
 602      *            the types to convert. Primitive types are represented by
 603      *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
 604      *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
 605      *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
 606      *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
 607      *            represented by a single element). Reference types are
 608      *            represented by String objects (representing internal names),
 609      *            and uninitialized types by Label objects (this label
 610      *            designates the NEW instruction that created this uninitialized
 611      *            value).
 612      * @param output
 613      *            where to store the converted types.
 614      * @return the number of output elements.
 615      */
 616     private static int convert(ClassWriter cw, int nInput, Object[] input,
 617             int[] output) {
 618         int i = 0;
 619         for (int j = 0; j < nInput; ++j) {
 620             if (input[j] instanceof Integer) {
 621                 output[i++] = BASE | ((Integer) input[j]).intValue();
 622                 if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) {
 623                     output[i++] = TOP;
 624                 }
 625             } else if (input[j] instanceof String) {
 626                 output[i++] = type(cw, Type.getObjectType((String) input[j])
 627                         .getDescriptor());
 628             } else {
 629                 output[i++] = UNINITIALIZED
 630                         | cw.addUninitializedType("",
 631                                 ((Label) input[j]).position);
 632             }
 633         }
 634         return i;
 635     }
 636 
 637     /**
 638      * Sets this frame to the value of the given frame. WARNING: after this
 639      * method is called the two frames share the same data structures. It is
 640      * recommended to discard the given frame f to avoid unexpected side
 641      * effects.
 642      *
 643      * @param f
 644      *            The new frame value.
 645      */
 646     final void set(final Frame f) {
 647         inputLocals = f.inputLocals;
 648         inputStack = f.inputStack;
 649         outputLocals = f.outputLocals;
 650         outputStack = f.outputStack;
 651         outputStackTop = f.outputStackTop;
 652         initializationCount = f.initializationCount;
 653         initializations = f.initializations;
 654     }
 655 
 656     /**
 657      * Returns the output frame local variable type at the given index.
 658      *
 659      * @param local
 660      *            the index of the local that must be returned.
 661      * @return the output frame local variable type at the given index.
 662      */
 663     private int get(final int local) {
 664         if (outputLocals == null || local >= outputLocals.length) {
 665             // this local has never been assigned in this basic block,
 666             // so it is still equal to its value in the input frame
 667             return LOCAL | local;
 668         } else {
 669             int type = outputLocals[local];
 670             if (type == 0) {
 671                 // this local has never been assigned in this basic block,
 672                 // so it is still equal to its value in the input frame
 673                 type = outputLocals[local] = LOCAL | local;
 674             }
 675             return type;
 676         }


 701 
 702     /**
 703      * Pushes a new type onto the output frame stack.
 704      *
 705      * @param type
 706      *            the type that must be pushed.
 707      */
 708     private void push(final int type) {
 709         // creates and/or resizes the output stack array if necessary
 710         if (outputStack == null) {
 711             outputStack = new int[10];
 712         }
 713         int n = outputStack.length;
 714         if (outputStackTop >= n) {
 715             int[] t = new int[Math.max(outputStackTop + 1, 2 * n)];
 716             System.arraycopy(outputStack, 0, t, 0, n);
 717             outputStack = t;
 718         }
 719         // pushes the type on the output stack
 720         outputStack[outputStackTop++] = type;
 721         // updates the maximum height reached by the output stack, if needed
 722         int top = owner.inputStackTop + outputStackTop;
 723         if (top > owner.outputStackMax) {
 724             owner.outputStackMax = top;
 725         }
 726     }
 727 
 728     /**
 729      * Pushes a new type onto the output frame stack.
 730      *
 731      * @param cw
 732      *            the ClassWriter to which this label belongs.
 733      * @param desc
 734      *            the descriptor of the type to be pushed. Can also be a method
 735      *            descriptor (in this case this method pushes its return type
 736      *            onto the output frame stack).
 737      */
 738     private void push(final ClassWriter cw, final String desc) {
 739         int type = type(cw, desc);
 740         if (type != 0) {
 741             push(type);
 742             if (type == LONG || type == DOUBLE) {
 743                 push(TOP);
 744             }
 745         }
 746     }
 747 
 748     /**
 749      * Returns the int encoding of the given type.
 750      *
 751      * @param cw
 752      *            the ClassWriter to which this label belongs.
 753      * @param desc
 754      *            a type descriptor.
 755      * @return the int encoding of the given type.
 756      */
 757     static int type(final ClassWriter cw, final String desc) {
 758         String t;
 759         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
 760         switch (desc.charAt(index)) {
 761         case 'V':
 762             return 0;
 763         case 'Z':
 764         case 'C':
 765         case 'B':
 766         case 'S':
 767         case 'I':
 768             return INTEGER;
 769         case 'F':
 770             return FLOAT;
 771         case 'J':
 772             return LONG;
 773         case 'D':
 774             return DOUBLE;
 775         case 'L':
 776             // stores the internal name, not the descriptor!
 777             t = desc.substring(index + 1, desc.length() - 1);


 925             if (t == u) {
 926                 return s;
 927             }
 928         }
 929         return t;
 930     }
 931 
 932     /**
 933      * Initializes the input frame of the first basic block from the method
 934      * descriptor.
 935      *
 936      * @param cw
 937      *            the ClassWriter to which this label belongs.
 938      * @param access
 939      *            the access flags of the method to which this label belongs.
 940      * @param args
 941      *            the formal parameter types of this method.
 942      * @param maxLocals
 943      *            the maximum number of local variables of this method.
 944      */
 945     final void initInputFrame(final ClassWriter cw, final int access,
 946             final Type[] args, final int maxLocals) {
 947         inputLocals = new int[maxLocals];
 948         inputStack = new int[0];
 949         int i = 0;
 950         if ((access & Opcodes.ACC_STATIC) == 0) {
 951             if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) {
 952                 inputLocals[i++] = OBJECT | cw.addType(cw.thisName);
 953             } else {
 954                 inputLocals[i++] = UNINITIALIZED_THIS;
 955             }
 956         }
 957         for (int j = 0; j < args.length; ++j) {
 958             int t = type(cw, args[j].getDescriptor());
 959             inputLocals[i++] = t;
 960             if (t == LONG || t == DOUBLE) {
 961                 inputLocals[i++] = TOP;
 962             }
 963         }
 964         while (i < maxLocals) {
 965             inputLocals[i++] = TOP;


1068             break;
1069         case Opcodes.LALOAD:
1070         case Opcodes.D2L:
1071             pop(2);
1072             push(LONG);
1073             push(TOP);
1074             break;
1075         case Opcodes.FALOAD:
1076             pop(2);
1077             push(FLOAT);
1078             break;
1079         case Opcodes.DALOAD:
1080         case Opcodes.L2D:
1081             pop(2);
1082             push(DOUBLE);
1083             push(TOP);
1084             break;
1085         case Opcodes.AALOAD:
1086             pop(1);
1087             t1 = pop();
1088             push(t1 == NULL ? t1 : ELEMENT_OF + t1);
1089             break;
1090         case Opcodes.ISTORE:
1091         case Opcodes.FSTORE:
1092         case Opcodes.ASTORE:
1093             t1 = pop();
1094             set(arg, t1);
1095             if (arg > 0) {
1096                 t2 = get(arg - 1);
1097                 // if t2 is of kind STACK or LOCAL we cannot know its size!
1098                 if (t2 == LONG || t2 == DOUBLE) {
1099                     set(arg - 1, TOP);
1100                 } else if ((t2 & KIND) != BASE) {
1101                     set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
1102                 }
1103             }
1104             break;
1105         case Opcodes.LSTORE:
1106         case Opcodes.DSTORE:
1107             pop(1);
1108             t1 = pop();


1399             push(cw, item.strVal1);
1400             break;
1401         }
1402     }
1403 
1404     /**
1405      * Merges the input frame of the given basic block with the input and output
1406      * frames of this basic block. Returns <tt>true</tt> if the input frame of
1407      * the given label has been changed by this operation.
1408      *
1409      * @param cw
1410      *            the ClassWriter to which this label belongs.
1411      * @param frame
1412      *            the basic block whose input frame must be updated.
1413      * @param edge
1414      *            the kind of the {@link Edge} between this label and 'label'.
1415      *            See {@link Edge#info}.
1416      * @return <tt>true</tt> if the input frame of the given label has been
1417      *         changed by this operation.
1418      */
1419     final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
1420         boolean changed = false;
1421         int i, s, dim, kind, t;
1422 
1423         int nLocal = inputLocals.length;
1424         int nStack = inputStack.length;
1425         if (frame.inputLocals == null) {
1426             frame.inputLocals = new int[nLocal];
1427             changed = true;
1428         }
1429 
1430         for (i = 0; i < nLocal; ++i) {
1431             if (outputLocals != null && i < outputLocals.length) {
1432                 s = outputLocals[i];
1433                 if (s == 0) {
1434                     t = inputLocals[i];
1435                 } else {
1436                     dim = s & DIM;
1437                     kind = s & KIND;
1438                     if (kind == BASE) {
1439                         t = s;


< prev index next >