< prev index next >

src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java

Print this page




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 


< prev index next >