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;
|