Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Loskutov2020-08-16 16:28:06 -0400
committerAndrey Loskutov2020-08-16 16:28:59 -0400
commit76efe9ba43b37439a0a6b7ea4fbe4ec7f3da6caf (patch)
tree98bb5d2c2ec7b8809328f1cd2bf9056b03efafdf
parent9ceeac56c5b6cbdf7d200620db098a097d629e82 (diff)
downloadeclipse.jdt.core-I20200817-0600.tar.gz
eclipse.jdt.core-I20200817-0600.tar.xz
eclipse.jdt.core-I20200817-0600.zip
Revert "Bug 565787 - Invalid code generated for records -I20200817-0600I20200817-0450I20200816-1800
java.lang.invoke.LambdaConversionException at runtime" This reverts commit 9ceeac56c5b6cbdf7d200620db098a097d629e82. The commit above caused blocker regressions in PDE, looks like generated classfiles aren't valid in some cases. See bug 566106 and bug 566110.
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java17
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java359
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java2
-rw-r--r--org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java2
5 files changed, 188 insertions, 193 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
index 8aa63ad5af..6de0a9b851 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
@@ -3922,21 +3922,4 @@ public void testBug565830_01() {
},
"private final int X$1Bar.x");
}
-public void testBug565787_01() {
- runConformTest(
- new String[] {
- "X.java",
- "public record X(String s) {\n"+
- " public X {\n"+
- " s.codePoints()\n"+
- " .forEach(cp -> System.out.println((java.util.function.Predicate<String>) \"\"::equals));\n"+
- " }\n"+
- " public static void main(String[] args) {\n"+
- " X a = new X(\"\");\n"+
- " a.equals(a);\n"+
- " }\n"+
- "}",
- },
- "");
-}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 3f728a020a..974f01248a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -160,7 +160,8 @@ public class ClassFile implements TypeConstants, TypeIds {
// that collection contains all the remaining bytes of the .class file
public int headerOffset;
public Map<TypeBinding, Boolean> innerClassesBindings;
- public List<ASTNode> bootstrapMethods = null;
+ public List bootstrapMethods = null;
+ public List<TypeBinding> recordBootstrapMethods = null;
public int methodCount;
public int methodCountOffset;
// pool managment
@@ -176,9 +177,6 @@ public class ClassFile implements TypeConstants, TypeIds {
public Set visitedTypes;
- private int indexForMetaFactory = 0;
- private int indexForAltMetaFactory = 0;
- private int indexForObjectMethodBootStrap = 0;
public static final int INITIAL_CONTENTS_SIZE = 400;
public static final int INITIAL_HEADER_SIZE = 1500;
public static final int INNER_CLASSES_SIZE = 5;
@@ -425,8 +423,9 @@ public class ClassFile implements TypeConstants, TypeIds {
attributesNumber += generateHierarchyInconsistentAttribute();
}
// Functional expression, lambda bootstrap methods and record bootstrap methods
- if (this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) {
- attributesNumber += generateBootstrapMethods(this.bootstrapMethods);
+ if ((this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) ||
+ (this.recordBootstrapMethods != null && !this.recordBootstrapMethods.isEmpty())) {
+ attributesNumber += generateBootstrapMethods(this.bootstrapMethods, this.recordBootstrapMethods);
}
// Inner class attribute
int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size();
@@ -1079,7 +1078,7 @@ public class ClassFile implements TypeConstants, TypeIds {
* - default abstract methods
* - lambda methods.
*/
- public void addSpecialMethods(TypeDeclaration typeDecl) {
+ public void addSpecialMethods() {
// add all methods (default abstract methods and synthetic)
@@ -1166,7 +1165,7 @@ public class ClassFile implements TypeConstants, TypeIds {
case SyntheticMethodBinding.RecordOverrideEquals:
case SyntheticMethodBinding.RecordOverrideHashCode:
case SyntheticMethodBinding.RecordOverrideToString:
- addSyntheticRecordOverrideMethods(typeDecl, syntheticMethod, syntheticMethod.purpose);
+ addSyntheticRecordOverrideMethods(syntheticMethod, syntheticMethod.purpose);
break;
}
}
@@ -1198,12 +1197,13 @@ public class ClassFile implements TypeConstants, TypeIds {
}
}
- private void addSyntheticRecordOverrideMethods(TypeDeclaration typeDecl, SyntheticMethodBinding methodBinding, int purpose) {
- if (this.bootstrapMethods == null)
- this.bootstrapMethods = new ArrayList<>(3);
- if (!this.bootstrapMethods.contains(typeDecl))
- this.bootstrapMethods.add(typeDecl);
- int index = this.bootstrapMethods.indexOf(typeDecl);
+ private void addSyntheticRecordOverrideMethods(SyntheticMethodBinding methodBinding, int purpose) {
+ if (this.recordBootstrapMethods == null)
+ this.recordBootstrapMethods = new ArrayList<>(3);
+ if (!this.recordBootstrapMethods.contains(methodBinding.declaringClass))
+ this.recordBootstrapMethods.add(methodBinding.declaringClass);
+ int index = this.bootstrapMethods != null ? this.bootstrapMethods.size() +
+ this.recordBootstrapMethods.size() - 1 : 0;
generateMethodInfoHeader(methodBinding);
int methodAttributeOffset = this.contentsOffset;
// this will add exception attribute, synthetic attribute, deprecated attribute,...
@@ -3576,7 +3576,7 @@ public class ClassFile implements TypeConstants, TypeIds {
return 1;
}
- private int generateBootstrapMethods(List<ASTNode> bootStrapMethodsList) {
+ private int generateBootstrapMethods(List functionalExpressionList, List<TypeBinding> recordBootstrapMethods2) {
/* See JVM spec 4.7.21
The BootstrapMethods attribute has the following format:
BootstrapMethods_attribute {
@@ -3594,7 +3594,9 @@ public class ClassFile implements TypeConstants, TypeIds {
if (methodHandlesLookup == null) return 0; // skip bootstrap section, class path problem already reported, just avoid NPE.
recordInnerClasses(methodHandlesLookup); // Should be done, it's what javac does also
- int numberOfBootstraps = bootStrapMethodsList != null ? bootStrapMethodsList.size() : 0;
+ int nfunctionalExpressions = functionalExpressionList != null ? functionalExpressionList.size() : 0;
+ int nRecordBootStraps = recordBootstrapMethods2 != null ? recordBootstrapMethods2.size() : 0;
+ int numberOfBootstraps = nfunctionalExpressions + nRecordBootStraps;
int localContentsOffset = this.contentsOffset;
// Generate the boot strap attribute - since we are only making lambdas and
// functional expressions, we know the size ahead of time - this less general
@@ -3617,14 +3619,12 @@ public class ClassFile implements TypeConstants, TypeIds {
this.contents[localContentsOffset++] = (byte) (numberOfBootstraps >> 8);
this.contents[localContentsOffset++] = (byte) numberOfBootstraps;
- for (int i = 0; i < numberOfBootstraps; i++) {
- Object o = this.bootstrapMethods.get(i);
- if (o instanceof FunctionalExpression) {
- localContentsOffset = addBootStrapLambdaEntry(localContentsOffset, (FunctionalExpression) o);
- } else if (o instanceof TypeDeclaration) {
- localContentsOffset = addBootStrapRecordEntry(localContentsOffset, (TypeDeclaration) o);
- }
- }
+ if (nfunctionalExpressions > 0)
+ localContentsOffset = generateLambdaMetaFactoryBootStrapMethods(functionalExpressionList,
+ localContentsOffset, contentsEntries);
+ if (nRecordBootStraps > 0)
+ localContentsOffset = generateObjectMethodsBootStrapMethods(recordBootstrapMethods2, localContentsOffset,
+ contentsEntries);
int attributeLength = localContentsOffset - attributeLengthPosition - 4;
this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 24);
@@ -3635,173 +3635,184 @@ public class ClassFile implements TypeConstants, TypeIds {
return 1;
}
- private int addBootStrapLambdaEntry(int localContentsOffset, FunctionalExpression functional) {
- MethodBinding [] bridges = functional.getRequiredBridges();
- TypeBinding[] markerInterfaces = null;
- final int contentsEntries = 10;
- if ((functional instanceof LambdaExpression
- && (((markerInterfaces = ((LambdaExpression) functional).getMarkerInterfaces()) != null))
- || bridges != null) || functional.isSerializable) {
- // may need even more space
- int extraSpace = 2; // at least 2 more than when the normal metafactory is used, for the bitflags entry
- if (markerInterfaces != null) {
- // 2 for the marker interface list size then 2 per marker interface index
- extraSpace += (2 + 2 * markerInterfaces.length);
- }
- if (bridges != null) {
- // 2 for bridge count then 2 per bridge method type.
- extraSpace += (2 + 2 * bridges.length);
- }
- if (extraSpace + contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(extraSpace + contentsEntries);
- }
+ private int generateLambdaMetaFactoryBootStrapMethods(List functionalExpressionList,
+ int localContentsOffset, final int contentsEntries) {
+ ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
+ int numberOfBootstraps = functionalExpressionList.size();
- if (this.indexForAltMetaFactory == 0) {
- ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
- this.indexForAltMetaFactory =
- this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
- ConstantPool.ALTMETAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE, false);
- }
- this.contents[localContentsOffset++] = (byte) (this.indexForAltMetaFactory >> 8);
- this.contents[localContentsOffset++] = (byte) this.indexForAltMetaFactory;
+ // Depending on the complexity of the expression it may be necessary to use the altMetafactory() rather than the metafactory()
+ int indexForMetaFactory = 0;
+ int indexForAltMetaFactory = 0;
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) (4 + (markerInterfaces==null?0:1+markerInterfaces.length) +
- (bridges == null ? 0 : 1 + bridges.length));
+ for (int i = 0; i < numberOfBootstraps; i++) {
+ FunctionalExpression functional = (FunctionalExpression) functionalExpressionList.get(i);
+ MethodBinding [] bridges = functional.getRequiredBridges();
+ TypeBinding[] markerInterfaces = null;
+ if ((functional instanceof LambdaExpression
+ && (((markerInterfaces = ((LambdaExpression) functional).getMarkerInterfaces()) != null))
+ || bridges != null) || functional.isSerializable) {
+ // may need even more space
+ int extraSpace = 2; // at least 2 more than when the normal metafactory is used, for the bitflags entry
+ if (markerInterfaces != null) {
+ // 2 for the marker interface list size then 2 per marker interface index
+ extraSpace += (2 + 2 * markerInterfaces.length);
+ }
+ if (bridges != null) {
+ // 2 for bridge count then 2 per bridge method type.
+ extraSpace += (2 + 2 * bridges.length);
+ }
+ if (extraSpace + contentsEntries + localContentsOffset >= this.contents.length) {
+ resizeContents(extraSpace + contentsEntries);
+ }
- int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
- this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
+ if (indexForAltMetaFactory == 0) {
+ indexForAltMetaFactory =
+ this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
+ ConstantPool.ALTMETAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE, false);
+ }
+ this.contents[localContentsOffset++] = (byte) (indexForAltMetaFactory >> 8);
+ this.contents[localContentsOffset++] = (byte) indexForAltMetaFactory;
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ // u2 num_bootstrap_arguments
+ this.contents[localContentsOffset++] = 0;
+ this.contents[localContentsOffset++] = (byte) (4 + (markerInterfaces==null?0:1+markerInterfaces.length) +
+ (bridges == null ? 0 : 1 + bridges.length));
- char [] instantiatedSignature = functional.descriptor.signature();
- int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
- this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodTypeIndex;
+ int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
+ this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
- int bitflags = 0;
- if (functional.isSerializable) {
- bitflags |= ClassFileConstants.FLAG_SERIALIZABLE;
- }
- if (markerInterfaces!=null) {
- bitflags |= ClassFileConstants.FLAG_MARKERS;
- }
- if (bridges != null) {
- bitflags |= ClassFileConstants.FLAG_BRIDGES;
- }
- int indexForBitflags = this.constantPool.literalIndex(bitflags);
+ int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
+ this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodHandleIndex;
- this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8);
- this.contents[localContentsOffset++] = (byte)(indexForBitflags);
+ char [] instantiatedSignature = functional.descriptor.signature();
+ int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
+ this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodTypeIndex;
- if (markerInterfaces != null) {
- int markerInterfaceCountIndex = this.constantPool.literalIndex(markerInterfaces.length);
- this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex>>8);
- this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex);
- for (int m = 0, maxm = markerInterfaces.length; m < maxm; m++) {
- int classTypeIndex = this.constantPool.literalIndexForType(markerInterfaces[m]);
- this.contents[localContentsOffset++] = (byte)(classTypeIndex>>8);
- this.contents[localContentsOffset++] = (byte)(classTypeIndex);
+ int bitflags = 0;
+ if (functional.isSerializable) {
+ bitflags |= ClassFileConstants.FLAG_SERIALIZABLE;
}
- }
- if (bridges != null) {
- int bridgeCountIndex = this.constantPool.literalIndex(bridges.length);
- this.contents[localContentsOffset++] = (byte) (bridgeCountIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (bridgeCountIndex);
- for (int m = 0, maxm = bridges.length; m < maxm; m++) {
- char [] bridgeSignature = bridges[m].signature();
- int bridgeMethodTypeIndex = this.constantPool.literalIndexForMethodType(bridgeSignature);
- this.contents[localContentsOffset++] = (byte) (bridgeMethodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) bridgeMethodTypeIndex;
+ if (markerInterfaces!=null) {
+ bitflags |= ClassFileConstants.FLAG_MARKERS;
}
- }
- } else {
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (this.indexForMetaFactory == 0) {
- ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
- this.indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
- ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false);
- }
- this.contents[localContentsOffset++] = (byte) (this.indexForMetaFactory >> 8);
- this.contents[localContentsOffset++] = (byte) this.indexForMetaFactory;
+ if (bridges != null) {
+ bitflags |= ClassFileConstants.FLAG_BRIDGES;
+ }
+ int indexForBitflags = this.constantPool.literalIndex(bitflags);
+
+ this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8);
+ this.contents[localContentsOffset++] = (byte)(indexForBitflags);
+
+ if (markerInterfaces != null) {
+ int markerInterfaceCountIndex = this.constantPool.literalIndex(markerInterfaces.length);
+ this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex>>8);
+ this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex);
+ for (int m = 0, maxm = markerInterfaces.length; m < maxm; m++) {
+ int classTypeIndex = this.constantPool.literalIndexForType(markerInterfaces[m]);
+ this.contents[localContentsOffset++] = (byte)(classTypeIndex>>8);
+ this.contents[localContentsOffset++] = (byte)(classTypeIndex);
+ }
+ }
+ if (bridges != null) {
+ int bridgeCountIndex = this.constantPool.literalIndex(bridges.length);
+ this.contents[localContentsOffset++] = (byte) (bridgeCountIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) (bridgeCountIndex);
+ for (int m = 0, maxm = bridges.length; m < maxm; m++) {
+ char [] bridgeSignature = bridges[m].signature();
+ int bridgeMethodTypeIndex = this.constantPool.literalIndexForMethodType(bridgeSignature);
+ this.contents[localContentsOffset++] = (byte) (bridgeMethodTypeIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) bridgeMethodTypeIndex;
+ }
+ }
+ } else {
+ if (contentsEntries + localContentsOffset >= this.contents.length) {
+ resizeContents(contentsEntries);
+ }
+ if (indexForMetaFactory == 0) {
+ indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
+ ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false);
+ }
+ this.contents[localContentsOffset++] = (byte) (indexForMetaFactory >> 8);
+ this.contents[localContentsOffset++] = (byte) indexForMetaFactory;
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) 3;
+ // u2 num_bootstrap_arguments
+ this.contents[localContentsOffset++] = 0;
+ this.contents[localContentsOffset++] = (byte) 3;
- int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
- this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
+ int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
+ this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding instanceof PolymorphicMethodBinding ? functional.binding : functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding instanceof PolymorphicMethodBinding ? functional.binding : functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
+ this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodHandleIndex;
- char [] instantiatedSignature = functional.descriptor.signature();
- int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
- this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodTypeIndex;
+ char [] instantiatedSignature = functional.descriptor.signature();
+ int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
+ this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodTypeIndex;
+ }
}
return localContentsOffset;
}
+ private int generateObjectMethodsBootStrapMethods(List<TypeBinding> recordList,
+ int localContentsOffset, final int contentsEntries) {
+ ReferenceBinding javaLangRuntimeObjectMethods = this.referenceBinding.scope.getJavaLangRuntimeObjectMethods();
+ int numberOfBootstraps = recordList.size();
+ int indexForObjectMethodBootStrap = 0;
+ for (int i = 0; i < numberOfBootstraps; i++) {
+ if (contentsEntries + localContentsOffset >= this.contents.length) {
+ resizeContents(contentsEntries);
+ }
+ if (indexForObjectMethodBootStrap == 0) {
+ indexForObjectMethodBootStrap = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeObjectMethods,
+ ConstantPool.BOOTSTRAP, ConstantPool.JAVA_LANG_RUNTIME_OBJECTMETHOD_BOOTSTRAP_SIGNATURE, false);
+ }
+ this.contents[localContentsOffset++] = (byte) (indexForObjectMethodBootStrap >> 8);
+ this.contents[localContentsOffset++] = (byte) indexForObjectMethodBootStrap;
- private int addBootStrapRecordEntry(int localContentsOffset, TypeDeclaration typeDecl) {
- TypeBinding type = typeDecl.binding;
- assert type.isRecord(); // sanity check
- final int contentsEntries = 10;
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (this.indexForObjectMethodBootStrap == 0) {
- ReferenceBinding javaLangRuntimeObjectMethods = this.referenceBinding.scope.getJavaLangRuntimeObjectMethods();
- this.indexForObjectMethodBootStrap = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeObjectMethods,
- ConstantPool.BOOTSTRAP, ConstantPool.JAVA_LANG_RUNTIME_OBJECTMETHOD_BOOTSTRAP_SIGNATURE, false);
- }
- this.contents[localContentsOffset++] = (byte) (this.indexForObjectMethodBootStrap >> 8);
- this.contents[localContentsOffset++] = (byte) this.indexForObjectMethodBootStrap;
-
- // u2 num_bootstrap_arguments
- int numArgsLocation = localContentsOffset;
- localContentsOffset += 2;
+ // u2 num_bootstrap_arguments
+ int numArgsLocation = localContentsOffset;
+ localContentsOffset += 2;
- char[] recordName = type.constantPoolName();
- int recordIndex = this.constantPool.literalIndexForType(recordName);
- this.contents[localContentsOffset++] = (byte) (recordIndex >> 8);
- this.contents[localContentsOffset++] = (byte) recordIndex;
+ TypeBinding type = recordList.get(i);
+ assert type.isRecord(); // sanity check
+ char[] recordName = type.constantPoolName();
+ int recordIndex = this.constantPool.literalIndexForType(recordName);
+ this.contents[localContentsOffset++] = (byte) (recordIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) recordIndex;
- assert type instanceof SourceTypeBinding;
- SourceTypeBinding sourceType = (SourceTypeBinding) type;
- FieldBinding[] recordComponents = sourceType.getImplicitComponentFields();
+ assert type instanceof SourceTypeBinding;
+ SourceTypeBinding sourceType = (SourceTypeBinding) type;
+ FieldBinding[] recordComponents = sourceType.getImplicitComponentFields();
- int numArgs = 2 + recordComponents.length;
- this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
- this.contents[numArgsLocation] = (byte) numArgs;
+ int numArgs = 2 + recordComponents.length;
+ this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
+ this.contents[numArgsLocation] = (byte) numArgs;
- String names =
- Arrays.stream(recordComponents)
- .map(f -> new String(f.name))
- .reduce((s1, s2) -> { return s1 + ";" + s2;}) //$NON-NLS-1$
- .orElse(Util.EMPTY_STRING);
- int namesIndex = this.constantPool.literalIndex(names);
- this.contents[localContentsOffset++] = (byte) (namesIndex >> 8);
- this.contents[localContentsOffset++] = (byte) namesIndex;
+ String names =
+ Arrays.stream(recordComponents)
+ .map(f -> new String(f.name))
+ .reduce((s1, s2) -> { return s1 + ";" + s2;}) //$NON-NLS-1$
+ .orElse(Util.EMPTY_STRING);
+ int namesIndex = this.constantPool.literalIndex(names);
+ this.contents[localContentsOffset++] = (byte) (namesIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) namesIndex;
- if (recordComponents.length * 2 + localContentsOffset >= this.contents.length) {
- resizeContents(recordComponents.length * 2);
- }
- for (FieldBinding field : recordComponents) {
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandleFieldRef(
- ClassFileConstants.MethodHandleRefKindGetField,
- recordName, field.name, field.type.signature());
+ if (recordComponents.length * 2 + localContentsOffset >= this.contents.length) {
+ resizeContents(recordComponents.length * 2);
+ }
+ for (FieldBinding field : recordComponents) {
+ int methodHandleIndex = this.constantPool.literalIndexForMethodHandleFieldRef(
+ ClassFileConstants.MethodHandleRefKindGetField,
+ recordName, field.name, field.type.signature());
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ }
}
return localContentsOffset;
}
@@ -6018,13 +6029,10 @@ public class ClassFile implements TypeConstants, TypeIds {
}
if (expression instanceof ReferenceExpression) {
for (int i = 0; i < this.bootstrapMethods.size(); i++) {
- ASTNode node = this.bootstrapMethods.get(i);
- if (node instanceof FunctionalExpression) {
- FunctionalExpression fexp = (FunctionalExpression) node;
- if (fexp.binding == expression.binding
- && TypeBinding.equalsEquals(fexp.expectedType(), expression.expectedType()))
- return expression.bootstrapMethodNumber = i;
- }
+ FunctionalExpression fexp = (FunctionalExpression) this.bootstrapMethods.get(i);
+ if (fexp.binding == expression.binding
+ && TypeBinding.equalsEquals(fexp.expectedType(), expression.expectedType()))
+ return expression.bootstrapMethodNumber = i;
}
}
this.bootstrapMethods.add(expression);
@@ -6073,6 +6081,9 @@ public class ClassFile implements TypeConstants, TypeIds {
if (this.bootstrapMethods != null) {
this.bootstrapMethods.clear();
}
+ if (this.recordBootstrapMethods != null) {
+ this.recordBootstrapMethods.clear();
+ }
this.missingTypes = null;
this.visitedTypes = null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 8beee5a001..bfc5cb05fe 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -174,6 +174,7 @@ public void cleanUp() {
classFile.referenceBinding = null;
classFile.innerClassesBindings = null;
classFile.bootstrapMethods = null;
+ classFile.recordBootstrapMethods = null;
classFile.missingTypes = null;
classFile.visitedTypes = null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index e6e22c8815..ba892531da 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -748,7 +748,7 @@ public void generateCode(ClassFile enclosingClassFile) {
}
}
// generate all synthetic and abstract methods
- classFile.addSpecialMethods(this);
+ classFile.addSpecialMethods();
if (this.ignoreFurtherInvestigation) { // trigger problem type generation for code gen errors
throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null);
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
index 8510532dac..330d96b226 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
@@ -76,7 +76,7 @@ public void generateCode(ClassFile enclosingClassFile) {
}
// generate all methods
- classFile.addSpecialMethods(this);
+ classFile.addSpecialMethods();
if (this.ignoreFurtherInvestigation){ // trigger problem type generation for code gen errors
throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null);

Back to the top