diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java index 7095af1..a21b681 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -58,6 +58,9 @@ public interface ClassFileConstants { int MethodRefTag = 10; int InterfaceMethodRefTag = 11; int NameAndTypeTag = 12; + int MethodHandleTag = 15; + int MethodTypeTag = 16; + int InvokeDynamicTag = 18; int ConstantMethodRefFixedSize = 5; int ConstantClassFixedSize = 3; @@ -70,6 +73,9 @@ public interface ClassFileConstants { int ConstantStringFixedSize = 3; int ConstantUtf8FixedSize = 3; int ConstantNameAndTypeFixedSize = 5; + int ConstantMethodHandleFixedSize = 4; + int ConstantMethodTypeFixedSize = 3; + int ConstantInvokeDynamicFixedSize = 5; int MAJOR_VERSION_1_1 = 45; int MAJOR_VERSION_1_2 = 46; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java index d2a2b62..8fec4cb 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -207,6 +207,19 @@ public ClassFileReader(byte[] classFileBytes, char[] fileName, boolean fullyInit case ClassFileConstants.NameAndTypeTag : this.constantPoolOffsets[i] = readOffset; readOffset += ClassFileConstants.ConstantNameAndTypeFixedSize; + break; + case ClassFileConstants.MethodHandleTag : + this.constantPoolOffsets[i] = readOffset; + readOffset += ClassFileConstants.ConstantMethodHandleFixedSize; + break; + case ClassFileConstants.MethodTypeTag : + this.constantPoolOffsets[i] = readOffset; + readOffset += ClassFileConstants.ConstantMethodTypeFixedSize; + break; + case ClassFileConstants.InvokeDynamicTag : + this.constantPoolOffsets[i] = readOffset; + readOffset += ClassFileConstants.ConstantInvokeDynamicFixedSize; + break; } } // Read and validate access flags diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java index dd894ad..c23af13 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -923,8 +923,9 @@ public class ByteCodeVisitorAdapter implements IBytecodeVisitor { // default behavior is to do nothing } /** - * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry) + * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry, IConstantPoolEntry) * @since 3.6 + * @deprecated This has been replaced with {@link IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry)} */ public void _invokedynamic( int pc, @@ -934,6 +935,16 @@ public class ByteCodeVisitorAdapter implements IBytecodeVisitor { // default behavior is to do nothing } /** + * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry) + * @since 3.8 + */ + public void _invokedynamic( + int pc, + int index, + IConstantPoolEntry invokeDynamicEntry) { + // default behavior is to do nothing + } + /** * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry) */ public void _invokeinterface( diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java index e5dafa4..da838ec 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -140,4 +140,10 @@ public interface IAttributeNamesConstants { * @since 3.2 */ char[] STACK_MAP = "StackMap".toCharArray(); //$NON-NLS-1$ + + /** + * "BootstrapMethods" attribute (added in cldc1.0). + * @since 3.8 + */ + char[] BOOTSTRAP_METHODS = "BootstrapMethods".toCharArray(); //$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java new file mode 100644 index 0000000..a0b8166 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.util; + +/** + * Description of a bootstrap methods attribute as described in the JVM specifications. + * + * This interface may be implemented by clients. + * + * @since 3.8 + */ +public interface IBootstrapMethodsAttribute extends IClassFileAttribute { + + /** + * Answer back the number of bootstrap methods of this entry as specified in + * the JVM specifications. + * + * @return the local variable table length of this entry as specified in + * the JVM specifications + */ + int getBootstrapMethodsLength(); + + /** + * Answer back the bootstrap methods table of this entry as specified in + * the JVM specifications. Answer an empty array if none. + * + * @return the bootstrap methods table of this entry as specified in + * the JVM specifications. Answer an empty array if none + */ + IBootstrapMethodsEntry[] getBootstrapMethods(); + +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java new file mode 100644 index 0000000..4078e85 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.util; + +/** + * Description of a bootstrap method table entry as specified in the JVM specifications. + * + * This interface may be implemented by clients. + * + * @since 3.8 + */ +public interface IBootstrapMethodsEntry { + + int getBootstrapMethodReference(); + int[] getBootstrapArguments(); +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java index 52ccb16..f36db8c 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -168,12 +168,20 @@ public interface IBytecodeVisitor { IConstantPoolEntry constantClass); /** * @since 3.6 + * @deprecated This has been replaced with {@link #_invokedynamic(int, int, IConstantPoolEntry)} */ void _invokedynamic( int pc, int index, IConstantPoolEntry nameEntry, IConstantPoolEntry descriptorEntry); + /** + * @since 3.8 + */ + void _invokedynamic( + int pc, + int index, + IConstantPoolEntry invokeDynamic); void _invokeinterface( int pc, int index, diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java index 6952606..9f57bb1 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -27,8 +27,7 @@ public interface IConstantPool { int getConstantPoolCount(); /** - * Answer back the type of the entry at the index @index - * in the constant pool. + * Answer back the type of the entry at the given index in the constant pool. * * @param index the index of the entry in the constant pool * @return the type of the entry at the index @index in the constant pool @@ -36,11 +35,14 @@ public interface IConstantPool { int getEntryKind(int index); /** - * Answer back the entry at the index @index - * in the constant pool. + * Answer back the entry at the given index in the constant pool. + * + *

The return value can be an instance of {@link IConstantPoolEntry2} if the value returned + * by {@link #getEntryKind(int)} is either {@link IConstantPoolConstant#CONSTANT_MethodHandle}, + * {@link IConstantPoolConstant#CONSTANT_MethodType} or {@link IConstantPoolConstant#CONSTANT_InvokeDynamic}.

* * @param index the index of the entry in the constant pool - * @return the entry at the index @index in the constant pool + * @return the entry at the given index in the constant pool */ IConstantPoolEntry decodeEntry(int index); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java index bc7cb54..ff6ed22 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -29,6 +29,18 @@ public interface IConstantPoolConstant { int CONSTANT_Double = 6; int CONSTANT_NameAndType = 12; int CONSTANT_Utf8 = 1; + /** + * @since 3.8 + */ + int CONSTANT_MethodHandle = 15; + /** + * @since 3.8 + */ + int CONSTANT_MethodType = 16; + /** + * @since 3.8 + */ + int CONSTANT_InvokeDynamic = 18; int CONSTANT_Methodref_SIZE = 5; int CONSTANT_Class_SIZE = 3; @@ -41,5 +53,62 @@ public interface IConstantPoolConstant { int CONSTANT_String_SIZE = 3; int CONSTANT_Utf8_SIZE = 3; int CONSTANT_NameAndType_SIZE = 5; + /** + * @since 3.8 + */ + int CONSTANT_MethodHandle_SIZE = 4; + /** + * @since 3.8 + */ + int CONSTANT_MethodType_SIZE = 3; + /** + * @since 3.8 + */ + int CONSTANT_InvokeDynamic_SIZE = 5; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_GetField = 1; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_GetStatic = 2; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_PutField = 3; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_PutStatic = 4; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_InvokeVirtual = 5; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_InvokeStatic = 6; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_InvokeSpecial = 7; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_NewInvokeSpecial = 8; + /** + * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). + * @since 3.8 + */ + int METHOD_TYPE_REF_InvokeInterface = 9; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java index 487ad82..c75bd40 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -32,6 +32,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the name index for a CONSTANT_Class type entry + * @see IConstantPoolConstant#CONSTANT_Class */ int getClassInfoNameIndex(); @@ -42,16 +43,25 @@ public interface IConstantPoolEntry { * * @return the class index for a CONSTANT_Fieldref, * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry + * @see IConstantPoolConstant#CONSTANT_Fieldref + * @see IConstantPoolConstant#CONSTANT_Methodref + * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref */ int getClassIndex(); /** * Returns the nameAndType index for a CONSTANT_Fieldref, - * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry. + * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, + * CONSTANT_InvokeDynamic type entry. * The value is unspecified otherwise. * * @return the nameAndType index for a CONSTANT_Fieldref, - * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry + * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, + * CONSTANT_InvokeDynamic type entry + * @see IConstantPoolConstant#CONSTANT_Fieldref + * @see IConstantPoolConstant#CONSTANT_Methodref + * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref + * @see IConstantPoolConstant#CONSTANT_InvokeDynamic */ int getNameAndTypeIndex(); @@ -60,6 +70,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the string index for a CONSTANT_String type entry + * @see IConstantPoolConstant#CONSTANT_String */ int getStringIndex(); @@ -68,6 +79,7 @@ public interface IConstantPoolEntry { * Returns null otherwise. * * @return the string value for a CONSTANT_String type entry + * @see IConstantPoolConstant#CONSTANT_String */ String getStringValue(); @@ -76,6 +88,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the integer value for a CONSTANT_Integer type entry + * @see IConstantPoolConstant#CONSTANT_Integer */ int getIntegerValue(); @@ -84,6 +97,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the float value for a CONSTANT_Float type entry + * @see IConstantPoolConstant#CONSTANT_Float */ float getFloatValue(); @@ -92,6 +106,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the double value for a CONSTANT_Double type entry + * @see IConstantPoolConstant#CONSTANT_Double */ double getDoubleValue(); @@ -100,6 +115,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the long value for a CONSTANT_Long type entry + * @see IConstantPoolConstant#CONSTANT_Long */ long getLongValue(); @@ -108,6 +124,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the descriptor index for a CONSTANT_NameAndType type entry + * @see IConstantPoolConstant#CONSTANT_NameAndType */ int getNameAndTypeInfoDescriptorIndex(); @@ -116,6 +133,7 @@ public interface IConstantPoolEntry { * The value is unspecified otherwise. * * @return the name index for a CONSTANT_NameAndType type entry + * @see IConstantPoolConstant#CONSTANT_NameAndType */ int getNameAndTypeInfoNameIndex(); @@ -124,6 +142,7 @@ public interface IConstantPoolEntry { * Returns null otherwise. * * @return the class name for a CONSTANT_Class type entry + * @see IConstantPoolConstant#CONSTANT_Class */ char[] getClassInfoName(); @@ -134,6 +153,9 @@ public interface IConstantPoolEntry { * * @return the class name for a CONSTANT_Fieldref, * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry + * @see IConstantPoolConstant#CONSTANT_Fieldref + * @see IConstantPoolConstant#CONSTANT_Methodref + * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref */ char[] getClassName(); @@ -142,16 +164,20 @@ public interface IConstantPoolEntry { * Returns null otherwise. * * @return the field name for a CONSTANT_Fieldref type entry + * @see IConstantPoolConstant#CONSTANT_Fieldref */ char[] getFieldName(); /** - * Returns the field name for a CONSTANT_Methodref or CONSTANT_InterfaceMethodred - * type entry. + * Returns the field name for a CONSTANT_Methodref, CONSTANT_InterfaceMethodref + * or CONSTANT_InvokeDynamic type entry. * Returns null otherwise. * - * @return the field name for a CONSTANT_Methodref or CONSTANT_InterfaceMethodred - * type entry + * @return the method name for a CONSTANT_Methodref, CONSTANT_InterfaceMethodref + * or CONSTANT_InvokeDynamic type entry + * @see IConstantPoolConstant#CONSTANT_Methodref + * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref + * @see IConstantPoolConstant#CONSTANT_InvokeDynamic */ char[] getMethodName(); @@ -162,18 +188,27 @@ public interface IConstantPoolEntry { * * @return the field descriptor value for a CONSTANT_Fieldref type entry. This value * is set only when decoding the CONSTANT_Fieldref entry + * @see IConstantPoolConstant#CONSTANT_Fieldref */ char[] getFieldDescriptor(); /** * Returns the method descriptor value for a CONSTANT_Methodref or * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the - * CONSTANT_Methodref or CONSTANT_InterfaceMethodref entry. + * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, CONSTANT_MethodType + * or CONSTANT_InvokeDynamic entry. + * * Returns null otherwise. * - * @return the method descriptor value for a CONSTANT_Methodref or + * @return the method descriptor value for a CONSTANT_Methodref, * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the - * CONSTANT_Methodref or CONSTANT_InterfaceMethodref entry + * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, CONSTANT_MethodType + * or CONSTANT_InvokeDynamic entry + * + * @see IConstantPoolConstant#CONSTANT_Methodref + * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref + * @see IConstantPoolConstant#CONSTANT_MethodType + * @see IConstantPoolConstant#CONSTANT_InvokeDynamic */ char[] getMethodDescriptor(); @@ -184,6 +219,7 @@ public interface IConstantPoolEntry { * * @return the utf8 value for a CONSTANT_Utf8 type entry. This value is set only when * decoding a UTF8 entry + * @see IConstantPoolConstant#CONSTANT_Utf8 */ char[] getUtf8Value(); @@ -194,6 +230,7 @@ public interface IConstantPoolEntry { * * @return the utf8 length for a CONSTANT_Utf8 type entry. This value is set only when * decoding a UTF8 entry + * @see IConstantPoolConstant#CONSTANT_Utf8 */ int getUtf8Length(); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java new file mode 100644 index 0000000..3b4984b --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.util; + +/** + * Description of the new constant pool entry as described in the JVM specifications + * added for Java 7 support. + * Its contents is initialized according to its kind. + * + * This interface may be implemented by clients. + * + * @since 3.8 + */ +public interface IConstantPoolEntry2 extends IConstantPoolEntry { + /** + * Returns the descriptor index. This value is set only when decoding a MethodType entry. + * The value is unspecified otherwise. The corresponding UTF8 value can be retrieved by using + * {@link #getMethodDescriptor()}. + * + * @return the descriptor index. This value is set only when decoding a MethodType entry. + * @see IConstantPoolConstant#CONSTANT_MethodType + */ + int getDescriptorIndex(); + + /** + * Returns the reference kind. This value is set only when decoding a MethodHandle entry. + * The value is unspecified otherwise. + * + * @return the reference kind. This value is set only when decoding a MethodHandle entry. + * @see IConstantPoolConstant#CONSTANT_MethodHandle + */ + int getReferenceKind(); + + /** + * Returns the reference index. This value is set only when decoding a MethodHandle entry. + * The value is unspecified otherwise. + * + * @return the reference kind. This value is set only when decoding a MethodHandle entry. + * @see IConstantPoolConstant#CONSTANT_MethodHandle + */ + int getReferenceIndex(); + + /** + * Returns the bootstrap method attribute index. This value is set only when decoding a InvokeDynamic entry. + * The value is unspecified otherwise. + * + * @return the reference kind. This value is set only when decoding a MethodHandle entry. + * @see IConstantPoolConstant#CONSTANT_InvokeDynamic + */ + int getBootstrapMethodAttributeIndex(); +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java new file mode 100644 index 0000000..b196927 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IBootstrapMethodsAttribute; +import org.eclipse.jdt.core.util.IBootstrapMethodsEntry; +import org.eclipse.jdt.core.util.IConstantPool; + +/** + * Default implementation of IBootstrapMethodsAttribute. + */ +public class BootstrapMethodsAttribute extends ClassFileAttribute implements IBootstrapMethodsAttribute { + private static final IBootstrapMethodsEntry[] NO_ENTRIES = new IBootstrapMethodsEntry[0]; + + private IBootstrapMethodsEntry[] entries; + private int numberOfBootstrapMethods; + + /** + * Constructor for BootstrapMethodsAttribute. + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public BootstrapMethodsAttribute( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) throws ClassFormatException { + super(classFileBytes, constantPool, offset); + this.numberOfBootstrapMethods = u2At(classFileBytes, 6, offset); + final int length = this.numberOfBootstrapMethods; + if (length != 0) { + int readOffset = 8; + this.entries = new IBootstrapMethodsEntry[length]; + for (int i = 0; i < length; i++) { + this.entries[i] = new BootstrapMethodsEntry(classFileBytes, constantPool, offset + readOffset); + readOffset += 8; + } + } else { + this.entries = NO_ENTRIES; + } + } + + /** + * @see IBootstrapMethodsAttribute#getBootstrapMethods() + */ + public IBootstrapMethodsEntry[] getBootstrapMethods() { + return this.entries; + } + + public int getBootstrapMethodsLength() { + return this.numberOfBootstrapMethods; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java new file mode 100644 index 0000000..e444dbd --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IBootstrapMethodsEntry; +import org.eclipse.jdt.core.util.IConstantPool; + +/** + * Default implementation of {@link IBootstrapMethodsEntry} + */ +public class BootstrapMethodsEntry + extends ClassFileStruct + implements IBootstrapMethodsEntry { + + private int bootstrapMethodReference; + private int[] bootstrapArguments; + + public BootstrapMethodsEntry(byte classFileBytes[], IConstantPool constantPool, int offset) throws ClassFormatException { + this.bootstrapMethodReference = u2At(classFileBytes, 0, offset); + int length = u2At(classFileBytes, 2, offset); + int[] arguments = new int[length]; + int position = 4; + for (int i = 0; i < length; i++) { + arguments[i] = u2At(classFileBytes, position, offset); + position += 2; + } + this.bootstrapArguments = arguments; + } + + /** + * @see IBootstrapMethodsEntry#getBootstrapArguments() + */ + public int[] getBootstrapArguments() { + return this.bootstrapArguments; + } + + /** + * @see IBootstrapMethodsEntry#getBootstrapMethodReference() + */ + public int getBootstrapMethodReference() { + return this.bootstrapMethodReference; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java index 19b80dc..0426dc4 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -140,6 +140,18 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader constantPoolOffsets[i] = readOffset; readOffset += IConstantPoolConstant.CONSTANT_NameAndType_SIZE; break; + case IConstantPoolConstant.CONSTANT_MethodHandle : + constantPoolOffsets[i] = readOffset; + readOffset += IConstantPoolConstant.CONSTANT_MethodHandle_SIZE; + break; + case IConstantPoolConstant.CONSTANT_MethodType : + constantPoolOffsets[i] = readOffset; + readOffset += IConstantPoolConstant.CONSTANT_MethodType_SIZE; + break; + case IConstantPoolConstant.CONSTANT_InvokeDynamic : + constantPoolOffsets[i] = readOffset; + readOffset += IConstantPoolConstant.CONSTANT_InvokeDynamic_SIZE; + break; default: throw new ClassFormatException(ClassFormatException.INVALID_TAG_CONSTANT); } @@ -261,6 +273,8 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset); } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) { this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.BOOTSTRAP_METHODS)) { + this.attributes[attributesIndex++] = new BootstrapMethodsAttribute(classFileBytes, this.constantPool, readOffset); } else { this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, this.constantPool, readOffset); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java index 82ba955..a281ab0 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -1049,14 +1049,13 @@ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute case IOpcodeMnemonics.INVOKEDYNAMIC : index = u2At(this.classFileBytes, 1, pc); constantPoolEntry = this.constantPool.decodeEntry(index); - if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_NameAndType) { + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_InvokeDynamic) { throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); } visitor._invokedynamic( pc - this.codeOffset, index, - this.constantPool.decodeEntry(constantPoolEntry.getNameAndTypeInfoNameIndex()), - this.constantPool.decodeEntry(constantPoolEntry.getNameAndTypeInfoDescriptorIndex())); + constantPoolEntry); pc += 5; break; case IOpcodeMnemonics.NEW : diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java index aeeee24..a9c4699 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -33,19 +33,28 @@ public class ConstantPool extends ClassFileStruct implements IConstantPool { * @see IConstantPool#decodeEntry(int) */ public IConstantPoolEntry decodeEntry(int index) { - ConstantPoolEntry constantPoolEntry = new ConstantPoolEntry(); - constantPoolEntry.reset(); + ConstantPoolEntry constantPoolEntry = null; int kind = getEntryKind(index); - constantPoolEntry.setKind(kind); switch(kind) { case IConstantPoolConstant.CONSTANT_Class : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setClassInfoNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setClassInfoName(getUtf8ValueAt(constantPoolEntry.getClassInfoNameIndex())); break; case IConstantPoolConstant.CONSTANT_Double : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setDoubleValue(doubleAt(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_Fieldref : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); int declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]); constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex)); @@ -57,6 +66,11 @@ public class ConstantPool extends ClassFileStruct implements IConstantPool { break; case IConstantPoolConstant.CONSTANT_Methodref : case IConstantPoolConstant.CONSTANT_InterfaceMethodref : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]); constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex)); @@ -67,25 +81,76 @@ public class ConstantPool extends ClassFileStruct implements IConstantPool { constantPoolEntry.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex)); break; case IConstantPoolConstant.CONSTANT_Float : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setFloatValue(floatAt(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_Integer : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setIntegerValue(i4At(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_Long : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setLongValue(i8At(this.classFileBytes, 1, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_NameAndType : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setNameAndTypeNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setNameAndTypeDescriptorIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index])); break; case IConstantPoolConstant.CONSTANT_String : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setStringIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setStringValue(getUtf8ValueAt(constantPoolEntry.getStringIndex())); break; case IConstantPoolConstant.CONSTANT_Utf8 : + constantPoolEntry = new ConstantPoolEntry(); + constantPoolEntry.reset(); + constantPoolEntry.setKind(kind); constantPoolEntry.setUtf8Length(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); constantPoolEntry.setUtf8Value(getUtf8ValueAt(index)); + break; + case IConstantPoolConstant.CONSTANT_MethodHandle : + ConstantPoolEntry2 constantPoolEntry2 = new ConstantPoolEntry2(); + constantPoolEntry2.reset(); + constantPoolEntry2.setKind(kind); + constantPoolEntry2.setReferenceKind(u1At(this.classFileBytes, 1, this.constantPoolOffset[index])); + constantPoolEntry2.setReferenceIndex(u2At(this.classFileBytes, 2, this.constantPoolOffset[index])); + constantPoolEntry = constantPoolEntry2; + break; + case IConstantPoolConstant.CONSTANT_MethodType : + constantPoolEntry2 = new ConstantPoolEntry2(); + constantPoolEntry2.reset(); + constantPoolEntry2.setKind(kind); + methodDescriptorIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[index]); + constantPoolEntry2.setDescriptorIndex(methodDescriptorIndex); + constantPoolEntry2.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex)); + constantPoolEntry = constantPoolEntry2; + break; + case IConstantPoolConstant.CONSTANT_InvokeDynamic : + constantPoolEntry2 = new ConstantPoolEntry2(); + constantPoolEntry2.reset(); + constantPoolEntry2.setKind(kind); + constantPoolEntry2.setBootstrapMethodAttributeIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); + int nameAndTypeIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[index]); + constantPoolEntry2.setNameAndTypeIndex(nameAndTypeIndex); + methodNameIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[nameAndTypeIndex]); + methodDescriptorIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[nameAndTypeIndex]); + constantPoolEntry2.setMethodName(getUtf8ValueAt(methodNameIndex)); + constantPoolEntry2.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex)); + constantPoolEntry = constantPoolEntry2; + break; } return constantPoolEntry; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java index 55cc170..9f9cae6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -341,6 +341,7 @@ public class ConstantPoolEntry implements IConstantPoolEntry { /** * Sets the methodDescriptor. + * * @param methodDescriptor The methodDescriptor to set */ public void setMethodDescriptor(char[] methodDescriptor) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java new file mode 100644 index 0000000..c6c9686 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2011 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.IConstantPoolEntry2; + +/** + * Default implementation of IConstantPoolEntry + * + * @since 2.0 + */ +public class ConstantPoolEntry2 extends ConstantPoolEntry implements IConstantPoolEntry2 { + + private int descriptorIndex; + private int referenceKind; + private int referenceIndex; + private int bootstrapMethodAttributeIndex; + + public int getDescriptorIndex() { + return this.descriptorIndex; + } + + public int getReferenceKind() { + return this.referenceKind; + } + + public int getReferenceIndex() { + return this.referenceIndex; + } + + public int getBootstrapMethodAttributeIndex() { + return this.bootstrapMethodAttributeIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public void setReferenceKind(int referenceKind) { + this.referenceKind = referenceKind; + } + + public void setReferenceIndex(int referenceIndex) { + this.referenceIndex = referenceIndex; + } + + public void setBootstrapMethodAttributeIndex(int bootstrapMethodAttributeIndex) { + this.bootstrapMethodAttributeIndex = bootstrapMethodAttributeIndex; + } + + public void reset() { + super.reset(); + this.descriptorIndex = 0; + this.referenceKind = 0; + this.referenceIndex = 0; + this.bootstrapMethodAttributeIndex = 0; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java index d94dd4e..b5fe2ab 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,6 +17,7 @@ import org.eclipse.jdt.core.util.IBytecodeVisitor; import org.eclipse.jdt.core.util.ICodeAttribute; import org.eclipse.jdt.core.util.IConstantPoolConstant; import org.eclipse.jdt.core.util.IConstantPoolEntry; +import org.eclipse.jdt.core.util.IConstantPoolEntry2; import org.eclipse.jdt.core.util.ILocalVariableAttribute; import org.eclipse.jdt.core.util.ILocalVariableTableEntry; import org.eclipse.jdt.core.util.OpcodeStringValues; @@ -1491,7 +1492,7 @@ public class DefaultBytecodeVisitor implements IBytecodeVisitor { writeNewLine(); } /** - * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry, IConstantPoolEntry) + * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry) */ public void _invokedynamic( int pc, @@ -1513,6 +1514,30 @@ public class DefaultBytecodeVisitor implements IBytecodeVisitor { writeNewLine(); } /** + * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry) + */ + public void _invokedynamic( + int pc, + int index, + IConstantPoolEntry invokeDynamicEntry) { + + dumpPcNumber(pc); + IConstantPoolEntry2 entry = (IConstantPoolEntry2) invokeDynamicEntry; + this.buffer.append(Messages.bind(Messages.classformat_invokedynamic, + new String[] { + OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEDYNAMIC], + Integer.toString(index), + Integer.toString(entry.getBootstrapMethodAttributeIndex()), + Util.toString( + null, + entry.getMethodName(), + entry.getMethodDescriptor(), + true, + isCompact()) + })); + writeNewLine(); + } + /** * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry) */ public void _invokeinterface( diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java index c54fd73..81b88f2 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java @@ -801,6 +801,8 @@ public class Disassembler extends ClassFileBytesDisassembler { IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS); IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS); + IClassFileAttribute bootstrapMethods = Util.getAttribute(classFileReader, IAttributeNamesConstants.BOOTSTRAP_METHODS); + if (checkMode(mode, DETAILED)) { // disassemble compact version of annotations if (runtimeInvisibleAnnotationsAttribute != null) { @@ -904,28 +906,15 @@ public class Disassembler extends ClassFileBytesDisassembler { IClassFileAttribute[] attributes = classFileReader.getAttributes(); int length = attributes.length; IEnclosingMethodAttribute enclosingMethodAttribute = getEnclosingMethodAttribute(classFileReader); - int remainingAttributesLength = length; - if (innerClassesAttribute != null) { - remainingAttributesLength--; - } - if (enclosingMethodAttribute != null) { - remainingAttributesLength--; - } - if (sourceAttribute != null) { - remainingAttributesLength--; - } - if (signatureAttribute != null) { - remainingAttributesLength--; - } - if (innerClassesAttribute != null || enclosingMethodAttribute != null || remainingAttributesLength != 0) { - writeNewLine(buffer, lineSeparator, 0); - } if (innerClassesAttribute != null) { disassemble(innerClassesAttribute, buffer, lineSeparator, 1); } if (enclosingMethodAttribute != null) { disassemble(enclosingMethodAttribute, buffer, lineSeparator, 0); } + if (bootstrapMethods != null) { + disassemble((IBootstrapMethodsAttribute) bootstrapMethods, buffer, lineSeparator, 0); + } if (checkMode(mode, SYSTEM)) { if (runtimeVisibleAnnotationsAttribute != null) { disassemble((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode); @@ -937,13 +926,14 @@ public class Disassembler extends ClassFileBytesDisassembler { for (int i = 0; i < length; i++) { IClassFileAttribute attribute = attributes[i]; if (attribute != innerClassesAttribute - && attribute != sourceAttribute - && attribute != signatureAttribute - && attribute != enclosingMethodAttribute - && attribute != runtimeInvisibleAnnotationsAttribute - && attribute != runtimeVisibleAnnotationsAttribute - && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED) - && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC)) { + && attribute != sourceAttribute + && attribute != signatureAttribute + && attribute != enclosingMethodAttribute + && attribute != runtimeInvisibleAnnotationsAttribute + && attribute != runtimeVisibleAnnotationsAttribute + && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED) + && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC) + && attribute != bootstrapMethods) { disassemble(attribute, buffer, lineSeparator, 0, mode); } } @@ -1408,9 +1398,73 @@ public class Disassembler extends ClassFileBytesDisassembler { Integer.toString(i), decodeStringValue(new String(constantPoolEntry.getUtf8Value()))})); break; + case IConstantPoolConstant.CONSTANT_MethodHandle : + IConstantPoolEntry2 entry2 = (IConstantPoolEntry2) constantPoolEntry; + buffer.append( + Messages.bind(Messages.disassembler_constantpool_methodhandle, + new String[] { + Integer.toString(i), + getReferenceKind(entry2.getReferenceKind()), + Integer.toString(entry2.getReferenceIndex()), + })); + break; + case IConstantPoolConstant.CONSTANT_MethodType : + entry2 = (IConstantPoolEntry2) constantPoolEntry; + buffer.append( + Messages.bind(Messages.disassembler_constantpool_methodtype, + new String[] { + Integer.toString(i), + Integer.toString(entry2.getDescriptorIndex()), + String.valueOf(entry2.getMethodDescriptor()), + })); + break; + case IConstantPoolConstant.CONSTANT_InvokeDynamic : + entry2 = (IConstantPoolEntry2) constantPoolEntry; + buffer.append( + Messages.bind(Messages.disassembler_constantpool_invokedynamic, + new String[] { + Integer.toString(i), + Integer.toString(entry2.getBootstrapMethodAttributeIndex()), + Integer.toString(entry2.getNameAndTypeIndex()), + new String(constantPoolEntry.getMethodName()), + new String(constantPoolEntry.getMethodDescriptor()) + })); } } } + + private String getReferenceKind(int referenceKind) { + String message = null; + switch(referenceKind) { + case IConstantPoolConstant.METHOD_TYPE_REF_GetField : + message = Messages.disassembler_method_type_ref_getfield; + break; + case IConstantPoolConstant.METHOD_TYPE_REF_GetStatic : + message = Messages.disassembler_method_type_ref_getstatic; + break; + case IConstantPoolConstant.METHOD_TYPE_REF_PutField : + message = Messages.disassembler_method_type_ref_putfield; + break; + case IConstantPoolConstant.METHOD_TYPE_REF_PutStatic : + message = Messages.disassembler_method_type_ref_putstatic; + break; + case IConstantPoolConstant.METHOD_TYPE_REF_InvokeInterface : + message = Messages.disassembler_method_type_ref_invokeinterface; + break; + case IConstantPoolConstant.METHOD_TYPE_REF_InvokeSpecial : + message = Messages.disassembler_method_type_ref_invokespecial; + break; + case IConstantPoolConstant.METHOD_TYPE_REF_InvokeStatic : + message = Messages.disassembler_method_type_ref_invokestatic; + break; + case IConstantPoolConstant.METHOD_TYPE_REF_InvokeVirtual : + message = Messages.disassembler_method_type_ref_invokevirtual; + break; + default : + message = Messages.disassembler_method_type_ref_newinvokespecial; + } + return Messages.bind(message, new String[] { Integer.toString(referenceKind) }); + } private void disassemble(IEnclosingMethodAttribute enclosingMethodAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) { writeNewLine(buffer, lineSeparator, tabNumber + 1); @@ -1669,6 +1723,46 @@ public class Disassembler extends ClassFileBytesDisassembler { } } + private void disassemble(IBootstrapMethodsAttribute bootstrapMethodsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) { + writeNewLine(buffer, lineSeparator, tabNumber); + buffer.append(Messages.disassembler_bootstrapmethodattributesheader); + writeNewLine(buffer, lineSeparator, tabNumber + 1); + IBootstrapMethodsEntry[] entries = bootstrapMethodsAttribute.getBootstrapMethods(); + int length = entries.length; + for (int i = 0; i < length; i++) { + if (i != 0) { + buffer.append(Messages.disassembler_comma); + writeNewLine(buffer, lineSeparator, tabNumber + 1); + } + IBootstrapMethodsEntry entry = entries[i]; + buffer.append( + Messages.bind( + Messages.disassembler_bootstrapmethodentry, + new String[] { + Integer.toString(i), + Integer.toString(entry.getBootstrapMethodReference()), + getArguments(entry.getBootstrapArguments()) + })); + } + } + + private String getArguments(int[] arguments) { + StringBuffer buffer = new StringBuffer(); + buffer.append('{'); + for (int i = 0, max = arguments.length; i < max; i++) { + if (i != 0) { + buffer.append(Messages.disassembler_comma); + } + buffer.append( + Messages.bind( + Messages.disassembler_bootstrapmethodentry_argument, + new String[] { + Integer.toString(arguments[i]), + })); + } + buffer.append('}'); + return String.valueOf(buffer); + } private void disassemble(int index, IParameterAnnotation parameterAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) { IAnnotation[] annotations = parameterAnnotation.getAnnotations(); writeNewLine(buffer, lineSeparator, tabNumber + 1); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java index 75ecbab..ff1cf83 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java @@ -259,6 +259,9 @@ public final class Messages extends NLS { public static String disassembler_inner_accessflags; public static String disassembler_genericattributeheader; public static String disassembler_signatureattributeheader; + public static String disassembler_bootstrapmethodattributesheader; + public static String disassembler_bootstrapmethodentry; + public static String disassembler_bootstrapmethodentry_argument; public static String disassembler_indentation; public static String disassembler_constantpoolindex; public static String disassembler_space; @@ -278,6 +281,9 @@ public final class Messages extends NLS { public static String disassembler_constantpool_methodref; public static String disassembler_constantpool_name_and_type; public static String disassembler_constantpool_utf8; + public static String disassembler_constantpool_methodhandle; + public static String disassembler_constantpool_methodtype; + public static String disassembler_constantpool_invokedynamic; public static String disassembler_annotationdefaultheader; public static String disassembler_annotationdefaultvalue; public static String disassembler_annotationenumvalue; @@ -348,6 +354,16 @@ public final class Messages extends NLS { public static String disassembler_frame_same_frame; public static String disassembler_frame_same_locals_1_stack_item; public static String code_assist_internal_error; + + public static String disassembler_method_type_ref_getfield; + public static String disassembler_method_type_ref_putfield; + public static String disassembler_method_type_ref_getstatic; + public static String disassembler_method_type_ref_putstatic; + public static String disassembler_method_type_ref_invokestatic; + public static String disassembler_method_type_ref_invokevirtual; + public static String disassembler_method_type_ref_invokespecial; + public static String disassembler_method_type_ref_invokeinterface; + public static String disassembler_method_type_ref_newinvokespecial; static { NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties index e75e56b..5af88db 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties @@ -285,6 +285,9 @@ disassembler_genericattributeheader = Attribute: {0} Length: {1} disassembler_stackmaptableattributeheader = Stack map table: number of frames {0} disassembler_stackmapattributeheader = Stack map : number of frames {0} disassembler_signatureattributeheader = // Signature: {0} +disassembler_bootstrapmethodattributesheader = Bootstrap methods: +disassembler_bootstrapmethodentry = {0} : # {1} arguments: {2} +disassembler_bootstrapmethodentry_argument = #{0} disassembler_indentation = \ disassembler_constantpoolindex =\ # disassembler_space = \ @@ -304,6 +307,9 @@ disassembler_constantpool_interfacemethodref = constant #{0} interface_method_re disassembler_constantpool_methodref = constant #{0} method_ref: #{1}.#{2} {3}.{4} {5} disassembler_constantpool_name_and_type = constant #{0} name_and_type: #{1}.#{2} {3} {4} disassembler_constantpool_utf8 = constant #{0} utf8: "{1}" +disassembler_constantpool_methodhandle = constant #{0} method handle: {1} #{2} +disassembler_constantpool_methodtype = constant #{0} method type: #{1} {2} +disassembler_constantpool_invokedynamic = constant #{0} invoke dynamic: #{1} #{2} {3} {4} disassembler_annotationdefaultheader = Annotation Default:\ disassembler_annotationdefaultvalue= {0} (constant type) disassembler_annotationenumvalue = {2}.{3}(enum type #{0}.#{1}) @@ -323,6 +329,15 @@ disassembler_frame_same_locals_1_stack_item_extended=[pc: {0}, same_locals_1_sta disassembler_frame_chop=[pc: {0}, chop {1} local(s)] disassembler_frame_same_frame_extended=[pc: {0}, same_extended] disassembler_frame_append=[pc: {0}, append: {1}] +disassembler_method_type_ref_getfield = getfield ({0}) +disassembler_method_type_ref_putfield = putfield ({0}) +disassembler_method_type_ref_getstatic = getstatic ({0}) +disassembler_method_type_ref_putstatic = putstatic ({0}) +disassembler_method_type_ref_invokestatic = invokestatic ({0}) +disassembler_method_type_ref_invokevirtual = invokevirtual ({0}) +disassembler_method_type_ref_invokeinterface = invokeinterface ({0}) +disassembler_method_type_ref_invokespecial = invokespecial ({0}) +disassembler_method_type_ref_newinvokespecial = newinvokespecial ({0}) # {0} = offset delta # {1} = number of locals # {2} = locals @@ -358,7 +373,7 @@ classformat_new = {0} {2} [{1}] classformat_iinc = {0} {1} {2}{3} classformat_invokespecial ={0} {2} [{1}] classformat_invokeinterface ={0} {3} [{1}] [nargs: {2}] -classformat_invokedynamic={0} {2} [{1}] +classformat_invokedynamic={0} {2} {3} [{1}] classformat_invokestatic ={0} {2} [{1}] classformat_invokevirtual ={0} {2} [{1}] classformat_getfield ={0} {2}.{3} : {4} [{1}]