src/org/nutz/repo/org/objectweb/asm/ClassWriter.java
Item newInvokeDynamicItem(final String name, final String desc,
            final Handle bsm, final Object... bsmArgs) {
        // cache for performance
        ByteVector bootstrapMethods = this.bootstrapMethods;
        if (bootstrapMethods == null) {
            bootstrapMethods = this.bootstrapMethods = new ByteVector();
        }

        int position = bootstrapMethods.length; // record current position

        int hashCode = bsm.hashCode();
        bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
                bsm.desc, bsm.isInterface()));

        int argsLength = bsmArgs.length;
        bootstrapMethods.putShort(argsLength);

        for (int i = 0; i < argsLength; i++) {
            Object bsmArg = bsmArgs[i];
            hashCode ^= bsmArg.hashCode();
            bootstrapMethods.putShort(newConst(bsmArg));
        }

        byte[] data = bootstrapMethods.data;
        int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
        hashCode &= 0x7FFFFFFF;
        Item result = items[hashCode % items.length];
        loop: while (result != null) {
            if (result.type != BSM || result.hashCode != hashCode) {
                result = result.next;
                continue;
            }

            // because the data encode the size of the argument
            // we don't need to test if these size are equals
            int resultPosition = result.intVal;
            for (int p = 0; p < length; p++) {
                if (data[position + p] != data[resultPosition + p]) {
                    result = result.next;
                    continue loop;
                }
            }
            break;
        }

        int bootstrapMethodIndex;
        if (result != null) {
            bootstrapMethodIndex = result.index;
            bootstrapMethods.length = position; // revert to old position
        } else {
            bootstrapMethodIndex = bootstrapMethodsCount++;
            result = new Item(bootstrapMethodIndex);
            result.set(position, hashCode);
            put(result);
        }

        // now, create the InvokeDynamic constant
        key3.set(name, desc, bootstrapMethodIndex);
        result = get(key3);
        if (result == null) {
            put122(INDY, bootstrapMethodIndex, newNameType(name, desc));
            result = new Item(index++, key3);
            put(result);
        }
        return result;
    }
Item newInvokeDynamicItem(final String name, final String desc,
            final Handle bsm, final Object... bsmArgs) {
        // cache for performance
        ByteVector bootstrapMethods = this.bootstrapMethods;
        if (bootstrapMethods == null) {
            bootstrapMethods = this.bootstrapMethods = new ByteVector();
        }

        int position = bootstrapMethods.length; // record current position

        int hashCode = bsm.hashCode();
        bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
                bsm.desc, bsm.isInterface()));

        int argsLength = bsmArgs.length;
        bootstrapMethods.putShort(argsLength);

        for (int i = 0; i < argsLength; i++) {
            Object bsmArg = bsmArgs[i];
            hashCode ^= bsmArg.hashCode();
            bootstrapMethods.putShort(newConst(bsmArg));
        }

        byte[] data = bootstrapMethods.data;
        int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
        hashCode &= 0x7FFFFFFF;
        Item result = items[hashCode % items.length];
        loop: while (result != null) {
            if (result.type != BSM || result.hashCode != hashCode) {
                result = result.next;
                continue;
            }

            // because the data encode the size of the argument
            // we don't need to test if these size are equals
            int resultPosition = result.intVal;
            for (int p = 0; p < length; p++) {
                if (data[position + p] != data[resultPosition + p]) {
                    result = result.next;
                    continue loop;
                }
            }
            break;
        }

        int bootstrapMethodIndex;
        if (result != null) {
            bootstrapMethodIndex = result.index;
            bootstrapMethods.length = position; // revert to old position
        } else {
            bootstrapMethodIndex = bootstrapMethodsCount++;
            result = new Item(bootstrapMethodIndex);
            result.set(position, hashCode);
            put(result);
        }

        // now, create the InvokeDynamic constant
        key3.set(name, desc, bootstrapMethodIndex);
        result = get(key3);
        if (result == null) {
            put122(INDY, bootstrapMethodIndex, newNameType(name, desc));
            result = new Item(index++, key3);
            put(result);
        }
        return result;
    }
Item newInvokeDynamicItem ( final String name , final String desc , final Handle bsm , final Object ... bsmArgs ) { // cache for performance ByteVector bootstrapMethods = this . bootstrapMethods ; if ( bootstrapMethods == null ) { bootstrapMethods = this . bootstrapMethods = new ByteVector ( ) ; } int position = bootstrapMethods . length ; // record current position int hashCode = bsm . hashCode ( ) ; bootstrapMethods . putShort ( newHandle ( bsm . tag , bsm . owner , bsm . name , bsm . desc , bsm . isInterface ( ) ) ) ; int argsLength = bsmArgs . length ; bootstrapMethods . putShort ( argsLength ) ; for ( int i = 0 ; i < argsLength ; i ++ ) { Object bsmArg = bsmArgs [ i ] ; hashCode ^= bsmArg . hashCode ( ) ; bootstrapMethods . putShort ( newConst ( bsmArg ) ) ; } byte [ ] data = bootstrapMethods . data ; int length = ( 1 + 1 + argsLength ) << 1 ; // (bsm + argCount + arguments) hashCode &= 0x7FFFFFFF ; Item result = items [ hashCode % items . length ] ; loop : while ( result != null ) { if ( result . type != BSM || result . hashCode != hashCode ) { result = result . next ; continue ; } // because the data encode the size of the argument // we don't need to test if these size are equals int resultPosition = result . intVal ; for ( int p = 0 ; p < length ; p ++ ) { if ( data [ position + p ] != data [ resultPosition + p ] ) { result = result . next ; continue loop ; } } break ; } int bootstrapMethodIndex ; if ( result != null ) { bootstrapMethodIndex = result . index ; bootstrapMethods . length = position ; // revert to old position } else { bootstrapMethodIndex = bootstrapMethodsCount ++ ; result = new Item ( bootstrapMethodIndex ) ; result . set ( position , hashCode ) ; put ( result ) ; } // now, create the InvokeDynamic constant key3 . set ( name , desc , bootstrapMethodIndex ) ; result = get ( key3 ) ; if ( result == null ) { put122 ( INDY , bootstrapMethodIndex , newNameType ( name , desc ) ) ; result = new Item ( index ++ , key3 ) ; put ( result ) ; } return result ; }
Adds an invokedynamic 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 name
name of the invoked method.
@param desc
descriptor of the invoke method.
@param bsm
the bootstrap method.
@param bsmArgs
the bootstrap method constant arguments.

@return a new or an already existing invokedynamic type reference item.
Adds an invokedynamic 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 >