Adds a bootstrap method to the BootstrapMethods attribute of this symbol table. Does nothing if the BootstrapMethods already contains a similar bootstrap method. @param bootstrapMethodHandle a bootstrap method handle. @param bootstrapMethodArguments the bootstrap method arguments. @return a new or
(
final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments)
| 1049 | * @return a new or already existing Symbol with the given value. |
| 1050 | */ |
| 1051 | Symbol addBootstrapMethod( |
| 1052 | final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) { |
| 1053 | ByteVector bootstrapMethodsAttribute = bootstrapMethods; |
| 1054 | if (bootstrapMethodsAttribute == null) { |
| 1055 | bootstrapMethodsAttribute = bootstrapMethods = new ByteVector(); |
| 1056 | } |
| 1057 | |
| 1058 | // The bootstrap method arguments can be Constant_Dynamic values, which reference other |
| 1059 | // bootstrap methods. We must therefore add the bootstrap method arguments to the constant pool |
| 1060 | // and BootstrapMethods attribute first, so that the BootstrapMethods attribute is not modified |
| 1061 | // while adding the given bootstrap method to it, in the rest of this method. |
| 1062 | for (Object bootstrapMethodArgument : bootstrapMethodArguments) { |
| 1063 | addConstant(bootstrapMethodArgument); |
| 1064 | } |
| 1065 | |
| 1066 | // Write the bootstrap method in the BootstrapMethods table. This is necessary to be able to |
| 1067 | // compare it with existing ones, and will be reverted below if there is already a similar |
| 1068 | // bootstrap method. |
| 1069 | int bootstrapMethodOffset = bootstrapMethodsAttribute.length; |
| 1070 | bootstrapMethodsAttribute.putShort( |
| 1071 | addConstantMethodHandle( |
| 1072 | bootstrapMethodHandle.getTag(), |
| 1073 | bootstrapMethodHandle.getOwner(), |
| 1074 | bootstrapMethodHandle.getName(), |
| 1075 | bootstrapMethodHandle.getDesc(), |
| 1076 | bootstrapMethodHandle.isInterface()) |
| 1077 | .index); |
| 1078 | int numBootstrapArguments = bootstrapMethodArguments.length; |
| 1079 | bootstrapMethodsAttribute.putShort(numBootstrapArguments); |
| 1080 | for (Object bootstrapMethodArgument : bootstrapMethodArguments) { |
| 1081 | bootstrapMethodsAttribute.putShort(addConstant(bootstrapMethodArgument).index); |
| 1082 | } |
| 1083 | |
| 1084 | // Compute the length and the hash code of the bootstrap method. |
| 1085 | int bootstrapMethodlength = bootstrapMethodsAttribute.length - bootstrapMethodOffset; |
| 1086 | int hashCode = bootstrapMethodHandle.hashCode(); |
| 1087 | for (Object bootstrapMethodArgument : bootstrapMethodArguments) { |
| 1088 | hashCode ^= bootstrapMethodArgument.hashCode(); |
| 1089 | } |
| 1090 | hashCode &= 0x7FFFFFFF; |
| 1091 | |
| 1092 | // Add the bootstrap method to the symbol table or revert the above changes. |
| 1093 | return addBootstrapMethod(bootstrapMethodOffset, bootstrapMethodlength, hashCode); |
| 1094 | } |
| 1095 | |
| 1096 | /** |
| 1097 | * Adds a bootstrap method to the BootstrapMethods attribute of this symbol table. Does nothing if |
no test coverage detected