1 /*
2 * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.constant.ClassOrInterfaceDescImpl;
29 import jdk.internal.misc.CDS;
30 import jdk.internal.util.ClassFileDumper;
31 import sun.invoke.util.VerifyAccess;
32
33 import java.io.Serializable;
34 import java.lang.classfile.ClassBuilder;
35 import java.lang.classfile.ClassFile;
36 import java.lang.classfile.CodeBuilder;
37 import java.lang.classfile.MethodBuilder;
38 import java.lang.classfile.Opcode;
39 import java.lang.classfile.TypeKind;
40 import java.lang.constant.ClassDesc;
41 import java.lang.constant.MethodTypeDesc;
42 import java.lang.reflect.Modifier;
43 import java.util.LinkedHashSet;
44 import java.util.List;
45 import java.util.Set;
46 import java.util.function.Consumer;
47
48 import static java.lang.classfile.ClassFile.*;
49 import java.lang.classfile.attribute.ExceptionsAttribute;
50 import java.lang.classfile.constantpool.ClassEntry;
51 import java.lang.classfile.constantpool.ConstantPoolBuilder;
52
53 import static java.lang.constant.ConstantDescs.*;
54 import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS;
55 import static java.lang.invoke.MethodHandleNatives.Constants.STRONG_LOADER_LINK;
56 import jdk.internal.constant.ConstantUtils;
57 import jdk.internal.constant.MethodTypeDescImpl;
58 import jdk.internal.vm.annotation.Stable;
59 import sun.invoke.util.Wrapper;
60
61 /**
293 private Class<?> generateInnerClass() throws LambdaConversionException {
294 List<ClassDesc> interfaces;
295 ClassDesc interfaceDesc = classDesc(interfaceClass);
296 boolean accidentallySerializable = !isSerializable && Serializable.class.isAssignableFrom(interfaceClass);
297 if (altInterfaces.length == 0) {
298 interfaces = List.of(interfaceDesc);
299 } else {
300 // Assure no duplicate interfaces (ClassFormatError)
301 Set<ClassDesc> itfs = LinkedHashSet.newLinkedHashSet(altInterfaces.length + 1);
302 itfs.add(interfaceDesc);
303 for (Class<?> i : altInterfaces) {
304 itfs.add(classDesc(i));
305 accidentallySerializable |= !isSerializable && Serializable.class.isAssignableFrom(i);
306 }
307 interfaces = List.copyOf(itfs);
308 }
309 final boolean finalAccidentallySerializable = accidentallySerializable;
310 final byte[] classBytes = ClassFile.of().build(lambdaClassEntry, pool, new Consumer<ClassBuilder>() {
311 @Override
312 public void accept(ClassBuilder clb) {
313 clb.withFlags(ACC_SUPER | ACC_FINAL | ACC_SYNTHETIC)
314 .withInterfaceSymbols(interfaces);
315 // Generate final fields to be filled in by constructor
316 for (int i = 0; i < argDescs.length; i++) {
317 clb.withField(argName(i), argDescs[i], ACC_PRIVATE | ACC_FINAL);
318 }
319
320 generateConstructor(clb);
321
322 if (factoryType.parameterCount() == 0 && disableEagerInitialization) {
323 generateClassInitializer(clb);
324 }
325
326 // Forward the SAM method
327 clb.withMethodBody(interfaceMethodName,
328 methodDesc(interfaceMethodType),
329 ACC_PUBLIC,
330 forwardingMethod(interfaceMethodType));
331
332 // Forward the bridges
333 if (altMethods != null) {
334 for (MethodType mt : altMethods) {
|
1 /*
2 * Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.constant.ClassOrInterfaceDescImpl;
29 import jdk.internal.misc.PreviewFeatures;
30 import jdk.internal.misc.CDS;
31 import jdk.internal.util.ClassFileDumper;
32 import sun.invoke.util.VerifyAccess;
33
34 import java.io.Serializable;
35 import java.lang.classfile.ClassBuilder;
36 import java.lang.classfile.ClassFile;
37 import java.lang.classfile.CodeBuilder;
38 import java.lang.classfile.MethodBuilder;
39 import java.lang.classfile.Opcode;
40 import java.lang.classfile.TypeKind;
41 import java.lang.constant.ClassDesc;
42 import java.lang.constant.MethodTypeDesc;
43 import java.lang.reflect.ClassFileFormatVersion;
44 import java.lang.reflect.Modifier;
45 import java.util.LinkedHashSet;
46 import java.util.List;
47 import java.util.Set;
48 import java.util.function.Consumer;
49
50 import static java.lang.classfile.ClassFile.*;
51 import java.lang.classfile.attribute.ExceptionsAttribute;
52 import java.lang.classfile.constantpool.ClassEntry;
53 import java.lang.classfile.constantpool.ConstantPoolBuilder;
54
55 import static java.lang.constant.ConstantDescs.*;
56 import static java.lang.invoke.MethodHandleNatives.Constants.NESTMATE_CLASS;
57 import static java.lang.invoke.MethodHandleNatives.Constants.STRONG_LOADER_LINK;
58 import jdk.internal.constant.ConstantUtils;
59 import jdk.internal.constant.MethodTypeDescImpl;
60 import jdk.internal.vm.annotation.Stable;
61 import sun.invoke.util.Wrapper;
62
63 /**
295 private Class<?> generateInnerClass() throws LambdaConversionException {
296 List<ClassDesc> interfaces;
297 ClassDesc interfaceDesc = classDesc(interfaceClass);
298 boolean accidentallySerializable = !isSerializable && Serializable.class.isAssignableFrom(interfaceClass);
299 if (altInterfaces.length == 0) {
300 interfaces = List.of(interfaceDesc);
301 } else {
302 // Assure no duplicate interfaces (ClassFormatError)
303 Set<ClassDesc> itfs = LinkedHashSet.newLinkedHashSet(altInterfaces.length + 1);
304 itfs.add(interfaceDesc);
305 for (Class<?> i : altInterfaces) {
306 itfs.add(classDesc(i));
307 accidentallySerializable |= !isSerializable && Serializable.class.isAssignableFrom(i);
308 }
309 interfaces = List.copyOf(itfs);
310 }
311 final boolean finalAccidentallySerializable = accidentallySerializable;
312 final byte[] classBytes = ClassFile.of().build(lambdaClassEntry, pool, new Consumer<ClassBuilder>() {
313 @Override
314 public void accept(ClassBuilder clb) {
315 clb.withVersion(ClassFileFormatVersion.latest().major(), (PreviewFeatures.isEnabled() ? ClassFile.PREVIEW_MINOR_VERSION : 0))
316 .withFlags(ACC_SUPER | ACC_FINAL | ACC_SYNTHETIC)
317 .withInterfaceSymbols(interfaces);
318 // All Classes in the BSM argument method types are loaded; no need for LoadableDescriptors
319
320 // Generate final fields to be filled in by constructor
321 for (int i = 0; i < argDescs.length; i++) {
322 clb.withField(argName(i), argDescs[i], ACC_PRIVATE | ACC_FINAL);
323 }
324
325 generateConstructor(clb);
326
327 if (factoryType.parameterCount() == 0 && disableEagerInitialization) {
328 generateClassInitializer(clb);
329 }
330
331 // Forward the SAM method
332 clb.withMethodBody(interfaceMethodName,
333 methodDesc(interfaceMethodType),
334 ACC_PUBLIC,
335 forwardingMethod(interfaceMethodType));
336
337 // Forward the bridges
338 if (altMethods != null) {
339 for (MethodType mt : altMethods) {
|