[jboss-cvs] javassist/src/main/javassist/bytecode ...

Shigeru Chiba chiba at is.titech.ac.jp
Thu May 1 06:47:58 EDT 2008


  User: chiba   
  Date: 08/05/01 06:47:58

  Modified:    src/main/javassist/bytecode     StackMapTable.java
                        LocalVariableAttribute.java CodeAttribute.java
                        Descriptor.java
  Log:
  fixed JASSIST-47 and 60.
  
  Revision  Changes    Path
  1.13      +88 -0     javassist/src/main/javassist/bytecode/StackMapTable.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: StackMapTable.java
  ===================================================================
  RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/StackMapTable.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -b -r1.12 -r1.13
  --- StackMapTable.java	15 Apr 2008 07:39:24 -0000	1.12
  +++ StackMapTable.java	1 May 2008 10:47:58 -0000	1.13
  @@ -425,6 +425,94 @@
       }
   
       /**
  +     * Updates this stack map table when a new local variable is added.
  +     *
  +     * @param index          the index of the added local variable.
  +     * @param tag            the type tag of that local variable. 
  +     * @param classInfo      the index of the <code>CONSTANT_Class_info</code> structure
  +     *                       in a constant pool table.  This should be zero unless the tag
  +     *                       is <code>ITEM_Object</code>.
  +     *
  +     * @see #typeTagOf(char)
  +     * @see ConstPool
  +     */
  +    public void insertLocal(int index, int tag, int classInfo)
  +        throws BadBytecode
  +    {
  +        byte[] data = new InsertLocal(this.get(), index, tag, classInfo).doit();
  +        this.set(data);
  +    }
  +
  +    /**
  +     * Returns the tag of the type specified by the
  +     * descriptor.  This method returns <code>INTEGER</code>
  +     * unless the descriptor is either D (double), F (float),
  +     * J (long), L (class type), or [ (array).
  +     *
  +     * @param descriptor        the type descriptor.
  +     * @see Descriptor
  +     */
  +    public static int typeTagOf(char descriptor) {
  +        switch (descriptor) {
  +        case 'D' :
  +            return DOUBLE;
  +        case 'F' :
  +            return FLOAT;
  +        case 'J' :
  +            return LONG;
  +        case 'L' :
  +        case '[' :
  +            return OBJECT;
  +        // case 'V' :
  +        default :
  +            return INTEGER;
  +        }
  +    }
  +
  +    static class InsertLocal extends SimpleCopy {
  +        private int varIndex;
  +        private int varTag, varData;
  +
  +        public InsertLocal(byte[] data, int varIndex, int varTag, int varData) {
  +            super(data);
  +            this.varIndex = varIndex;
  +            this.varTag = varTag;
  +            this.varData = varData;
  +        }
  +
  +        public void fullFrame(int pos, int offsetDelta, int[] localTags, int[] localData,
  +                              int[] stackTags, int[] stackData) {
  +            int len = localTags.length;
  +            if (len < varIndex) {
  +                super.fullFrame(pos, offsetDelta, localTags, localData, stackTags, stackData);
  +                return;
  +            }
  +
  +            int typeSize = (varTag == LONG || varTag == DOUBLE) ? 2 : 1;
  +            int[] localTags2 = new int[len + typeSize];
  +            int[] localData2 = new int[len + typeSize];
  +            int index = varIndex;
  +            int j = 0;
  +            for (int i = 0; i < len; i++) {
  +                if (j == index)
  +                    j += typeSize;
  +
  +                localTags2[j] = localTags[i];
  +                localData2[j++] = localData[i];
  +            }
  +
  +            localTags2[index] = varTag;
  +            localData2[index] = varData;
  +            if (typeSize > 1) {
  +                localTags2[index + 1] = TOP;
  +                localData2[index + 1] = 0;
  +            }
  +
  +            super.fullFrame(pos, offsetDelta, localTags2, localData2, stackTags, stackData);
  +        }
  +    }
  +
  +    /**
        * A writer of stack map tables.
        */
       public static class Writer {
  
  
  
  1.12      +16 -0     javassist/src/main/javassist/bytecode/LocalVariableAttribute.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: LocalVariableAttribute.java
  ===================================================================
  RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/LocalVariableAttribute.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -b -r1.11 -r1.12
  --- LocalVariableAttribute.java	13 Aug 2007 09:06:31 -0000	1.11
  +++ LocalVariableAttribute.java	1 May 2008 10:47:58 -0000	1.12
  @@ -92,6 +92,22 @@
       }
   
       /**
  +     * For each <code>local_variable_table[i].index</code>,
  +     * this method increases <code>index</code> by <code>delta</code>.
  +     *
  +     * @param lessThan      the index does not change if it
  +     *                      is less than this value.
  +     */
  +    public void shiftIndex(int lessThan, int delta) {
  +        int size = info.length;
  +        for (int i = 2; i < size; i += 10){
  +            int org = ByteArray.readU16bit(info, i + 8);
  +            if (org >= lessThan)
  +                ByteArray.write16bit(org + delta, info, i + 8);
  +        }
  +    }
  +
  +    /**
        * Returns <code>local_variable_table_length</code>.
        * This represents the number of entries in the table.
        */
  
  
  
  1.15      +144 -15   javassist/src/main/javassist/bytecode/CodeAttribute.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: CodeAttribute.java
  ===================================================================
  RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/CodeAttribute.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -b -r1.14 -r1.15
  --- CodeAttribute.java	14 Nov 2007 08:39:42 -0000	1.14
  +++ CodeAttribute.java	1 May 2008 10:47:58 -0000	1.15
  @@ -395,9 +395,8 @@
           newcode[i] = (byte)(index >> 8);
           newcode[i + 1] = (byte)index;
       }
  -}
   
  -final class LdcEntry {
  +    static class LdcEntry {
       LdcEntry next;
       int where;
       int index;
  @@ -416,4 +415,134 @@
   
           return code;
       }
  +    }
  +
  +    /**
  +     * Changes the index numbers of the local variables
  +     * to append a new parameter.
  +     * This method does not update <code>LocalVariableAttribute</code>
  +     * or <code>StackMapTable</code>.  These attributes must be
  +     * explicitly updated.
  +     *
  +     * @param where         the index of the new parameter.
  +     * @param size         the type size of the new parameter (1 or 2).
  +     *
  +     * @see LocalVariableAttribute#shiftIndex(int, int)
  +     * @see StackMapTable#insertLocal(int, int, int)
  +     */
  +    public void insertLocalVar(int where, int size) throws BadBytecode {
  +        CodeIterator ci = iterator();
  +        while (ci.hasNext())
  +            shiftIndex(ci, where, size);
  +
  +        setMaxLocals(getMaxLocals() + size);
  +    }
  +
  +    /**
  +     * @param lessThan      If the index of the local variable is
  +     *                      less than this value, it does not change.
  +     *                      Otherwise, the index is increased.
  +     * @param delta         the indexes of the local variables are
  +     *                      increased by this value.
  +     */
  +    private static void shiftIndex(CodeIterator ci, int lessThan, int delta) throws BadBytecode {
  +        int index = ci.next();
  +        int opcode = ci.byteAt(index);
  +        if (opcode < ILOAD)
  +            return;
  +        else if (opcode < IASTORE) {
  +            if (opcode < ILOAD_0) {
  +                // iload, lload, fload, dload, aload
  +                shiftIndex8(ci, index, opcode, lessThan, delta);
  +            }
  +            else if (opcode < IALOAD) {
  +                // iload_0, ..., aload_3
  +                shiftIndex0(ci, index, opcode, lessThan, delta, ILOAD_0, ILOAD);
  +            }
  +            else if (opcode < ISTORE)
  +                return;
  +            else if (opcode < ISTORE_0) {
  +                // istore, lstore, ...
  +                shiftIndex8(ci, index, opcode, lessThan, delta);
  +            }
  +            else {
  +                // istore_0, ..., astore_3
  +                shiftIndex0(ci, index, opcode, lessThan, delta, ISTORE_0, ISTORE);
  +            }
  +        }
  +        else if (opcode == IINC) {
  +            int var = ci.byteAt(index + 1);
  +            if (var < lessThan)
  +                return;
  +
  +            var += delta;
  +            if (var < 0x100)
  +                ci.writeByte(var, index + 1);
  +            else {
  +                int plus = ci.byteAt(index + 2);
  +                ci.insertExGap(3);
  +                ci.writeByte(WIDE, index);
  +                ci.writeByte(IINC, index + 1);
  +                ci.write16bit(var, index + 2);
  +                ci.write16bit(plus, index + 4);
  +            }
  +        }
  +        else if (opcode == RET)
  +            shiftIndex8(ci, index, opcode, lessThan, delta);
  +        else if (opcode == WIDE) {
  +            int var = ci.u16bitAt(index + 2);
  +            if (var < lessThan)
  +                return;
  +
  +            var += delta;
  +            ci.write16bit(var, index + 2);
  +        }
  +    }
  +
  +    private static void shiftIndex8(CodeIterator ci, int index, int opcode,
  +                                    int lessThan, int delta)
  +         throws BadBytecode
  +    {
  +        int var = ci.byteAt(index + 1);
  +        if (var < lessThan)
  +            return;
  +
  +        var += delta;
  +        if (var < 0x100)
  +            ci.writeByte(var, index + 1);
  +        else {
  +            ci.insertExGap(2);
  +            ci.writeByte(WIDE, index);
  +            ci.writeByte(opcode, index + 1);
  +            ci.write16bit(var, index + 2);
  +        }
  +    }
  +
  +    private static void shiftIndex0(CodeIterator ci, int index, int opcode,
  +                                    int lessThan, int delta,
  +                                    int opcode_i_0, int opcode_i)
  +        throws BadBytecode
  +    {
  +        int var = (opcode - opcode_i_0) % 4;
  +        if (var < lessThan)
  +            return;
  +
  +        var += delta;
  +        if (var < 4)
  +            ci.writeByte(opcode + delta, index);
  +        else {
  +            opcode = (opcode - opcode_i_0) / 4 + opcode_i;
  +            if (var < 0x100) {
  +                ci.insertExGap(1);
  +                ci.writeByte(opcode, index);
  +                ci.writeByte(var, index + 1);
  +            }
  +            else {
  +                ci.insertExGap(3);
  +                ci.writeByte(WIDE, index);
  +                ci.writeByte(opcode, index + 1);
  +                ci.write16bit(var, index + 2);
  +            }
  +        }
  +    }
   }
  
  
  
  1.22      +37 -0     javassist/src/main/javassist/bytecode/Descriptor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Descriptor.java
  ===================================================================
  RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/Descriptor.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -b -r1.21 -r1.22
  --- Descriptor.java	4 Jun 2007 03:11:09 -0000	1.21
  +++ Descriptor.java	1 May 2008 10:47:58 -0000	1.22
  @@ -353,6 +353,43 @@
       }
   
       /**
  +     * Appends a parameter type to the parameter list represented
  +     * by the given descriptor.  The appended parameter becomes
  +     * the last parameter.
  +     *
  +     * @param type      the type of the appended parameter.
  +     * @param desc      descriptor
  +     */
  +    public static String appendParameter(CtClass type, String descriptor) {
  +        int i = descriptor.indexOf(')');
  +        if (i < 0)
  +            return descriptor;
  +        else {
  +            StringBuffer newdesc = new StringBuffer();
  +            newdesc.append(descriptor.substring(0, i));
  +            toDescriptor(newdesc, type);
  +            newdesc.append(descriptor.substring(i));
  +            return newdesc.toString();
  +        }
  +    }
  +
  +    /**
  +     * Inserts a parameter type at the beginning of the parameter
  +     * list represented
  +     * by the given descriptor.
  +     *
  +     * @param type              the type of the inserted parameter.
  +     * @param descriptor        the descriptor of the method.
  +     */
  +    public static String insertParameter(CtClass type,
  +                                         String descriptor) {
  +        if (descriptor.charAt(0) != '(')
  +            return descriptor;
  +        else
  +            return "(" + of(type) + descriptor.substring(1);
  +    }
  +
  +    /**
        * Changes the return type included in the given descriptor.
        *
        * <p><code>classname</code> must not be an array type.
  
  
  



More information about the jboss-cvs-commits mailing list