⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classwriter.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        return out.data;
    }

    // ------------------------------------------------------------------------
    // Utility methods: constant pool management
    // ------------------------------------------------------------------------

    /**
     * Adds a number or string constant to the constant pool of the class being
     * build. Does nothing if the constant pool already contains a similar item.
     * 
     * @param cst the value of the constant to be added to the constant pool.
     *        This parameter must be an {@link Integer}, a {@link Float}, a
     *        {@link Long}, a {@link Double}, a {@link String} or a
     *        {@link Type}.
     * @return a new or already existing constant item with the given value.
     */
    Item newConstItem(final Object cst) {
        if ( cst instanceof Integer ) {
            final int val = ((Integer) cst).intValue();
            return newInteger( val );
        } else if ( cst instanceof Byte ) {
            final int val = ((Byte) cst).intValue();
            return newInteger( val );
        } else if ( cst instanceof Character ) {
            final int val = ((Character) cst).charValue();
            return newInteger( val );
        } else if ( cst instanceof Short ) {
            final int val = ((Short) cst).intValue();
            return newInteger( val );
        } else if ( cst instanceof Boolean ) {
            final int val = ((Boolean) cst).booleanValue() ? 1 : 0;
            return newInteger( val );
        } else if ( cst instanceof Float ) {
            final float val = ((Float) cst).floatValue();
            return newFloat( val );
        } else if ( cst instanceof Long ) {
            final long val = ((Long) cst).longValue();
            return newLong( val );
        } else if ( cst instanceof Double ) {
            final double val = ((Double) cst).doubleValue();
            return newDouble( val );
        } else if ( cst instanceof String ) {
            return newString( (String) cst );
        } else if ( cst instanceof Type ) {
            final Type t = (Type) cst;
            return newClassItem( t.getSort() == Type.OBJECT ? t.getInternalName() : t.getDescriptor() );
        } else {
            throw new IllegalArgumentException( "value " + cst );
        }
    }

    /**
     * Adds a number or string constant to the constant pool of the class being
     * build. Does nothing if the constant pool already contains a similar item.
     * <i>This method is intended for {@link Attribute} sub classes, and is
     * normally not needed by class generators or adapters.</i>
     * 
     * @param cst the value of the constant to be added to the constant pool.
     *        This parameter must be an {@link Integer}, a {@link Float}, a
     *        {@link Long}, a {@link Double} or a {@link String}.
     * @return the index of a new or already existing constant item with the
     *         given value.
     */
    public int newConst(final Object cst) {
        return newConstItem( cst ).index;
    }

    /**
     * Adds an UTF8 string to the constant pool of the class being build. Does
     * nothing if the constant pool already contains a similar item. <i>This
     * method is intended for {@link Attribute} sub classes, and is normally not
     * needed by class generators or adapters.</i>
     * 
     * @param value the String value.
     * @return the index of a new or already existing UTF8 item.
     */
    public int newUTF8(final String value) {
        this.key.set( ClassWriter.UTF8,
                      value,
                      null,
                      null );
        Item result = get( this.key );
        if ( result == null ) {
            this.pool.putByte( ClassWriter.UTF8 ).putUTF8( value );
            result = new Item( this.index++,
                               this.key );
            put( result );
        }
        return result.index;
    }

    /**
     * Adds a class reference to the constant pool of the class being build.
     * Does nothing if the constant pool already contains a similar item.
     * <i>This method is intended for {@link Attribute} sub classes, and is
     * normally not needed by class generators or adapters.</i>
     * 
     * @param value the internal name of the class.
     * @return the index of a new or already existing class reference item.
     */
    public int newClass(final String value) {
        return newClassItem( value ).index;
    }

    /**
     * Adds a class reference to the constant pool of the class being build.
     * Does nothing if the constant pool already contains a similar item.
     * <i>This method is intended for {@link Attribute} sub classes, and is
     * normally not needed by class generators or adapters.</i>
     * 
     * @param value the internal name of the class.
     * @return a new or already existing class reference item.
     */
    private Item newClassItem(final String value) {
        this.key2.set( ClassWriter.CLASS,
                       value,
                       null,
                       null );
        Item result = get( this.key2 );
        if ( result == null ) {
            this.pool.put12( ClassWriter.CLASS,
                             newUTF8( value ) );
            result = new Item( this.index++,
                               this.key2 );
            put( result );
        }
        return result;
    }

    /**
     * Adds a field reference to the constant pool of the class being build.
     * Does nothing if the constant pool already contains a similar item.
     * <i>This method is intended for {@link Attribute} sub classes, and is
     * normally not needed by class generators or adapters.</i>
     * 
     * @param owner the internal name of the field's owner class.
     * @param name the field's name.
     * @param desc the field's descriptor.
     * @return the index of a new or already existing field reference item.
     */
    public int newField(final String owner,
                        final String name,
                        final String desc) {
        this.key3.set( ClassWriter.FIELD,
                       owner,
                       name,
                       desc );
        Item result = get( this.key3 );
        if ( result == null ) {
            put122( ClassWriter.FIELD,
                    newClass( owner ),
                    newNameType( name,
                                 desc ) );
            result = new Item( this.index++,
                               this.key3 );
            put( result );
        }
        return result.index;
    }

    /**
     * Adds a method reference to the constant pool of the class being build.
     * Does nothing if the constant pool already contains a similar item.
     * 
     * @param owner the internal name of the method's owner class.
     * @param name the method's name.
     * @param desc the method's descriptor.
     * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
     * @return a new or already existing method reference item.
     */
    Item newMethodItem(final String owner,
                       final String name,
                       final String desc,
                       final boolean itf) {
        final int type = itf ? ClassWriter.IMETH : ClassWriter.METH;
        this.key3.set( type,
                       owner,
                       name,
                       desc );
        Item result = get( this.key3 );
        if ( result == null ) {
            put122( type,
                    newClass( owner ),
                    newNameType( name,
                                 desc ) );
            result = new Item( this.index++,
                               this.key3 );
            put( result );
        }
        return result;
    }

    /**
     * Adds a method reference to the constant pool of the class being build.
     * Does nothing if the constant pool already contains a similar item.
     * <i>This method is intended for {@link Attribute} sub classes, and is
     * normally not needed by class generators or adapters.</i>
     * 
     * @param owner the internal name of the method's owner class.
     * @param name the method's name.
     * @param desc the method's descriptor.
     * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
     * @return the index of a new or already existing method reference item.
     */
    public int newMethod(final String owner,
                         final String name,
                         final String desc,
                         final boolean itf) {
        return newMethodItem( owner,
                              name,
                              desc,
                              itf ).index;
    }

    /**
     * Adds an integer to the constant pool of the class being build. Does
     * nothing if the constant pool already contains a similar item.
     * 
     * @param value the int value.
     * @return a new or already existing int item.
     */
    Item newInteger(final int value) {
        this.key.set( value );
        Item result = get( this.key );
        if ( result == null ) {
            this.pool.putByte( ClassWriter.INT ).putInt( value );
            result = new Item( this.index++,
                               this.key );
            put( result );
        }
        return result;
    }

    /**
     * Adds a float to the constant pool of the class being build. Does nothing
     * if the constant pool already contains a similar item.
     * 
     * @param value the float value.
     * @return a new or already existing float item.
     */
    Item newFloat(final float value) {
        this.key.set( value );
        Item result = get( this.key );
        if ( result == null ) {
            this.pool.putByte( ClassWriter.FLOAT ).putInt( Float.floatToIntBits( value ) );
            result = new Item( this.index++,
                               this.key );
            put( result );
        }
        return result;
    }

    /**
     * Adds a long to the constant pool of the class being build. Does nothing
     * if the constant pool already contains a similar item.
     * 
     * @param value the long value.
     * @return a new or already existing long item.
     */
    Item newLong(final long value) {
        this.key.set( value );
        Item result = get( this.key );
        if ( result == null ) {
            this.pool.putByte( ClassWriter.LONG ).putLong( value );
            result = new Item( this.index,
                               this.key );
            put( result );
            this.index += 2;
        }
        return result;
    }

    /**
     * Adds a double to the constant pool of the class being build. Does nothing
     * if the constant pool already contains a similar item.
     * 
     * @param value the double value.
     * @return a new or already existing double item.
     */
    Item newDouble(final double value) {
        this.key.set( value );
        Item result = get( this.key );
        if ( result == null ) {
            this.pool.putByte( ClassWriter.DOUBLE ).putLong( Double.doubleToLongBits( value ) );
            result = new Item( this.index,
                               this.key );
            put( result );
            this.index += 2;
        }
        return result;
    }

    /**
     * Adds a string to the constant pool of the class being build. Does nothing
     * if the constant pool already contains a similar item.
     * 
     * @param value the String value.
     * @return a new or already existing string item.
     */
    private Item newString(final String value) {
        this.key2.set( ClassWriter.STR,
                       value,
                       null,
                       null );
        Item result = get( this.key2 );
        if ( result == null ) {
            this.pool.put12( ClassWriter.STR,
                             newUTF8( value ) );
            result = new Item( this.index++,
                               this.key2 );
            put( result );
        }
        return result;
    }

    /**
     * Adds a name and type to the constant pool of the class being build. Does
     * nothing if the constant pool already contains a similar item. <i>This
     * method is intended for {@link Attribute} sub classes, and is normally not
     * needed by class generators or adapters.</i>
     * 
     * @param name a name.
     * @param desc a type descriptor.
     * @return the index of a new or already existing name and type item.
     */
    public int newNameType(final String name,
                           final String desc) {
        this.key2.set( ClassWriter.NAME_TYPE,
                       name,
                       desc,
                       null );
        Item result = get( this.key2 );
        if ( result == null ) {
            put122( ClassWriter.NAME_TYPE,
                    newUTF8( name ),
                    newUTF8( desc ) );
            result = new Item( this.index++,
                               this.key2 );
            put( result );
        }
        return result.index;
    }

    /**
     * Returns the constant pool's hash table item which is equal to the given
     * item.
     * 
     * @param key a constant pool item.
     * @return the constant pool's hash table item which is equal to the given
     *         item, or <tt>null</tt> if there is no such item.
     */
    private Item get(final Item key) {
        Item i = this.items[key.hashCode % this.items.length];
        while ( i != null && !key.isEqualTo( i ) ) {
            i = i.next;
        }
        return i;
    }

    /**
     * Puts the given item in the constant pool's hash table. The hash table
     * <i>must</i> not already contains this item.
     * 
     * @param i the item to be added to the constant pool's hash table.
     */
    private void put(final Item i) {
        if ( this.index > this.threshold ) {
            final int ll = this.items.length;
            final int nl = ll * 2 + 1;
            final Item[] newItems = new Item[nl];
            for ( int l = ll - 1; l >= 0; --l ) {
                Item j = this.items[l];
                while ( j != null ) {
                    final int index = j.hashCode % newItems.length;
                    final Item k = j.next;
                    j.next = newItems[index];
                    newItems[index] = j;
                    j = k;
                }
            }
            this.items = newItems;
            this.threshold = (int) (nl * 0.75);
        }
        final int index = i.hashCode % this.items.length;
        i.next = this.items[index];
        this.items[index] = i;
    }

    /**
     * Puts one byte and two shorts into the constant pool.
     * 
     * @param b a byte.
     * @param s1 a short.
     * @param s2 another short.
     */
    private void put122(final int b,
                        final int s1,
                        final int s2) {
        this.pool.put12( b,
                         s1 ).putShort( s2 );
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -