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.itf);
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 itf
1220 * true if the owner is an interface.
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 itf) {
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, itf));
1234 }
1235 result = new Item(index++, key4);
1236 put(result);
1237 }
1238 return result;
1239 }
1240
1241 /**
1242 * Adds a handle to the constant pool of the class being build. Does nothing
1243 * if the constant pool already contains a similar item. <i>This method is
1244 * intended for {@link Attribute} sub classes, and is normally not needed by
1245 * class generators or adapters.</i>
1246 *
1247 * @param tag
1248 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1249 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1250 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1251 * {@link Opcodes#H_INVOKESTATIC},
1252 * {@link Opcodes#H_INVOKESPECIAL},
1253 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1254 * {@link Opcodes#H_INVOKEINTERFACE}.
1255 * @param owner
1256 * the internal name of the field or method owner class.
1257 * @param name
1258 * the name of the field or method.
1259 * @param desc
1260 * the descriptor of the field or method.
1261 * @return the index of a new or already existing method type reference
1262 * item.
1263 *
1264 * @deprecated this method is superseded by
1265 * {@link #newHandle(int, String, String, String, boolean)}.
1266 */
1267 @Deprecated
1268 public int newHandle(final int tag, final String owner, final String name,
1269 final String desc) {
1270 return newHandle(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
1271 }
1272
1273 /**
1274 * Adds a handle to the constant pool of the class being build. Does nothing
1275 * if the constant pool already contains a similar item. <i>This method is
1276 * intended for {@link Attribute} sub classes, and is normally not needed by
1277 * class generators or adapters.</i>
1278 *
1279 * @param tag
1280 * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
1281 * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
1282 * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
1283 * {@link Opcodes#H_INVOKESTATIC},
1284 * {@link Opcodes#H_INVOKESPECIAL},
1285 * {@link Opcodes#H_NEWINVOKESPECIAL} or
1286 * {@link Opcodes#H_INVOKEINTERFACE}.
1287 * @param owner
1288 * the internal name of the field or method owner class.
1289 * @param name
1290 * the name of the field or method.
1291 * @param desc
1292 * the descriptor of the field or method.
1293 * @param itf
1294 * true if the owner is an interface.
1295 * @return the index of a new or already existing method type reference
1296 * item.
1297 */
1298 public int newHandle(final int tag, final String owner, final String name,
1299 final String desc, final boolean itf) {
1300 return newHandleItem(tag, owner, name, desc, itf).index;
1301 }
1302
1303 /**
1304 * Adds an invokedynamic reference to the constant pool of the class being
1305 * build. Does nothing if the constant pool already contains a similar item.
1306 * <i>This method is intended for {@link Attribute} sub classes, and is
1307 * normally not needed by class generators or adapters.</i>
1308 *
1309 * @param name
1310 * name of the invoked method.
1311 * @param desc
1312 * descriptor of the invoke method.
1313 * @param bsm
1314 * the bootstrap method.
1315 * @param bsmArgs
1316 * the bootstrap method constant arguments.
1317 *
1318 * @return a new or an already existing invokedynamic type reference item.
1319 */
1320 Item newInvokeDynamicItem(final String name, final String desc,
1321 final Handle bsm, final Object... bsmArgs) {
1322 // cache for performance
1323 ByteVector bootstrapMethods = this.bootstrapMethods;
1324 if (bootstrapMethods == null) {
1325 bootstrapMethods = this.bootstrapMethods = new ByteVector();
1326 }
1327
1328 int position = bootstrapMethods.length; // record current position
1329
1330 int hashCode = bsm.hashCode();
1331 bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
1332 bsm.desc, bsm.isInterface()));
1333
1334 int argsLength = bsmArgs.length;
1335 bootstrapMethods.putShort(argsLength);
1336
1337 for (int i = 0; i < argsLength; i++) {
1338 Object bsmArg = bsmArgs[i];
1339 hashCode ^= bsmArg.hashCode();
1340 bootstrapMethods.putShort(newConst(bsmArg));
1341 }
1342
1343 byte[] data = bootstrapMethods.data;
1344 int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
1345 hashCode &= 0x7FFFFFFF;
1346 Item result = items[hashCode % items.length];
1347 loop: while (result != null) {
1348 if (result.type != BSM || result.hashCode != hashCode) {
1349 result = result.next;
1350 continue;
1351 }
1352
|