• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.24
/main/src/main/java/mockit/asm/classes/BootstrapMethodsWriter.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.asm.classes;
7

8
import static mockit.asm.jvmConstants.ConstantPoolTypes.INVOKE_DYNAMIC;
9

10
import edu.umd.cs.findbugs.annotations.NonNull;
11

12
import mockit.asm.constantPool.AttributeWriter;
13
import mockit.asm.constantPool.BootstrapMethodItem;
14
import mockit.asm.constantPool.ConstantPoolGeneration;
15
import mockit.asm.constantPool.DynamicItem;
16
import mockit.asm.constantPool.Item;
17
import mockit.asm.constantPool.MethodHandleItem;
18
import mockit.asm.util.ByteVector;
19
import mockit.asm.util.MethodHandle;
20

21
import org.checkerframework.checker.index.qual.NonNegative;
22

23
/**
24
 * Generates the "BootstrapMethods" attribute in a class file being written by a {@link ClassWriter}.
25
 */
26
final class BootstrapMethodsWriter extends AttributeWriter {
27
    @NonNull
28
    private final ByteVector bootstrapMethods;
29
    @NonNegative
30
    private final int bootstrapMethodsCount;
31
    @NonNegative
32
    private final int bsmStartCodeIndex;
33

34
    BootstrapMethodsWriter(@NonNull ConstantPoolGeneration cp, @NonNull ClassReader cr) {
35
        super(cp);
1✔
36

37
        int attrSize = cr.readInt();
1✔
38
        bootstrapMethods = new ByteVector(attrSize + 62);
1✔
39
        bootstrapMethodsCount = cr.readUnsignedShort();
1✔
40

41
        bsmStartCodeIndex = cr.codeIndex;
1✔
42
        bootstrapMethods.putByteArray(cr.code, bsmStartCodeIndex, attrSize - 2);
1✔
43
    }
1✔
44

45
    /**
46
     * Copies the bootstrap method data from the given {@link ClassReader}.
47
     */
48
    void copyBootstrapMethods(@NonNull ClassReader cr, @NonNull Item[] items) {
49
        int previousCodeIndex = cr.codeIndex;
1✔
50
        cr.codeIndex = bsmStartCodeIndex;
1✔
51

52
        for (int bsmIndex = 0, bsmCount = bootstrapMethodsCount; bsmIndex < bsmCount; bsmIndex++) {
1✔
53
            copyBootstrapMethod(cr, items, bsmIndex);
1✔
54
        }
55

56
        cr.codeIndex = previousCodeIndex;
1✔
57
    }
1✔
58

59
    private void copyBootstrapMethod(@NonNull ClassReader cr, @NonNull Item[] items, @NonNegative int bsmIndex) {
60
        int position = cr.codeIndex - bsmStartCodeIndex;
1✔
61
        MethodHandle bsm = cr.readMethodHandle();
1✔
62
        int hashCode = bsm.hashCode();
1✔
63

64
        for (int bsmArgCount = cr.readUnsignedShort(); bsmArgCount > 0; bsmArgCount--) {
1✔
65
            Object bsmArg = cr.readConstItem();
1✔
66
            hashCode ^= bsmArg.hashCode();
1✔
67
        }
68

69
        BootstrapMethodItem item = new BootstrapMethodItem(bsmIndex, position, hashCode);
1✔
70
        item.setNext(items);
1✔
71
    }
1✔
72

73
    /**
74
     * Adds an invokedynamic reference to the constant pool of the class being built. Does nothing if the constant pool
75
     * already contains a similar item.
76
     *
77
     * @param name
78
     *            name of the invoked method
79
     * @param desc
80
     *            descriptor of the invoke method
81
     * @param bsm
82
     *            the bootstrap method
83
     * @param bsmArgs
84
     *            the bootstrap method constant arguments
85
     *
86
     * @return a new or an already existing invokedynamic type reference item
87
     */
88
    @NonNull
89
    DynamicItem addInvokeDynamicReference(@NonNull String name, @NonNull String desc, @NonNull MethodHandle bsm,
90
            @NonNull Object... bsmArgs) {
91
        ByteVector methods = bootstrapMethods;
1✔
92
        int position = methods.getLength(); // record current position
1✔
93

94
        MethodHandleItem methodHandleItem = cp.newMethodHandleItem(bsm);
1✔
95
        methods.putShort(methodHandleItem.index);
1✔
96

97
        int argsLength = bsmArgs.length;
1✔
98
        methods.putShort(argsLength);
1✔
99

100
        int hashCode = bsm.hashCode();
1✔
101
        hashCode = putBSMArgs(hashCode, bsmArgs);
1✔
102
        hashCode &= 0x7FFFFFFF;
1✔
103

104
        methods.setLength(position); // revert to old position
1✔
105

106
        BootstrapMethodItem bsmItem = getBSMItem(hashCode);
1✔
107
        return cp.createDynamicItem(INVOKE_DYNAMIC, name, desc, bsmItem.index);
1✔
108
    }
109

110
    private int putBSMArgs(int hashCode, @NonNull Object[] bsmArgs) {
111
        for (Object bsmArg : bsmArgs) {
1✔
112
            hashCode ^= bsmArg.hashCode();
1✔
113

114
            Item constItem = cp.newConstItem(bsmArg);
1✔
115
            bootstrapMethods.putShort(constItem.index);
1✔
116
        }
117

118
        return hashCode;
1✔
119
    }
120

121
    @NonNull
122
    private BootstrapMethodItem getBSMItem(@NonNegative int hashCode) {
123
        Item item = cp.getItem(hashCode);
1✔
124

125
        while (item != null) {
1!
126
            if (item instanceof BootstrapMethodItem && item.getHashCode() == hashCode) {
1!
127
                return (BootstrapMethodItem) item;
1✔
128
            }
129

130
            item = item.getNext();
1✔
131
        }
132

133
        throw new IllegalStateException("BootstrapMethodItem not found for hash code " + hashCode);
×
134
    }
135

136
    @NonNegative
137
    @Override
138
    public int getSize() {
139
        return 8 + bootstrapMethods.getLength();
1✔
140
    }
141

142
    @Override
143
    public void put(@NonNull ByteVector out) {
144
        setAttribute("BootstrapMethods");
1✔
145
        put(out, 2 + bootstrapMethods.getLength());
1✔
146
        out.putShort(bootstrapMethodsCount);
1✔
147
        out.putByteVector(bootstrapMethods);
1✔
148
    }
1✔
149
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc