diff --git a/src/main/java/me/coley/cafedude/Constants.java b/src/main/java/me/coley/cafedude/Constants.java deleted file mode 100644 index fb3b6f0..0000000 --- a/src/main/java/me/coley/cafedude/Constants.java +++ /dev/null @@ -1,393 +0,0 @@ -package me.coley.cafedude; - -import me.coley.cafedude.classfile.annotation.TargetInfoType; - -/** - * Class file constants. - * - * @author Matt Coley - */ -public interface Constants { - // TODO: Document and add TLDR what in the class file changed between each version - int JAVA1 = 45; - int JAVA2 = 46; - int JAVA3 = 47; - int JAVA4 = 48; - int JAVA5 = 49; - int JAVA6 = 50; - int JAVA7 = 51; - int JAVA8 = 52; - int JAVA9 = 53; - int JAVA10 = 54; - int JAVA11 = 55; - int JAVA12 = 56; - int JAVA13 = 57; - int JAVA14 = 58; - int JAVA15 = 59; - int JAVA16 = 60; - int JAVA17 = 61; - - // TODO: Move this to access flag utility - int ACC_ANNOTATION = 0x2000; - int ACC_ABSTRACT = 0x0400; - - - /** - * Constants for constant pool. - */ - interface ConstantPool { - /** Constant pool identifier for UTF8 values. These values are used by other constants. */ - int UTF8 = 1; - /** Constant pool identifier for integers. */ - int INTEGER = 3; - /** Constant pool identifier for floats. */ - int FLOAT = 4; - /** Constant pool identifier for longs. */ - int LONG = 5; - /** Constant pool identifier for doubles. */ - int DOUBLE = 6; - /** Constant pool identifier for classes. */ - int CLASS = 7; - /** Constant pool identifier for strings. */ - int STRING = 8; - /** Constant pool identifier for field references. */ - int FIELD_REF = 9; - /** Constant pool identifier for method references. */ - int METHOD_REF = 10; - /** Constant pool identifier for interface method references. */ - int INTERFACE_METHOD_REF = 11; - /** Constant pool identifier for name-type. These are simply name/descriptor pairs. */ - int NAME_TYPE = 12; - /** Constant pool identifier for method handles. */ - int METHOD_HANDLE = 15; - /** Constant pool identifier for method types. These are simply descriptor UTF8s. */ - int METHOD_TYPE = 16; - /** Constant pool identifier for dynamically fetched values to be held by constants. */ - int DYNAMIC = 17; - /** Constant pool identifier for dynamically fetched method handles. */ - int INVOKE_DYNAMIC = 18; - /** Constant pool identifier for modules. */ - int MODULE = 19; - /** Constant pool identifier for packages. */ - int PACKAGE = 20; - } - - /** - * Constants for attributes. - */ - interface Attributes { - // TODO: Differentiate in documentation - // - More definitions @ https://github.com/openjdk/jdk/blob/master/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String ANNOTATION_DEFAULT = "AnnotationDefault"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String BOOTSTRAP_METHODS = "BootstrapMethods"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String CHARACTER_RANGE_TABLE = "CharacterRangeTable"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String CODE = "Code"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String CONSTANT_VALUE = "ConstantValue"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String COMPILATION_ID = "CompilationID"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String DEPRECATED = "Deprecated"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String ENCLOSING_METHOD = "EnclosingMethod"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String EXCEPTIONS = "Exceptions"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String INNER_CLASSES = "InnerClasses"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String LINE_NUMBER_TABLE = "LineNumberTable"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String LOCAL_VARIABLE_TABLE = "LocalVariableTable"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String METHOD_PARAMETERS = "MethodParameters"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String MODULE = "Module"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String MODULE_HASHES = "ModuleHashes"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String MODULE_MAIN_CLASS = "ModuleMainClass"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String MODULE_PACKAGES = "ModulePackages"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String MODULE_RESOLUTION = "ModuleResolution"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String MODULE_TARGET = "ModuleTarget"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String NEST_HOST = "NestHost"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String NEST_MEMBERS = "NestMembers"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String RECORD = "Record"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String PERMITTED_SUBCLASSES = "PermittedSubclasses"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String SIGNATURE = "Signature"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String SOURCE_DEBUG_EXTENSION = "SourceDebugExtension"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String SOURCE_FILE = "SourceFile"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String SOURCE_ID = "SourceID"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String STACK_MAP_TABLE = "StackMapTable"; - /** Attribute string value, used to indicate an attribute's type when parsed. */ - String SYNTHETIC = "Synthetic"; - } - - /** - * Constants for annotation attributes. - */ - interface Annotations { - /** - * Type parameter declaration of generic class or interface. - *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_TARGET} - *
Location: Class - */ - int PARAMETER_OF_CLASS_OR_INTERFACE = 0x00; - /** - * Type parameter declaration of generic method or constructor. - *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_TARGET} - *
Location: Method - */ - int PARAMETER_OF_METHOD = 0x01; - /** - * Type in {@code extends} or {@code implements} clause of class declaration - * (including the direct superclass or direct superinterface of an anonymous class declaration), - * or in extends clause of interface declaration. - *
Indicates type: {@link TargetInfoType#SUPERTYPE_TARGET} - *
Location: Class - */ - int SUPERTYPE = 0x10; - /** - * Type in bound of type parameter declaration of generic class or interface. - *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_BOUND_TARGET} - *
Location: Class - */ - int BOUND_TYPE_PARAMETER_OF_CLASS = 0x11; - /** - * Type in bound of type parameter declaration of generic method or constructor. - *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_BOUND_TARGET} - *
Location: Method - */ - int BOUND_TYPE_PARAMETER_OF_METHOD = 0x12; - /** - * Type in field declaration. - *
Indicates type: {@link TargetInfoType#EMPTY_TARGET} - *
Location: Field - */ - int FIELD = 0x13; - /** - * return type of method, or type of newly constructed object. - *
Indicates type: {@link TargetInfoType#EMPTY_TARGET} - *
Location: Method - */ - int METHOD_RETURN_TYPE = 0x14; - /** - * receiver type of method or constructor. - *
Indicates type: {@link TargetInfoType#EMPTY_TARGET} - *
Location: Method - */ - int METHOD_RECEIVER_TYPE = 0x15; - /** - * Type in formal parameter declaration of method, constructor, or lambda expression. - *
Indicates type: {@link TargetInfoType#FORMAL_PARAMETER_TARGET} - *
Location: Method - */ - int METHOD_PARAMETER = 0x16; - /** - * Type in {@code throws} clause of method or constructor. - *
Indicates type: {@link TargetInfoType#THROWS_TARGET} - *
Location: Method - */ - int METHOD_THROWS = 0x17; - /** - * Type in local variable declaration. - *
Indicates type: {@link TargetInfoType#LOCALVAR_TARGET} - *
Location: Code - */ - int LOCAL_VARIABLE_DECLARATION = 0x40; - /** - * Type in resource variable declaration. - *
Indicates type: {@link TargetInfoType#LOCALVAR_TARGET} - *
Location: Code - */ - int RESOURCE_VARIABLE_DECLARATION = 0x41; - /** - * Type in exception parameter declaration. - *
Indicates type: {@link TargetInfoType#CATCH_TARGET} - *
Location: Code - */ - int EXCEPTION_PARAMETER_DECLARATION = 0x42; - /** - * Type in {@code instanceof} expression. - *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} - *
Location: Code - */ - int INSTANCEOF_EXPRESSION = 0x43; - /** - * Type in {@code new} expression. - *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} - *
Location: Code - */ - int NEW_EXPRESSION = 0x44; - /** - * Type in method reference expression using {@code ::new}. - *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} - *
Location: Code - */ - int LAMBDA_NEW_EXPRESSION = 0x45; - /** - * Type in method reference expression using {@code ::Identifier}. - *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} - *
Location: Code - */ - int LAMBDA_METHOD_REF_EXPRESSION = 0x46; - /** - * Type in cast expression. - *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} - *
Location: Code - */ - int CAST_EXPRESSION = 0x47; - /** - * Type argument for generic constructor in new expression or explicit constructor invocation statement. - *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} - *
Location: Code - */ - int TYPE_ARGUMENT_OF_NEW_GENERIC_EXPRESSION = 0x48; - /** - * Type argument for generic method in method invocation expression. - *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} - *
Location: Code - */ - int TYPE_ARGUMENT_OF_GENERIC_NEW_METHOD_REF_EXPRESSION = 0x49; - /** - * Type argument for generic constructor in method reference expression using {@code ::new}. - *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} - *
Location: Code - */ - int TYPE_ARGUMENT_OF_GENERIC_NEW_LAMBDA_CONSTRUCTOR_EXPRESSION = 0x4A; - /** - * Type argument for generic method in method reference expression using {@code ::Identifier}. - *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} - *
Location: Code - */ - int TYPE_ARGUMENT_OF_GENERIC_METHOD_REF_EXPRESSION = 0x4B; - } - - /** - * Constants for the stack map table. - */ - interface StackMapTable { - /** - * Indicates the verification type {@code top}. - */ - int ITEM_TOP = 0; - /** - * Indicates the verification type {@code int}. - */ - int ITEM_INTEGER = 1; - /** - * Indicates the verification type {@code float}. - */ - int ITEM_FLOAT = 2; - /** - * Indicates the verification type {@code double}. - */ - int ITEM_DOUBLE = 3; - /** - * Indicates the verification type {@code long}. - */ - int ITEM_LONG = 4; - /** - * Indicates the verification type {@code null}. - */ - int ITEM_NULL = 5; - /** - * Indicates the verification type {@code uninitializedThis}. - */ - int ITEM_UNINITIALIZED_THIS = 6; - /** - * Indicates the verification type of a class reference. - */ - int ITEM_OBJECT = 7; - /** - * Indicates the verification type {@code uninitialized}. - */ - int ITEM_UNINITIALIZED = 8; - - /** - * The lower bound of the {@code same_frame}'s {@code frame_type}. - */ - int SAME_FRAME_MIN = 0; - /** - * The upper bound of the {@code same_frame}'s {@code frame_type}. - */ - int SAME_FRAME_MAX = 63; - /** - * The lower bound of the {@code same_locals_1_stack_item_frame}'s {@code frame_type}. - */ - int SAME_LOCALS_ONE_STACK_ITEM_MIN = 64; - /** - * The upper bound of the {@code same_locals_1_stack_item_frame}'s {@code frame_type}. - */ - int SAME_LOCALS_ONE_STACK_ITEM_MAX = 127; - /** - * The lower bound of the {@code same_locals_1_stack_item_frame_extended}'s {@code frame_type}. - */ - int SAME_LOCALS_ONE_STACK_ITEM_EXTENDED_MIN = 247; - /** - * The upper bound of the {@code same_locals_1_stack_item_frame_extended}'s {@code frame_type}. - */ - int SAME_LOCALS_ONE_STACK_ITEM_EXTENDED_MAX = 247; - /** - * The lower bound of the {@code chop_frame}'s {@code frame_type}. - */ - int CHOP_FRAME_MIN = 248; - /** - * The upper bound of the {@code chop_frame}'s {@code frame_type}. - */ - int CHOP_FRAME_MAX = 250; - /** - * The lower bound of the {@code same_frame_extended}'s {@code frame_type}. - */ - int SAME_FRAME_EXTENDED_MIN = 251; - /** - * The upper bound of the {@code same_frame_extended}'s {@code frame_type}. - */ - int SAME_FRAME_EXTENDED_MAX = 251; - /** - * The lower bound of the {@code append_frame}'s {@code frame_type}. - */ - int APPEND_FRAME_MIN = 252; - /** - * The upper bound of the {@code append_frame}'s {@code frame_type}. - */ - int APPEND_FRAME_MAX = 254; - /** - * The lower bound of the {@code full_frame}'s {@code frame_type}. - */ - int FULL_FRAME_MIN = 255; - /** - * The upper bound of the {@code full_frame}'s {@code frame_type}. - */ - int FULL_FRAME_MAX = 255; - } -} diff --git a/src/main/java/me/coley/cafedude/classfile/AnnotationConstants.java b/src/main/java/me/coley/cafedude/classfile/AnnotationConstants.java new file mode 100644 index 0000000..cf2be27 --- /dev/null +++ b/src/main/java/me/coley/cafedude/classfile/AnnotationConstants.java @@ -0,0 +1,145 @@ +package me.coley.cafedude.classfile; + +import me.coley.cafedude.classfile.annotation.TargetInfoType; + +/** + * Constants for annotation attributes. + * + * @author Matt Coley + */ +public interface AnnotationConstants { + /** + * Type parameter declaration of generic class or interface. + *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_TARGET} + *
Location: Class + */ + int PARAMETER_OF_CLASS_OR_INTERFACE = 0x00; + /** + * Type parameter declaration of generic method or constructor. + *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_TARGET} + *
Location: Method + */ + int PARAMETER_OF_METHOD = 0x01; + /** + * Type in {@code extends} or {@code implements} clause of class declaration + * (including the direct superclass or direct superinterface of an anonymous class declaration), + * or in extends clause of interface declaration. + *
Indicates type: {@link TargetInfoType#SUPERTYPE_TARGET} + *
Location: Class + */ + int SUPERTYPE = 0x10; + /** + * Type in bound of type parameter declaration of generic class or interface. + *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_BOUND_TARGET} + *
Location: Class + */ + int BOUND_TYPE_PARAMETER_OF_CLASS = 0x11; + /** + * Type in bound of type parameter declaration of generic method or constructor. + *
Indicates type: {@link TargetInfoType#TYPE_PARAMETER_BOUND_TARGET} + *
Location: Method + */ + int BOUND_TYPE_PARAMETER_OF_METHOD = 0x12; + /** + * Type in field declaration. + *
Indicates type: {@link TargetInfoType#EMPTY_TARGET} + *
Location: Field + */ + int FIELD = 0x13; + /** + * return type of method, or type of newly constructed object. + *
Indicates type: {@link TargetInfoType#EMPTY_TARGET} + *
Location: Method + */ + int METHOD_RETURN_TYPE = 0x14; + /** + * receiver type of method or constructor. + *
Indicates type: {@link TargetInfoType#EMPTY_TARGET} + *
Location: Method + */ + int METHOD_RECEIVER_TYPE = 0x15; + /** + * Type in formal parameter declaration of method, constructor, or lambda expression. + *
Indicates type: {@link TargetInfoType#FORMAL_PARAMETER_TARGET} + *
Location: Method + */ + int METHOD_PARAMETER = 0x16; + /** + * Type in {@code throws} clause of method or constructor. + *
Indicates type: {@link TargetInfoType#THROWS_TARGET} + *
Location: Method + */ + int METHOD_THROWS = 0x17; + /** + * Type in local variable declaration. + *
Indicates type: {@link TargetInfoType#LOCALVAR_TARGET} + *
Location: Code + */ + int LOCAL_VARIABLE_DECLARATION = 0x40; + /** + * Type in resource variable declaration. + *
Indicates type: {@link TargetInfoType#LOCALVAR_TARGET} + *
Location: Code + */ + int RESOURCE_VARIABLE_DECLARATION = 0x41; + /** + * Type in exception parameter declaration. + *
Indicates type: {@link TargetInfoType#CATCH_TARGET} + *
Location: Code + */ + int EXCEPTION_PARAMETER_DECLARATION = 0x42; + /** + * Type in {@code instanceof} expression. + *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} + *
Location: Code + */ + int INSTANCEOF_EXPRESSION = 0x43; + /** + * Type in {@code new} expression. + *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} + *
Location: Code + */ + int NEW_EXPRESSION = 0x44; + /** + * Type in method reference expression using {@code ::new}. + *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} + *
Location: Code + */ + int LAMBDA_NEW_EXPRESSION = 0x45; + /** + * Type in method reference expression using {@code ::Identifier}. + *
Indicates type: {@link TargetInfoType#OFFSET_TARGET} + *
Location: Code + */ + int LAMBDA_METHOD_REF_EXPRESSION = 0x46; + /** + * Type in cast expression. + *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} + *
Location: Code + */ + int CAST_EXPRESSION = 0x47; + /** + * Type argument for generic constructor in new expression or explicit constructor invocation statement. + *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} + *
Location: Code + */ + int TYPE_ARGUMENT_OF_NEW_GENERIC_EXPRESSION = 0x48; + /** + * Type argument for generic method in method invocation expression. + *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} + *
Location: Code + */ + int TYPE_ARGUMENT_OF_GENERIC_NEW_METHOD_REF_EXPRESSION = 0x49; + /** + * Type argument for generic constructor in method reference expression using {@code ::new}. + *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} + *
Location: Code + */ + int TYPE_ARGUMENT_OF_GENERIC_NEW_LAMBDA_CONSTRUCTOR_EXPRESSION = 0x4A; + /** + * Type argument for generic method in method reference expression using {@code ::Identifier}. + *
Indicates type: {@link TargetInfoType#TYPE_ARGUMENT_TARGET} + *
Location: Code + */ + int TYPE_ARGUMENT_OF_GENERIC_METHOD_REF_EXPRESSION = 0x4B; +} diff --git a/src/main/java/me/coley/cafedude/classfile/AttributeConstants.java b/src/main/java/me/coley/cafedude/classfile/AttributeConstants.java new file mode 100644 index 0000000..5ad1981 --- /dev/null +++ b/src/main/java/me/coley/cafedude/classfile/AttributeConstants.java @@ -0,0 +1,222 @@ +package me.coley.cafedude.classfile; + +import me.coley.cafedude.classfile.attribute.AnnotationDefaultAttribute; +import me.coley.cafedude.classfile.attribute.AnnotationsAttribute; +import me.coley.cafedude.classfile.attribute.BootstrapMethodsAttribute; +import me.coley.cafedude.classfile.attribute.CodeAttribute; +import me.coley.cafedude.classfile.attribute.ConstantValueAttribute; +import me.coley.cafedude.classfile.attribute.DeprecatedAttribute; +import me.coley.cafedude.classfile.attribute.EnclosingMethodAttribute; +import me.coley.cafedude.classfile.attribute.ExceptionsAttribute; +import me.coley.cafedude.classfile.attribute.InnerClassesAttribute; +import me.coley.cafedude.classfile.attribute.LineNumberTableAttribute; +import me.coley.cafedude.classfile.attribute.LocalVariableTableAttribute; +import me.coley.cafedude.classfile.attribute.LocalVariableTypeTableAttribute; +import me.coley.cafedude.classfile.attribute.ModuleAttribute; +import me.coley.cafedude.classfile.attribute.NestHostAttribute; +import me.coley.cafedude.classfile.attribute.NestMembersAttribute; +import me.coley.cafedude.classfile.attribute.ParameterAnnotationsAttribute; +import me.coley.cafedude.classfile.attribute.PermittedClassesAttribute; +import me.coley.cafedude.classfile.attribute.RecordAttribute; +import me.coley.cafedude.classfile.attribute.SignatureAttribute; +import me.coley.cafedude.classfile.attribute.SourceDebugExtensionAttribute; +import me.coley.cafedude.classfile.attribute.SourceFileAttribute; +import me.coley.cafedude.classfile.attribute.StackMapTableAttribute; +import me.coley.cafedude.classfile.attribute.SyntheticAttribute; + +/** + * Constants for attribute names. + * + * @author Matt Coley + */ +public interface AttributeConstants { + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see AnnotationDefaultAttribute + */ + String ANNOTATION_DEFAULT = "AnnotationDefault"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see BootstrapMethodsAttribute + */ + String BOOTSTRAP_METHODS = "BootstrapMethods"; + // TODO: Internal attribute? + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String CHARACTER_RANGE_TABLE = "CharacterRangeTable"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see CodeAttribute + */ + String CODE = "Code"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see ConstantValueAttribute + */ + String CONSTANT_VALUE = "ConstantValue"; + // TODO: Internal attribute? + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String COMPILATION_ID = "CompilationID"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see DeprecatedAttribute + */ + String DEPRECATED = "Deprecated"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see EnclosingMethodAttribute + */ + String ENCLOSING_METHOD = "EnclosingMethod"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see ExceptionsAttribute + */ + String EXCEPTIONS = "Exceptions"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see InnerClassesAttribute + */ + String INNER_CLASSES = "InnerClasses"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see LineNumberTableAttribute + */ + String LINE_NUMBER_TABLE = "LineNumberTable"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see LocalVariableTableAttribute + */ + String LOCAL_VARIABLE_TABLE = "LocalVariableTable"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see LocalVariableTypeTableAttribute + */ + String LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"; + // TODO: Attribute type + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String METHOD_PARAMETERS = "MethodParameters"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see ModuleAttribute + */ + String MODULE = "Module"; + // TODO: Internal attribute? + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String MODULE_HASHES = "ModuleHashes"; + // TODO: Attribute type + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String MODULE_MAIN_CLASS = "ModuleMainClass"; + // TODO: Attribute type + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String MODULE_PACKAGES = "ModulePackages"; + // TODO: Internal attribute? + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String MODULE_RESOLUTION = "ModuleResolution"; + // TODO: Internal attribute? + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String MODULE_TARGET = "ModuleTarget"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see NestHostAttribute + */ + String NEST_HOST = "NestHost"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see NestMembersAttribute + */ + String NEST_MEMBERS = "NestMembers"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see RecordAttribute + */ + String RECORD = "Record"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see AnnotationsAttribute + */ + String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see ParameterAnnotationsAttribute + */ + String RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see AnnotationsAttribute + */ + String RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see AnnotationsAttribute + */ + String RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see ParameterAnnotationsAttribute + */ + String RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see AnnotationsAttribute + */ + String RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see PermittedClassesAttribute + */ + String PERMITTED_SUBCLASSES = "PermittedSubclasses"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see SignatureAttribute + */ + String SIGNATURE = "Signature"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see SourceDebugExtensionAttribute + */ + String SOURCE_DEBUG_EXTENSION = "SourceDebugExtension"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see SourceFileAttribute + */ + String SOURCE_FILE = "SourceFile"; + // TODO: Internal attribute? + /** Attribute string value, used to indicate an attribute's type when parsed. */ + String SOURCE_ID = "SourceID"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see StackMapTableAttribute + */ + String STACK_MAP_TABLE = "StackMapTable"; + /** + * Attribute string value, used to indicate an attribute's type when parsed. + * + * @see SyntheticAttribute + */ + String SYNTHETIC = "Synthetic"; +} diff --git a/src/main/java/me/coley/cafedude/classfile/ConstantPoolConstants.java b/src/main/java/me/coley/cafedude/classfile/ConstantPoolConstants.java new file mode 100644 index 0000000..01276d8 --- /dev/null +++ b/src/main/java/me/coley/cafedude/classfile/ConstantPoolConstants.java @@ -0,0 +1,43 @@ +package me.coley.cafedude.classfile; + +/** + * Constants for constant pool. + * + * @author Matt Coley + */ +public interface ConstantPoolConstants { + /** Constant pool identifier for UTF8 values. These values are used by other constants. */ + int UTF8 = 1; + /** Constant pool identifier for integers. */ + int INTEGER = 3; + /** Constant pool identifier for floats. */ + int FLOAT = 4; + /** Constant pool identifier for longs. */ + int LONG = 5; + /** Constant pool identifier for doubles. */ + int DOUBLE = 6; + /** Constant pool identifier for classes. */ + int CLASS = 7; + /** Constant pool identifier for strings. */ + int STRING = 8; + /** Constant pool identifier for field references. */ + int FIELD_REF = 9; + /** Constant pool identifier for method references. */ + int METHOD_REF = 10; + /** Constant pool identifier for interface method references. */ + int INTERFACE_METHOD_REF = 11; + /** Constant pool identifier for name-type. These are simply name/descriptor pairs. */ + int NAME_TYPE = 12; + /** Constant pool identifier for method handles. */ + int METHOD_HANDLE = 15; + /** Constant pool identifier for method types. These are simply descriptor UTF8s. */ + int METHOD_TYPE = 16; + /** Constant pool identifier for dynamically fetched values to be held by constants. */ + int DYNAMIC = 17; + /** Constant pool identifier for dynamically fetched method handles. */ + int INVOKE_DYNAMIC = 18; + /** Constant pool identifier for modules. */ + int MODULE = 19; + /** Constant pool identifier for packages. */ + int PACKAGE = 20; +} diff --git a/src/main/java/me/coley/cafedude/classfile/Modifiers.java b/src/main/java/me/coley/cafedude/classfile/Modifiers.java new file mode 100644 index 0000000..af6a44f --- /dev/null +++ b/src/main/java/me/coley/cafedude/classfile/Modifiers.java @@ -0,0 +1,270 @@ +package me.coley.cafedude.classfile; + +/** + * Modifiers for flags on classes/fields/methods/attributes. + * Additionally, contains a few utility methods for managing masks. + * + * @author Matt Coley + */ +public interface Modifiers { + /** + * Applies to: + * + */ + int ACC_PUBLIC = 0x0001; + /** + * Applies to: + * + */ + int ACC_PRIVATE = 0x0002; + /** + * Applies to: + * + */ + int ACC_PROTECTED = 0x0004; + /** + * Applies to: + * + */ + int ACC_STATIC = 0x0008; + /** + * Applies to: + * + */ + int ACC_FINAL = 0x0010; + /** + * Applies to: + * + */ + int ACC_SUPER = 0x0020; + /** + * Applies to: + * + */ + int ACC_SYNCHRONIZED = 0x0020; + /** + * Applies to: + * + */ + int ACC_OPEN = 0x0020; + /** + * Applies to: + * + */ + int ACC_TRANSITIVE = 0x0020; + /** + * Applies to: + * + */ + int ACC_VOLATILE = 0x0040; + /** + * Applies to: + * + */ + int ACC_BRIDGE = 0x0040; + /** + * Applies to: + * + */ + int ACC_STATIC_PHASE = 0x0040; + /** + * Applies to: + * + */ + int ACC_VARARGS = 0x0080; + /** + * Applies to: + * + */ + int ACC_TRANSIENT = 0x0080; + /** + * Applies to: + * + */ + int ACC_NATIVE = 0x0100; + /** + * Applies to: + * + */ + int ACC_INTERFACE = 0x0200; + /** + * Applies to: + * + */ + int ACC_ABSTRACT = 0x0400; + /** + * Applies to: + * + */ + int ACC_STRICT = 0x0800; + /** + * Applies to: + * + */ + int ACC_SYNTHETIC = 0x1000; + /** + * Applies to: + * + */ + int ACC_ANNOTATION = 0x2000; + /** + * Applies to: + * + */ + int ACC_ENUM = 0x4000; + /** + * Applies to: + * + */ + int ACC_MANDATED = 0x8000; + /** + * Applies to: + * + */ + int ACC_MODULE = 0x8000; + + /** + * @param mask + * Modifier mask. + * @param flag + * Flag to check. + * + * @return {@code true} when the mask contains the flag. + */ + static boolean has(int mask, int flag) { + return (mask & flag) != 0; + } + + /** + * @param mask + * Modifier mask. + * @param flag + * Flag to flip in the mask. + * + * @return The mask with the flag value flipped. + */ + static int flip(int mask, int flag) { + return has(mask, flag) ? remove(mask, flag) : mask | flag; + } + + /** + * @param mask + * Modifier mask. + * @param flag + * Flag to remove from the mask. + * + * @return The mask without the flag. + */ + static int remove(int mask, int flag) { + return mask & ~flag; + } + + /** + * @param mask + * Modifier mask. + * @param flags + * Flags to check. + * + * @return {@code true} when the mask contains each flag. + */ + static boolean hasAll(int mask, int... flags) { + for (int flag : flags) + if ((mask & flag) == 0) + return false; + return true; + } + + /** + * @param mask + * Modifier mask. + * @param flags + * Flags to check. + * + * @return {@code true} when the mask contains any of the flags. + */ + static boolean hasAny(int mask, int... flags) { + for (int flag : flags) + if ((mask & flag) != 0) + return true; + return false; + } + + /** + * @param flags + * Flags to use. + * + * @return Mask containing the each flag. + */ + static int createMask(int... flags) { + int acc = 0; + for (int flag : flags) acc |= flag; + return acc; + } +} \ No newline at end of file diff --git a/src/main/java/me/coley/cafedude/classfile/StackMapTableConstants.java b/src/main/java/me/coley/cafedude/classfile/StackMapTableConstants.java new file mode 100644 index 0000000..d738677 --- /dev/null +++ b/src/main/java/me/coley/cafedude/classfile/StackMapTableConstants.java @@ -0,0 +1,101 @@ +package me.coley.cafedude.classfile; + +/** + * Constants for the stack map table. + * + * @author Matt Coley + */ +public interface StackMapTableConstants { + /** + * Indicates the verification type {@code top}. + */ + int ITEM_TOP = 0; + /** + * Indicates the verification type {@code int}. + */ + int ITEM_INTEGER = 1; + /** + * Indicates the verification type {@code float}. + */ + int ITEM_FLOAT = 2; + /** + * Indicates the verification type {@code double}. + */ + int ITEM_DOUBLE = 3; + /** + * Indicates the verification type {@code long}. + */ + int ITEM_LONG = 4; + /** + * Indicates the verification type {@code null}. + */ + int ITEM_NULL = 5; + /** + * Indicates the verification type {@code uninitializedThis}. + */ + int ITEM_UNINITIALIZED_THIS = 6; + /** + * Indicates the verification type of a class reference. + */ + int ITEM_OBJECT = 7; + /** + * Indicates the verification type {@code uninitialized}. + */ + int ITEM_UNINITIALIZED = 8; + /** + * The lower bound of the {@code same_frame}'s {@code frame_type}. + */ + int SAME_FRAME_MIN = 0; + /** + * The upper bound of the {@code same_frame}'s {@code frame_type}. + */ + int SAME_FRAME_MAX = 63; + /** + * The lower bound of the {@code same_locals_1_stack_item_frame}'s {@code frame_type}. + */ + int SAME_LOCALS_ONE_STACK_ITEM_MIN = 64; + /** + * The upper bound of the {@code same_locals_1_stack_item_frame}'s {@code frame_type}. + */ + int SAME_LOCALS_ONE_STACK_ITEM_MAX = 127; + /** + * The lower bound of the {@code same_locals_1_stack_item_frame_extended}'s {@code frame_type}. + */ + int SAME_LOCALS_ONE_STACK_ITEM_EXTENDED_MIN = 247; + /** + * The upper bound of the {@code same_locals_1_stack_item_frame_extended}'s {@code frame_type}. + */ + int SAME_LOCALS_ONE_STACK_ITEM_EXTENDED_MAX = 247; + /** + * The lower bound of the {@code chop_frame}'s {@code frame_type}. + */ + int CHOP_FRAME_MIN = 248; + /** + * The upper bound of the {@code chop_frame}'s {@code frame_type}. + */ + int CHOP_FRAME_MAX = 250; + /** + * The lower bound of the {@code same_frame_extended}'s {@code frame_type}. + */ + int SAME_FRAME_EXTENDED_MIN = 251; + /** + * The upper bound of the {@code same_frame_extended}'s {@code frame_type}. + */ + int SAME_FRAME_EXTENDED_MAX = 251; + /** + * The lower bound of the {@code append_frame}'s {@code frame_type}. + */ + int APPEND_FRAME_MIN = 252; + /** + * The upper bound of the {@code append_frame}'s {@code frame_type}. + */ + int APPEND_FRAME_MAX = 254; + /** + * The lower bound of the {@code full_frame}'s {@code frame_type}. + */ + int FULL_FRAME_MIN = 255; + /** + * The upper bound of the {@code full_frame}'s {@code frame_type}. + */ + int FULL_FRAME_MAX = 255; +} diff --git a/src/main/java/me/coley/cafedude/classfile/VersionConstants.java b/src/main/java/me/coley/cafedude/classfile/VersionConstants.java new file mode 100644 index 0000000..3d77e49 --- /dev/null +++ b/src/main/java/me/coley/cafedude/classfile/VersionConstants.java @@ -0,0 +1,30 @@ +package me.coley.cafedude.classfile; + +/** + * Constants for class file major versions. + * + * @author Matt Coley + */ +public interface VersionConstants { + // TODO: Document and add TLDR what in the class file changed between each version + int JAVA1 = 45; + int JAVA2 = 46; + int JAVA3 = 47; + int JAVA4 = 48; + int JAVA5 = 49; + int JAVA6 = 50; + int JAVA7 = 51; + int JAVA8 = 52; + int JAVA9 = 53; + int JAVA10 = 54; + int JAVA11 = 55; + int JAVA12 = 56; + int JAVA13 = 57; + int JAVA14 = 58; + int JAVA15 = 59; + int JAVA16 = 60; + int JAVA17 = 61; + int JAVA18 = 62; + int JAVA19 = 63; + int JAVA20 = 64; +} diff --git a/src/main/java/me/coley/cafedude/classfile/annotation/TargetInfoType.java b/src/main/java/me/coley/cafedude/classfile/annotation/TargetInfoType.java index 598bbeb..354f535 100644 --- a/src/main/java/me/coley/cafedude/classfile/annotation/TargetInfoType.java +++ b/src/main/java/me/coley/cafedude/classfile/annotation/TargetInfoType.java @@ -1,13 +1,13 @@ package me.coley.cafedude.classfile.annotation; -import me.coley.cafedude.Constants; +import me.coley.cafedude.classfile.AnnotationConstants; /** * Target information denoting which type in a declaration or expression is annotated. * * @author Matt Coley */ -public enum TargetInfoType implements Constants.Annotations { +public enum TargetInfoType implements AnnotationConstants { TYPE_PARAMETER_TARGET, SUPERTYPE_TARGET, TYPE_PARAMETER_BOUND_TARGET, diff --git a/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationDefaultAttribute.java b/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationDefaultAttribute.java index 76518bc..de3f1e2 100644 --- a/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationDefaultAttribute.java +++ b/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationDefaultAttribute.java @@ -5,7 +5,7 @@ import java.util.Set; /** - * Represents the default value of a annotation field (Which are technically methods, but I digress). + * Represents the default value of an annotation field (Which are technically methods, but I digress). * * @author Matt Coley */ diff --git a/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationsAttribute.java b/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationsAttribute.java index 44e125d..e9a1c00 100644 --- a/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationsAttribute.java +++ b/src/main/java/me/coley/cafedude/classfile/attribute/AnnotationsAttribute.java @@ -8,8 +8,8 @@ /** * Annotation collection attribute. Represents either: * * * @author Matt Coley diff --git a/src/main/java/me/coley/cafedude/classfile/attribute/AttributeContexts.java b/src/main/java/me/coley/cafedude/classfile/attribute/AttributeContexts.java index c04eeca..c162e26 100644 --- a/src/main/java/me/coley/cafedude/classfile/attribute/AttributeContexts.java +++ b/src/main/java/me/coley/cafedude/classfile/attribute/AttributeContexts.java @@ -1,6 +1,6 @@ package me.coley.cafedude.classfile.attribute; -import me.coley.cafedude.Constants.Attributes; +import me.coley.cafedude.classfile.AttributeConstants; import me.coley.cafedude.io.AttributeContext; import java.util.Collection; @@ -11,54 +11,54 @@ * * @author Matt Coley */ -public class AttributeContexts { +public class AttributeContexts implements AttributeConstants { /** * For more information on location see: * jvms-4.7 Table 4.7-C * * @param attributeName - * Name of attribute, see {@link Attributes}. + * Name of attribute, see {@link AttributeConstants}. * * @return Allowed locations for attribute. * If the attribute's allowed locations are unknown, then {@code -1}. */ public static Collection getAllowedContexts(String attributeName) { switch (attributeName) { - case Attributes.BOOTSTRAP_METHODS: - case Attributes.ENCLOSING_METHOD: - case Attributes.INNER_CLASSES: - case Attributes.MODULE: - case Attributes.MODULE_MAIN_CLASS: - case Attributes.MODULE_PACKAGES: - case Attributes.NEST_HOST: - case Attributes.NEST_MEMBERS: - case Attributes.PERMITTED_SUBCLASSES: - case Attributes.RECORD: - case Attributes.SOURCE_DEBUG_EXTENSION: - case Attributes.SOURCE_FILE: + case BOOTSTRAP_METHODS: + case ENCLOSING_METHOD: + case INNER_CLASSES: + case MODULE: + case MODULE_MAIN_CLASS: + case MODULE_PACKAGES: + case NEST_HOST: + case NEST_MEMBERS: + case PERMITTED_SUBCLASSES: + case RECORD: + case SOURCE_DEBUG_EXTENSION: + case SOURCE_FILE: return EnumSet.of(AttributeContext.CLASS); - case Attributes.CONSTANT_VALUE: + case CONSTANT_VALUE: return EnumSet.of(AttributeContext.FIELD); - case Attributes.ANNOTATION_DEFAULT: - case Attributes.CODE: - case Attributes.EXCEPTIONS: - case Attributes.METHOD_PARAMETERS: - case Attributes.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: - case Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: + case ANNOTATION_DEFAULT: + case CODE: + case EXCEPTIONS: + case METHOD_PARAMETERS: + case RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: + case RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: return EnumSet.of(AttributeContext.METHOD); - case Attributes.DEPRECATED: - case Attributes.SYNTHETIC: + case DEPRECATED: + case SYNTHETIC: return EnumSet.of(AttributeContext.CLASS, AttributeContext.FIELD, AttributeContext.METHOD); - case Attributes.LINE_NUMBER_TABLE: - case Attributes.LOCAL_VARIABLE_TABLE: - case Attributes.LOCAL_VARIABLE_TYPE_TABLE: - case Attributes.STACK_MAP_TABLE: + case LINE_NUMBER_TABLE: + case LOCAL_VARIABLE_TABLE: + case LOCAL_VARIABLE_TYPE_TABLE: + case STACK_MAP_TABLE: return EnumSet.of(AttributeContext.ATTRIBUTE); - case Attributes.RUNTIME_VISIBLE_ANNOTATIONS: - case Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS: - case Attributes.RUNTIME_INVISIBLE_ANNOTATIONS: - case Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: - case Attributes.SIGNATURE: + case RUNTIME_VISIBLE_ANNOTATIONS: + case RUNTIME_VISIBLE_TYPE_ANNOTATIONS: + case RUNTIME_INVISIBLE_ANNOTATIONS: + case RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: + case SIGNATURE: return EnumSet.allOf(AttributeContext.class); default: break; diff --git a/src/main/java/me/coley/cafedude/classfile/attribute/AttributeVersions.java b/src/main/java/me/coley/cafedude/classfile/attribute/AttributeVersions.java index 53a8183..0a136d6 100644 --- a/src/main/java/me/coley/cafedude/classfile/attribute/AttributeVersions.java +++ b/src/main/java/me/coley/cafedude/classfile/attribute/AttributeVersions.java @@ -1,67 +1,67 @@ package me.coley.cafedude.classfile.attribute; -import me.coley.cafedude.Constants; -import me.coley.cafedude.Constants.Attributes; +import me.coley.cafedude.classfile.AttributeConstants; +import me.coley.cafedude.classfile.VersionConstants; /** * Attribute relations to class file versions. * * @author Matt Coley */ -public class AttributeVersions { +public class AttributeVersions implements AttributeConstants, VersionConstants { /** * For more information on history see: * jvms-4.7 Table 4.7-B * * @param attributeName - * Name of attribute, see {@link Attributes}. + * Name of attribute, see {@link AttributeConstants}. * * @return Java version attribute was introduced in. * If the attribute's introduction version is unknown, then {@code -1}. */ public static int getIntroducedVersion(String attributeName) { switch (attributeName) { - case Attributes.CODE: - case Attributes.CONSTANT_VALUE: - case Attributes.DEPRECATED: - case Attributes.EXCEPTIONS: - case Attributes.INNER_CLASSES: - case Attributes.LINE_NUMBER_TABLE: - case Attributes.LOCAL_VARIABLE_TABLE: - case Attributes.SOURCE_FILE: - case Attributes.SYNTHETIC: - return Constants.JAVA1; - case Attributes.ANNOTATION_DEFAULT: - case Attributes.ENCLOSING_METHOD: - case Attributes.LOCAL_VARIABLE_TYPE_TABLE: - case Attributes.RUNTIME_INVISIBLE_ANNOTATIONS: - case Attributes.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: - case Attributes.RUNTIME_VISIBLE_ANNOTATIONS: - case Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: - case Attributes.SIGNATURE: - case Attributes.SOURCE_DEBUG_EXTENSION: - return Constants.JAVA5; - case Attributes.STACK_MAP_TABLE: - return Constants.JAVA6; - case Attributes.BOOTSTRAP_METHODS: - return Constants.JAVA7; - case Attributes.METHOD_PARAMETERS: - case Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: - case Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS: - return Constants.JAVA8; - case Attributes.MODULE: - case Attributes.MODULE_MAIN_CLASS: - case Attributes.MODULE_PACKAGES: - return Constants.JAVA9; - case Attributes.NEST_HOST: - case Attributes.NEST_MEMBERS: - return Constants.JAVA11; - case Attributes.RECORD: + case CODE: + case CONSTANT_VALUE: + case DEPRECATED: + case EXCEPTIONS: + case INNER_CLASSES: + case LINE_NUMBER_TABLE: + case LOCAL_VARIABLE_TABLE: + case SOURCE_FILE: + case SYNTHETIC: + return JAVA1; + case ANNOTATION_DEFAULT: + case ENCLOSING_METHOD: + case LOCAL_VARIABLE_TYPE_TABLE: + case RUNTIME_INVISIBLE_ANNOTATIONS: + case RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: + case RUNTIME_VISIBLE_ANNOTATIONS: + case RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: + case SIGNATURE: + case SOURCE_DEBUG_EXTENSION: + return JAVA5; + case STACK_MAP_TABLE: + return JAVA6; + case BOOTSTRAP_METHODS: + return JAVA7; + case METHOD_PARAMETERS: + case RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: + case RUNTIME_VISIBLE_TYPE_ANNOTATIONS: + return JAVA8; + case MODULE: + case MODULE_MAIN_CLASS: + case MODULE_PACKAGES: + return JAVA9; + case NEST_HOST: + case NEST_MEMBERS: + return JAVA11; + case RECORD: // Records first preview in 14 - return Constants.JAVA14; - case Attributes.PERMITTED_SUBCLASSES: + return JAVA14; + case PERMITTED_SUBCLASSES: // Sealed classes first preview in 15 - return Constants.JAVA15; + return JAVA15; default: break; } diff --git a/src/main/java/me/coley/cafedude/classfile/attribute/DebugExtensionAttribute.java b/src/main/java/me/coley/cafedude/classfile/attribute/SourceDebugExtensionAttribute.java similarity index 84% rename from src/main/java/me/coley/cafedude/classfile/attribute/DebugExtensionAttribute.java rename to src/main/java/me/coley/cafedude/classfile/attribute/SourceDebugExtensionAttribute.java index 2465430..6248ee2 100644 --- a/src/main/java/me/coley/cafedude/classfile/attribute/DebugExtensionAttribute.java +++ b/src/main/java/me/coley/cafedude/classfile/attribute/SourceDebugExtensionAttribute.java @@ -5,7 +5,7 @@ * * @author Matt Coley */ -public class DebugExtensionAttribute extends Attribute { +public class SourceDebugExtensionAttribute extends Attribute { private byte[] debugExtension; /** @@ -14,7 +14,7 @@ public class DebugExtensionAttribute extends Attribute { * @param debugExtension * Extension data stored in attribute. */ - public DebugExtensionAttribute(int nameIndex, byte[] debugExtension) { + public SourceDebugExtensionAttribute(int nameIndex, byte[] debugExtension) { super(nameIndex); this.debugExtension = debugExtension; } diff --git a/src/main/java/me/coley/cafedude/classfile/attribute/StackMapTableAttribute.java b/src/main/java/me/coley/cafedude/classfile/attribute/StackMapTableAttribute.java index cce83c1..cebc514 100644 --- a/src/main/java/me/coley/cafedude/classfile/attribute/StackMapTableAttribute.java +++ b/src/main/java/me/coley/cafedude/classfile/attribute/StackMapTableAttribute.java @@ -1,6 +1,6 @@ package me.coley.cafedude.classfile.attribute; -import me.coley.cafedude.Constants; +import me.coley.cafedude.classfile.StackMapTableConstants; import me.coley.cafedude.classfile.behavior.CpAccessor; import java.util.Collections; @@ -23,7 +23,7 @@ */ public class StackMapTableAttribute extends Attribute - implements Constants.StackMapTable { + implements StackMapTableConstants { /** * A list of this table's stack map frames. */ diff --git a/src/main/java/me/coley/cafedude/classfile/constant/ConstPoolEntry.java b/src/main/java/me/coley/cafedude/classfile/constant/ConstPoolEntry.java index a741a1b..fb40d49 100644 --- a/src/main/java/me/coley/cafedude/classfile/constant/ConstPoolEntry.java +++ b/src/main/java/me/coley/cafedude/classfile/constant/ConstPoolEntry.java @@ -1,13 +1,13 @@ package me.coley.cafedude.classfile.constant; -import me.coley.cafedude.Constants; +import me.coley.cafedude.classfile.ConstantPoolConstants; /** * Base constant pool entry. * * @author Matt Coley */ -public abstract class ConstPoolEntry implements Constants.ConstantPool { +public abstract class ConstPoolEntry implements ConstantPoolConstants { private final int tag; /** diff --git a/src/main/java/me/coley/cafedude/classfile/constant/ConstRef.java b/src/main/java/me/coley/cafedude/classfile/constant/ConstRef.java index 88d5ea4..a46ef9a 100644 --- a/src/main/java/me/coley/cafedude/classfile/constant/ConstRef.java +++ b/src/main/java/me/coley/cafedude/classfile/constant/ConstRef.java @@ -1,6 +1,6 @@ package me.coley.cafedude.classfile.constant; -import me.coley.cafedude.Constants; +import me.coley.cafedude.classfile.ConstantPoolConstants; /** * Base reference pool entry. Points to a reference's {@link CpClass defining class} in pool @@ -15,8 +15,8 @@ public abstract class ConstRef extends ConstPoolEntry { /** * @param type * Reference type. - * Must be {@link Constants.ConstantPool#FIELD_REF}, {@link Constants.ConstantPool#METHOD_REF}, - * or {@link Constants.ConstantPool#INTERFACE_METHOD_REF}. + * Must be {@link ConstantPoolConstants#FIELD_REF}, {@link ConstantPoolConstants#METHOD_REF}, + * or {@link ConstantPoolConstants#INTERFACE_METHOD_REF}. * @param classIndex * Index of reference {@link CpClass defining class} in pool. * @param nameTypeIndex diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/BasicInstruction.java b/src/main/java/me/coley/cafedude/classfile/instruction/BasicInstruction.java index 21ecba6..779b2c1 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/BasicInstruction.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/BasicInstruction.java @@ -6,7 +6,6 @@ * @author xDark */ public class BasicInstruction extends Instruction { - /** * @param opcode * Instruction opcode. diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/BiIntOperandInstruction.java b/src/main/java/me/coley/cafedude/classfile/instruction/BiIntOperandInstruction.java index 1dab22c..0c26a19 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/BiIntOperandInstruction.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/BiIntOperandInstruction.java @@ -6,7 +6,6 @@ * @author xDark */ public class BiIntOperandInstruction extends BasicInstruction { - private int firstOperand; private int secondOperand; diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/Instruction.java b/src/main/java/me/coley/cafedude/classfile/instruction/Instruction.java index 95851e9..84bbaad 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/Instruction.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/Instruction.java @@ -6,7 +6,6 @@ * @author xDark */ public abstract class Instruction { - private int opcode; /** diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/IntOperandInstruction.java b/src/main/java/me/coley/cafedude/classfile/instruction/IntOperandInstruction.java index 7a82ac1..21e188f 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/IntOperandInstruction.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/IntOperandInstruction.java @@ -6,7 +6,6 @@ * @author xDark */ public class IntOperandInstruction extends BasicInstruction { - private int operand; /** diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/LookupSwitchInstruction.java b/src/main/java/me/coley/cafedude/classfile/instruction/LookupSwitchInstruction.java index 96bbcb6..c0e2fed 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/LookupSwitchInstruction.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/LookupSwitchInstruction.java @@ -8,7 +8,6 @@ * @author xDark */ public class LookupSwitchInstruction extends BasicInstruction { - private int dflt; private List keys; private List offsets; @@ -21,7 +20,7 @@ public class LookupSwitchInstruction extends BasicInstruction { * @param offsets * Branch offsets. */ - public LookupSwitchInstruction(int dflt, List keys, Listoffsets) { + public LookupSwitchInstruction(int dflt, List keys, List offsets) { super(Opcodes.LOOKUPSWITCH); this.dflt = dflt; this.keys = keys; diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/Opcodes.java b/src/main/java/me/coley/cafedude/classfile/instruction/Opcodes.java index f40a3e3..3943ac1 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/Opcodes.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/Opcodes.java @@ -1,12 +1,12 @@ package me.coley.cafedude.classfile.instruction; /** - * Class containing all JVM opcodes. + * Set of all JVM opcodes. * * @author xDark + * @see ReservedOpcodes Additional reserved set of opcodes. */ public interface Opcodes { - int NOP = 0; int ACONST_NULL = 1; int ICONST_M1 = 2; diff --git a/src/main/java/me/coley/cafedude/transform/ReservedBytecodes.java b/src/main/java/me/coley/cafedude/classfile/instruction/ReservedOpcodes.java similarity index 62% rename from src/main/java/me/coley/cafedude/transform/ReservedBytecodes.java rename to src/main/java/me/coley/cafedude/classfile/instruction/ReservedOpcodes.java index 7a28c61..8853ddf 100644 --- a/src/main/java/me/coley/cafedude/transform/ReservedBytecodes.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/ReservedOpcodes.java @@ -1,12 +1,18 @@ -package me.coley.cafedude.transform; +package me.coley.cafedude.classfile.instruction; + +import me.coley.cafedude.classfile.instruction.Opcodes; /** * Set of JVM reserved opcodes. + * * * @author xDark + * @see Opcodes Base set of opcodes. */ -public interface ReservedBytecodes { - +public interface ReservedOpcodes { int breakpoint = 202; int fast_agetfield = 203; int fast_bgetfield = 204; diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/TableSwitchInstruction.java b/src/main/java/me/coley/cafedude/classfile/instruction/TableSwitchInstruction.java index 5a2f708..654ba53 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/TableSwitchInstruction.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/TableSwitchInstruction.java @@ -8,7 +8,6 @@ * @author xDark */ public class TableSwitchInstruction extends BasicInstruction { - private int dflt; private int low; private int high; diff --git a/src/main/java/me/coley/cafedude/classfile/instruction/WideInstruction.java b/src/main/java/me/coley/cafedude/classfile/instruction/WideInstruction.java index 4fe4497..0c7b334 100644 --- a/src/main/java/me/coley/cafedude/classfile/instruction/WideInstruction.java +++ b/src/main/java/me/coley/cafedude/classfile/instruction/WideInstruction.java @@ -2,9 +2,10 @@ /** * Wide instruction + * + * @author xDark */ public class WideInstruction extends BasicInstruction { - private final Instruction backing; /** diff --git a/src/main/java/me/coley/cafedude/io/AttributeContext.java b/src/main/java/me/coley/cafedude/io/AttributeContext.java index 2fddcb1..963073e 100644 --- a/src/main/java/me/coley/cafedude/io/AttributeContext.java +++ b/src/main/java/me/coley/cafedude/io/AttributeContext.java @@ -1,10 +1,10 @@ package me.coley.cafedude.io; -import me.coley.cafedude.Constants; +import me.coley.cafedude.classfile.AnnotationConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static me.coley.cafedude.Constants.Annotations.*; +import static me.coley.cafedude.classfile.AnnotationConstants.*; /** * Indicates where attribute is applied to. @@ -35,7 +35,7 @@ public static AttributeContext fromAnnotationTargetType(int targetType) { case METHOD_PARAMETER: case METHOD_THROWS: return AttributeContext.METHOD; - case Constants.Annotations.FIELD: + case AnnotationConstants.FIELD: return AttributeContext.FIELD; case LOCAL_VARIABLE_DECLARATION: case RESOURCE_VARIABLE_DECLARATION: diff --git a/src/main/java/me/coley/cafedude/io/AttributeReader.java b/src/main/java/me/coley/cafedude/io/AttributeReader.java index 478cecb..ce556cf 100644 --- a/src/main/java/me/coley/cafedude/io/AttributeReader.java +++ b/src/main/java/me/coley/cafedude/io/AttributeReader.java @@ -1,6 +1,6 @@ package me.coley.cafedude.io; -import me.coley.cafedude.Constants.Attributes; +import me.coley.cafedude.classfile.AttributeConstants; import me.coley.cafedude.classfile.ConstPool; import me.coley.cafedude.classfile.attribute.AnnotationDefaultAttribute; import me.coley.cafedude.classfile.attribute.AnnotationsAttribute; @@ -11,7 +11,7 @@ import me.coley.cafedude.classfile.attribute.CodeAttribute; import me.coley.cafedude.classfile.attribute.CodeAttribute.ExceptionTableEntry; import me.coley.cafedude.classfile.attribute.ConstantValueAttribute; -import me.coley.cafedude.classfile.attribute.DebugExtensionAttribute; +import me.coley.cafedude.classfile.attribute.SourceDebugExtensionAttribute; import me.coley.cafedude.classfile.attribute.DefaultAttribute; import me.coley.cafedude.classfile.attribute.DeprecatedAttribute; import me.coley.cafedude.classfile.attribute.EnclosingMethodAttribute; @@ -51,8 +51,8 @@ import java.util.ArrayList; import java.util.List; -import static me.coley.cafedude.Constants.Attributes.*; -import static me.coley.cafedude.Constants.StackMapTable.*; +import static me.coley.cafedude.classfile.AttributeConstants.*; +import static me.coley.cafedude.classfile.StackMapTableConstants.*; /** * Attribute reader for all attributes. @@ -181,7 +181,7 @@ private Attribute read(AttributeContext context) throws IOException { return readSignature(); case SOURCE_FILE: return readSourceFile(); - case Attributes.MODULE: + case AttributeConstants.MODULE: return readModule(); case STACK_MAP_TABLE: return readStackMapTable(); @@ -484,7 +484,7 @@ private NestMembersAttribute readNestMembers() throws IOException { * @throws IOException * When the stream is unexpectedly closed or ends. */ - private DebugExtensionAttribute readSourceDebugExtension() throws IOException { + private SourceDebugExtensionAttribute readSourceDebugExtension() throws IOException { byte[] debugExtension = new byte[expectedContentLength]; is.readFully(debugExtension); // Validate data represents UTF text @@ -494,7 +494,7 @@ private DebugExtensionAttribute readSourceDebugExtension() throws IOException { logger.debug("Invalid SourceDebugExtension, not a valid UTF"); return null; } - return new DebugExtensionAttribute(nameIndex, debugExtension); + return new SourceDebugExtensionAttribute(nameIndex, debugExtension); } /** diff --git a/src/main/java/me/coley/cafedude/io/AttributeWriter.java b/src/main/java/me/coley/cafedude/io/AttributeWriter.java index 1fe8648..099ba6b 100644 --- a/src/main/java/me/coley/cafedude/io/AttributeWriter.java +++ b/src/main/java/me/coley/cafedude/io/AttributeWriter.java @@ -1,7 +1,7 @@ package me.coley.cafedude.io; +import me.coley.cafedude.classfile.AttributeConstants; import me.coley.cafedude.classfile.ClassFile; -import me.coley.cafedude.Constants; import me.coley.cafedude.InvalidClassException; import me.coley.cafedude.classfile.attribute.AnnotationDefaultAttribute; import me.coley.cafedude.classfile.attribute.AnnotationsAttribute; @@ -10,7 +10,7 @@ import me.coley.cafedude.classfile.attribute.BootstrapMethodsAttribute.BootstrapMethod; import me.coley.cafedude.classfile.attribute.CodeAttribute; import me.coley.cafedude.classfile.attribute.ConstantValueAttribute; -import me.coley.cafedude.classfile.attribute.DebugExtensionAttribute; +import me.coley.cafedude.classfile.attribute.SourceDebugExtensionAttribute; import me.coley.cafedude.classfile.attribute.DefaultAttribute; import me.coley.cafedude.classfile.attribute.EnclosingMethodAttribute; import me.coley.cafedude.classfile.attribute.ExceptionsAttribute; @@ -96,7 +96,7 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla // so I don't think its super necessary to break these into separate methods. String attrName = ((CpUtf8) cpName).getText(); switch (attrName) { - case Constants.Attributes.BOOTSTRAP_METHODS: + case AttributeConstants.BOOTSTRAP_METHODS: BootstrapMethodsAttribute bsms = (BootstrapMethodsAttribute) attribute; out.writeShort(bsms.getBootstrapMethods().size()); for (BootstrapMethod bsm : bsms.getBootstrapMethods()) { @@ -107,9 +107,9 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla } } break; - case Constants.Attributes.CHARACTER_RANGE_TABLE: + case AttributeConstants.CHARACTER_RANGE_TABLE: break; - case Constants.Attributes.CODE: + case AttributeConstants.CODE: CodeAttribute code = (CodeAttribute) attribute; out.writeShort(code.getMaxStack()); out.writeShort(code.getMaxLocals()); @@ -126,27 +126,27 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla for (Attribute subAttribute : code.getAttributes()) out.write(writeAttribute(subAttribute)); break; - case Constants.Attributes.CONSTANT_VALUE: + case AttributeConstants.CONSTANT_VALUE: out.writeShort(((ConstantValueAttribute) attribute).getConstantValueIndex()); break; - case Constants.Attributes.COMPILATION_ID: + case AttributeConstants.COMPILATION_ID: break; - case Constants.Attributes.DEPRECATED: - case Constants.Attributes.SYNTHETIC: + case AttributeConstants.DEPRECATED: + case AttributeConstants.SYNTHETIC: break; - case Constants.Attributes.ENCLOSING_METHOD: + case AttributeConstants.ENCLOSING_METHOD: EnclosingMethodAttribute enclosingMethodAttribute = (EnclosingMethodAttribute) attribute; out.writeShort(enclosingMethodAttribute.getClassIndex()); out.writeShort(enclosingMethodAttribute.getMethodIndex()); break; - case Constants.Attributes.EXCEPTIONS: + case AttributeConstants.EXCEPTIONS: ExceptionsAttribute exceptionsAttribute = (ExceptionsAttribute) attribute; out.writeShort(exceptionsAttribute.getExceptionIndexTable().size()); for (int index : exceptionsAttribute.getExceptionIndexTable()) { out.writeShort(index); } break; - case Constants.Attributes.INNER_CLASSES: + case AttributeConstants.INNER_CLASSES: InnerClassesAttribute innerClassesAttribute = (InnerClassesAttribute) attribute; out.writeShort(innerClassesAttribute.getInnerClasses().size()); for (InnerClass ic : innerClassesAttribute.getInnerClasses()) { @@ -156,7 +156,7 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla out.writeShort(ic.getInnerClassAccessFlags()); } break; - case Constants.Attributes.LINE_NUMBER_TABLE: + case AttributeConstants.LINE_NUMBER_TABLE: LineNumberTableAttribute lineNumbers = (LineNumberTableAttribute) attribute; out.writeShort(lineNumbers.getEntries().size()); for (LineEntry entry : lineNumbers.getEntries()) { @@ -164,7 +164,7 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla out.writeShort(entry.getLine()); } break; - case Constants.Attributes.LOCAL_VARIABLE_TABLE: + case AttributeConstants.LOCAL_VARIABLE_TABLE: LocalVariableTableAttribute varTable = (LocalVariableTableAttribute) attribute; out.writeShort(varTable.getEntries().size()); for (VarEntry entry : varTable.getEntries()) { @@ -175,7 +175,7 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla out.writeShort(entry.getIndex()); } break; - case Constants.Attributes.LOCAL_VARIABLE_TYPE_TABLE: + case AttributeConstants.LOCAL_VARIABLE_TYPE_TABLE: LocalVariableTypeTableAttribute typeTable = (LocalVariableTypeTableAttribute) attribute; out.writeShort(typeTable.getEntries().size()); for (VarTypeEntry entry : typeTable.getEntries()) { @@ -186,9 +186,9 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla out.writeShort(entry.getIndex()); } break; - case Constants.Attributes.METHOD_PARAMETERS: + case AttributeConstants.METHOD_PARAMETERS: break; - case Constants.Attributes.MODULE: + case AttributeConstants.MODULE: ModuleAttribute moduleAttribute = (ModuleAttribute) attribute; out.writeShort(moduleAttribute.getModuleIndex()); out.writeShort(moduleAttribute.getFlags()); @@ -231,28 +231,28 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla out.writeShort(i); } break; - case Constants.Attributes.MODULE_HASHES: + case AttributeConstants.MODULE_HASHES: break; - case Constants.Attributes.MODULE_MAIN_CLASS: + case AttributeConstants.MODULE_MAIN_CLASS: break; - case Constants.Attributes.MODULE_PACKAGES: + case AttributeConstants.MODULE_PACKAGES: break; - case Constants.Attributes.MODULE_RESOLUTION: + case AttributeConstants.MODULE_RESOLUTION: break; - case Constants.Attributes.MODULE_TARGET: + case AttributeConstants.MODULE_TARGET: break; - case Constants.Attributes.NEST_HOST: + case AttributeConstants.NEST_HOST: NestHostAttribute nestHost = (NestHostAttribute) attribute; out.writeShort(nestHost.getHostClassIndex()); break; - case Constants.Attributes.NEST_MEMBERS: + case AttributeConstants.NEST_MEMBERS: NestMembersAttribute nestMembers = (NestMembersAttribute) attribute; out.writeShort(nestMembers.getMemberClassIndices().size()); for (int classIndex : nestMembers.getMemberClassIndices()) { out.writeShort(classIndex); } break; - case Constants.Attributes.RECORD: + case AttributeConstants.RECORD: RecordAttribute recordAttribute = (RecordAttribute) attribute; out.writeShort(recordAttribute.getComponents().size()); for (RecordComponent component : recordAttribute.getComponents()) { @@ -263,42 +263,42 @@ public byte[] writeAttribute(Attribute attribute) throws IOException, InvalidCla out.write(writeAttribute(subAttribute)); } break; - case Constants.Attributes.RUNTIME_VISIBLE_ANNOTATIONS: - case Constants.Attributes.RUNTIME_INVISIBLE_ANNOTATIONS: + case AttributeConstants.RUNTIME_VISIBLE_ANNOTATIONS: + case AttributeConstants.RUNTIME_INVISIBLE_ANNOTATIONS: new AnnotationWriter(out).writeAnnotations((AnnotationsAttribute) attribute); break; - case Constants.Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: - case Constants.Attributes.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: + case AttributeConstants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: + case AttributeConstants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: new AnnotationWriter(out).writeParameterAnnotations((ParameterAnnotationsAttribute) attribute); break; - case Constants.Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS: - case Constants.Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: + case AttributeConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS: + case AttributeConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS: new AnnotationWriter(out).writeTypeAnnotations((AnnotationsAttribute) attribute); break; - case Constants.Attributes.ANNOTATION_DEFAULT: + case AttributeConstants.ANNOTATION_DEFAULT: new AnnotationWriter(out).writeAnnotationDefault((AnnotationDefaultAttribute) attribute); break; - case Constants.Attributes.PERMITTED_SUBCLASSES: + case AttributeConstants.PERMITTED_SUBCLASSES: PermittedClassesAttribute permittedClasses = (PermittedClassesAttribute) attribute; out.writeShort(permittedClasses.getClasses().size()); for (int classIndex : permittedClasses.getClasses()) out.writeShort(classIndex); break; - case Constants.Attributes.SIGNATURE: + case AttributeConstants.SIGNATURE: SignatureAttribute signatureAttribute = (SignatureAttribute) attribute; out.writeShort(signatureAttribute.getSignatureIndex()); break; - case Constants.Attributes.SOURCE_DEBUG_EXTENSION: - DebugExtensionAttribute debugExtension = (DebugExtensionAttribute) attribute; + case AttributeConstants.SOURCE_DEBUG_EXTENSION: + SourceDebugExtensionAttribute debugExtension = (SourceDebugExtensionAttribute) attribute; out.write(debugExtension.getDebugExtension()); break; - case Constants.Attributes.SOURCE_FILE: + case AttributeConstants.SOURCE_FILE: SourceFileAttribute sourceFileAttribute = (SourceFileAttribute) attribute; out.writeShort(sourceFileAttribute.getSourceFileNameIndex()); break; - case Constants.Attributes.SOURCE_ID: + case AttributeConstants.SOURCE_ID: break; - case Constants.Attributes.STACK_MAP_TABLE: + case AttributeConstants.STACK_MAP_TABLE: StackMapTableAttribute stackMapTable = (StackMapTableAttribute) attribute; writeStackMapTable(out, stackMapTable); diff --git a/src/main/java/me/coley/cafedude/io/ClassBuilder.java b/src/main/java/me/coley/cafedude/io/ClassBuilder.java index 51ce3c9..c34e4db 100644 --- a/src/main/java/me/coley/cafedude/io/ClassBuilder.java +++ b/src/main/java/me/coley/cafedude/io/ClassBuilder.java @@ -2,15 +2,15 @@ import me.coley.cafedude.classfile.ClassFile; import me.coley.cafedude.classfile.ConstPool; -import me.coley.cafedude.Constants; import me.coley.cafedude.classfile.Field; import me.coley.cafedude.classfile.Method; +import me.coley.cafedude.classfile.Modifiers; import me.coley.cafedude.classfile.attribute.Attribute; import java.util.ArrayList; import java.util.List; -import static me.coley.cafedude.Constants.JAVA1; +import static me.coley.cafedude.classfile.VersionConstants.JAVA1; /** * Builder for a {@link ClassFile}. @@ -40,7 +40,7 @@ public boolean isOakVersion() { * @return {@code true} when the access flags indicate the class is an annotation. */ public boolean isAnnotation() { - return (access & Constants.ACC_ANNOTATION) != 0; + return Modifiers.has(access, Modifiers.ACC_ANNOTATION); } /** diff --git a/src/main/java/me/coley/cafedude/io/ClassFileReader.java b/src/main/java/me/coley/cafedude/io/ClassFileReader.java index 66df3e0..8051afa 100644 --- a/src/main/java/me/coley/cafedude/io/ClassFileReader.java +++ b/src/main/java/me/coley/cafedude/io/ClassFileReader.java @@ -1,7 +1,7 @@ package me.coley.cafedude.io; import me.coley.cafedude.classfile.ClassFile; -import me.coley.cafedude.Constants.ConstantPool; +import me.coley.cafedude.classfile.ConstantPoolConstants; import me.coley.cafedude.classfile.Field; import me.coley.cafedude.InvalidClassException; import me.coley.cafedude.classfile.Method; @@ -31,7 +31,7 @@ import java.util.ArrayList; import java.util.List; -import static me.coley.cafedude.Constants.ConstantPool.*; +import static me.coley.cafedude.classfile.ConstantPoolConstants.*; /** * Class file format parser. @@ -153,7 +153,7 @@ private ConstPoolEntry readPoolEntry() throws IOException, InvalidClassException return new CpMethodType(is.readUnsignedShort()); case INVOKE_DYNAMIC: return new CpInvokeDynamic(is.readUnsignedShort(), is.readUnsignedShort()); - case ConstantPool.MODULE: + case ConstantPoolConstants.MODULE: return new CpModule(is.readUnsignedShort()); case PACKAGE: return new CpPackage(is.readUnsignedShort()); diff --git a/src/main/java/me/coley/cafedude/io/ClassFileWriter.java b/src/main/java/me/coley/cafedude/io/ClassFileWriter.java index c5c1ba5..e31a3eb 100644 --- a/src/main/java/me/coley/cafedude/io/ClassFileWriter.java +++ b/src/main/java/me/coley/cafedude/io/ClassFileWriter.java @@ -1,7 +1,7 @@ package me.coley.cafedude.io; +import me.coley.cafedude.classfile.ConstantPoolConstants; import me.coley.cafedude.classfile.ClassFile; -import me.coley.cafedude.Constants; import me.coley.cafedude.classfile.Field; import me.coley.cafedude.InvalidClassException; import me.coley.cafedude.classfile.Method; @@ -101,56 +101,56 @@ private void writeCpEntry(ConstPoolEntry entry) throws IOException, InvalidClass int tag = entry.getTag(); out.writeByte(tag); switch (tag) { - case Constants.ConstantPool.UTF8: + case ConstantPoolConstants.UTF8: out.writeUTF(((CpUtf8) entry).getText()); break; - case Constants.ConstantPool.INTEGER: + case ConstantPoolConstants.INTEGER: out.writeInt(((CpInt) entry).getValue()); break; - case Constants.ConstantPool.FLOAT: + case ConstantPoolConstants.FLOAT: out.writeFloat(((CpFloat) entry).getValue()); break; - case Constants.ConstantPool.LONG: + case ConstantPoolConstants.LONG: out.writeLong(((CpLong) entry).getValue()); break; - case Constants.ConstantPool.DOUBLE: + case ConstantPoolConstants.DOUBLE: out.writeDouble(((CpDouble) entry).getValue()); break; - case Constants.ConstantPool.STRING: + case ConstantPoolConstants.STRING: out.writeShort(((CpString) entry).getIndex()); break; - case Constants.ConstantPool.CLASS: + case ConstantPoolConstants.CLASS: out.writeShort(((CpClass) entry).getIndex()); break; - case Constants.ConstantPool.FIELD_REF: - case Constants.ConstantPool.METHOD_REF: - case Constants.ConstantPool.INTERFACE_METHOD_REF: + case ConstantPoolConstants.FIELD_REF: + case ConstantPoolConstants.METHOD_REF: + case ConstantPoolConstants.INTERFACE_METHOD_REF: out.writeShort(((ConstRef) entry).getClassIndex()); out.writeShort(((ConstRef) entry).getNameTypeIndex()); break; - case Constants.ConstantPool.NAME_TYPE: + case ConstantPoolConstants.NAME_TYPE: out.writeShort(((CpNameType) entry).getNameIndex()); out.writeShort(((CpNameType) entry).getTypeIndex()); break; - case Constants.ConstantPool.DYNAMIC: + case ConstantPoolConstants.DYNAMIC: out.writeShort(((CpDynamic) entry).getBsmIndex()); out.writeShort(((CpDynamic) entry).getNameTypeIndex()); break; - case Constants.ConstantPool.METHOD_HANDLE: + case ConstantPoolConstants.METHOD_HANDLE: out.writeByte(((CpMethodHandle) entry).getKind()); out.writeShort(((CpMethodHandle) entry).getReferenceIndex()); break; - case Constants.ConstantPool.METHOD_TYPE: + case ConstantPoolConstants.METHOD_TYPE: out.writeShort(((CpMethodType) entry).getIndex()); break; - case Constants.ConstantPool.INVOKE_DYNAMIC: + case ConstantPoolConstants.INVOKE_DYNAMIC: out.writeShort(((CpInvokeDynamic) entry).getBsmIndex()); out.writeShort(((CpInvokeDynamic) entry).getNameTypeIndex()); break; - case Constants.ConstantPool.MODULE: + case ConstantPoolConstants.MODULE: out.writeShort(((CpModule) entry).getIndex()); break; - case Constants.ConstantPool.PACKAGE: + case ConstantPoolConstants.PACKAGE: out.writeShort(((CpPackage) entry).getIndex()); break; default: diff --git a/src/main/java/me/coley/cafedude/io/FallbackInstructionReader.java b/src/main/java/me/coley/cafedude/io/FallbackInstructionReader.java index 51a2b49..59488c4 100644 --- a/src/main/java/me/coley/cafedude/io/FallbackInstructionReader.java +++ b/src/main/java/me/coley/cafedude/io/FallbackInstructionReader.java @@ -11,7 +11,6 @@ * @author xDark */ public interface FallbackInstructionReader { - /** * @param opcode * Instruction opcode. diff --git a/src/main/java/me/coley/cafedude/io/FallbackInstructionWriter.java b/src/main/java/me/coley/cafedude/io/FallbackInstructionWriter.java index 4799290..3818aa5 100644 --- a/src/main/java/me/coley/cafedude/io/FallbackInstructionWriter.java +++ b/src/main/java/me/coley/cafedude/io/FallbackInstructionWriter.java @@ -9,7 +9,6 @@ * @author xDark */ public interface FallbackInstructionWriter { - /** * @param instruction * Instruction to write. diff --git a/src/main/java/me/coley/cafedude/io/InstructionReader.java b/src/main/java/me/coley/cafedude/io/InstructionReader.java index 97fb696..03940e3 100644 --- a/src/main/java/me/coley/cafedude/io/InstructionReader.java +++ b/src/main/java/me/coley/cafedude/io/InstructionReader.java @@ -1,7 +1,13 @@ package me.coley.cafedude.io; import me.coley.cafedude.classfile.attribute.CodeAttribute; -import me.coley.cafedude.classfile.instruction.*; +import me.coley.cafedude.classfile.instruction.BasicInstruction; +import me.coley.cafedude.classfile.instruction.BiIntOperandInstruction; +import me.coley.cafedude.classfile.instruction.Instruction; +import me.coley.cafedude.classfile.instruction.IntOperandInstruction; +import me.coley.cafedude.classfile.instruction.LookupSwitchInstruction; +import me.coley.cafedude.classfile.instruction.TableSwitchInstruction; +import me.coley.cafedude.classfile.instruction.WideInstruction; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -16,7 +22,6 @@ * @author xDark */ public class InstructionReader { - private final FallbackInstructionReader fallbackReader; /** @@ -47,7 +52,7 @@ public List read(CodeAttribute attribute) { ByteBuffer buffer = ByteBuffer.wrap(attribute.getCode()); FallbackInstructionReader fallbackReader = this.fallbackReader; while (buffer.hasRemaining()) { - int opcode = buffer.get() & 0xff; + int opcode = buffer.get() & 0xFF; switch (opcode) { case NOP: case ACONST_NULL: @@ -74,18 +79,18 @@ public List read(CodeAttribute attribute) { instructions.add(new IntOperandInstruction(opcode, buffer.getShort())); break; case LDC: - instructions.add(new IntOperandInstruction(LDC, buffer.get() & 0xff)); + instructions.add(new IntOperandInstruction(LDC, buffer.get() & 0xFF)); break; case LDC_W: case LDC2_W: - instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xffff)); + instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xFFFF)); break; case ILOAD: case LLOAD: case FLOAD: case DLOAD: case ALOAD: - instructions.add(new IntOperandInstruction(opcode, buffer.get() & 0xff)); + instructions.add(new IntOperandInstruction(opcode, buffer.get() & 0xFF)); break; case ILOAD_0: case ILOAD_1: @@ -124,7 +129,7 @@ public List read(CodeAttribute attribute) { case FSTORE: case DSTORE: case ASTORE: - instructions.add(new IntOperandInstruction(opcode, buffer.get() & 0xff)); + instructions.add(new IntOperandInstruction(opcode, buffer.get() & 0xFF)); break; case ISTORE_0: case ISTORE_1: @@ -208,7 +213,7 @@ public List read(CodeAttribute attribute) { instructions.add(new BasicInstruction(opcode)); break; case IINC: - instructions.add(new BiIntOperandInstruction(IINC, buffer.get() & 0xff, buffer.get())); + instructions.add(new BiIntOperandInstruction(IINC, buffer.get() & 0xFF, buffer.get())); break; case I2L: case I2F: @@ -259,7 +264,7 @@ public List read(CodeAttribute attribute) { instructions.add(new IntOperandInstruction(JSR, buffer.getShort())); break; case RET: - instructions.add(new IntOperandInstruction(RET, buffer.get() & 0xff)); + instructions.add(new IntOperandInstruction(RET, buffer.get() & 0xFF)); break; case TABLESWITCH: { int pos = buffer.position(); @@ -303,16 +308,16 @@ public List read(CodeAttribute attribute) { case PUTSTATIC: case GETFIELD: case PUTFIELD: - instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xffff)); + instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xFFFF)); break; case INVOKEVIRTUAL: case INVOKESPECIAL: case INVOKESTATIC: case INVOKEINTERFACE: - instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xffff)); + instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xFFFF)); break; case INVOKEDYNAMIC: { - int index = buffer.getShort() & 0xffff; + int index = buffer.getShort() & 0xFFFF; if ((buffer.get() | buffer.get()) != 0) { // TODO: should we silently ignore, or throw? throw new IllegalStateException("InvokeDynamic padding bytes are non-zero"); @@ -321,13 +326,13 @@ public List read(CodeAttribute attribute) { break; } case NEW: - instructions.add(new IntOperandInstruction(NEW, buffer.getShort() & 0xffff)); + instructions.add(new IntOperandInstruction(NEW, buffer.getShort() & 0xFFFF)); break; case NEWARRAY: - instructions.add(new IntOperandInstruction(NEWARRAY, buffer.get() & 0xff)); + instructions.add(new IntOperandInstruction(NEWARRAY, buffer.get() & 0xFF)); break; case ANEWARRAY: - instructions.add(new IntOperandInstruction(ANEWARRAY, buffer.getShort() & 0xffff)); + instructions.add(new IntOperandInstruction(ANEWARRAY, buffer.getShort() & 0xFFFF)); break; case ARRAYLENGTH: instructions.add(new BasicInstruction(ARRAYLENGTH)); @@ -337,14 +342,14 @@ public List read(CodeAttribute attribute) { break; case CHECKCAST: case INSTANCEOF: - instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xffff)); + instructions.add(new IntOperandInstruction(opcode, buffer.getShort() & 0xFFFF)); break; case MONITORENTER: case MONITOREXIT: instructions.add(new BasicInstruction(opcode)); break; case WIDE: - int type = buffer.get() & 0xff; + int type = buffer.get() & 0xFF; switch (type) { case ILOAD: case FLOAD: @@ -356,11 +361,11 @@ public List read(CodeAttribute attribute) { case DSTORE: case RET: instructions.add(new WideInstruction(new IntOperandInstruction(type, - buffer.getShort() & 0xffff))); + buffer.getShort() & 0xFFFF))); break; case IINC: instructions.add(new WideInstruction(new BiIntOperandInstruction(IINC, - buffer.getShort() & 0xffff, buffer.getShort()))); + buffer.getShort() & 0xFFFF, buffer.getShort()))); break; default: throw new IllegalStateException("Illegal wide instruction type: " + type); @@ -368,7 +373,7 @@ public List read(CodeAttribute attribute) { break; case MULTIANEWARRAY: instructions.add(new BiIntOperandInstruction(MULTIANEWARRAY, - buffer.getShort() & 0xffff, buffer.get() & 0xff)); + buffer.getShort() & 0xFFFF, buffer.get() & 0xFF)); break; case IFNULL: case IFNONNULL: diff --git a/src/main/java/me/coley/cafedude/io/InstructionWriter.java b/src/main/java/me/coley/cafedude/io/InstructionWriter.java index 3e22769..bbe0d69 100644 --- a/src/main/java/me/coley/cafedude/io/InstructionWriter.java +++ b/src/main/java/me/coley/cafedude/io/InstructionWriter.java @@ -1,6 +1,11 @@ package me.coley.cafedude.io; -import me.coley.cafedude.classfile.instruction.*; +import me.coley.cafedude.classfile.instruction.BiIntOperandInstruction; +import me.coley.cafedude.classfile.instruction.Instruction; +import me.coley.cafedude.classfile.instruction.IntOperandInstruction; +import me.coley.cafedude.classfile.instruction.LookupSwitchInstruction; +import me.coley.cafedude.classfile.instruction.TableSwitchInstruction; +import me.coley.cafedude.classfile.instruction.WideInstruction; import me.coley.cafedude.util.GrowingByteBuffer; import java.nio.ByteBuffer; @@ -16,7 +21,6 @@ * @author xDark */ public class InstructionWriter { - private final FallbackInstructionWriter fallbackWriter; /** @@ -48,7 +52,7 @@ public byte[] writeCode(List list) { FallbackInstructionWriter fallbackWriter = this.fallbackWriter; for (Instruction instruction : list) { int opcode = instruction.getOpcode(); - buffer.put(opcode & 0Xff); + buffer.put(opcode & 0xFF); switch (opcode) { case NOP: case ACONST_NULL: @@ -235,7 +239,7 @@ public byte[] writeCode(List list) { case ASTORE: case RET: case NEWARRAY: - buffer.put(((IntOperandInstruction) instruction).getOperand() & 0xff); + buffer.put(((IntOperandInstruction) instruction).getOperand() & 0xFF); break; case LDC_W: case LDC2_W: @@ -251,11 +255,11 @@ public byte[] writeCode(List list) { case ANEWARRAY: case CHECKCAST: case INSTANCEOF: - buffer.putShort(((IntOperandInstruction) instruction).getOperand() & 0xffff); + buffer.putShort(((IntOperandInstruction) instruction).getOperand() & 0xFFFF); break; case IINC: { BiIntOperandInstruction iinc = (BiIntOperandInstruction) instruction; - buffer.put(iinc.getFirstOperand() & 0xff); + buffer.put(iinc.getFirstOperand() & 0xFF); buffer.put(iinc.getSecondOperand()); break; } @@ -287,13 +291,13 @@ public byte[] writeCode(List list) { } break; case INVOKEDYNAMIC: - buffer.putShort(((IntOperandInstruction) instruction).getOperand() & 0xffff); + buffer.putShort(((IntOperandInstruction) instruction).getOperand() & 0xFFFF); buffer.putShort(0); break; case WIDE: Instruction backing = ((WideInstruction) instruction).getBacking(); int type = backing.getOpcode(); - buffer.put(type & 0xff); + buffer.put(type & 0xFF); switch (type) { case ILOAD: case FLOAD: @@ -304,11 +308,11 @@ public byte[] writeCode(List list) { case FSTORE: case DSTORE: case RET: - buffer.putShort(((IntOperandInstruction) backing).getOperand() & 0xffff); + buffer.putShort(((IntOperandInstruction) backing).getOperand() & 0xFFFF); break; case IINC: BiIntOperandInstruction iinc = (BiIntOperandInstruction) backing; - buffer.putShort(iinc.getFirstOperand() & 0xffff); + buffer.putShort(iinc.getFirstOperand() & 0xFFFF); buffer.putShort(iinc.getSecondOperand()); break; default: @@ -317,8 +321,8 @@ public byte[] writeCode(List list) { break; case MULTIANEWARRAY: BiIntOperandInstruction multiNewArray = (BiIntOperandInstruction) instruction; - buffer.putShort(multiNewArray.getFirstOperand() & 0xffff); - buffer.put(multiNewArray.getSecondOperand() & 0xff); + buffer.putShort(multiNewArray.getFirstOperand() & 0xFFFF); + buffer.put(multiNewArray.getSecondOperand() & 0xFF); break; case GOTO_W: case JSR_W: diff --git a/src/main/java/me/coley/cafedude/transform/IllegalRewritingInstructionsReader.java b/src/main/java/me/coley/cafedude/transform/IllegalRewritingInstructionsReader.java index f83ea89..8aaefe0 100644 --- a/src/main/java/me/coley/cafedude/transform/IllegalRewritingInstructionsReader.java +++ b/src/main/java/me/coley/cafedude/transform/IllegalRewritingInstructionsReader.java @@ -1,34 +1,48 @@ package me.coley.cafedude.transform; import me.coley.cafedude.classfile.ConstPool; -import me.coley.cafedude.classfile.constant.*; +import me.coley.cafedude.classfile.constant.ConstPoolEntry; +import me.coley.cafedude.classfile.constant.CpDynamic; +import me.coley.cafedude.classfile.constant.CpMethodHandle; +import me.coley.cafedude.classfile.constant.CpMethodType; +import me.coley.cafedude.classfile.constant.CpString; import me.coley.cafedude.classfile.instruction.BasicInstruction; import me.coley.cafedude.classfile.instruction.Instruction; import me.coley.cafedude.classfile.instruction.IntOperandInstruction; +import me.coley.cafedude.classfile.instruction.ReservedOpcodes; import me.coley.cafedude.io.FallbackInstructionReader; import java.nio.ByteBuffer; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static me.coley.cafedude.classfile.instruction.Opcodes.*; -import static me.coley.cafedude.transform.ReservedBytecodes.*; +import static me.coley.cafedude.classfile.instruction.ReservedOpcodes.*; /** * Illegal instruction rewriter. - * + * * @author xDark + * @see ReservedOpcodes Opcodes of reserved instructions. + * @see IllegalStrippingTransformer Example usage. */ final class IllegalRewritingInstructionsReader implements FallbackInstructionReader { - private static final Instruction NOP_INSN = new BasicInstruction(NOP); private static final Instruction ALOAD_0_INSN = new BasicInstruction(ALOAD_0); private static final Instruction RETURN_INSN = new BasicInstruction(RETURN); - + private final ConstPool cp; private Map cpMap; boolean rewritten; - IllegalRewritingInstructionsReader(ConstPool cp) { + /** + * @param cp + * Constant pool used to pull references from. + */ + public IllegalRewritingInstructionsReader(ConstPool cp) { this.cp = cp; } @@ -44,18 +58,16 @@ public List read(int opcode, ByteBuffer buffer) { return Collections.singletonList(ALOAD_0_INSN); case fast_aldc: rewritten = true; - return Collections.singletonList(new IntOperandInstruction(LDC, - rewriteIndex(buffer.get() & 0xff))); + return Collections.singletonList(new IntOperandInstruction(LDC, + rewriteIndex(buffer.get() & 0xFF))); case fast_aldc_w: rewritten = true; short idx = buffer.getShort(); - int newIndex = rewriteIndex(idx & 0xffff); - if (newIndex == -1) { - newIndex = rewriteIndex(swap(idx) & 0xffff); - } - if (newIndex == -1) { + int newIndex = rewriteIndex(idx & 0xFFFF); + if (newIndex == -1) + newIndex = rewriteIndex(swap(idx) & 0xFFFF); + if (newIndex == -1) throw new IllegalStateException("Failed to rewrite fast_aldc_w: " + idx); - } return Collections.singletonList(new IntOperandInstruction(LDC_W, newIndex)); case return_register_finalizer: rewritten = true; @@ -67,7 +79,7 @@ public List read(int opcode, ByteBuffer buffer) { throw new IllegalStateException("Don't know how to rewrite " + opcode); } } - + private int rewriteIndex(int idx) { Map cpMap = this.cpMap; if (cpMap == null) { @@ -75,7 +87,7 @@ private int rewriteIndex(int idx) { int index = 0; int cpIndex = 1; for (ConstPoolEntry item : cp) { - if (item instanceof CpString || item instanceof CpMethodHandle + if (item instanceof CpString || item instanceof CpMethodHandle || item instanceof CpMethodType || item instanceof CpDynamic) { cpMap.put(index++, cpIndex); } @@ -89,8 +101,8 @@ private int rewriteIndex(int idx) { Integer v = cpMap.get(idx); return v == null ? -1 : v; } - + private static short swap(short x) { - return (short) (((x >> 8) & 0xff) | (x << 8)); + return (short) (((x >> 8) & 0xFF) | (x << 8)); } } diff --git a/src/main/java/me/coley/cafedude/transform/IllegalStrippingTransformer.java b/src/main/java/me/coley/cafedude/transform/IllegalStrippingTransformer.java index f1e8766..a142391 100644 --- a/src/main/java/me/coley/cafedude/transform/IllegalStrippingTransformer.java +++ b/src/main/java/me/coley/cafedude/transform/IllegalStrippingTransformer.java @@ -1,12 +1,12 @@ package me.coley.cafedude.transform; -import me.coley.cafedude.Constants; -import me.coley.cafedude.Constants.Attributes; -import me.coley.cafedude.Constants.ConstantPool; +import me.coley.cafedude.classfile.AttributeConstants; import me.coley.cafedude.classfile.ClassFile; +import me.coley.cafedude.classfile.ConstantPoolConstants; import me.coley.cafedude.classfile.Descriptor; import me.coley.cafedude.classfile.Field; import me.coley.cafedude.classfile.Method; +import me.coley.cafedude.classfile.Modifiers; import me.coley.cafedude.classfile.annotation.Annotation; import me.coley.cafedude.classfile.annotation.ClassElementValue; import me.coley.cafedude.classfile.annotation.ElementValue; @@ -60,17 +60,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.Predicate; -import static me.coley.cafedude.Constants.Attributes.*; +import static me.coley.cafedude.classfile.AttributeConstants.*; /** * A transformer to remove illegal attributes and data from a class. * * @author Matt Coley */ -public class IllegalStrippingTransformer extends Transformer { +public class IllegalStrippingTransformer extends Transformer implements ConstantPoolConstants { private static final int FORCE_FAIL = -1; private static final Logger logger = LoggerFactory.getLogger(IllegalStrippingTransformer.class); @@ -88,30 +93,32 @@ public IllegalStrippingTransformer(ClassFile clazz) { public void transform() { logger.info("Transforming '{}'", clazz.getName()); // Patch illegal instructions. - // This must be done first because we are rewriting constant pool - // below. + // This must be done first because we are rewriting constant pool below. IllegalRewritingInstructionsReader fallbackReader = new IllegalRewritingInstructionsReader(pool); InstructionReader reader = new InstructionReader(fallbackReader); InstructionWriter writer = new InstructionWriter(); for (Method method : clazz.getMethods()) { - if ((method.getAccess() & Constants.ACC_ABSTRACT) > 0) { + if (Modifiers.has(method.getAccess(), Modifiers.ACC_ABSTRACT)) continue; - } - Optional attribute = method.getAttributes().stream() - .filter(x -> x instanceof CodeAttribute) + Optional codeAttribute = method.getAttributes().stream() + .filter(attribute -> attribute instanceof CodeAttribute) .findFirst(); - if (attribute.isPresent()) { - CodeAttribute code = (CodeAttribute) attribute.get(); + // Code found, check if we rewrite anything. + if (codeAttribute.isPresent()) { + // Reset flag fallbackReader.rewritten = false; + // Read the code attribute and see if we found any illegal instructions. + CodeAttribute code = (CodeAttribute) codeAttribute.get(); List instructions = reader.read(code); if (fallbackReader.rewritten) { + // Update code with rewritten instructions. code.setCode(writer.writeCode(instructions)); } } } - // Record existing CP refs + // Record existing CP refs. Set cpAccesses = clazz.cpAccesses(); - // Strip attributes that are not valid + // Strip attributes that are not valid. clazz.getAttributes().removeIf(attribute -> !isValidWrapped(clazz, attribute)); for (Field field : clazz.getFields()) field.getAttributes().removeIf(attribute -> !isValidWrapped(field, attribute)); @@ -128,8 +135,8 @@ public void transform() { continue; ConstPoolEntry cpe = pool.get(index); switch (cpe.getTag()) { - case ConstantPool.DYNAMIC: - case ConstantPool.INVOKE_DYNAMIC: + case DYNAMIC: + case INVOKE_DYNAMIC: logger.debug("Removing now unused CP entry: {}={}", index, cpe.getClass().getSimpleName()); pool.set(index, new CpInt(0)); break; @@ -178,7 +185,7 @@ private boolean isValid(AttributeHolder holder, Attribute attribute) { switch (name) { case CONSTANT_VALUE: int valueIndex = ((ConstantValueAttribute) attribute).getConstantValueIndex(); - expectedTypeMasks.put(valueIndex, i -> (i >= ConstantPool.INTEGER && i <= ConstantPool.STRING)); + expectedTypeMasks.put(valueIndex, i -> (i >= INTEGER && i <= STRING)); break; case RUNTIME_INVISIBLE_ANNOTATIONS: case RUNTIME_VISIBLE_ANNOTATIONS: @@ -218,43 +225,43 @@ private boolean isValid(AttributeHolder holder, Attribute attribute) { break; case NEST_HOST: NestHostAttribute nestHost = (NestHostAttribute) attribute; - expectedTypeMasks.put(nestHost.getHostClassIndex(), i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(nestHost.getHostClassIndex(), i -> i == CLASS); cpEntryValidators.put(nestHost.getHostClassIndex(), matchClassType()); break; case NEST_MEMBERS: NestMembersAttribute nestMembers = (NestMembersAttribute) attribute; for (int memberIndex : nestMembers.getMemberClassIndices()) { - expectedTypeMasks.put(memberIndex, i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(memberIndex, i -> i == CLASS); cpEntryValidators.put(memberIndex, matchClassType()); } break; case ENCLOSING_METHOD: EnclosingMethodAttribute enclosingMethod = (EnclosingMethodAttribute) attribute; - expectedTypeMasks.put(enclosingMethod.getClassIndex(), i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(enclosingMethod.getClassIndex(), i -> i == CLASS); cpEntryValidators.put(enclosingMethod.getClassIndex(), matchClassType()); // method_index must be zero if the current class was immediately enclosed in source code by an // instance initializer, static initializer, instance variable initializer, // or class variable initializer // Otherwise it points to the method name_type value - expectedTypeMasks.put(enclosingMethod.getMethodIndex(), i -> i == 0 || i == ConstantPool.NAME_TYPE); + expectedTypeMasks.put(enclosingMethod.getMethodIndex(), i -> i == 0 || i == NAME_TYPE); allow0Case = (enclosingMethod.getMethodIndex() == 0); break; case EXCEPTIONS: ExceptionsAttribute exceptions = (ExceptionsAttribute) attribute; for (int exceptionTypeIndex : exceptions.getExceptionIndexTable()) { - expectedTypeMasks.put(exceptionTypeIndex, i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(exceptionTypeIndex, i -> i == CLASS); cpEntryValidators.put(exceptionTypeIndex, matchClassType()); } break; case INNER_CLASSES: InnerClassesAttribute innerClasses = (InnerClassesAttribute) attribute; for (InnerClass innerClass : innerClasses.getInnerClasses()) { - expectedTypeMasks.put(innerClass.getInnerClassInfoIndex(), i -> i == 0 || i == ConstantPool.CLASS); + expectedTypeMasks.put(innerClass.getInnerClassInfoIndex(), i -> i == 0 || i == CLASS); cpEntryValidators.put(innerClass.getInnerClassInfoIndex(), matchClassType()); // 0 if the defining class is the top-level class - expectedTypeMasks.put(innerClass.getOuterClassInfoIndex(), i -> i == 0 || i == ConstantPool.CLASS); + expectedTypeMasks.put(innerClass.getOuterClassInfoIndex(), i -> i == 0 || i == CLASS); // 0 if anonymous, otherwise name index - expectedTypeMasks.put(innerClass.getInnerNameIndex(), i -> i == 0 || i == ConstantPool.UTF8); + expectedTypeMasks.put(innerClass.getInnerNameIndex(), i -> i == 0 || i == UTF8); allow0Case |= innerClass.getInnerClassInfoIndex() == 0 || innerClass.getOuterClassInfoIndex() == 0 || innerClass.getInnerNameIndex() == 0; @@ -266,7 +273,7 @@ private boolean isValid(AttributeHolder holder, Attribute attribute) { return false; // Method cannot be abstract Method method = (Method) holder; - if ((method.getAccess() & Constants.ACC_ABSTRACT) > 0) { + if ((method.getAccess() & Modifiers.ACC_ABSTRACT) > 0) { logger.debug("Illegal 'Code' attribute on abstract method {}", pool.getUtf(method.getNameIndex())); return false; } @@ -275,7 +282,7 @@ private boolean isValid(AttributeHolder holder, Attribute attribute) { code.getAttributes().removeIf(sub -> !isValid(code, sub)); // Ensure exception indices are valid for (ExceptionTableEntry entry : code.getExceptionTable()) { - expectedTypeMasks.put(entry.getCatchTypeIndex(), i -> i == 0 || i == ConstantPool.CLASS); + expectedTypeMasks.put(entry.getCatchTypeIndex(), i -> i == 0 || i == CLASS); if (entry.getCatchTypeIndex() == 0) { allow0Case = true; } else { @@ -286,60 +293,60 @@ private boolean isValid(AttributeHolder holder, Attribute attribute) { } case SIGNATURE: SignatureAttribute signatureAttribute = (SignatureAttribute) attribute; - expectedTypeMasks.put(signatureAttribute.getSignatureIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(signatureAttribute.getSignatureIndex(), i -> i == UTF8); cpEntryValidators.put(signatureAttribute.getSignatureIndex(), matchNonEmptyUtf8()); break; case SOURCE_FILE: SourceFileAttribute sourceFileAttribute = (SourceFileAttribute) attribute; - expectedTypeMasks.put(sourceFileAttribute.getSourceFileNameIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(sourceFileAttribute.getSourceFileNameIndex(), i -> i == UTF8); cpEntryValidators.put(sourceFileAttribute.getSourceFileNameIndex(), matchNonEmptyUtf8()); break; - case Attributes.MODULE: + case AttributeConstants.MODULE: ModuleAttribute moduleAttribute = (ModuleAttribute) attribute; - expectedTypeMasks.put(moduleAttribute.getModuleIndex(), i -> i == ConstantPool.MODULE); - expectedTypeMasks.put(moduleAttribute.getVersionIndex(), i -> i == 0 || i == ConstantPool.UTF8); + expectedTypeMasks.put(moduleAttribute.getModuleIndex(), i -> i == MODULE); + expectedTypeMasks.put(moduleAttribute.getVersionIndex(), i -> i == 0 || i == UTF8); if (moduleAttribute.getVersionIndex() == 0) allow0Case = true; for (Requires requires : moduleAttribute.getRequires()) { - expectedTypeMasks.put(requires.getIndex(), i -> i == ConstantPool.MODULE); - expectedTypeMasks.put(requires.getVersionIndex(), i -> i == 0 || i == ConstantPool.UTF8); + expectedTypeMasks.put(requires.getIndex(), i -> i == MODULE); + expectedTypeMasks.put(requires.getVersionIndex(), i -> i == 0 || i == UTF8); } for (Exports exports : moduleAttribute.getExports()) { - expectedTypeMasks.put(exports.getIndex(), i -> i == ConstantPool.PACKAGE); + expectedTypeMasks.put(exports.getIndex(), i -> i == PACKAGE); for (int moduleIndex : exports.getToIndices()) - expectedTypeMasks.put(moduleIndex, i -> i == ConstantPool.MODULE); + expectedTypeMasks.put(moduleIndex, i -> i == MODULE); } for (Opens opens : moduleAttribute.getOpens()) { - expectedTypeMasks.put(opens.getIndex(), i -> i == ConstantPool.PACKAGE); + expectedTypeMasks.put(opens.getIndex(), i -> i == PACKAGE); for (int moduleIndex : opens.getToIndices()) - expectedTypeMasks.put(moduleIndex, i -> i == ConstantPool.MODULE); + expectedTypeMasks.put(moduleIndex, i -> i == MODULE); } for (Provides provides : moduleAttribute.getProvides()) { - expectedTypeMasks.put(provides.getIndex(), i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(provides.getIndex(), i -> i == CLASS); for (int implIndex : provides.getWithIndices()) - expectedTypeMasks.put(implIndex, i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(implIndex, i -> i == CLASS); } for (int use : moduleAttribute.getUses()) { - expectedTypeMasks.put(use, i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(use, i -> i == CLASS); } break; case BOOTSTRAP_METHODS: BootstrapMethodsAttribute bootstrapMethodsAttribute = (BootstrapMethodsAttribute) attribute; for (BootstrapMethod bsm : bootstrapMethodsAttribute.getBootstrapMethods()) { - expectedTypeMasks.put(bsm.getBsmMethodref(), i -> i == ConstantPool.METHOD_HANDLE); + expectedTypeMasks.put(bsm.getBsmMethodref(), i -> i == METHOD_HANDLE); // Arguments must be loadable types for (int arg : bsm.getArgs()) { expectedTypeMasks.put(arg, i -> - (i >= ConstantPool.INTEGER && i <= ConstantPool.STRING) || - (i >= ConstantPool.METHOD_HANDLE && i <= ConstantPool.DYNAMIC)); + (i >= INTEGER && i <= STRING) || + (i >= METHOD_HANDLE && i <= DYNAMIC)); } } break; case LOCAL_VARIABLE_TABLE: LocalVariableTableAttribute varTable = (LocalVariableTableAttribute) attribute; for (VarEntry entry : varTable.getEntries()) { - expectedTypeMasks.put(entry.getNameIndex(), i -> i == ConstantPool.UTF8); - expectedTypeMasks.put(entry.getDescIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(entry.getNameIndex(), i -> i == UTF8); + expectedTypeMasks.put(entry.getDescIndex(), i -> i == UTF8); cpEntryValidators.put(entry.getNameIndex(), matchNonEmptyUtf8().and(matchWordUtf8())); cpEntryValidators.put(entry.getDescIndex(), matchNonEmptyUtf8()); } @@ -347,8 +354,8 @@ private boolean isValid(AttributeHolder holder, Attribute attribute) { case LOCAL_VARIABLE_TYPE_TABLE: LocalVariableTypeTableAttribute typeTable = (LocalVariableTypeTableAttribute) attribute; for (VarTypeEntry entry : typeTable.getEntries()) { - expectedTypeMasks.put(entry.getNameIndex(), i -> i == ConstantPool.UTF8); - expectedTypeMasks.put(entry.getSignatureIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(entry.getNameIndex(), i -> i == UTF8); + expectedTypeMasks.put(entry.getSignatureIndex(), i -> i == UTF8); cpEntryValidators.put(entry.getNameIndex(), matchNonEmptyUtf8().and(matchWordUtf8())); cpEntryValidators.put(entry.getSignatureIndex(), matchNonEmptyUtf8()); } @@ -356,16 +363,16 @@ private boolean isValid(AttributeHolder holder, Attribute attribute) { case PERMITTED_SUBCLASSES: PermittedClassesAttribute permittedClassesAttribute = (PermittedClassesAttribute) attribute; for (int index : permittedClassesAttribute.getClasses()) { - expectedTypeMasks.put(index, i -> i == ConstantPool.CLASS); + expectedTypeMasks.put(index, i -> i == CLASS); cpEntryValidators.put(index, matchClassType()); } break; case RECORD: RecordAttribute recordAttribute = (RecordAttribute) attribute; for (RecordComponent component : recordAttribute.getComponents()) { - expectedTypeMasks.put(component.getNameIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(component.getNameIndex(), i -> i == UTF8); cpEntryValidators.put(component.getNameIndex(), matchWordUtf8()); - expectedTypeMasks.put(component.getDescIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(component.getDescIndex(), i -> i == UTF8); cpEntryValidators.put(component.getDescIndex(), matchNonEmptyUtf8()); } break; @@ -427,11 +434,11 @@ private void addAnnotationValidation(AttributeHolder holder, Map> expectedTypeMasks, Map> cpEntryValidators, Annotation anno) { - expectedTypeMasks.put(anno.getTypeIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(anno.getTypeIndex(), i -> i == UTF8); cpEntryValidators.put(anno.getTypeIndex(), matchUtf8ClassType()); for (Map.Entry entry : anno.getValues().entrySet()) { int elementTypeIndex = entry.getKey(); - expectedTypeMasks.put(elementTypeIndex, i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(elementTypeIndex, i -> i == UTF8); cpEntryValidators.put(elementTypeIndex, matchUtf8ClassType()); addElementValueValidation(holder, expectedTypeMasks, cpEntryValidators, entry.getValue()); } @@ -454,7 +461,7 @@ private void addAnnotationValidation(AttributeHolder holder, // TODO: Verify with a sample what the target holder type should be break; case OFFSET_TARGET: - // TODO: relies on instructions being parsed + // TODO: Compare to code instructions / length break; case SUPERTYPE_TARGET: if (holder instanceof ClassFile) { @@ -499,19 +506,19 @@ private void addElementValueValidation(AttributeHolder holder, ElementValue elementValue) { if (elementValue instanceof ClassElementValue) { int classIndex = ((ClassElementValue) elementValue).getClassIndex(); - expectedTypeMasks.put(classIndex, i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(classIndex, i -> i == UTF8); cpEntryValidators.put(classIndex, matchUtf8ClassType()); } else if (elementValue instanceof EnumElementValue) { EnumElementValue enumElementValue = (EnumElementValue) elementValue; - expectedTypeMasks.put(enumElementValue.getNameIndex(), i -> i == ConstantPool.UTF8); - expectedTypeMasks.put(enumElementValue.getTypeIndex(), i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(enumElementValue.getNameIndex(), i -> i == UTF8); + expectedTypeMasks.put(enumElementValue.getTypeIndex(), i -> i == UTF8); cpEntryValidators.put(enumElementValue.getTypeIndex(), matchUtf8ClassType()); } else if (elementValue instanceof Utf8ElementValue) { int utfIndex = ((Utf8ElementValue) elementValue).getUtfIndex(); - expectedTypeMasks.put(utfIndex, i -> i == ConstantPool.UTF8); + expectedTypeMasks.put(utfIndex, i -> i == UTF8); } else if (elementValue instanceof PrimitiveElementValue) { int primValueIndex = ((PrimitiveElementValue) elementValue).getValueIndex(); - expectedTypeMasks.put(primValueIndex, i -> (i >= ConstantPool.INTEGER && i <= ConstantPool.DOUBLE)); + expectedTypeMasks.put(primValueIndex, i -> (i >= INTEGER && i <= DOUBLE)); } } diff --git a/src/main/java/me/coley/cafedude/util/GrowingByteBuffer.java b/src/main/java/me/coley/cafedude/util/GrowingByteBuffer.java index 0ec6699..e37c028 100644 --- a/src/main/java/me/coley/cafedude/util/GrowingByteBuffer.java +++ b/src/main/java/me/coley/cafedude/util/GrowingByteBuffer.java @@ -8,7 +8,6 @@ * @author xDark */ public class GrowingByteBuffer { - private ByteBuffer buffer = ByteBuffer.allocate(1024); /**