1064 } else if (cst instanceof Long) {
1065 long val = ((Long) cst).longValue();
1066 return newLong(val);
1067 } else if (cst instanceof Double) {
1068 double val = ((Double) cst).doubleValue();
1069 return newDouble(val);
1070 } else if (cst instanceof String) {
1071 return newString((String) cst);
1072 } else if (cst instanceof Type) {
1073 Type t = (Type) cst;
1074 int s = t.getSort();
1075 if (s == Type.OBJECT) {
1076 return newClassItem(t.getInternalName());
1077 } else if (s == Type.METHOD) {
1078 return newMethodTypeItem(t.getDescriptor());
1079 } else { // s == primitive type or array
1080 return newClassItem(t.getDescriptor());
1081 }
1082 } else if (cst instanceof Handle) {
1083 Handle h = (Handle) cst;
1084 return newHandleItem(h.tag, h.owner, h.name, h.desc);
1085 } else {
1086 throw new IllegalArgumentException("value " + cst);
1087 }
1088 }
1089
1090 /**
1091 * Adds a number or string constant to the constant pool of the class being
1092 * build. Does nothing if the constant pool already contains a similar item.
1093 * <i>This method is intended for {@link Attribute} sub classes, and is
1094 * normally not needed by class generators or adapters.</i>
1095 *
1096 * @param cst
1097 * the value of the constant to be added to the constant pool.
1098 * This parameter must be an {@link Integer}, a {@link Float}, a
1099 * {@link Long}, a {@link Double} or a {@link String}.
1100 * @return the index of a new or already existing constant item with the
1101 * given value.
1102 */
1103 public int newConst(final Object cst) {
1104 return newConstItem(cst).index;
1199 /**
1200 * Adds a handle to the constant pool of the class being build. Does nothing
1201 * if the constant pool already contains a similar item. <i>This method is
1202 * intended for {@link Attribute} sub classes, and is normally not needed by
1203 * class generators or adapters.</i>
1204 *
1205 * @param tag
1206 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1207 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1208 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1209 * {@link Opcodes#H_INVOKESTATIC},
1210 * {@link Opcodes#H_INVOKESPECIAL},
1211 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1212 * {@link Opcodes#H_INVOKEINTERFACE}.
1213 * @param owner
1214 * the internal name of the field or method owner class.
1215 * @param name
1216 * the name of the field or method.
1217 * @param desc
1218 * the descriptor of the field or method.
1219 * @return a new or an already existing method type reference item.
1220 */
1221 Item newHandleItem(final int tag, final String owner, final String name,
1222 final String desc) {
1223 key4.set(HANDLE_BASE + tag, owner, name, desc);
1224 Item result = get(key4);
1225 if (result == null) {
1226 if (tag <= Opcodes.H_PUTSTATIC) {
1227 put112(HANDLE, tag, newField(owner, name, desc));
1228 } else {
1229 put112(HANDLE,
1230 tag,
1231 newMethod(owner, name, desc,
1232 tag == Opcodes.H_INVOKEINTERFACE));
1233 }
1234 result = new Item(index++, key4);
1235 put(result);
1236 }
1237 return result;
1238 }
1239
1240 /**
1241 * Adds a handle to the constant pool of the class being build. Does nothing
1242 * if the constant pool already contains a similar item. <i>This method is
1243 * intended for {@link Attribute} sub classes, and is normally not needed by
1244 * class generators or adapters.</i>
1245 *
1246 * @param tag
1247 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1248 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1249 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1250 * {@link Opcodes#H_INVOKESTATIC},
1251 * {@link Opcodes#H_INVOKESPECIAL},
1252 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1253 * {@link Opcodes#H_INVOKEINTERFACE}.
1254 * @param owner
1255 * the internal name of the field or method owner class.
1256 * @param name
1257 * the name of the field or method.
1258 * @param desc
1259 * the descriptor of the field or method.
1260 * @return the index of a new or already existing method type reference
1261 * item.
1262 */
1263 public int newHandle(final int tag, final String owner, final String name,
1264 final String desc) {
1265 return newHandleItem(tag, owner, name, desc).index;
1266 }
1267
1268 /**
1269 * Adds an invokedynamic reference to the constant pool of the class being
1270 * build. Does nothing if the constant pool already contains a similar item.
1271 * <i>This method is intended for {@link Attribute} sub classes, and is
1272 * normally not needed by class generators or adapters.</i>
1273 *
1274 * @param name
1275 * name of the invoked method.
1276 * @param desc
1277 * descriptor of the invoke method.
1278 * @param bsm
1279 * the bootstrap method.
1280 * @param bsmArgs
1281 * the bootstrap method constant arguments.
1282 *
1283 * @return a new or an already existing invokedynamic type reference item.
1284 */
1285 Item newInvokeDynamicItem(final String name, final String desc,
1286 final Handle bsm, final Object... bsmArgs) {
1287 // cache for performance
1288 ByteVector bootstrapMethods = this.bootstrapMethods;
1289 if (bootstrapMethods == null) {
1290 bootstrapMethods = this.bootstrapMethods = new ByteVector();
1291 }
1292
1293 int position = bootstrapMethods.length; // record current position
1294
1295 int hashCode = bsm.hashCode();
1296 bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
1297 bsm.desc));
1298
1299 int argsLength = bsmArgs.length;
1300 bootstrapMethods.putShort(argsLength);
1301
1302 for (int i = 0; i < argsLength; i++) {
1303 Object bsmArg = bsmArgs[i];
1304 hashCode ^= bsmArg.hashCode();
1305 bootstrapMethods.putShort(newConst(bsmArg));
1306 }
1307
1308 byte[] data = bootstrapMethods.data;
1309 int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
1310 hashCode &= 0x7FFFFFFF;
1311 Item result = items[hashCode % items.length];
1312 loop: while (result != null) {
1313 if (result.type != BSM || result.hashCode != hashCode) {
1314 result = result.next;
1315 continue;
1316 }
1317
|
1064 } else if (cst instanceof Long) {
1065 long val = ((Long) cst).longValue();
1066 return newLong(val);
1067 } else if (cst instanceof Double) {
1068 double val = ((Double) cst).doubleValue();
1069 return newDouble(val);
1070 } else if (cst instanceof String) {
1071 return newString((String) cst);
1072 } else if (cst instanceof Type) {
1073 Type t = (Type) cst;
1074 int s = t.getSort();
1075 if (s == Type.OBJECT) {
1076 return newClassItem(t.getInternalName());
1077 } else if (s == Type.METHOD) {
1078 return newMethodTypeItem(t.getDescriptor());
1079 } else { // s == primitive type or array
1080 return newClassItem(t.getDescriptor());
1081 }
1082 } else if (cst instanceof Handle) {
1083 Handle h = (Handle) cst;
1084 return newHandleItem(h.tag, h.owner, h.name, h.desc, h.intfs);
1085 } else {
1086 throw new IllegalArgumentException("value " + cst);
1087 }
1088 }
1089
1090 /**
1091 * Adds a number or string constant to the constant pool of the class being
1092 * build. Does nothing if the constant pool already contains a similar item.
1093 * <i>This method is intended for {@link Attribute} sub classes, and is
1094 * normally not needed by class generators or adapters.</i>
1095 *
1096 * @param cst
1097 * the value of the constant to be added to the constant pool.
1098 * This parameter must be an {@link Integer}, a {@link Float}, a
1099 * {@link Long}, a {@link Double} or a {@link String}.
1100 * @return the index of a new or already existing constant item with the
1101 * given value.
1102 */
1103 public int newConst(final Object cst) {
1104 return newConstItem(cst).index;
1199 /**
1200 * Adds a handle to the constant pool of the class being build. Does nothing
1201 * if the constant pool already contains a similar item. <i>This method is
1202 * intended for {@link Attribute} sub classes, and is normally not needed by
1203 * class generators or adapters.</i>
1204 *
1205 * @param tag
1206 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1207 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1208 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1209 * {@link Opcodes#H_INVOKESTATIC},
1210 * {@link Opcodes#H_INVOKESPECIAL},
1211 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1212 * {@link Opcodes#H_INVOKEINTERFACE}.
1213 * @param owner
1214 * the internal name of the field or method owner class.
1215 * @param name
1216 * the name of the field or method.
1217 * @param desc
1218 * the descriptor of the field or method.
1219 * @param intfs
1220 * the indicator of interface static method
1221 * @return a new or an already existing method type reference item.
1222 */
1223 Item newHandleItem(final int tag, final String owner, final String name,
1224 final String desc, final boolean intfs) {
1225 key4.set(HANDLE_BASE + tag, owner, name, desc);
1226 Item result = get(key4);
1227 if (result == null) {
1228 if (tag <= Opcodes.H_PUTSTATIC) {
1229 put112(HANDLE, tag, newField(owner, name, desc));
1230 } else {
1231 put112(HANDLE,
1232 tag,
1233 newMethod(owner, name, desc,
1234 tag == Opcodes.H_INVOKEINTERFACE || intfs));
1235 }
1236 result = new Item(index++, key4);
1237 put(result);
1238 }
1239 return result;
1240 }
1241
1242 /**
1243 * Adds a handle to the constant pool of the class being build. Does nothing
1244 * if the constant pool already contains a similar item. <i>This method is
1245 * intended for {@link Attribute} sub classes, and is normally not needed by
1246 * class generators or adapters.</i>
1247 *
1248 * @param tag
1249 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1250 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1251 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1252 * {@link Opcodes#H_INVOKESTATIC},
1253 * {@link Opcodes#H_INVOKESPECIAL},
1254 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1255 * {@link Opcodes#H_INVOKEINTERFACE}.
1256 * @param owner
1257 * the internal name of the field or method owner class.
1258 * @param name
1259 * the name of the field or method.
1260 * @param desc
1261 * the descriptor of the field or method.
1262 * @param intfs
1263 * the indicator of interface static method
1264 * @return the index of a new or already existing method type reference
1265 * item.
1266 */
1267 public int newHandle(final int tag, final String owner, final String name,
1268 final String desc, final boolean intfs) {
1269 return newHandleItem(tag, owner, name, desc, intfs).index;
1270 }
1271
1272 /**
1273 * Adds an invokedynamic reference to the constant pool of the class being
1274 * build. Does nothing if the constant pool already contains a similar item.
1275 * <i>This method is intended for {@link Attribute} sub classes, and is
1276 * normally not needed by class generators or adapters.</i>
1277 *
1278 * @param name
1279 * name of the invoked method.
1280 * @param desc
1281 * descriptor of the invoke method.
1282 * @param bsm
1283 * the bootstrap method.
1284 * @param bsmArgs
1285 * the bootstrap method constant arguments.
1286 *
1287 * @return a new or an already existing invokedynamic type reference item.
1288 */
1289 Item newInvokeDynamicItem(final String name, final String desc,
1290 final Handle bsm, final Object... bsmArgs) {
1291 // cache for performance
1292 ByteVector bootstrapMethods = this.bootstrapMethods;
1293 if (bootstrapMethods == null) {
1294 bootstrapMethods = this.bootstrapMethods = new ByteVector();
1295 }
1296
1297 int position = bootstrapMethods.length; // record current position
1298
1299 int hashCode = bsm.hashCode();
1300 bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
1301 bsm.desc, bsm.intfs));
1302
1303 int argsLength = bsmArgs.length;
1304 bootstrapMethods.putShort(argsLength);
1305
1306 for (int i = 0; i < argsLength; i++) {
1307 Object bsmArg = bsmArgs[i];
1308 hashCode ^= bsmArg.hashCode();
1309 bootstrapMethods.putShort(newConst(bsmArg));
1310 }
1311
1312 byte[] data = bootstrapMethods.data;
1313 int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
1314 hashCode &= 0x7FFFFFFF;
1315 Item result = items[hashCode % items.length];
1316 loop: while (result != null) {
1317 if (result.type != BSM || result.hashCode != hashCode) {
1318 result = result.next;
1319 continue;
1320 }
1321
|