< 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

@@ -61,11 +61,11 @@
 /**
  * Information about the input and output stack map frames of a basic block.
  *
  * @author Eric Bruneton
  */
-final class Frame {
+class Frame {
 
     /*
      * Frames are computed in a two steps process: during the visit of each
      * instruction, the state of the frame at the end of current basic block is
      * updated by simulating the action of the instruction on the previous state

@@ -523,11 +523,11 @@
      * the output stack relatively to the top of the input stack.
      *
      * When the stack map frames are completely computed, this field is the
      * actual number of types in {@link #outputStack}.
      */
-    private int outputStackTop;
+    int outputStackTop;
 
     /**
      * Number of types that are initialized in the basic block.
      *
      * @see #initializations

@@ -548,10 +548,114 @@
      * description of the algorithm).
      */
     private int[] initializations;
 
     /**
+     * Sets this frame to the given value.
+     *
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nLocal
+     *            the number of local variables.
+     * @param local
+     *            the local variable types. Primitive types are represented by
+     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+     *            represented by a single element). Reference types are
+     *            represented by String objects (representing internal names),
+     *            and uninitialized types by Label objects (this label
+     *            designates the NEW instruction that created this uninitialized
+     *            value).
+     * @param nStack
+     *            the number of operand stack elements.
+     * @param stack
+     *            the operand stack types (same format as the "local" array).
+     */
+    final void set(ClassWriter cw, final int nLocal, final Object[] local,
+            final int nStack, final Object[] stack) {
+        int i = convert(cw, nLocal, local, inputLocals);
+        while (i < local.length) {
+            inputLocals[i++] = TOP;
+        }
+        int nStackTop = 0;
+        for (int j = 0; j < nStack; ++j) {
+            if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) {
+                ++nStackTop;
+            }
+        }
+        inputStack = new int[nStack + nStackTop];
+        convert(cw, nStack, stack, inputStack);
+        outputStackTop = 0;
+        initializationCount = 0;
+    }
+
+    /**
+     * Converts types from the MethodWriter.visitFrame() format to the Frame
+     * format.
+     *
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nInput
+     *            the number of types to convert.
+     * @param input
+     *            the types to convert. Primitive types are represented by
+     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+     *            represented by a single element). Reference types are
+     *            represented by String objects (representing internal names),
+     *            and uninitialized types by Label objects (this label
+     *            designates the NEW instruction that created this uninitialized
+     *            value).
+     * @param output
+     *            where to store the converted types.
+     * @return the number of output elements.
+     */
+    private static int convert(ClassWriter cw, int nInput, Object[] input,
+            int[] output) {
+        int i = 0;
+        for (int j = 0; j < nInput; ++j) {
+            if (input[j] instanceof Integer) {
+                output[i++] = BASE | ((Integer) input[j]).intValue();
+                if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) {
+                    output[i++] = TOP;
+                }
+            } else if (input[j] instanceof String) {
+                output[i++] = type(cw, Type.getObjectType((String) input[j])
+                        .getDescriptor());
+            } else {
+                output[i++] = UNINITIALIZED
+                        | cw.addUninitializedType("",
+                                ((Label) input[j]).position);
+            }
+        }
+        return i;
+    }
+
+    /**
+     * Sets this frame to the value of the given frame. WARNING: after this
+     * method is called the two frames share the same data structures. It is
+     * recommended to discard the given frame f to avoid unexpected side
+     * effects.
+     *
+     * @param f
+     *            The new frame value.
+     */
+    final void set(final Frame f) {
+        inputLocals = f.inputLocals;
+        inputStack = f.inputStack;
+        outputLocals = f.outputLocals;
+        outputStack = f.outputStack;
+        outputStackTop = f.outputStackTop;
+        initializationCount = f.initializationCount;
+        initializations = f.initializations;
+    }
+
+    /**
      * Returns the output frame local variable type at the given index.
      *
      * @param local
      *            the index of the local that must be returned.
      * @return the output frame local variable type at the given index.

@@ -612,11 +716,11 @@
             System.arraycopy(outputStack, 0, t, 0, n);
             outputStack = t;
         }
         // pushes the type on the output stack
         outputStack[outputStackTop++] = type;
-        // updates the maximun height reached by the output stack, if needed
+        // updates the maximum height reached by the output stack, if needed
         int top = owner.inputStackTop + outputStackTop;
         if (top > owner.outputStackMax) {
             owner.outputStackMax = top;
         }
     }

@@ -648,11 +752,11 @@
      *            the ClassWriter to which this label belongs.
      * @param desc
      *            a type descriptor.
      * @return the int encoding of the given type.
      */
-    private static int type(final ClassWriter cw, final String desc) {
+    static int type(final ClassWriter cw, final String desc) {
         String t;
         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
         switch (desc.charAt(index)) {
         case 'V':
             return 0;

@@ -836,11 +940,11 @@
      * @param args
      *            the formal parameter types of this method.
      * @param maxLocals
      *            the maximum number of local variables of this method.
      */
-    void initInputFrame(final ClassWriter cw, final int access,
+    final void initInputFrame(final ClassWriter cw, final int access,
             final Type[] args, final int maxLocals) {
         inputLocals = new int[maxLocals];
         inputStack = new int[0];
         int i = 0;
         if ((access & Opcodes.ACC_STATIC) == 0) {

@@ -979,11 +1083,11 @@
             push(TOP);
             break;
         case Opcodes.AALOAD:
             pop(1);
             t1 = pop();
-            push(ELEMENT_OF + t1);
+            push(t1 == NULL ? t1 : ELEMENT_OF + t1);
             break;
         case Opcodes.ISTORE:
         case Opcodes.FSTORE:
         case Opcodes.ASTORE:
             t1 = pop();

@@ -1310,11 +1414,11 @@
      *            the kind of the {@link Edge} between this label and 'label'.
      *            See {@link Edge#info}.
      * @return <tt>true</tt> if the input frame of the given label has been
      *         changed by this operation.
      */
-    boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+    final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
         boolean changed = false;
         int i, s, dim, kind, t;
 
         int nLocal = inputLocals.length;
         int nStack = inputStack.length;
< prev index next >