142 this.parameterTypes = parameterTypes; 143 this.returnType = returnType; 144 this.modifiers = modifiers; 145 this.isConstructor = isConstructor; 146 this.forSerialization = forSerialization; 147 148 this.cpClassPool = new ConstantPoolClassPool(); 149 150 asm.emitMagicAndVersion(); 151 152 // Constant pool entries: 153 // ( * = Boxing information: optional) 154 // (+ = Shared entries provided by AccessorGenerator) 155 // (^ = Only present if generating SerializationConstructorAccessor) 156 // [UTF-8] [This class's name] 157 // [CONSTANT_Class_info] for above 158 // [UTF-8] "jdk/internal/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}" 159 // [CONSTANT_Class_info] for above 160 // [UTF-8] [Target class's name] 161 // [CONSTANT_Class_info] for above 162 // [UTF-8] descriptor for type of non-primitive parameter 1 163 // [CONSTANT_Class_info] for type of non-primitive parameter 1 164 // ... 165 // [UTF-8] descriptor for type of non-primitive parameter n 166 // [CONSTANT_Class_info] for type of non-primitive parameter n 167 // [UTF-8] descriptor for declared value types if not present in CP 168 // [CONSTANT_Class_info] for declared value types if not present in CP 169 // ... 170 // ^ [UTF-8] [Serialization: Class's name in which to invoke constructor] 171 // ^ [CONSTANT_Class_info] for above 172 // [UTF-8] target method or constructor name 173 // [UTF-8] target method or constructor signature 174 // [CONSTANT_NameAndType_info] for above 175 // [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method 176 // [UTF-8] "invoke" or "newInstance" 177 // [UTF-8] invoke or newInstance descriptor 178 // + [UTF-8] "java/lang/Exception" 179 // + [CONSTANT_Class_info] for above 180 // + [UTF-8] "java/lang/ClassCastException" 181 // + [CONSTANT_Class_info] for above 182 // + [UTF-8] "java/lang/NullPointerException" 183 // + [CONSTANT_Class_info] for above 184 // + [UTF-8] "java/lang/IllegalArgumentException" 185 // + [CONSTANT_Class_info] for above 186 // + [UTF-8] "java/lang/InvocationTargetException" 187 // + [CONSTANT_Class_info] for above 188 // + [UTF-8] "<init>" 189 // + [UTF-8] "()V" 190 // + [CONSTANT_NameAndType_info] for above 191 // + [CONSTANT_Methodref_info] for NullPointerException's constructor 192 // + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor 193 // + [UTF-8] "(Ljava/lang/String;)V" 194 // + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V" 195 // + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String 295 } 296 297 asm.emitShort(add(numCPEntries, S1)); 298 299 final String generatedName = generateName(isConstructor, forSerialization); 300 asm.emitConstantPoolUTF8(generatedName); 301 asm.emitConstantPoolClass(asm.cpi()); 302 thisClass = asm.cpi(); 303 if (isConstructor) { 304 if (forSerialization) { 305 asm.emitConstantPoolUTF8 306 ("jdk/internal/reflect/SerializationConstructorAccessorImpl"); 307 } else { 308 asm.emitConstantPoolUTF8("jdk/internal/reflect/ConstructorAccessorImpl"); 309 } 310 } else { 311 asm.emitConstantPoolUTF8("jdk/internal/reflect/MethodAccessorImpl"); 312 } 313 asm.emitConstantPoolClass(asm.cpi()); 314 superClass = asm.cpi(); 315 316 // emit constant pool entries for declaring class, parameter types and return type 317 cpClassPool.emitConstantPoolEntries(); 318 targetClass = cpClassPool.cpIndex(declaringClass); 319 320 short serializationTargetClassIdx = (short) 0; 321 if (forSerialization) { 322 asm.emitConstantPoolUTF8(getClassName(serializationTargetClass, false)); 323 asm.emitConstantPoolClass(asm.cpi()); 324 serializationTargetClassIdx = asm.cpi(); 325 } 326 asm.emitConstantPoolUTF8(name); 327 asm.emitConstantPoolUTF8(buildInternalSignature()); 328 asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi()); 329 if (isInterface()) { 330 asm.emitConstantPoolInterfaceMethodref(targetClass, asm.cpi()); 331 } else { 332 if (forSerialization) { 333 asm.emitConstantPoolMethodref(serializationTargetClassIdx, asm.cpi()); 334 } else { 335 asm.emitConstantPoolMethodref(targetClass, asm.cpi()); 336 } 337 } 338 targetMethodRef = asm.cpi(); 339 if (isConstructor) { 340 asm.emitConstantPoolUTF8("newInstance"); 341 } else { 342 asm.emitConstantPoolUTF8("invoke"); 343 } 344 invokeIdx = asm.cpi(); 345 if (isConstructor) { 346 asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;"); 347 } else { 348 asm.emitConstantPoolUTF8 349 ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); 350 } 351 invokeDescriptorIdx = asm.cpi(); 352 353 // emit name index for "ValueTypes" attribute 354 if (cpClassPool.hasDeclaredValueTypes()) { 355 asm.emitConstantPoolUTF8("ValueTypes"); 356 valueTypesAttrIdx = asm.cpi(); 357 } 358 824 addCPEntry(type); 825 addIfDeclaredValueType(declaredValueTypes, type); 826 } 827 828 // add if this type or its component type is a declared value type 829 private void addIfDeclaredValueType(Set<String> declaredValueTypes, Class<?> type) { 830 Class<?> c = type; 831 while (c.isArray()) c = c.getComponentType(); 832 if (declaredValueTypes.contains(c.getName())) { 833 valueTypes.add(c); 834 addCPEntry(c); 835 } 836 } 837 838 int numConstantPoolEntries() { 839 return types.size() * 2; 840 } 841 842 void emitConstantPoolEntries() { 843 for (Class<?> c : types) { 844 cpEntries.put(c, emitConstantPoolEntries(c)); 845 } 846 } 847 848 private short emitConstantPoolEntries(Class<?> c) { 849 asm.emitConstantPoolUTF8(getClassName(c, false)); 850 asm.emitConstantPoolClass(asm.cpi()); 851 return asm.cpi(); 852 } 853 854 boolean hasDeclaredValueTypes() { 855 return !valueTypes.isEmpty(); 856 } 857 858 short cpIndex(Class<?> c) { 859 return cpEntries.get(c); 860 } 861 862 short[] declaredValueTypes() { 863 short[] idx = new short[valueTypes.size()]; 864 int i=0; 865 for (Class<?> c: valueTypes) { 866 idx[i++] = cpIndex(c); 867 } 868 return idx; 869 } 870 } 871 } | 142 this.parameterTypes = parameterTypes; 143 this.returnType = returnType; 144 this.modifiers = modifiers; 145 this.isConstructor = isConstructor; 146 this.forSerialization = forSerialization; 147 148 this.cpClassPool = new ConstantPoolClassPool(); 149 150 asm.emitMagicAndVersion(); 151 152 // Constant pool entries: 153 // ( * = Boxing information: optional) 154 // (+ = Shared entries provided by AccessorGenerator) 155 // (^ = Only present if generating SerializationConstructorAccessor) 156 // [UTF-8] [This class's name] 157 // [CONSTANT_Class_info] for above 158 // [UTF-8] "jdk/internal/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}" 159 // [CONSTANT_Class_info] for above 160 // [UTF-8] [Target class's name] 161 // [CONSTANT_Class_info] for above 162 // ^ [UTF-8] [Serialization: Class's name in which to invoke constructor] 163 // ^ [CONSTANT_Class_info] for above 164 // [UTF-8] target method or constructor name 165 // [UTF-8] target method or constructor signature 166 // [CONSTANT_NameAndType_info] for above 167 // [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method 168 // [UTF-8] descriptor for type of non-primitive parameter 1 169 // [CONSTANT_Class_info] for type of non-primitive parameter 1 170 // ... 171 // [UTF-8] descriptor for type of non-primitive parameter n 172 // [CONSTANT_Class_info] for type of non-primitive parameter n 173 // [UTF-8] descriptor for declared value types if not present in CP 174 // [CONSTANT_Class_info] for declared value types if not present in CP 175 // ... 176 // [UTF-8] "invoke" or "newInstance" 177 // [UTF-8] invoke or newInstance descriptor 178 // + [UTF-8] "java/lang/Exception" 179 // + [CONSTANT_Class_info] for above 180 // + [UTF-8] "java/lang/ClassCastException" 181 // + [CONSTANT_Class_info] for above 182 // + [UTF-8] "java/lang/NullPointerException" 183 // + [CONSTANT_Class_info] for above 184 // + [UTF-8] "java/lang/IllegalArgumentException" 185 // + [CONSTANT_Class_info] for above 186 // + [UTF-8] "java/lang/InvocationTargetException" 187 // + [CONSTANT_Class_info] for above 188 // + [UTF-8] "<init>" 189 // + [UTF-8] "()V" 190 // + [CONSTANT_NameAndType_info] for above 191 // + [CONSTANT_Methodref_info] for NullPointerException's constructor 192 // + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor 193 // + [UTF-8] "(Ljava/lang/String;)V" 194 // + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V" 195 // + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String 295 } 296 297 asm.emitShort(add(numCPEntries, S1)); 298 299 final String generatedName = generateName(isConstructor, forSerialization); 300 asm.emitConstantPoolUTF8(generatedName); 301 asm.emitConstantPoolClass(asm.cpi()); 302 thisClass = asm.cpi(); 303 if (isConstructor) { 304 if (forSerialization) { 305 asm.emitConstantPoolUTF8 306 ("jdk/internal/reflect/SerializationConstructorAccessorImpl"); 307 } else { 308 asm.emitConstantPoolUTF8("jdk/internal/reflect/ConstructorAccessorImpl"); 309 } 310 } else { 311 asm.emitConstantPoolUTF8("jdk/internal/reflect/MethodAccessorImpl"); 312 } 313 asm.emitConstantPoolClass(asm.cpi()); 314 superClass = asm.cpi(); 315 targetClass = cpClassPool.cpIndex(declaringClass); 316 short serializationTargetClassIdx = (short) 0; 317 if (forSerialization) { 318 asm.emitConstantPoolUTF8(getClassName(serializationTargetClass, false)); 319 asm.emitConstantPoolClass(asm.cpi()); 320 serializationTargetClassIdx = asm.cpi(); 321 } 322 asm.emitConstantPoolUTF8(name); 323 asm.emitConstantPoolUTF8(buildInternalSignature()); 324 asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi()); 325 if (isInterface()) { 326 asm.emitConstantPoolInterfaceMethodref(targetClass, asm.cpi()); 327 } else { 328 if (forSerialization) { 329 asm.emitConstantPoolMethodref(serializationTargetClassIdx, asm.cpi()); 330 } else { 331 asm.emitConstantPoolMethodref(targetClass, asm.cpi()); 332 } 333 } 334 targetMethodRef = asm.cpi(); 335 336 // emit constant pool entries for parameter types and return type 337 cpClassPool.emitConstantPoolEntries(); 338 339 if (isConstructor) { 340 asm.emitConstantPoolUTF8("newInstance"); 341 } else { 342 asm.emitConstantPoolUTF8("invoke"); 343 } 344 invokeIdx = asm.cpi(); 345 if (isConstructor) { 346 asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;"); 347 } else { 348 asm.emitConstantPoolUTF8 349 ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); 350 } 351 invokeDescriptorIdx = asm.cpi(); 352 353 // emit name index for "ValueTypes" attribute 354 if (cpClassPool.hasDeclaredValueTypes()) { 355 asm.emitConstantPoolUTF8("ValueTypes"); 356 valueTypesAttrIdx = asm.cpi(); 357 } 358 824 addCPEntry(type); 825 addIfDeclaredValueType(declaredValueTypes, type); 826 } 827 828 // add if this type or its component type is a declared value type 829 private void addIfDeclaredValueType(Set<String> declaredValueTypes, Class<?> type) { 830 Class<?> c = type; 831 while (c.isArray()) c = c.getComponentType(); 832 if (declaredValueTypes.contains(c.getName())) { 833 valueTypes.add(c); 834 addCPEntry(c); 835 } 836 } 837 838 int numConstantPoolEntries() { 839 return types.size() * 2; 840 } 841 842 void emitConstantPoolEntries() { 843 for (Class<?> c : types) { 844 cpEntries.computeIfAbsent(c, this::emitConstantPoolEntries); 845 } 846 } 847 848 private short emitConstantPoolEntries(Class<?> c) { 849 asm.emitConstantPoolUTF8(getClassName(c, false)); 850 asm.emitConstantPoolClass(asm.cpi()); 851 return asm.cpi(); 852 } 853 854 boolean hasDeclaredValueTypes() { 855 return !valueTypes.isEmpty(); 856 } 857 858 short cpIndex(Class<?> c) { 859 return cpEntries.computeIfAbsent(c, this::emitConstantPoolEntries); 860 } 861 862 short[] declaredValueTypes() { 863 short[] idx = new short[valueTypes.size()]; 864 int i=0; 865 for (Class<?> c: valueTypes) { 866 idx[i++] = cpIndex(c); 867 } 868 return idx; 869 } 870 } 871 } |