Bug 534608 - Stack overflow in MethodInfo.getModifers() after recent
changes in JDT
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.java
index a1bea9e..2cac7b0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.java
@@ -102,6 +102,9 @@
this.defaultValue = defaultValue;
this.accessFlags = methodInfo.accessFlags;
+//{ObjectTeams:
+ this.callBaseCtor = methodInfo.callBaseCtor;
+// SH}
this.attributeBytes = methodInfo.attributeBytes;
this.descriptor = methodInfo.descriptor;
this.exceptionNames = methodInfo.exceptionNames;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
index cc72520..2bb2ddf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
@@ -27,13 +27,13 @@
import java.util.LinkedList;
import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
@@ -75,9 +75,7 @@
/* After reading a method its attributes are stored here. */
private LinkedList<AbstractAttribute> methodAttributes = new LinkedList<AbstractAttribute>();
// more bits decoded from attributes:
- protected int otModifiers;
- // constants for the above:
- static final int AccCallsBaseCtor = ASTNode.Bit1;
+ protected boolean callBaseCtor;
// SH}
public static MethodInfo createMethod(byte classFileBytes[], int offsets[], int offset, long version) {
@@ -177,15 +175,12 @@
}
//{ObjectTeams
-public void setAccessFlags (int flags) {
- this.accessFlags = flags;
-}
// special flag which needs to be added to the regular access flags:
public void setCallsBaseCtor() {
- this.otModifiers |= AccCallsBaseCtor;
+ this.callBaseCtor = true;
}
public boolean callsBaseCtor() {
- return (this.otModifiers & AccCallsBaseCtor) != 0;
+ return this.callBaseCtor;
}
public void maybeRegister(
BinaryTypeBinding clazz,
@@ -512,6 +507,9 @@
}
private synchronized void readModifierRelatedAttributes() {
int flags = u2At(0);
+//{ObjectTeams:
+ int otFlags = 0;
+// SH}
int attributesCount = u2At(6);
int readOffset = 8;
for (int i = 0; i < attributesCount; i++) {
@@ -538,12 +536,20 @@
//{ObjectTeams: read method attributes
break;
default:
- readOTAttribute(attributeName, this, readOffset+6, this.structOffset, this.constantPoolOffsets);
+ otFlags |= readOTAttribute(attributeName, this, readOffset+6, this.structOffset, this.constantPoolOffsets);
// SH}
}
}
readOffset += (6 + u4At(readOffset + 2));
}
+//{ObjectTeams: combine sets of modifiers
+ if (otFlags != 0) {
+ if ((otFlags & ExtraCompilerModifiers.AccVisibilityMASK) != 0) {
+ flags &= ~ExtraCompilerModifiers.AccVisibilityMASK; // replace those bits
+ }
+ flags |= otFlags;
+ }
+// SH}
this.accessFlags = flags;
}
//{ObjectTeams: OT method attributes:
@@ -556,7 +562,7 @@
* @param aStructOffset (subtract when indexing via constantPoolOffsets)
* @param someConstantPoolOffsets
*/
- void readOTAttribute(
+ int readOTAttribute(
char[] attributeName,
MethodInfo info,
int readOffset,
@@ -564,15 +570,15 @@
int[] someConstantPoolOffsets)
{
if (CharOperation.equals(attributeName, AttributeNamesConstants.CodeName))
- return; // optimization only.
+ return 0; // optimization only.
if (CharOperation.equals(attributeName, MODIFIERS_NAME))
{
- WordValueAttribute.readModifiers(info, readOffset);
+ return WordValueAttribute.readModifiers(info, readOffset);
// not added to _readAttributes because evaluated immediately.
}
else if (CharOperation.equals(attributeName, ROLECLASS_METHOD_MODIFIERS_NAME))
{
- WordValueAttribute.readRoleClassMethodModifiersAttribute(info, readOffset);
+ return WordValueAttribute.readModifiers(info, readOffset);
// not added to _readAttributes because evaluated immediately.
}
else if (CharOperation.equals(attributeName, CALLS_BASE_CTOR))
@@ -583,6 +589,7 @@
else if (CharOperation.equals(attributeName, CALLIN_FLAGS))
{
this.methodAttributes.add(WordValueAttribute.readCallinFlags(info, readOffset));
+ return ExtraCompilerModifiers.AccCallin;
}
else if (CharOperation.equals(attributeName, TYPE_ANCHOR_LIST))
{
@@ -592,6 +599,7 @@
{
this.methodAttributes.add(CopyInheritanceSourceAttribute.readcopyInherSrc(info, readOffset, aStructOffset, someConstantPoolOffsets));
}
+ return 0;
}
// SH}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java
index 53bd90a..02f0a0e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java
@@ -20,6 +20,9 @@
this.annotations = annotations;
this.accessFlags = methodInfo.accessFlags;
+//{ObjectTeams:
+ this.callBaseCtor = methodInfo.callBaseCtor;
+// SH}
this.attributeBytes = methodInfo.attributeBytes;
this.descriptor = methodInfo.descriptor;
this.exceptionNames = methodInfo.exceptionNames;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/WordValueAttribute.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/WordValueAttribute.java
index 90535c5..93b5a1a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/WordValueAttribute.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/WordValueAttribute.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2004, 2014 Fraunhofer Gesellschaft, Munich, Germany,
+ * Copyright 2004, 2018 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
@@ -180,16 +180,16 @@
}
/**
- * Read and evaluate a "Modifiers" attribute from byte code.
- * @param method this method shall be modified.
+ * Read the value of a "Modifiers" or "RoleClassMethodModifiers" attribute from byte code.
+ * @param method method to read from
* @param readOffset where to read
+ * @return the modifier flags
*/
- public static void readModifiers(
+ public static int readModifiers(
MethodInfo method,
int readOffset)
{
- int value = method.u2At(readOffset);
- method.setAccessFlags(value);
+ return method.u2At(readOffset);
}
/**
@@ -209,12 +209,6 @@
return new WordValueAttribute(ROLECLASS_METHOD_MODIFIERS_NAME, modifiers);
}
- public static void readRoleClassMethodModifiersAttribute(MethodInfo info, int readOffset) {
- int binaryFlags = info.getModifiers() & ~ExtraCompilerModifiers.AccVisibilityMASK; // reset these bits first
- int newFlags = info.u2At(readOffset);
- info.setAccessFlags(binaryFlags | newFlags);
- }
-
/**
* Read and evaluate a "CallinFlags" attribute from byte code.
* @param method this method shall be modified.
@@ -225,7 +219,6 @@
int readOffset)
{
int value = method.u2At(readOffset);
- method.setAccessFlags(method.getModifiers()|ExtraCompilerModifiers.AccCallin);
// create and store an attribute anyway, in order to store the actual bits.
WordValueAttribute result = callinFlagsAttribute(value);
result._methodInfo = method;