From 4f00ab70b1a4e993d6e4fb6e15fb2803290ff932 Mon Sep 17 00:00:00 2001 From: Shevchik Date: Sun, 15 Dec 2013 15:26:10 +0400 Subject: [PATCH] Clean up apache BCEL lib, no more stupid warnings --- src/org/apache/bcel/Constants.java | 1449 ++++----- src/org/apache/bcel/ExceptionConstants.java | 112 +- src/org/apache/bcel/Repository.java | 416 +-- .../apache/bcel/classfile/AccessFlags.java | 388 ++- src/org/apache/bcel/classfile/Attribute.java | 473 +-- .../bcel/classfile/AttributeReader.java | 62 +- .../bcel/classfile/ClassFormatException.java | 27 +- .../apache/bcel/classfile/ClassParser.java | 513 ++-- src/org/apache/bcel/classfile/Code.java | 619 ++-- .../apache/bcel/classfile/CodeException.java | 340 ++- src/org/apache/bcel/classfile/Constant.java | 289 +- src/org/apache/bcel/classfile/ConstantCP.java | 188 +- .../apache/bcel/classfile/ConstantClass.java | 184 +- .../apache/bcel/classfile/ConstantDouble.java | 169 +- .../bcel/classfile/ConstantFieldref.java | 82 +- .../apache/bcel/classfile/ConstantFloat.java | 171 +- .../bcel/classfile/ConstantInteger.java | 169 +- .../classfile/ConstantInterfaceMethodref.java | 86 +- .../apache/bcel/classfile/ConstantLong.java | 169 +- .../bcel/classfile/ConstantMethodref.java | 82 +- .../bcel/classfile/ConstantNameAndType.java | 220 +- .../apache/bcel/classfile/ConstantObject.java | 19 +- .../apache/bcel/classfile/ConstantPool.java | 627 ++-- .../apache/bcel/classfile/ConstantString.java | 183 +- .../apache/bcel/classfile/ConstantUtf8.java | 165 +- .../apache/bcel/classfile/ConstantValue.java | 247 +- src/org/apache/bcel/classfile/Deprecated.java | 214 +- .../bcel/classfile/DescendingVisitor.java | 660 ++-- .../apache/bcel/classfile/EmptyVisitor.java | 204 +- .../apache/bcel/classfile/ExceptionTable.java | 293 +- src/org/apache/bcel/classfile/Field.java | 299 +- .../apache/bcel/classfile/FieldOrMethod.java | 328 +- src/org/apache/bcel/classfile/InnerClass.java | 337 +-- .../apache/bcel/classfile/InnerClasses.java | 234 +- src/org/apache/bcel/classfile/JavaClass.java | 1658 +++++----- src/org/apache/bcel/classfile/LineNumber.java | 203 +- .../bcel/classfile/LineNumberTable.java | 349 ++- .../apache/bcel/classfile/LocalVariable.java | 400 +-- .../bcel/classfile/LocalVariableTable.java | 321 +- src/org/apache/bcel/classfile/Method.java | 416 +-- src/org/apache/bcel/classfile/Node.java | 6 +- src/org/apache/bcel/classfile/PMGClass.java | 258 +- src/org/apache/bcel/classfile/Signature.java | 446 +-- src/org/apache/bcel/classfile/SourceFile.java | 222 +- src/org/apache/bcel/classfile/StackMap.java | 237 +- .../apache/bcel/classfile/StackMapEntry.java | 321 +- .../apache/bcel/classfile/StackMapType.java | 237 +- src/org/apache/bcel/classfile/Synthetic.java | 231 +- src/org/apache/bcel/classfile/Unknown.java | 295 +- src/org/apache/bcel/classfile/Utility.java | 2687 +++++++++-------- src/org/apache/bcel/classfile/Visitor.java | 113 +- src/org/apache/bcel/generic/AALOAD.java | 58 +- src/org/apache/bcel/generic/AASTORE.java | 60 +- src/org/apache/bcel/generic/ACONST_NULL.java | 73 +- src/org/apache/bcel/generic/ALOAD.java | 73 +- src/org/apache/bcel/generic/ANEWARRAY.java | 110 +- src/org/apache/bcel/generic/ARETURN.java | 61 +- src/org/apache/bcel/generic/ARRAYLENGTH.java | 74 +- src/org/apache/bcel/generic/ASTORE.java | 73 +- src/org/apache/bcel/generic/ATHROW.java | 75 +- .../bcel/generic/AllocationInstruction.java | 4 +- .../bcel/generic/ArithmeticInstruction.java | 136 +- .../apache/bcel/generic/ArrayInstruction.java | 112 +- src/org/apache/bcel/generic/ArrayType.java | 193 +- src/org/apache/bcel/generic/BALOAD.java | 58 +- src/org/apache/bcel/generic/BASTORE.java | 60 +- src/org/apache/bcel/generic/BIPUSH.java | 146 +- src/org/apache/bcel/generic/BREAKPOINT.java | 38 +- src/org/apache/bcel/generic/BasicType.java | 110 +- src/org/apache/bcel/generic/BranchHandle.java | 165 +- .../bcel/generic/BranchInstruction.java | 395 +-- src/org/apache/bcel/generic/CALOAD.java | 58 +- src/org/apache/bcel/generic/CASTORE.java | 60 +- src/org/apache/bcel/generic/CHECKCAST.java | 122 +- .../apache/bcel/generic/CPInstruction.java | 208 +- src/org/apache/bcel/generic/ClassGen.java | 1019 ++++--- .../bcel/generic/ClassGenException.java | 26 +- .../apache/bcel/generic/ClassObserver.java | 6 +- .../apache/bcel/generic/CodeExceptionGen.java | 294 +- .../bcel/generic/CompoundInstruction.java | 23 +- .../apache/bcel/generic/ConstantPoolGen.java | 1482 ++++----- .../bcel/generic/ConstantPushInstruction.java | 18 +- .../bcel/generic/ConversionInstruction.java | 100 +- src/org/apache/bcel/generic/D2F.java | 58 +- src/org/apache/bcel/generic/D2I.java | 58 +- src/org/apache/bcel/generic/D2L.java | 58 +- src/org/apache/bcel/generic/DADD.java | 61 +- src/org/apache/bcel/generic/DALOAD.java | 58 +- src/org/apache/bcel/generic/DASTORE.java | 60 +- src/org/apache/bcel/generic/DCMPG.java | 70 +- src/org/apache/bcel/generic/DCMPL.java | 70 +- src/org/apache/bcel/generic/DCONST.java | 112 +- src/org/apache/bcel/generic/DDIV.java | 63 +- src/org/apache/bcel/generic/DLOAD.java | 73 +- src/org/apache/bcel/generic/DMUL.java | 61 +- src/org/apache/bcel/generic/DNEG.java | 53 +- src/org/apache/bcel/generic/DREM.java | 61 +- src/org/apache/bcel/generic/DRETURN.java | 60 +- src/org/apache/bcel/generic/DSTORE.java | 73 +- src/org/apache/bcel/generic/DSUB.java | 61 +- src/org/apache/bcel/generic/DUP.java | 51 +- src/org/apache/bcel/generic/DUP2.java | 51 +- src/org/apache/bcel/generic/DUP2_X1.java | 47 +- src/org/apache/bcel/generic/DUP2_X2.java | 47 +- src/org/apache/bcel/generic/DUP_X1.java | 47 +- src/org/apache/bcel/generic/DUP_X2.java | 47 +- src/org/apache/bcel/generic/EmptyVisitor.java | 1083 +++---- .../apache/bcel/generic/ExceptionThrower.java | 30 +- src/org/apache/bcel/generic/F2D.java | 58 +- src/org/apache/bcel/generic/F2I.java | 58 +- src/org/apache/bcel/generic/F2L.java | 58 +- src/org/apache/bcel/generic/FADD.java | 58 +- src/org/apache/bcel/generic/FALOAD.java | 58 +- src/org/apache/bcel/generic/FASTORE.java | 60 +- src/org/apache/bcel/generic/FCMPG.java | 67 +- src/org/apache/bcel/generic/FCMPL.java | 67 +- src/org/apache/bcel/generic/FCONST.java | 116 +- src/org/apache/bcel/generic/FDIV.java | 56 +- src/org/apache/bcel/generic/FLOAD.java | 73 +- src/org/apache/bcel/generic/FMUL.java | 56 +- src/org/apache/bcel/generic/FNEG.java | 53 +- src/org/apache/bcel/generic/FREM.java | 56 +- src/org/apache/bcel/generic/FRETURN.java | 60 +- src/org/apache/bcel/generic/FSTORE.java | 73 +- src/org/apache/bcel/generic/FSUB.java | 56 +- src/org/apache/bcel/generic/FieldGen.java | 579 ++-- .../bcel/generic/FieldGenOrMethodGen.java | 177 +- .../apache/bcel/generic/FieldInstruction.java | 103 +- .../apache/bcel/generic/FieldObserver.java | 10 +- .../apache/bcel/generic/FieldOrMethod.java | 192 +- src/org/apache/bcel/generic/GETFIELD.java | 111 +- src/org/apache/bcel/generic/GETSTATIC.java | 108 +- src/org/apache/bcel/generic/GOTO.java | 123 +- src/org/apache/bcel/generic/GOTO_W.java | 100 +- .../apache/bcel/generic/GotoInstruction.java | 31 +- src/org/apache/bcel/generic/I2B.java | 58 +- src/org/apache/bcel/generic/I2C.java | 58 +- src/org/apache/bcel/generic/I2D.java | 56 +- src/org/apache/bcel/generic/I2F.java | 58 +- src/org/apache/bcel/generic/I2L.java | 56 +- src/org/apache/bcel/generic/I2S.java | 51 +- src/org/apache/bcel/generic/IADD.java | 58 +- src/org/apache/bcel/generic/IALOAD.java | 59 +- src/org/apache/bcel/generic/IAND.java | 53 +- src/org/apache/bcel/generic/IASTORE.java | 61 +- src/org/apache/bcel/generic/ICONST.java | 111 +- src/org/apache/bcel/generic/IDIV.java | 73 +- src/org/apache/bcel/generic/IFEQ.java | 79 +- src/org/apache/bcel/generic/IFGE.java | 79 +- src/org/apache/bcel/generic/IFGT.java | 79 +- src/org/apache/bcel/generic/IFLE.java | 79 +- src/org/apache/bcel/generic/IFLT.java | 79 +- src/org/apache/bcel/generic/IFNE.java | 79 +- src/org/apache/bcel/generic/IFNONNULL.java | 79 +- src/org/apache/bcel/generic/IFNULL.java | 79 +- src/org/apache/bcel/generic/IF_ACMPEQ.java | 79 +- src/org/apache/bcel/generic/IF_ACMPNE.java | 79 +- src/org/apache/bcel/generic/IF_ICMPEQ.java | 79 +- src/org/apache/bcel/generic/IF_ICMPGE.java | 79 +- src/org/apache/bcel/generic/IF_ICMPGT.java | 79 +- src/org/apache/bcel/generic/IF_ICMPLE.java | 79 +- src/org/apache/bcel/generic/IF_ICMPLT.java | 79 +- src/org/apache/bcel/generic/IF_ICMPNE.java | 79 +- src/org/apache/bcel/generic/IINC.java | 243 +- src/org/apache/bcel/generic/ILOAD.java | 73 +- src/org/apache/bcel/generic/IMPDEP1.java | 38 +- src/org/apache/bcel/generic/IMPDEP2.java | 38 +- src/org/apache/bcel/generic/IMUL.java | 58 +- src/org/apache/bcel/generic/INEG.java | 53 +- src/org/apache/bcel/generic/INSTANCEOF.java | 98 +- .../apache/bcel/generic/INVOKEINTERFACE.java | 196 +- .../apache/bcel/generic/INVOKESPECIAL.java | 102 +- src/org/apache/bcel/generic/INVOKESTATIC.java | 94 +- .../apache/bcel/generic/INVOKEVIRTUAL.java | 98 +- src/org/apache/bcel/generic/IOR.java | 53 +- src/org/apache/bcel/generic/IREM.java | 73 +- src/org/apache/bcel/generic/IRETURN.java | 60 +- src/org/apache/bcel/generic/ISHL.java | 51 +- src/org/apache/bcel/generic/ISHR.java | 51 +- src/org/apache/bcel/generic/ISTORE.java | 73 +- src/org/apache/bcel/generic/ISUB.java | 58 +- src/org/apache/bcel/generic/IUSHR.java | 53 +- src/org/apache/bcel/generic/IXOR.java | 53 +- .../apache/bcel/generic/IfInstruction.java | 48 +- .../bcel/generic/IndexedInstruction.java | 13 +- src/org/apache/bcel/generic/Instruction.java | 487 +-- .../bcel/generic/InstructionComparator.java | 83 +- .../bcel/generic/InstructionConstants.java | 518 ++-- .../bcel/generic/InstructionFactory.java | 1339 ++++---- .../bcel/generic/InstructionHandle.java | 462 +-- .../apache/bcel/generic/InstructionList.java | 2519 +++++++-------- .../bcel/generic/InstructionListObserver.java | 13 +- .../bcel/generic/InstructionTargeter.java | 13 +- .../bcel/generic/InvokeInstruction.java | 168 +- src/org/apache/bcel/generic/JSR.java | 116 +- src/org/apache/bcel/generic/JSR_W.java | 100 +- .../apache/bcel/generic/JsrInstruction.java | 108 +- src/org/apache/bcel/generic/L2D.java | 53 +- src/org/apache/bcel/generic/L2F.java | 51 +- src/org/apache/bcel/generic/L2I.java | 51 +- src/org/apache/bcel/generic/LADD.java | 56 +- src/org/apache/bcel/generic/LALOAD.java | 58 +- src/org/apache/bcel/generic/LAND.java | 56 +- src/org/apache/bcel/generic/LASTORE.java | 60 +- src/org/apache/bcel/generic/LCMP.java | 68 +- src/org/apache/bcel/generic/LCONST.java | 112 +- src/org/apache/bcel/generic/LDC.java | 236 +- src/org/apache/bcel/generic/LDC2_W.java | 119 +- src/org/apache/bcel/generic/LDC_W.java | 55 +- src/org/apache/bcel/generic/LDIV.java | 66 +- src/org/apache/bcel/generic/LLOAD.java | 64 +- src/org/apache/bcel/generic/LMUL.java | 56 +- src/org/apache/bcel/generic/LNEG.java | 53 +- src/org/apache/bcel/generic/LOOKUPSWITCH.java | 134 +- src/org/apache/bcel/generic/LOR.java | 53 +- src/org/apache/bcel/generic/LREM.java | 63 +- src/org/apache/bcel/generic/LRETURN.java | 55 +- src/org/apache/bcel/generic/LSHL.java | 53 +- src/org/apache/bcel/generic/LSHR.java | 53 +- src/org/apache/bcel/generic/LSTORE.java | 64 +- src/org/apache/bcel/generic/LSUB.java | 56 +- src/org/apache/bcel/generic/LUSHR.java | 53 +- src/org/apache/bcel/generic/LXOR.java | 53 +- .../apache/bcel/generic/LineNumberGen.java | 154 +- src/org/apache/bcel/generic/LoadClass.java | 47 +- .../apache/bcel/generic/LoadInstruction.java | 81 +- .../apache/bcel/generic/LocalVariableGen.java | 337 ++- .../generic/LocalVariableInstruction.java | 336 ++- src/org/apache/bcel/generic/MONITORENTER.java | 62 +- src/org/apache/bcel/generic/MONITOREXIT.java | 62 +- .../apache/bcel/generic/MULTIANEWARRAY.java | 224 +- src/org/apache/bcel/generic/MethodGen.java | 2102 ++++++------- .../apache/bcel/generic/MethodObserver.java | 10 +- src/org/apache/bcel/generic/NEW.java | 102 +- src/org/apache/bcel/generic/NEWARRAY.java | 170 +- src/org/apache/bcel/generic/NOP.java | 38 +- .../apache/bcel/generic/NamedAndTyped.java | 15 +- src/org/apache/bcel/generic/ObjectType.java | 245 +- src/org/apache/bcel/generic/POP.java | 50 +- src/org/apache/bcel/generic/POP2.java | 50 +- src/org/apache/bcel/generic/PUSH.java | 290 +- src/org/apache/bcel/generic/PUTFIELD.java | 110 +- src/org/apache/bcel/generic/PUTSTATIC.java | 108 +- .../apache/bcel/generic/PopInstruction.java | 4 +- .../apache/bcel/generic/PushInstruction.java | 10 +- src/org/apache/bcel/generic/RET.java | 213 +- src/org/apache/bcel/generic/RETURN.java | 55 +- .../apache/bcel/generic/ReferenceType.java | 645 ++-- .../bcel/generic/ReturnInstruction.java | 97 +- .../bcel/generic/ReturnaddressType.java | 102 +- src/org/apache/bcel/generic/SALOAD.java | 53 +- src/org/apache/bcel/generic/SASTORE.java | 51 +- src/org/apache/bcel/generic/SIPUSH.java | 139 +- src/org/apache/bcel/generic/SWAP.java | 54 +- src/org/apache/bcel/generic/SWITCH.java | 240 +- src/org/apache/bcel/generic/Select.java | 400 +-- .../apache/bcel/generic/StackConsumer.java | 11 +- .../apache/bcel/generic/StackInstruction.java | 45 +- .../apache/bcel/generic/StackProducer.java | 15 +- .../apache/bcel/generic/StoreInstruction.java | 83 +- src/org/apache/bcel/generic/TABLESWITCH.java | 161 +- .../bcel/generic/TargetLostException.java | 49 +- src/org/apache/bcel/generic/Type.java | 552 ++-- .../apache/bcel/generic/TypedInstruction.java | 10 +- .../bcel/generic/UnconditionalBranch.java | 6 +- .../generic/VariableLengthInstruction.java | 13 +- src/org/apache/bcel/generic/Visitor.java | 550 ++-- src/org/apache/bcel/util/BCELComparator.java | 31 +- src/org/apache/bcel/util/BCELFactory.java | 492 +-- src/org/apache/bcel/util/BCELifier.java | 440 +-- src/org/apache/bcel/util/ByteSequence.java | 63 +- src/org/apache/bcel/util/ClassPath.java | 638 ++-- src/org/apache/bcel/util/ClassQueue.java | 40 +- src/org/apache/bcel/util/Repository.java | 72 +- .../apache/bcel/util/SyntheticRepository.java | 294 +- 275 files changed, 26436 insertions(+), 24293 deletions(-) diff --git a/src/org/apache/bcel/Constants.java b/src/org/apache/bcel/Constants.java index 04e06ba..39d0917 100644 --- a/src/org/apache/bcel/Constants.java +++ b/src/org/apache/bcel/Constants.java @@ -18,749 +18,780 @@ package org.apache.bcel; /** * Constants for the project, mostly defined in the JVM specification. - * + * * @version $Id: Constants.java 410087 2006-05-29 12:12:19Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface Constants { - /** Major and minor version of the code. - */ - public final static short MAJOR_1_1 = 45; - public final static short MINOR_1_1 = 3; - public final static short MAJOR_1_2 = 46; - public final static short MINOR_1_2 = 0; - public final static short MAJOR_1_3 = 47; - public final static short MINOR_1_3 = 0; - public final static short MAJOR_1_4 = 48; - public final static short MINOR_1_4 = 0; - public final static short MAJOR_1_5 = 49; - public final static short MINOR_1_5 = 0; - public final static short MAJOR = MAJOR_1_1; // Defaults - public final static short MINOR = MINOR_1_1; + /** + * Major and minor version of the code. + */ + public final static short MAJOR_1_1 = 45; + public final static short MINOR_1_1 = 3; + public final static short MAJOR_1_2 = 46; + public final static short MINOR_1_2 = 0; + public final static short MAJOR_1_3 = 47; + public final static short MINOR_1_3 = 0; + public final static short MAJOR_1_4 = 48; + public final static short MINOR_1_4 = 0; + public final static short MAJOR_1_5 = 49; + public final static short MINOR_1_5 = 0; + public final static short MAJOR = MAJOR_1_1; // Defaults + public final static short MINOR = MINOR_1_1; - /** Maximum value for an unsigned short. - */ - public final static int MAX_SHORT = 65535; // 2^16 - 1 + /** + * Maximum value for an unsigned short. + */ + public final static int MAX_SHORT = 65535; // 2^16 - 1 - /** Maximum value for an unsigned byte. - */ - public final static int MAX_BYTE = 255; // 2^8 - 1 + /** + * Maximum value for an unsigned byte. + */ + public final static int MAX_BYTE = 255; // 2^8 - 1 - /** Access flags for classes, fields and methods. - */ - public final static short ACC_PUBLIC = 0x0001; - public final static short ACC_PRIVATE = 0x0002; - public final static short ACC_PROTECTED = 0x0004; - public final static short ACC_STATIC = 0x0008; + /** + * Access flags for classes, fields and methods. + */ + public final static short ACC_PUBLIC = 0x0001; + public final static short ACC_PRIVATE = 0x0002; + public final static short ACC_PROTECTED = 0x0004; + public final static short ACC_STATIC = 0x0008; - public final static short ACC_FINAL = 0x0010; - public final static short ACC_SYNCHRONIZED = 0x0020; - public final static short ACC_VOLATILE = 0x0040; - public final static short ACC_BRIDGE = 0x0040; - public final static short ACC_TRANSIENT = 0x0080; - public final static short ACC_VARARGS = 0x0080; + public final static short ACC_FINAL = 0x0010; + public final static short ACC_SYNCHRONIZED = 0x0020; + public final static short ACC_VOLATILE = 0x0040; + public final static short ACC_BRIDGE = 0x0040; + public final static short ACC_TRANSIENT = 0x0080; + public final static short ACC_VARARGS = 0x0080; - public final static short ACC_NATIVE = 0x0100; - public final static short ACC_INTERFACE = 0x0200; - public final static short ACC_ABSTRACT = 0x0400; - public final static short ACC_STRICT = 0x0800; - - public final static short ACC_SYNTHETIC = 0x1000; - public final static short ACC_ANNOTATION = 0x2000; - public final static short ACC_ENUM = 0x4000; + public final static short ACC_NATIVE = 0x0100; + public final static short ACC_INTERFACE = 0x0200; + public final static short ACC_ABSTRACT = 0x0400; + public final static short ACC_STRICT = 0x0800; - // Applies to classes compiled by new compilers only - public final static short ACC_SUPER = 0x0020; + public final static short ACC_SYNTHETIC = 0x1000; + public final static short ACC_ANNOTATION = 0x2000; + public final static short ACC_ENUM = 0x4000; - public final static short MAX_ACC_FLAG = ACC_ENUM; + // Applies to classes compiled by new compilers only + public final static short ACC_SUPER = 0x0020; - public final static String[] ACCESS_NAMES = { - "public", "private", "protected", "static", "final", "synchronized", - "volatile", "transient", "native", "interface", "abstract", "strictfp", - "synthetic", "annotation", "enum" - }; + public final static short MAX_ACC_FLAG = ACC_ENUM; - /** Tags in constant pool to denote type of constant. - */ - public final static byte CONSTANT_Utf8 = 1; - public final static byte CONSTANT_Integer = 3; - public final static byte CONSTANT_Float = 4; - public final static byte CONSTANT_Long = 5; - public final static byte CONSTANT_Double = 6; - public final static byte CONSTANT_Class = 7; - public final static byte CONSTANT_Fieldref = 9; - public final static byte CONSTANT_String = 8; - public final static byte CONSTANT_Methodref = 10; - public final static byte CONSTANT_InterfaceMethodref = 11; - public final static byte CONSTANT_NameAndType = 12; + public final static String[] ACCESS_NAMES = { "public", "private", + "protected", "static", "final", "synchronized", "volatile", + "transient", "native", "interface", "abstract", "strictfp", + "synthetic", "annotation", "enum" }; - public final static String[] CONSTANT_NAMES = { - "", "CONSTANT_Utf8", "", "CONSTANT_Integer", - "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double", - "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", - "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref", - "CONSTANT_NameAndType" }; + /** + * Tags in constant pool to denote type of constant. + */ + public final static byte CONSTANT_Utf8 = 1; + public final static byte CONSTANT_Integer = 3; + public final static byte CONSTANT_Float = 4; + public final static byte CONSTANT_Long = 5; + public final static byte CONSTANT_Double = 6; + public final static byte CONSTANT_Class = 7; + public final static byte CONSTANT_Fieldref = 9; + public final static byte CONSTANT_String = 8; + public final static byte CONSTANT_Methodref = 10; + public final static byte CONSTANT_InterfaceMethodref = 11; + public final static byte CONSTANT_NameAndType = 12; - /** The name of the static initializer, also called "class - * initialization method" or "interface initialization - * method". This is "<clinit>". - */ - public final static String STATIC_INITIALIZER_NAME = ""; + public final static String[] CONSTANT_NAMES = { "", "CONSTANT_Utf8", "", + "CONSTANT_Integer", "CONSTANT_Float", "CONSTANT_Long", + "CONSTANT_Double", "CONSTANT_Class", "CONSTANT_String", + "CONSTANT_Fieldref", "CONSTANT_Methodref", + "CONSTANT_InterfaceMethodref", "CONSTANT_NameAndType" }; - /** The name of every constructor method in a class, also called - * "instance initialization method". This is "<init>". - */ - public final static String CONSTRUCTOR_NAME = ""; + /** + * The name of the static initializer, also called "class + * initialization method" or "interface initialization + * method". This is "<clinit>". + */ + public final static String STATIC_INITIALIZER_NAME = ""; - /** The names of the interfaces implemented by arrays */ - public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"}; + /** + * The name of every constructor method in a class, also called + * "instance initialization method". This is + * "<init>". + */ + public final static String CONSTRUCTOR_NAME = ""; - /** - * Limitations of the Java Virtual Machine. - * See The Java Virtual Machine Specification, Second Edition, page 152, chapter 4.10. - */ - public static final int MAX_CP_ENTRIES = 65535; - public static final int MAX_CODE_SIZE = 65536; //bytes + /** The names of the interfaces implemented by arrays */ + public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = { + "java.lang.Cloneable", "java.io.Serializable" }; - /** Java VM opcodes. - */ - public static final short NOP = 0; - public static final short ACONST_NULL = 1; - public static final short ICONST_M1 = 2; - public static final short ICONST_0 = 3; - public static final short ICONST_1 = 4; - public static final short ICONST_2 = 5; - public static final short ICONST_3 = 6; - public static final short ICONST_4 = 7; - public static final short ICONST_5 = 8; - public static final short LCONST_0 = 9; - public static final short LCONST_1 = 10; - public static final short FCONST_0 = 11; - public static final short FCONST_1 = 12; - public static final short FCONST_2 = 13; - public static final short DCONST_0 = 14; - public static final short DCONST_1 = 15; - public static final short BIPUSH = 16; - public static final short SIPUSH = 17; - public static final short LDC = 18; - public static final short LDC_W = 19; - public static final short LDC2_W = 20; - public static final short ILOAD = 21; - public static final short LLOAD = 22; - public static final short FLOAD = 23; - public static final short DLOAD = 24; - public static final short ALOAD = 25; - public static final short ILOAD_0 = 26; - public static final short ILOAD_1 = 27; - public static final short ILOAD_2 = 28; - public static final short ILOAD_3 = 29; - public static final short LLOAD_0 = 30; - public static final short LLOAD_1 = 31; - public static final short LLOAD_2 = 32; - public static final short LLOAD_3 = 33; - public static final short FLOAD_0 = 34; - public static final short FLOAD_1 = 35; - public static final short FLOAD_2 = 36; - public static final short FLOAD_3 = 37; - public static final short DLOAD_0 = 38; - public static final short DLOAD_1 = 39; - public static final short DLOAD_2 = 40; - public static final short DLOAD_3 = 41; - public static final short ALOAD_0 = 42; - public static final short ALOAD_1 = 43; - public static final short ALOAD_2 = 44; - public static final short ALOAD_3 = 45; - public static final short IALOAD = 46; - public static final short LALOAD = 47; - public static final short FALOAD = 48; - public static final short DALOAD = 49; - public static final short AALOAD = 50; - public static final short BALOAD = 51; - public static final short CALOAD = 52; - public static final short SALOAD = 53; - public static final short ISTORE = 54; - public static final short LSTORE = 55; - public static final short FSTORE = 56; - public static final short DSTORE = 57; - public static final short ASTORE = 58; - public static final short ISTORE_0 = 59; - public static final short ISTORE_1 = 60; - public static final short ISTORE_2 = 61; - public static final short ISTORE_3 = 62; - public static final short LSTORE_0 = 63; - public static final short LSTORE_1 = 64; - public static final short LSTORE_2 = 65; - public static final short LSTORE_3 = 66; - public static final short FSTORE_0 = 67; - public static final short FSTORE_1 = 68; - public static final short FSTORE_2 = 69; - public static final short FSTORE_3 = 70; - public static final short DSTORE_0 = 71; - public static final short DSTORE_1 = 72; - public static final short DSTORE_2 = 73; - public static final short DSTORE_3 = 74; - public static final short ASTORE_0 = 75; - public static final short ASTORE_1 = 76; - public static final short ASTORE_2 = 77; - public static final short ASTORE_3 = 78; - public static final short IASTORE = 79; - public static final short LASTORE = 80; - public static final short FASTORE = 81; - public static final short DASTORE = 82; - public static final short AASTORE = 83; - public static final short BASTORE = 84; - public static final short CASTORE = 85; - public static final short SASTORE = 86; - public static final short POP = 87; - public static final short POP2 = 88; - public static final short DUP = 89; - public static final short DUP_X1 = 90; - public static final short DUP_X2 = 91; - public static final short DUP2 = 92; - public static final short DUP2_X1 = 93; - public static final short DUP2_X2 = 94; - public static final short SWAP = 95; - public static final short IADD = 96; - public static final short LADD = 97; - public static final short FADD = 98; - public static final short DADD = 99; - public static final short ISUB = 100; - public static final short LSUB = 101; - public static final short FSUB = 102; - public static final short DSUB = 103; - public static final short IMUL = 104; - public static final short LMUL = 105; - public static final short FMUL = 106; - public static final short DMUL = 107; - public static final short IDIV = 108; - public static final short LDIV = 109; - public static final short FDIV = 110; - public static final short DDIV = 111; - public static final short IREM = 112; - public static final short LREM = 113; - public static final short FREM = 114; - public static final short DREM = 115; - public static final short INEG = 116; - public static final short LNEG = 117; - public static final short FNEG = 118; - public static final short DNEG = 119; - public static final short ISHL = 120; - public static final short LSHL = 121; - public static final short ISHR = 122; - public static final short LSHR = 123; - public static final short IUSHR = 124; - public static final short LUSHR = 125; - public static final short IAND = 126; - public static final short LAND = 127; - public static final short IOR = 128; - public static final short LOR = 129; - public static final short IXOR = 130; - public static final short LXOR = 131; - public static final short IINC = 132; - public static final short I2L = 133; - public static final short I2F = 134; - public static final short I2D = 135; - public static final short L2I = 136; - public static final short L2F = 137; - public static final short L2D = 138; - public static final short F2I = 139; - public static final short F2L = 140; - public static final short F2D = 141; - public static final short D2I = 142; - public static final short D2L = 143; - public static final short D2F = 144; - public static final short I2B = 145; - public static final short INT2BYTE = 145; // Old notion - public static final short I2C = 146; - public static final short INT2CHAR = 146; // Old notion - public static final short I2S = 147; - public static final short INT2SHORT = 147; // Old notion - public static final short LCMP = 148; - public static final short FCMPL = 149; - public static final short FCMPG = 150; - public static final short DCMPL = 151; - public static final short DCMPG = 152; - public static final short IFEQ = 153; - public static final short IFNE = 154; - public static final short IFLT = 155; - public static final short IFGE = 156; - public static final short IFGT = 157; - public static final short IFLE = 158; - public static final short IF_ICMPEQ = 159; - public static final short IF_ICMPNE = 160; - public static final short IF_ICMPLT = 161; - public static final short IF_ICMPGE = 162; - public static final short IF_ICMPGT = 163; - public static final short IF_ICMPLE = 164; - public static final short IF_ACMPEQ = 165; - public static final short IF_ACMPNE = 166; - public static final short GOTO = 167; - public static final short JSR = 168; - public static final short RET = 169; - public static final short TABLESWITCH = 170; - public static final short LOOKUPSWITCH = 171; - public static final short IRETURN = 172; - public static final short LRETURN = 173; - public static final short FRETURN = 174; - public static final short DRETURN = 175; - public static final short ARETURN = 176; - public static final short RETURN = 177; - public static final short GETSTATIC = 178; - public static final short PUTSTATIC = 179; - public static final short GETFIELD = 180; - public static final short PUTFIELD = 181; - public static final short INVOKEVIRTUAL = 182; - public static final short INVOKESPECIAL = 183; - public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 - public static final short INVOKESTATIC = 184; - public static final short INVOKEINTERFACE = 185; - public static final short NEW = 187; - public static final short NEWARRAY = 188; - public static final short ANEWARRAY = 189; - public static final short ARRAYLENGTH = 190; - public static final short ATHROW = 191; - public static final short CHECKCAST = 192; - public static final short INSTANCEOF = 193; - public static final short MONITORENTER = 194; - public static final short MONITOREXIT = 195; - public static final short WIDE = 196; - public static final short MULTIANEWARRAY = 197; - public static final short IFNULL = 198; - public static final short IFNONNULL = 199; - public static final short GOTO_W = 200; - public static final short JSR_W = 201; + /** + * Limitations of the Java Virtual Machine. See The Java Virtual Machine + * Specification, Second Edition, page 152, chapter 4.10. + */ + public static final int MAX_CP_ENTRIES = 65535; + public static final int MAX_CODE_SIZE = 65536; // bytes - /** - * Non-legal opcodes, may be used by JVM internally. - */ - public static final short BREAKPOINT = 202; - public static final short LDC_QUICK = 203; - public static final short LDC_W_QUICK = 204; - public static final short LDC2_W_QUICK = 205; - public static final short GETFIELD_QUICK = 206; - public static final short PUTFIELD_QUICK = 207; - public static final short GETFIELD2_QUICK = 208; - public static final short PUTFIELD2_QUICK = 209; - public static final short GETSTATIC_QUICK = 210; - public static final short PUTSTATIC_QUICK = 211; - public static final short GETSTATIC2_QUICK = 212; - public static final short PUTSTATIC2_QUICK = 213; - public static final short INVOKEVIRTUAL_QUICK = 214; - public static final short INVOKENONVIRTUAL_QUICK = 215; - public static final short INVOKESUPER_QUICK = 216; - public static final short INVOKESTATIC_QUICK = 217; - public static final short INVOKEINTERFACE_QUICK = 218; - public static final short INVOKEVIRTUALOBJECT_QUICK = 219; - public static final short NEW_QUICK = 221; - public static final short ANEWARRAY_QUICK = 222; - public static final short MULTIANEWARRAY_QUICK = 223; - public static final short CHECKCAST_QUICK = 224; - public static final short INSTANCEOF_QUICK = 225; - public static final short INVOKEVIRTUAL_QUICK_W = 226; - public static final short GETFIELD_QUICK_W = 227; - public static final short PUTFIELD_QUICK_W = 228; - public static final short IMPDEP1 = 254; - public static final short IMPDEP2 = 255; + /** + * Java VM opcodes. + */ + public static final short NOP = 0; + public static final short ACONST_NULL = 1; + public static final short ICONST_M1 = 2; + public static final short ICONST_0 = 3; + public static final short ICONST_1 = 4; + public static final short ICONST_2 = 5; + public static final short ICONST_3 = 6; + public static final short ICONST_4 = 7; + public static final short ICONST_5 = 8; + public static final short LCONST_0 = 9; + public static final short LCONST_1 = 10; + public static final short FCONST_0 = 11; + public static final short FCONST_1 = 12; + public static final short FCONST_2 = 13; + public static final short DCONST_0 = 14; + public static final short DCONST_1 = 15; + public static final short BIPUSH = 16; + public static final short SIPUSH = 17; + public static final short LDC = 18; + public static final short LDC_W = 19; + public static final short LDC2_W = 20; + public static final short ILOAD = 21; + public static final short LLOAD = 22; + public static final short FLOAD = 23; + public static final short DLOAD = 24; + public static final short ALOAD = 25; + public static final short ILOAD_0 = 26; + public static final short ILOAD_1 = 27; + public static final short ILOAD_2 = 28; + public static final short ILOAD_3 = 29; + public static final short LLOAD_0 = 30; + public static final short LLOAD_1 = 31; + public static final short LLOAD_2 = 32; + public static final short LLOAD_3 = 33; + public static final short FLOAD_0 = 34; + public static final short FLOAD_1 = 35; + public static final short FLOAD_2 = 36; + public static final short FLOAD_3 = 37; + public static final short DLOAD_0 = 38; + public static final short DLOAD_1 = 39; + public static final short DLOAD_2 = 40; + public static final short DLOAD_3 = 41; + public static final short ALOAD_0 = 42; + public static final short ALOAD_1 = 43; + public static final short ALOAD_2 = 44; + public static final short ALOAD_3 = 45; + public static final short IALOAD = 46; + public static final short LALOAD = 47; + public static final short FALOAD = 48; + public static final short DALOAD = 49; + public static final short AALOAD = 50; + public static final short BALOAD = 51; + public static final short CALOAD = 52; + public static final short SALOAD = 53; + public static final short ISTORE = 54; + public static final short LSTORE = 55; + public static final short FSTORE = 56; + public static final short DSTORE = 57; + public static final short ASTORE = 58; + public static final short ISTORE_0 = 59; + public static final short ISTORE_1 = 60; + public static final short ISTORE_2 = 61; + public static final short ISTORE_3 = 62; + public static final short LSTORE_0 = 63; + public static final short LSTORE_1 = 64; + public static final short LSTORE_2 = 65; + public static final short LSTORE_3 = 66; + public static final short FSTORE_0 = 67; + public static final short FSTORE_1 = 68; + public static final short FSTORE_2 = 69; + public static final short FSTORE_3 = 70; + public static final short DSTORE_0 = 71; + public static final short DSTORE_1 = 72; + public static final short DSTORE_2 = 73; + public static final short DSTORE_3 = 74; + public static final short ASTORE_0 = 75; + public static final short ASTORE_1 = 76; + public static final short ASTORE_2 = 77; + public static final short ASTORE_3 = 78; + public static final short IASTORE = 79; + public static final short LASTORE = 80; + public static final short FASTORE = 81; + public static final short DASTORE = 82; + public static final short AASTORE = 83; + public static final short BASTORE = 84; + public static final short CASTORE = 85; + public static final short SASTORE = 86; + public static final short POP = 87; + public static final short POP2 = 88; + public static final short DUP = 89; + public static final short DUP_X1 = 90; + public static final short DUP_X2 = 91; + public static final short DUP2 = 92; + public static final short DUP2_X1 = 93; + public static final short DUP2_X2 = 94; + public static final short SWAP = 95; + public static final short IADD = 96; + public static final short LADD = 97; + public static final short FADD = 98; + public static final short DADD = 99; + public static final short ISUB = 100; + public static final short LSUB = 101; + public static final short FSUB = 102; + public static final short DSUB = 103; + public static final short IMUL = 104; + public static final short LMUL = 105; + public static final short FMUL = 106; + public static final short DMUL = 107; + public static final short IDIV = 108; + public static final short LDIV = 109; + public static final short FDIV = 110; + public static final short DDIV = 111; + public static final short IREM = 112; + public static final short LREM = 113; + public static final short FREM = 114; + public static final short DREM = 115; + public static final short INEG = 116; + public static final short LNEG = 117; + public static final short FNEG = 118; + public static final short DNEG = 119; + public static final short ISHL = 120; + public static final short LSHL = 121; + public static final short ISHR = 122; + public static final short LSHR = 123; + public static final short IUSHR = 124; + public static final short LUSHR = 125; + public static final short IAND = 126; + public static final short LAND = 127; + public static final short IOR = 128; + public static final short LOR = 129; + public static final short IXOR = 130; + public static final short LXOR = 131; + public static final short IINC = 132; + public static final short I2L = 133; + public static final short I2F = 134; + public static final short I2D = 135; + public static final short L2I = 136; + public static final short L2F = 137; + public static final short L2D = 138; + public static final short F2I = 139; + public static final short F2L = 140; + public static final short F2D = 141; + public static final short D2I = 142; + public static final short D2L = 143; + public static final short D2F = 144; + public static final short I2B = 145; + public static final short INT2BYTE = 145; // Old notion + public static final short I2C = 146; + public static final short INT2CHAR = 146; // Old notion + public static final short I2S = 147; + public static final short INT2SHORT = 147; // Old notion + public static final short LCMP = 148; + public static final short FCMPL = 149; + public static final short FCMPG = 150; + public static final short DCMPL = 151; + public static final short DCMPG = 152; + public static final short IFEQ = 153; + public static final short IFNE = 154; + public static final short IFLT = 155; + public static final short IFGE = 156; + public static final short IFGT = 157; + public static final short IFLE = 158; + public static final short IF_ICMPEQ = 159; + public static final short IF_ICMPNE = 160; + public static final short IF_ICMPLT = 161; + public static final short IF_ICMPGE = 162; + public static final short IF_ICMPGT = 163; + public static final short IF_ICMPLE = 164; + public static final short IF_ACMPEQ = 165; + public static final short IF_ACMPNE = 166; + public static final short GOTO = 167; + public static final short JSR = 168; + public static final short RET = 169; + public static final short TABLESWITCH = 170; + public static final short LOOKUPSWITCH = 171; + public static final short IRETURN = 172; + public static final short LRETURN = 173; + public static final short FRETURN = 174; + public static final short DRETURN = 175; + public static final short ARETURN = 176; + public static final short RETURN = 177; + public static final short GETSTATIC = 178; + public static final short PUTSTATIC = 179; + public static final short GETFIELD = 180; + public static final short PUTFIELD = 181; + public static final short INVOKEVIRTUAL = 182; + public static final short INVOKESPECIAL = 183; + public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 + public static final short INVOKESTATIC = 184; + public static final short INVOKEINTERFACE = 185; + public static final short NEW = 187; + public static final short NEWARRAY = 188; + public static final short ANEWARRAY = 189; + public static final short ARRAYLENGTH = 190; + public static final short ATHROW = 191; + public static final short CHECKCAST = 192; + public static final short INSTANCEOF = 193; + public static final short MONITORENTER = 194; + public static final short MONITOREXIT = 195; + public static final short WIDE = 196; + public static final short MULTIANEWARRAY = 197; + public static final short IFNULL = 198; + public static final short IFNONNULL = 199; + public static final short GOTO_W = 200; + public static final short JSR_W = 201; - /** - * For internal purposes only. - */ - public static final short PUSH = 4711; - public static final short SWITCH = 4712; + /** + * Non-legal opcodes, may be used by JVM internally. + */ + public static final short BREAKPOINT = 202; + public static final short LDC_QUICK = 203; + public static final short LDC_W_QUICK = 204; + public static final short LDC2_W_QUICK = 205; + public static final short GETFIELD_QUICK = 206; + public static final short PUTFIELD_QUICK = 207; + public static final short GETFIELD2_QUICK = 208; + public static final short PUTFIELD2_QUICK = 209; + public static final short GETSTATIC_QUICK = 210; + public static final short PUTSTATIC_QUICK = 211; + public static final short GETSTATIC2_QUICK = 212; + public static final short PUTSTATIC2_QUICK = 213; + public static final short INVOKEVIRTUAL_QUICK = 214; + public static final short INVOKENONVIRTUAL_QUICK = 215; + public static final short INVOKESUPER_QUICK = 216; + public static final short INVOKESTATIC_QUICK = 217; + public static final short INVOKEINTERFACE_QUICK = 218; + public static final short INVOKEVIRTUALOBJECT_QUICK = 219; + public static final short NEW_QUICK = 221; + public static final short ANEWARRAY_QUICK = 222; + public static final short MULTIANEWARRAY_QUICK = 223; + public static final short CHECKCAST_QUICK = 224; + public static final short INSTANCEOF_QUICK = 225; + public static final short INVOKEVIRTUAL_QUICK_W = 226; + public static final short GETFIELD_QUICK_W = 227; + public static final short PUTFIELD_QUICK_W = 228; + public static final short IMPDEP1 = 254; + public static final short IMPDEP2 = 255; - /** - * Illegal codes - */ - public static final short UNDEFINED = -1; - public static final short UNPREDICTABLE = -2; - public static final short RESERVED = -3; - public static final String ILLEGAL_OPCODE = ""; - public static final String ILLEGAL_TYPE = ""; + /** + * For internal purposes only. + */ + public static final short PUSH = 4711; + public static final short SWITCH = 4712; - public static final byte T_BOOLEAN = 4; - public static final byte T_CHAR = 5; - public static final byte T_FLOAT = 6; - public static final byte T_DOUBLE = 7; - public static final byte T_BYTE = 8; - public static final byte T_SHORT = 9; - public static final byte T_INT = 10; - public static final byte T_LONG = 11; + /** + * Illegal codes + */ + public static final short UNDEFINED = -1; + public static final short UNPREDICTABLE = -2; + public static final short RESERVED = -3; + public static final String ILLEGAL_OPCODE = ""; + public static final String ILLEGAL_TYPE = ""; - public static final byte T_VOID = 12; // Non-standard - public static final byte T_ARRAY = 13; - public static final byte T_OBJECT = 14; - public static final byte T_REFERENCE = 14; // Deprecated - public static final byte T_UNKNOWN = 15; - public static final byte T_ADDRESS = 16; + public static final byte T_BOOLEAN = 4; + public static final byte T_CHAR = 5; + public static final byte T_FLOAT = 6; + public static final byte T_DOUBLE = 7; + public static final byte T_BYTE = 8; + public static final byte T_SHORT = 9; + public static final byte T_INT = 10; + public static final byte T_LONG = 11; - /** The primitive type names corresponding to the T_XX constants, - * e.g., TYPE_NAMES[T_INT] = "int" - */ - public static final String[] TYPE_NAMES = { - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, - "boolean", "char", "float", "double", "byte", "short", "int", "long", - "void", "array", "object", "unknown" // Non-standard - }; + public static final byte T_VOID = 12; // Non-standard + public static final byte T_ARRAY = 13; + public static final byte T_OBJECT = 14; + public static final byte T_REFERENCE = 14; // Deprecated + public static final byte T_UNKNOWN = 15; + public static final byte T_ADDRESS = 16; - /** The primitive class names corresponding to the T_XX constants, - * e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" - */ - public static final String[] CLASS_TYPE_NAMES = { - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, - "java.lang.Boolean", "java.lang.Character", "java.lang.Float", - "java.lang.Double", "java.lang.Byte", "java.lang.Short", - "java.lang.Integer", "java.lang.Long", "java.lang.Void", - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE - }; + /** + * The primitive type names corresponding to the T_XX constants, e.g., + * TYPE_NAMES[T_INT] = "int" + */ + public static final String[] TYPE_NAMES = { ILLEGAL_TYPE, ILLEGAL_TYPE, + ILLEGAL_TYPE, ILLEGAL_TYPE, "boolean", "char", "float", "double", + "byte", "short", "int", "long", "void", "array", "object", + "unknown" // Non-standard + }; - /** The signature characters corresponding to primitive types, - * e.g., SHORT_TYPE_NAMES[T_INT] = "I" - */ - public static final String[] SHORT_TYPE_NAMES = { - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, - "Z", "C", "F", "D", "B", "S", "I", "J", - "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE - }; + /** + * The primitive class names corresponding to the T_XX constants, e.g., + * CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" + */ + public static final String[] CLASS_TYPE_NAMES = { ILLEGAL_TYPE, + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "java.lang.Boolean", + "java.lang.Character", "java.lang.Float", "java.lang.Double", + "java.lang.Byte", "java.lang.Short", "java.lang.Integer", + "java.lang.Long", "java.lang.Void", ILLEGAL_TYPE, ILLEGAL_TYPE, + ILLEGAL_TYPE }; - /** - * Number of byte code operands, i.e., number of bytes after the tag byte - * itself. - */ - public static final short[] NO_OF_OPERANDS = { - 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, - 0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, - 0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/, - 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/, - 1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/, - 1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/, - 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/, - 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, - 0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, - 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/, - 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, - 0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/, - 0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/, - 1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/, - 1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/, - 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/, - 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, - 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, - 0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, - 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/, - 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, - 0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/, - 0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/, - 0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/, - 0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/, - 0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/, - 0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/, - 0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/, - 0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/, - 0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/, - 2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/, - 0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/, - 0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/, - 0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/, - 2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/, - 2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/, - 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/, - 2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/, - 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, - 0/*dreturn*/, 0/*areturn*/, 0/*return*/, - 2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/, - 2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/, - 4/*invokeinterface*/, UNDEFINED, 2/*new*/, - 1/*newarray*/, 2/*anewarray*/, - 0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/, - 2/*instanceof*/, 0/*monitorenter*/, - 0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/, - 2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/, - 4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/ - }; + /** + * The signature characters corresponding to primitive types, e.g., + * SHORT_TYPE_NAMES[T_INT] = "I" + */ + public static final String[] SHORT_TYPE_NAMES = { ILLEGAL_TYPE, + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "Z", "C", "F", "D", "B", + "S", "I", "J", "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE }; - /** - * How the byte code operands are to be interpreted. - */ - public static final short[][] TYPE_OF_OPERANDS = { - {}/*nop*/, {}/*aconst_null*/, {}/*iconst_m1*/, {}/*iconst_0*/, - {}/*iconst_1*/, {}/*iconst_2*/, {}/*iconst_3*/, {}/*iconst_4*/, - {}/*iconst_5*/, {}/*lconst_0*/, {}/*lconst_1*/, {}/*fconst_0*/, - {}/*fconst_1*/, {}/*fconst_2*/, {}/*dconst_0*/, {}/*dconst_1*/, - {T_BYTE}/*bipush*/, {T_SHORT}/*sipush*/, {T_BYTE}/*ldc*/, - {T_SHORT}/*ldc_w*/, {T_SHORT}/*ldc2_w*/, - {T_BYTE}/*iload*/, {T_BYTE}/*lload*/, {T_BYTE}/*fload*/, - {T_BYTE}/*dload*/, {T_BYTE}/*aload*/, {}/*iload_0*/, - {}/*iload_1*/, {}/*iload_2*/, {}/*iload_3*/, {}/*lload_0*/, - {}/*lload_1*/, {}/*lload_2*/, {}/*lload_3*/, {}/*fload_0*/, - {}/*fload_1*/, {}/*fload_2*/, {}/*fload_3*/, {}/*dload_0*/, - {}/*dload_1*/, {}/*dload_2*/, {}/*dload_3*/, {}/*aload_0*/, - {}/*aload_1*/, {}/*aload_2*/, {}/*aload_3*/, {}/*iaload*/, - {}/*laload*/, {}/*faload*/, {}/*daload*/, {}/*aaload*/, - {}/*baload*/, {}/*caload*/, {}/*saload*/, {T_BYTE}/*istore*/, - {T_BYTE}/*lstore*/, {T_BYTE}/*fstore*/, {T_BYTE}/*dstore*/, - {T_BYTE}/*astore*/, {}/*istore_0*/, {}/*istore_1*/, - {}/*istore_2*/, {}/*istore_3*/, {}/*lstore_0*/, {}/*lstore_1*/, - {}/*lstore_2*/, {}/*lstore_3*/, {}/*fstore_0*/, {}/*fstore_1*/, - {}/*fstore_2*/, {}/*fstore_3*/, {}/*dstore_0*/, {}/*dstore_1*/, - {}/*dstore_2*/, {}/*dstore_3*/, {}/*astore_0*/, {}/*astore_1*/, - {}/*astore_2*/, {}/*astore_3*/, {}/*iastore*/, {}/*lastore*/, - {}/*fastore*/, {}/*dastore*/, {}/*aastore*/, {}/*bastore*/, - {}/*castore*/, {}/*sastore*/, {}/*pop*/, {}/*pop2*/, {}/*dup*/, - {}/*dup_x1*/, {}/*dup_x2*/, {}/*dup2*/, {}/*dup2_x1*/, - {}/*dup2_x2*/, {}/*swap*/, {}/*iadd*/, {}/*ladd*/, {}/*fadd*/, - {}/*dadd*/, {}/*isub*/, {}/*lsub*/, {}/*fsub*/, {}/*dsub*/, - {}/*imul*/, {}/*lmul*/, {}/*fmul*/, {}/*dmul*/, {}/*idiv*/, - {}/*ldiv*/, {}/*fdiv*/, {}/*ddiv*/, {}/*irem*/, {}/*lrem*/, - {}/*frem*/, {}/*drem*/, {}/*ineg*/, {}/*lneg*/, {}/*fneg*/, - {}/*dneg*/, {}/*ishl*/, {}/*lshl*/, {}/*ishr*/, {}/*lshr*/, - {}/*iushr*/, {}/*lushr*/, {}/*iand*/, {}/*land*/, {}/*ior*/, - {}/*lor*/, {}/*ixor*/, {}/*lxor*/, {T_BYTE, T_BYTE}/*iinc*/, - {}/*i2l*/, {}/*i2f*/, {}/*i2d*/, {}/*l2i*/, {}/*l2f*/, {}/*l2d*/, - {}/*f2i*/, {}/*f2l*/, {}/*f2d*/, {}/*d2i*/, {}/*d2l*/, {}/*d2f*/, - {}/*i2b*/, {}/*i2c*/,{}/*i2s*/, {}/*lcmp*/, {}/*fcmpl*/, - {}/*fcmpg*/, {}/*dcmpl*/, {}/*dcmpg*/, {T_SHORT}/*ifeq*/, - {T_SHORT}/*ifne*/, {T_SHORT}/*iflt*/, {T_SHORT}/*ifge*/, - {T_SHORT}/*ifgt*/, {T_SHORT}/*ifle*/, {T_SHORT}/*if_icmpeq*/, - {T_SHORT}/*if_icmpne*/, {T_SHORT}/*if_icmplt*/, - {T_SHORT}/*if_icmpge*/, {T_SHORT}/*if_icmpgt*/, - {T_SHORT}/*if_icmple*/, {T_SHORT}/*if_acmpeq*/, - {T_SHORT}/*if_acmpne*/, {T_SHORT}/*goto*/, {T_SHORT}/*jsr*/, - {T_BYTE}/*ret*/, {}/*tableswitch*/, {}/*lookupswitch*/, - {}/*ireturn*/, {}/*lreturn*/, {}/*freturn*/, {}/*dreturn*/, - {}/*areturn*/, {}/*return*/, {T_SHORT}/*getstatic*/, - {T_SHORT}/*putstatic*/, {T_SHORT}/*getfield*/, - {T_SHORT}/*putfield*/, {T_SHORT}/*invokevirtual*/, - {T_SHORT}/*invokespecial*/, {T_SHORT}/*invokestatic*/, - {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {}, - {T_SHORT}/*new*/, {T_BYTE}/*newarray*/, - {T_SHORT}/*anewarray*/, {}/*arraylength*/, {}/*athrow*/, - {T_SHORT}/*checkcast*/, {T_SHORT}/*instanceof*/, - {}/*monitorenter*/, {}/*monitorexit*/, {T_BYTE}/*wide*/, - {T_SHORT, T_BYTE}/*multianewarray*/, {T_SHORT}/*ifnull*/, - {T_SHORT}/*ifnonnull*/, {T_INT}/*goto_w*/, {T_INT}/*jsr_w*/, - {}/*breakpoint*/, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}/*impdep1*/, {}/*impdep2*/ - }; + /** + * Number of byte code operands, i.e., number of bytes after the tag byte + * itself. + */ + public static final short[] NO_OF_OPERANDS = { 0/* nop */, + 0/* aconst_null */, 0/* iconst_m1 */, 0/* iconst_0 */, 0/* iconst_1 */, + 0/* iconst_2 */, 0/* iconst_3 */, 0/* iconst_4 */, 0/* iconst_5 */, + 0/* lconst_0 */, 0/* lconst_1 */, 0/* fconst_0 */, 0/* fconst_1 */, + 0/* fconst_2 */, 0/* dconst_0 */, 0/* dconst_1 */, 1/* bipush */, + 2/* sipush */, 1/* ldc */, 2/* ldc_w */, 2/* ldc2_w */, + 1/* iload */, 1/* lload */, 1/* fload */, 1/* dload */, 1/* aload */, + 0/* iload_0 */, 0/* iload_1 */, 0/* iload_2 */, 0/* iload_3 */, + 0/* lload_0 */, 0/* lload_1 */, 0/* lload_2 */, 0/* lload_3 */, + 0/* fload_0 */, 0/* fload_1 */, 0/* fload_2 */, 0/* fload_3 */, + 0/* dload_0 */, 0/* dload_1 */, 0/* dload_2 */, 0/* dload_3 */, + 0/* aload_0 */, 0/* aload_1 */, 0/* aload_2 */, 0/* aload_3 */, + 0/* iaload */, 0/* laload */, 0/* faload */, 0/* daload */, + 0/* aaload */, 0/* baload */, 0/* caload */, 0/* saload */, + 1/* istore */, 1/* lstore */, 1/* fstore */, 1/* dstore */, + 1/* astore */, 0/* istore_0 */, 0/* istore_1 */, 0/* istore_2 */, + 0/* istore_3 */, 0/* lstore_0 */, 0/* lstore_1 */, 0/* lstore_2 */, + 0/* lstore_3 */, 0/* fstore_0 */, 0/* fstore_1 */, 0/* fstore_2 */, + 0/* fstore_3 */, 0/* dstore_0 */, 0/* dstore_1 */, 0/* dstore_2 */, + 0/* dstore_3 */, 0/* astore_0 */, 0/* astore_1 */, 0/* astore_2 */, + 0/* astore_3 */, 0/* iastore */, 0/* lastore */, 0/* fastore */, + 0/* dastore */, 0/* aastore */, 0/* bastore */, 0/* castore */, + 0/* sastore */, 0/* pop */, 0/* pop2 */, 0/* dup */, 0/* dup_x1 */, + 0/* dup_x2 */, 0/* dup2 */, 0/* dup2_x1 */, 0/* dup2_x2 */, + 0/* swap */, 0/* iadd */, 0/* ladd */, 0/* fadd */, 0/* dadd */, + 0/* isub */, 0/* lsub */, 0/* fsub */, 0/* dsub */, 0/* imul */, + 0/* lmul */, 0/* fmul */, 0/* dmul */, 0/* idiv */, 0/* ldiv */, + 0/* fdiv */, 0/* ddiv */, 0/* irem */, 0/* lrem */, 0/* frem */, + 0/* drem */, 0/* ineg */, 0/* lneg */, 0/* fneg */, 0/* dneg */, + 0/* ishl */, 0/* lshl */, 0/* ishr */, 0/* lshr */, 0/* iushr */, + 0/* lushr */, 0/* iand */, 0/* land */, 0/* ior */, 0/* lor */, + 0/* ixor */, 0/* lxor */, 2/* iinc */, 0/* i2l */, 0/* i2f */, + 0/* i2d */, 0/* l2i */, 0/* l2f */, 0/* l2d */, 0/* f2i */, + 0/* f2l */, 0/* f2d */, 0/* d2i */, 0/* d2l */, 0/* d2f */, + 0/* i2b */, 0/* i2c */, 0/* i2s */, 0/* lcmp */, 0/* fcmpl */, + 0/* fcmpg */, 0/* dcmpl */, 0/* dcmpg */, 2/* ifeq */, 2/* ifne */, + 2/* iflt */, 2/* ifge */, 2/* ifgt */, 2/* ifle */, 2/* if_icmpeq */, + 2/* if_icmpne */, 2/* if_icmplt */, 2/* if_icmpge */, 2/* if_icmpgt */, + 2/* if_icmple */, 2/* if_acmpeq */, 2/* if_acmpne */, 2/* goto */, + 2/* jsr */, 1/* ret */, UNPREDICTABLE/* tableswitch */, + UNPREDICTABLE/* lookupswitch */, 0/* ireturn */, 0/* lreturn */, + 0/* freturn */, 0/* dreturn */, 0/* areturn */, 0/* return */, + 2/* getstatic */, 2/* putstatic */, 2/* getfield */, 2/* putfield */, + 2/* invokevirtual */, 2/* invokespecial */, 2/* invokestatic */, + 4/* invokeinterface */, UNDEFINED, 2/* new */, 1/* newarray */, + 2/* anewarray */, 0/* arraylength */, 0/* athrow */, + 2/* checkcast */, 2/* instanceof */, 0/* monitorenter */, + 0/* monitorexit */, UNPREDICTABLE/* wide */, 3/* multianewarray */, + 2/* ifnull */, 2/* ifnonnull */, 4/* goto_w */, 4/* jsr_w */, + 0/* breakpoint */, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + RESERVED/* impdep1 */, RESERVED /* impdep2 */ + }; - /** - * Names of opcodes. - */ - public static final String[] OPCODE_NAMES = { - "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1", - "iconst_2", "iconst_3", "iconst_4", "iconst_5", "lconst_0", - "lconst_1", "fconst_0", "fconst_1", "fconst_2", "dconst_0", - "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload", - "lload", "fload", "dload", "aload", "iload_0", "iload_1", "iload_2", - "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", - "fload_1", "fload_2", "fload_3", "dload_0", "dload_1", "dload_2", - "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload", - "laload", "faload", "daload", "aaload", "baload", "caload", "saload", - "istore", "lstore", "fstore", "dstore", "astore", "istore_0", - "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", - "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2", - "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3", - "astore_0", "astore_1", "astore_2", "astore_3", "iastore", "lastore", - "fastore", "dastore", "aastore", "bastore", "castore", "sastore", - "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1", - "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub", - "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv", - "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg", - "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr", - "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f", - "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f", - "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", - "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", - "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt", - "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret", - "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn", - "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield", - "putfield", "invokevirtual", "invokespecial", "invokestatic", - "invokeinterface", ILLEGAL_OPCODE, "new", "newarray", "anewarray", - "arraylength", "athrow", "checkcast", "instanceof", "monitorenter", - "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull", - "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, "impdep1", "impdep2" - }; + /** + * How the byte code operands are to be interpreted. + */ + public static final short[][] TYPE_OF_OPERANDS = { {}/* nop */, + {}/* aconst_null */, {}/* iconst_m1 */, {}/* iconst_0 */, + {}/* iconst_1 */, {}/* iconst_2 */, {}/* iconst_3 */, {}/* iconst_4 */, + {}/* iconst_5 */, {}/* lconst_0 */, {}/* lconst_1 */, {}/* fconst_0 */, + {}/* fconst_1 */, {}/* fconst_2 */, {}/* dconst_0 */, {}/* dconst_1 */, + { T_BYTE }/* bipush */, { T_SHORT }/* sipush */, { T_BYTE }/* ldc */, + { T_SHORT }/* ldc_w */, { T_SHORT }/* ldc2_w */, + { T_BYTE }/* iload */, { T_BYTE }/* lload */, + { T_BYTE }/* fload */, { T_BYTE }/* dload */, + { T_BYTE }/* aload */, {}/* iload_0 */, {}/* iload_1 */, + {}/* iload_2 */, {}/* iload_3 */, {}/* lload_0 */, {}/* lload_1 */, + {}/* lload_2 */, {}/* lload_3 */, {}/* fload_0 */, {}/* fload_1 */, + {}/* fload_2 */, {}/* fload_3 */, {}/* dload_0 */, {}/* dload_1 */, + {}/* dload_2 */, {}/* dload_3 */, {}/* aload_0 */, {}/* aload_1 */, + {}/* aload_2 */, {}/* aload_3 */, {}/* iaload */, {}/* laload */, + {}/* faload */, {}/* daload */, {}/* aaload */, {}/* baload */, + {}/* caload */, {}/* saload */, { T_BYTE }/* istore */, + { T_BYTE }/* lstore */, { T_BYTE }/* fstore */, + { T_BYTE }/* dstore */, { T_BYTE }/* astore */, {}/* istore_0 */, + {}/* istore_1 */, {}/* istore_2 */, {}/* istore_3 */, {}/* lstore_0 */, + {}/* lstore_1 */, {}/* lstore_2 */, {}/* lstore_3 */, {}/* fstore_0 */, + {}/* fstore_1 */, {}/* fstore_2 */, {}/* fstore_3 */, {}/* dstore_0 */, + {}/* dstore_1 */, {}/* dstore_2 */, {}/* dstore_3 */, {}/* astore_0 */, + {}/* astore_1 */, {}/* astore_2 */, {}/* astore_3 */, {}/* iastore */, + {}/* lastore */, {}/* fastore */, {}/* dastore */, {}/* aastore */, + {}/* bastore */, {}/* castore */, {}/* sastore */, {}/* pop */, + {}/* pop2 */, {}/* dup */, {}/* dup_x1 */, {}/* dup_x2 */, {}/* dup2 */, + {}/* dup2_x1 */, {}/* dup2_x2 */, {}/* swap */, {}/* iadd */, {}/* ladd */, + {}/* fadd */, {}/* dadd */, {}/* isub */, {}/* lsub */, {}/* fsub */, + {}/* dsub */, {}/* imul */, {}/* lmul */, {}/* fmul */, {}/* dmul */, + {}/* idiv */, {}/* ldiv */, {}/* fdiv */, {}/* ddiv */, {}/* irem */, + {}/* lrem */, {}/* frem */, {}/* drem */, {}/* ineg */, {}/* lneg */, + {}/* fneg */, {}/* dneg */, {}/* ishl */, {}/* lshl */, {}/* ishr */, + {}/* lshr */, {}/* iushr */, {}/* lushr */, {}/* iand */, {}/* land */, + {}/* ior */, {}/* lor */, {}/* ixor */, {}/* lxor */, + { T_BYTE, T_BYTE }/* iinc */, {}/* i2l */, {}/* i2f */, {}/* i2d */, + {}/* l2i */, {}/* l2f */, {}/* l2d */, {}/* f2i */, {}/* f2l */, + {}/* f2d */, {}/* d2i */, {}/* d2l */, {}/* d2f */, {}/* i2b */, + {}/* i2c */, {}/* i2s */, {}/* lcmp */, {}/* fcmpl */, {}/* fcmpg */, + {}/* dcmpl */, {}/* dcmpg */, { T_SHORT }/* ifeq */, + { T_SHORT }/* ifne */, { T_SHORT }/* iflt */, + { T_SHORT }/* ifge */, { T_SHORT }/* ifgt */, + { T_SHORT }/* ifle */, { T_SHORT }/* if_icmpeq */, + { T_SHORT }/* if_icmpne */, { T_SHORT }/* if_icmplt */, + { T_SHORT }/* if_icmpge */, { T_SHORT }/* if_icmpgt */, + { T_SHORT }/* if_icmple */, { T_SHORT }/* if_acmpeq */, + { T_SHORT }/* if_acmpne */, { T_SHORT }/* goto */, + { T_SHORT }/* jsr */, { T_BYTE }/* ret */, {}/* tableswitch */, + {}/* lookupswitch */, {}/* ireturn */, {}/* lreturn */, {}/* freturn */, + {}/* dreturn */, {}/* areturn */, {}/* return */, + { T_SHORT }/* getstatic */, { T_SHORT }/* putstatic */, + { T_SHORT }/* getfield */, { T_SHORT }/* putfield */, + { T_SHORT }/* invokevirtual */, { T_SHORT }/* invokespecial */, + { T_SHORT }/* invokestatic */, + { T_SHORT, T_BYTE, T_BYTE }/* invokeinterface */, {}, + { T_SHORT }/* new */, { T_BYTE }/* newarray */, + { T_SHORT }/* anewarray */, {}/* arraylength */, {}/* athrow */, + { T_SHORT }/* checkcast */, { T_SHORT }/* instanceof */, + {}/* monitorenter */, {}/* monitorexit */, { T_BYTE }/* wide */, + { T_SHORT, T_BYTE }/* multianewarray */, { T_SHORT }/* ifnull */, + { T_SHORT }/* ifnonnull */, { T_INT }/* goto_w */, + { T_INT }/* jsr_w */, {}/* breakpoint */, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}/* impdep1 */, {} /* impdep2 */ + }; - /** - * Number of words consumed on operand stack by instructions. - */ - public static final int[] CONSUME_STACK = { - 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, 0/*iconst_1*/, - 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, 0/*iconst_5*/, 0/*lconst_0*/, - 0/*lconst_1*/, 0/*fconst_0*/, 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, - 0/*dconst_1*/, 0/*bipush*/, 0/*sipush*/, 0/*ldc*/, 0/*ldc_w*/, 0/*ldc2_w*/, 0/*iload*/, - 0/*lload*/, 0/*fload*/, 0/*dload*/, 0/*aload*/, 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, - 0/*iload_3*/, 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, 0/*fload_0*/, - 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, - 0/*dload_3*/, 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, 2/*iaload*/, - 2/*laload*/, 2/*faload*/, 2/*daload*/, 2/*aaload*/, 2/*baload*/, 2/*caload*/, 2/*saload*/, - 1/*istore*/, 2/*lstore*/, 1/*fstore*/, 2/*dstore*/, 1/*astore*/, 1/*istore_0*/, - 1/*istore_1*/, 1/*istore_2*/, 1/*istore_3*/, 2/*lstore_0*/, 2/*lstore_1*/, - 2/*lstore_2*/, 2/*lstore_3*/, 1/*fstore_0*/, 1/*fstore_1*/, 1/*fstore_2*/, - 1/*fstore_3*/, 2/*dstore_0*/, 2/*dstore_1*/, 2/*dstore_2*/, 2/*dstore_3*/, - 1/*astore_0*/, 1/*astore_1*/, 1/*astore_2*/, 1/*astore_3*/, 3/*iastore*/, 4/*lastore*/, - 3/*fastore*/, 4/*dastore*/, 3/*aastore*/, 3/*bastore*/, 3/*castore*/, 3/*sastore*/, - 1/*pop*/, 2/*pop2*/, 1/*dup*/, 2/*dup_x1*/, 3/*dup_x2*/, 2/*dup2*/, 3/*dup2_x1*/, - 4/*dup2_x2*/, 2/*swap*/, 2/*iadd*/, 4/*ladd*/, 2/*fadd*/, 4/*dadd*/, 2/*isub*/, 4/*lsub*/, - 2/*fsub*/, 4/*dsub*/, 2/*imul*/, 4/*lmul*/, 2/*fmul*/, 4/*dmul*/, 2/*idiv*/, 4/*ldiv*/, - 2/*fdiv*/, 4/*ddiv*/, 2/*irem*/, 4/*lrem*/, 2/*frem*/, 4/*drem*/, 1/*ineg*/, 2/*lneg*/, - 1/*fneg*/, 2/*dneg*/, 2/*ishl*/, 3/*lshl*/, 2/*ishr*/, 3/*lshr*/, 2/*iushr*/, 3/*lushr*/, - 2/*iand*/, 4/*land*/, 2/*ior*/, 4/*lor*/, 2/*ixor*/, 4/*lxor*/, 0/*iinc*/, - 1/*i2l*/, 1/*i2f*/, 1/*i2d*/, 2/*l2i*/, 2/*l2f*/, 2/*l2d*/, 1/*f2i*/, 1/*f2l*/, - 1/*f2d*/, 2/*d2i*/, 2/*d2l*/, 2/*d2f*/, 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, - 4/*lcmp*/, 2/*fcmpl*/, 2/*fcmpg*/, 4/*dcmpl*/, 4/*dcmpg*/, 1/*ifeq*/, 1/*ifne*/, - 1/*iflt*/, 1/*ifge*/, 1/*ifgt*/, 1/*ifle*/, 2/*if_icmpeq*/, 2/*if_icmpne*/, 2/*if_icmplt*/, - 2 /*if_icmpge*/, 2/*if_icmpgt*/, 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, - 0/*goto*/, 0/*jsr*/, 0/*ret*/, 1/*tableswitch*/, 1/*lookupswitch*/, 1/*ireturn*/, - 2/*lreturn*/, 1/*freturn*/, 2/*dreturn*/, 1/*areturn*/, 0/*return*/, 0/*getstatic*/, - UNPREDICTABLE/*putstatic*/, 1/*getfield*/, UNPREDICTABLE/*putfield*/, - UNPREDICTABLE/*invokevirtual*/, UNPREDICTABLE/*invokespecial*/, - UNPREDICTABLE/*invokestatic*/, - UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 0/*new*/, 1/*newarray*/, 1/*anewarray*/, - 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 1/*monitorenter*/, - 1/*monitorexit*/, 0/*wide*/, UNPREDICTABLE/*multianewarray*/, 1/*ifnull*/, 1/*ifnonnull*/, - 0/*goto_w*/, 0/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/ - }; + /** + * Names of opcodes. + */ + public static final String[] OPCODE_NAMES = { "nop", "aconst_null", + "iconst_m1", "iconst_0", "iconst_1", "iconst_2", "iconst_3", + "iconst_4", "iconst_5", "lconst_0", "lconst_1", "fconst_0", + "fconst_1", "fconst_2", "dconst_0", "dconst_1", "bipush", "sipush", + "ldc", "ldc_w", "ldc2_w", "iload", "lload", "fload", "dload", + "aload", "iload_0", "iload_1", "iload_2", "iload_3", "lload_0", + "lload_1", "lload_2", "lload_3", "fload_0", "fload_1", "fload_2", + "fload_3", "dload_0", "dload_1", "dload_2", "dload_3", "aload_0", + "aload_1", "aload_2", "aload_3", "iaload", "laload", "faload", + "daload", "aaload", "baload", "caload", "saload", "istore", + "lstore", "fstore", "dstore", "astore", "istore_0", "istore_1", + "istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2", + "lstore_3", "fstore_0", "fstore_1", "fstore_2", "fstore_3", + "dstore_0", "dstore_1", "dstore_2", "dstore_3", "astore_0", + "astore_1", "astore_2", "astore_3", "iastore", "lastore", + "fastore", "dastore", "aastore", "bastore", "castore", "sastore", + "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1", + "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub", + "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv", + "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg", + "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr", + "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f", + "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", + "d2f", "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", "dcmpl", + "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", + "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt", + "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret", + "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn", + "dreturn", "areturn", "return", "getstatic", "putstatic", + "getfield", "putfield", "invokevirtual", "invokespecial", + "invokestatic", "invokeinterface", ILLEGAL_OPCODE, "new", + "newarray", "anewarray", "arraylength", "athrow", "checkcast", + "instanceof", "monitorenter", "monitorexit", "wide", + "multianewarray", "ifnull", "ifnonnull", "goto_w", "jsr_w", + "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + "impdep1", "impdep2" }; - /** - * Number of words produced onto operand stack by instructions. - */ - public static final int[] PRODUCE_STACK = { - 0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/, - 1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/, - 2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/, - 2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/, - 2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/, - 1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/, - 1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/, - 2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/, - 2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/, - 0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/, - 0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, - 0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, - 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/, - 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, - 0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/, - 0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/, - 6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/, - 1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/, - 1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/, - 1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/, - 1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/, - 0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/, - 2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/, - 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/, - 1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/, - 0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/, - 0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/, - 0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, - 0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/, - UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/, - UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/, - UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 1/*new*/, 1/*newarray*/, 1/*anewarray*/, - 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/, - 0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/, - 0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/ - }; + /** + * Number of words consumed on operand stack by instructions. + */ + public static final int[] CONSUME_STACK = { 0/* nop */, 0/* aconst_null */, + 0/* iconst_m1 */, 0/* iconst_0 */, 0/* iconst_1 */, 0/* iconst_2 */, + 0/* iconst_3 */, 0/* iconst_4 */, 0/* iconst_5 */, 0/* lconst_0 */, + 0/* lconst_1 */, 0/* fconst_0 */, 0/* fconst_1 */, 0/* fconst_2 */, + 0/* dconst_0 */, 0/* dconst_1 */, 0/* bipush */, 0/* sipush */, + 0/* ldc */, 0/* ldc_w */, 0/* ldc2_w */, 0/* iload */, 0/* lload */, + 0/* fload */, 0/* dload */, 0/* aload */, 0/* iload_0 */, 0/* iload_1 */, + 0/* iload_2 */, 0/* iload_3 */, 0/* lload_0 */, 0/* lload_1 */, + 0/* lload_2 */, 0/* lload_3 */, 0/* fload_0 */, 0/* fload_1 */, + 0/* fload_2 */, 0/* fload_3 */, 0/* dload_0 */, 0/* dload_1 */, + 0/* dload_2 */, 0/* dload_3 */, 0/* aload_0 */, 0/* aload_1 */, + 0/* aload_2 */, 0/* aload_3 */, 2/* iaload */, 2/* laload */, + 2/* faload */, 2/* daload */, 2/* aaload */, 2/* baload */, + 2/* caload */, 2/* saload */, 1/* istore */, 2/* lstore */, + 1/* fstore */, 2/* dstore */, 1/* astore */, 1/* istore_0 */, + 1/* istore_1 */, 1/* istore_2 */, 1/* istore_3 */, 2/* lstore_0 */, + 2/* lstore_1 */, 2/* lstore_2 */, 2/* lstore_3 */, 1/* fstore_0 */, + 1/* fstore_1 */, 1/* fstore_2 */, 1/* fstore_3 */, 2/* dstore_0 */, + 2/* dstore_1 */, 2/* dstore_2 */, 2/* dstore_3 */, 1/* astore_0 */, + 1/* astore_1 */, 1/* astore_2 */, 1/* astore_3 */, 3/* iastore */, + 4/* lastore */, 3/* fastore */, 4/* dastore */, 3/* aastore */, + 3/* bastore */, 3/* castore */, 3/* sastore */, 1/* pop */, + 2/* pop2 */, 1/* dup */, 2/* dup_x1 */, 3/* dup_x2 */, 2/* dup2 */, + 3/* dup2_x1 */, 4/* dup2_x2 */, 2/* swap */, 2/* iadd */, 4/* ladd */, + 2/* fadd */, 4/* dadd */, 2/* isub */, 4/* lsub */, 2/* fsub */, + 4/* dsub */, 2/* imul */, 4/* lmul */, 2/* fmul */, 4/* dmul */, + 2/* idiv */, 4/* ldiv */, 2/* fdiv */, 4/* ddiv */, 2/* irem */, + 4/* lrem */, 2/* frem */, 4/* drem */, 1/* ineg */, 2/* lneg */, + 1/* fneg */, 2/* dneg */, 2/* ishl */, 3/* lshl */, 2/* ishr */, + 3/* lshr */, 2/* iushr */, 3/* lushr */, 2/* iand */, 4/* land */, + 2/* ior */, 4/* lor */, 2/* ixor */, 4/* lxor */, 0/* iinc */, + 1/* i2l */, 1/* i2f */, 1/* i2d */, 2/* l2i */, 2/* l2f */, + 2/* l2d */, 1/* f2i */, 1/* f2l */, 1/* f2d */, 2/* d2i */, + 2/* d2l */, 2/* d2f */, 1/* i2b */, 1/* i2c */, 1/* i2s */, + 4/* lcmp */, 2/* fcmpl */, 2/* fcmpg */, 4/* dcmpl */, 4/* dcmpg */, + 1/* ifeq */, 1/* ifne */, 1/* iflt */, 1/* ifge */, 1/* ifgt */, + 1/* ifle */, 2/* if_icmpeq */, 2/* if_icmpne */, 2/* if_icmplt */, + 2 /* if_icmpge */, 2/* if_icmpgt */, 2/* if_icmple */, 2/* if_acmpeq */, + 2/* if_acmpne */, 0/* goto */, 0/* jsr */, 0/* ret */, + 1/* tableswitch */, 1/* lookupswitch */, 1/* ireturn */, + 2/* lreturn */, 1/* freturn */, 2/* dreturn */, 1/* areturn */, + 0/* return */, 0/* getstatic */, UNPREDICTABLE/* putstatic */, + 1/* getfield */, UNPREDICTABLE/* putfield */, + UNPREDICTABLE/* invokevirtual */, UNPREDICTABLE/* invokespecial */, + UNPREDICTABLE/* invokestatic */, UNPREDICTABLE/* invokeinterface */, + UNDEFINED, 0/* new */, 1/* newarray */, 1/* anewarray */, + 1/* arraylength */, 1/* athrow */, 1/* checkcast */, + 1/* instanceof */, 1/* monitorenter */, 1/* monitorexit */, + 0/* wide */, UNPREDICTABLE/* multianewarray */, 1/* ifnull */, + 1/* ifnonnull */, 0/* goto_w */, 0/* jsr_w */, 0/* breakpoint */, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNPREDICTABLE/* impdep1 */, + UNPREDICTABLE /* impdep2 */ + }; - /** Attributes and their corresponding names. - */ - public static final byte ATTR_UNKNOWN = -1; - public static final byte ATTR_SOURCE_FILE = 0; - public static final byte ATTR_CONSTANT_VALUE = 1; - public static final byte ATTR_CODE = 2; - public static final byte ATTR_EXCEPTIONS = 3; - public static final byte ATTR_LINE_NUMBER_TABLE = 4; - public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; - public static final byte ATTR_INNER_CLASSES = 6; - public static final byte ATTR_SYNTHETIC = 7; - public static final byte ATTR_DEPRECATED = 8; - public static final byte ATTR_PMG = 9; - public static final byte ATTR_SIGNATURE = 10; - public static final byte ATTR_STACK_MAP = 11; - public static final byte ATTR_RUNTIMEVISIBLE_ANNOTATIONS = 12; - public static final byte ATTR_RUNTIMEINVISIBLE_ANNOTATIONS = 13; - public static final byte ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS = 14; - public static final byte ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS = 15; - public static final byte ATTR_ANNOTATION_DEFAULT = 16; + /** + * Number of words produced onto operand stack by instructions. + */ + public static final int[] PRODUCE_STACK = { 0/* nop */, 1/* aconst_null */, + 1/* iconst_m1 */, 1/* iconst_0 */, 1/* iconst_1 */, 1/* iconst_2 */, + 1/* iconst_3 */, 1/* iconst_4 */, 1/* iconst_5 */, 2/* lconst_0 */, + 2/* lconst_1 */, 1/* fconst_0 */, 1/* fconst_1 */, 1/* fconst_2 */, + 2/* dconst_0 */, 2/* dconst_1 */, 1/* bipush */, 1/* sipush */, + 1/* ldc */, 1/* ldc_w */, 2/* ldc2_w */, 1/* iload */, 2/* lload */, + 1/* fload */, 2/* dload */, 1/* aload */, 1/* iload_0 */, 1/* iload_1 */, + 1/* iload_2 */, 1/* iload_3 */, 2/* lload_0 */, 2/* lload_1 */, + 2/* lload_2 */, 2/* lload_3 */, 1/* fload_0 */, 1/* fload_1 */, + 1/* fload_2 */, 1/* fload_3 */, 2/* dload_0 */, 2/* dload_1 */, + 2/* dload_2 */, 2/* dload_3 */, 1/* aload_0 */, 1/* aload_1 */, + 1/* aload_2 */, 1/* aload_3 */, 1/* iaload */, 2/* laload */, + 1/* faload */, 2/* daload */, 1/* aaload */, 1/* baload */, + 1/* caload */, 1/* saload */, 0/* istore */, 0/* lstore */, + 0/* fstore */, 0/* dstore */, 0/* astore */, 0/* istore_0 */, + 0/* istore_1 */, 0/* istore_2 */, 0/* istore_3 */, 0/* lstore_0 */, + 0/* lstore_1 */, 0/* lstore_2 */, 0/* lstore_3 */, 0/* fstore_0 */, + 0/* fstore_1 */, 0/* fstore_2 */, 0/* fstore_3 */, 0/* dstore_0 */, + 0/* dstore_1 */, 0/* dstore_2 */, 0/* dstore_3 */, 0/* astore_0 */, + 0/* astore_1 */, 0/* astore_2 */, 0/* astore_3 */, 0/* iastore */, + 0/* lastore */, 0/* fastore */, 0/* dastore */, 0/* aastore */, + 0/* bastore */, 0/* castore */, 0/* sastore */, 0/* pop */, + 0/* pop2 */, 2/* dup */, 3/* dup_x1 */, 4/* dup_x2 */, 4/* dup2 */, + 5/* dup2_x1 */, 6/* dup2_x2 */, 2/* swap */, 1/* iadd */, 2/* ladd */, + 1/* fadd */, 2/* dadd */, 1/* isub */, 2/* lsub */, 1/* fsub */, + 2/* dsub */, 1/* imul */, 2/* lmul */, 1/* fmul */, 2/* dmul */, + 1/* idiv */, 2/* ldiv */, 1/* fdiv */, 2/* ddiv */, 1/* irem */, + 2/* lrem */, 1/* frem */, 2/* drem */, 1/* ineg */, 2/* lneg */, + 1/* fneg */, 2/* dneg */, 1/* ishl */, 2/* lshl */, 1/* ishr */, + 2/* lshr */, 1/* iushr */, 2/* lushr */, 1/* iand */, 2/* land */, + 1/* ior */, 2/* lor */, 1/* ixor */, 2/* lxor */, 0/* iinc */, + 2/* i2l */, 1/* i2f */, 2/* i2d */, 1/* l2i */, 1/* l2f */, + 2/* l2d */, 1/* f2i */, 2/* f2l */, 2/* f2d */, 1/* d2i */, + 2/* d2l */, 1/* d2f */, 1/* i2b */, 1/* i2c */, 1/* i2s */, + 1/* lcmp */, 1/* fcmpl */, 1/* fcmpg */, 1/* dcmpl */, 1/* dcmpg */, + 0/* ifeq */, 0/* ifne */, 0/* iflt */, 0/* ifge */, 0/* ifgt */, + 0/* ifle */, 0/* if_icmpeq */, 0/* if_icmpne */, 0/* if_icmplt */, + 0/* if_icmpge */, 0/* if_icmpgt */, 0/* if_icmple */, 0/* if_acmpeq */, + 0/* if_acmpne */, 0/* goto */, 1/* jsr */, 0/* ret */, + 0/* tableswitch */, 0/* lookupswitch */, 0/* ireturn */, + 0/* lreturn */, 0/* freturn */, 0/* dreturn */, 0/* areturn */, + 0/* return */, UNPREDICTABLE/* getstatic */, 0/* putstatic */, + UNPREDICTABLE/* getfield */, 0/* putfield */, + UNPREDICTABLE/* invokevirtual */, UNPREDICTABLE/* invokespecial */, + UNPREDICTABLE/* invokestatic */, UNPREDICTABLE/* invokeinterface */, + UNDEFINED, 1/* new */, 1/* newarray */, 1/* anewarray */, + 1/* arraylength */, 1/* athrow */, 1/* checkcast */, + 1/* instanceof */, 0/* monitorenter */, 0/* monitorexit */, + 0/* wide */, 1/* multianewarray */, 0/* ifnull */, + 0/* ifnonnull */, 0/* goto_w */, 1/* jsr_w */, 0/* breakpoint */, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNPREDICTABLE/* impdep1 */, + UNPREDICTABLE /* impdep2 */ + }; - public static final short KNOWN_ATTRIBUTES = 12;//should be 17 + /** + * Attributes and their corresponding names. + */ + public static final byte ATTR_UNKNOWN = -1; + public static final byte ATTR_SOURCE_FILE = 0; + public static final byte ATTR_CONSTANT_VALUE = 1; + public static final byte ATTR_CODE = 2; + public static final byte ATTR_EXCEPTIONS = 3; + public static final byte ATTR_LINE_NUMBER_TABLE = 4; + public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; + public static final byte ATTR_INNER_CLASSES = 6; + public static final byte ATTR_SYNTHETIC = 7; + public static final byte ATTR_DEPRECATED = 8; + public static final byte ATTR_PMG = 9; + public static final byte ATTR_SIGNATURE = 10; + public static final byte ATTR_STACK_MAP = 11; + public static final byte ATTR_RUNTIMEVISIBLE_ANNOTATIONS = 12; + public static final byte ATTR_RUNTIMEINVISIBLE_ANNOTATIONS = 13; + public static final byte ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS = 14; + public static final byte ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS = 15; + public static final byte ATTR_ANNOTATION_DEFAULT = 16; - public static final String[] ATTRIBUTE_NAMES = { - "SourceFile", "ConstantValue", "Code", "Exceptions", - "LineNumberTable", "LocalVariableTable", - "InnerClasses", "Synthetic", "Deprecated", - "PMGClass", "Signature", "StackMap", - "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", - "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations", - "AnnotationDefault" - }; + public static final short KNOWN_ATTRIBUTES = 12;// should be 17 - /** Constants used in the StackMap attribute. - */ - public static final byte ITEM_Bogus = 0; - public static final byte ITEM_Integer = 1; - public static final byte ITEM_Float = 2; - public static final byte ITEM_Double = 3; - public static final byte ITEM_Long = 4; - public static final byte ITEM_Null = 5; - public static final byte ITEM_InitObject = 6; - public static final byte ITEM_Object = 7; - public static final byte ITEM_NewObject = 8; + public static final String[] ATTRIBUTE_NAMES = { "SourceFile", + "ConstantValue", "Code", "Exceptions", "LineNumberTable", + "LocalVariableTable", "InnerClasses", "Synthetic", "Deprecated", + "PMGClass", "Signature", "StackMap", "RuntimeVisibleAnnotations", + "RuntimeInvisibleAnnotations", + "RuntimeVisibleParameterAnnotations", + "RuntimeInvisibleParameterAnnotations", "AnnotationDefault" }; - public static final String[] ITEM_NAMES = { - "Bogus", "Integer", "Float", "Double", "Long", - "Null", "InitObject", "Object", "NewObject" - }; + /** + * Constants used in the StackMap attribute. + */ + public static final byte ITEM_Bogus = 0; + public static final byte ITEM_Integer = 1; + public static final byte ITEM_Float = 2; + public static final byte ITEM_Double = 3; + public static final byte ITEM_Long = 4; + public static final byte ITEM_Null = 5; + public static final byte ITEM_InitObject = 6; + public static final byte ITEM_Object = 7; + public static final byte ITEM_NewObject = 8; + + public static final String[] ITEM_NAMES = { "Bogus", "Integer", "Float", + "Double", "Long", "Null", "InitObject", "Object", "NewObject" }; } diff --git a/src/org/apache/bcel/ExceptionConstants.java b/src/org/apache/bcel/ExceptionConstants.java index c316ef0..fe8f3ee 100644 --- a/src/org/apache/bcel/ExceptionConstants.java +++ b/src/org/apache/bcel/ExceptionConstants.java @@ -18,59 +18,69 @@ package org.apache.bcel; /** * Exception constants. - * + * * @version $Id: ExceptionConstants.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author E. Haase + * @author E. Haase */ public interface ExceptionConstants { - /** The mother of all exceptions - */ - public static final Class THROWABLE = Throwable.class; - /** Super class of any run-time exception - */ - public static final Class RUNTIME_EXCEPTION = RuntimeException.class; - /** Super class of any linking exception (aka Linkage Error) - */ - public static final Class LINKING_EXCEPTION = LinkageError.class; - /** Linking Exceptions - */ - public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; - public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; - public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; - public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; - public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; - public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; - public static final Class INSTANTIATION_ERROR = InstantiationError.class; - public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; - public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; - public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; - public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; - public static final Class VERIFY_ERROR = VerifyError.class; - /* UnsupportedClassVersionError is new in JDK 1.2 */ - //public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; - /** Run-Time Exceptions - */ - public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; - public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; - public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; - public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; - public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; - public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; - /** Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual - * Machine Specification - */ - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { - NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, - EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR - }; // Chapter 5.1 - public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { - NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR - }; // Chapter 5.2 - public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) - public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; - // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) - public static final Class[] EXCS_ARRAY_EXCEPTION = { - NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION - }; + /** + * The mother of all exceptions + */ + public static final Class THROWABLE = Throwable.class; + /** + * Super class of any run-time exception + */ + public static final Class RUNTIME_EXCEPTION = RuntimeException.class; + /** + * Super class of any linking exception (aka Linkage Error) + */ + public static final Class LINKING_EXCEPTION = LinkageError.class; + /** + * Linking Exceptions + */ + public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; + public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; + public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; + public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; + public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; + public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; + public static final Class INSTANTIATION_ERROR = InstantiationError.class; + public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; + public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; + public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; + public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; + public static final Class VERIFY_ERROR = VerifyError.class; + /* UnsupportedClassVersionError is new in JDK 1.2 */ + // public static final Class UnsupportedClassVersionError = + // UnsupportedClassVersionError.class; + /** + * Run-Time Exceptions + */ + public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; + public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; + public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; + public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; + public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; + public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; + /** + * Pre-defined exception arrays according to chapters 5.1-5.4 of the Java + * Virtual Machine Specification + */ + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { + NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, + ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, + ILLEGAL_ACCESS_ERROR }; // Chapter 5.1 + public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { + NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR }; // Chapter + // 5.2 + public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter + // 5.3 + // (as + // below) + public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; + // Chapter 5.4 (no errors but the ones that _always_ could happen! How + // stupid.) + public static final Class[] EXCS_ARRAY_EXCEPTION = { + NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION }; } diff --git a/src/org/apache/bcel/Repository.java b/src/org/apache/bcel/Repository.java index 97da781..b06ec8e 100644 --- a/src/org/apache/bcel/Repository.java +++ b/src/org/apache/bcel/Repository.java @@ -23,239 +23,241 @@ import org.apache.bcel.util.SyntheticRepository; /** * The repository maintains informations about class interdependencies, e.g., - * whether a class is a sub-class of another. Delegates actual class loading - * to SyntheticRepository with current class path by default. - * + * whether a class is a sub-class of another. Delegates actual class loading to + * SyntheticRepository with current class path by default. + * * @see org.apache.bcel.util.Repository * @see org.apache.bcel.util.SyntheticRepository - * + * * @version $Id: Repository.java 386056 2006-03-15 11:31:56Z tcurdt $ * @author M. Dahm */ public abstract class Repository { - private static org.apache.bcel.util.Repository _repository = SyntheticRepository.getInstance(); + private static org.apache.bcel.util.Repository _repository = SyntheticRepository + .getInstance(); + /** + * @return currently used repository instance + */ + public static org.apache.bcel.util.Repository getRepository() { + return _repository; + } - /** @return currently used repository instance - */ - public static org.apache.bcel.util.Repository getRepository() { - return _repository; - } + /** + * Set repository instance to be used for class loading + */ + public static void setRepository(org.apache.bcel.util.Repository rep) { + _repository = rep; + } + /** + * Lookup class somewhere found on your CLASSPATH, or whereever the + * repository instance looks for it. + * + * @return class object for given fully qualified class name + * @throws ClassNotFoundException + * if the class could not be found or parsed correctly + */ + public static JavaClass lookupClass(String class_name) + throws ClassNotFoundException { + return _repository.loadClass(class_name); + } - /** Set repository instance to be used for class loading - */ - public static void setRepository( org.apache.bcel.util.Repository rep ) { - _repository = rep; - } + /** + * Try to find class source using the internal repository instance. + * + * @see Class + * @return JavaClass object for given runtime class + * @throws ClassNotFoundException + * if the class could not be found or parsed correctly + */ + public static JavaClass lookupClass(Class clazz) + throws ClassNotFoundException { + return _repository.loadClass(clazz); + } + /** + * @return class file object for given Java class by looking on the system + * class path; returns null if the class file can't be found + */ + public static ClassPath.ClassFile lookupClassFile(String class_name) { + try { + ClassPath path = _repository.getClassPath(); + if (path == null) { + return null; + } + return path.getClassFile(class_name); + } catch (IOException e) { + return null; + } + } - /** Lookup class somewhere found on your CLASSPATH, or whereever the - * repository instance looks for it. - * - * @return class object for given fully qualified class name - * @throws ClassNotFoundException if the class could not be found or - * parsed correctly - */ - public static JavaClass lookupClass( String class_name ) throws ClassNotFoundException { - return _repository.loadClass(class_name); - } + /** + * Clear the repository. + */ + public static void clearCache() { + _repository.clear(); + } + /** + * Add clazz to repository if there isn't an equally named class already in + * there. + * + * @return old entry in repository + */ + public static JavaClass addClass(JavaClass clazz) { + JavaClass old = _repository.findClass(clazz.getClassName()); + _repository.storeClass(clazz); + return old; + } - /** - * Try to find class source using the internal repository instance. - * @see Class - * @return JavaClass object for given runtime class - * @throws ClassNotFoundException if the class could not be found or - * parsed correctly - */ - public static JavaClass lookupClass( Class clazz ) throws ClassNotFoundException { - return _repository.loadClass(clazz); - } + /** + * Remove class with given (fully qualified) name from repository. + */ + public static void removeClass(String clazz) { + _repository.removeClass(_repository.findClass(clazz)); + } + /** + * Remove given class from repository. + */ + public static void removeClass(JavaClass clazz) { + _repository.removeClass(clazz); + } - /** - * @return class file object for given Java class by looking on the - * system class path; returns null if the class file can't be - * found - */ - public static ClassPath.ClassFile lookupClassFile( String class_name ) { - try { - ClassPath path = _repository.getClassPath(); - if (path == null) { - return null; - } - return path.getClassFile(class_name); - } catch (IOException e) { - return null; - } - } + /** + * @return list of super classes of clazz in ascending order, i.e., Object + * is always the last element + * @throws ClassNotFoundException + * if any of the superclasses can't be found + */ + public static JavaClass[] getSuperClasses(JavaClass clazz) + throws ClassNotFoundException { + return clazz.getSuperClasses(); + } + /** + * @return list of super classes of clazz in ascending order, i.e., Object + * is always the last element. + * @throws ClassNotFoundException + * if the named class or any of its superclasses can't be found + */ + public static JavaClass[] getSuperClasses(String class_name) + throws ClassNotFoundException { + JavaClass jc = lookupClass(class_name); + return getSuperClasses(jc); + } - /** Clear the repository. - */ - public static void clearCache() { - _repository.clear(); - } + /** + * @return all interfaces implemented by class and its super classes and the + * interfaces that those interfaces extend, and so on. (Some people + * call this a transitive hull). + * @throws ClassNotFoundException + * if any of the class's superclasses or superinterfaces can't + * be found + */ + public static JavaClass[] getInterfaces(JavaClass clazz) + throws ClassNotFoundException { + return clazz.getAllInterfaces(); + } + /** + * @return all interfaces implemented by class and its super classes and the + * interfaces that extend those interfaces, and so on + * @throws ClassNotFoundException + * if the named class can't be found, or if any of its + * superclasses or superinterfaces can't be found + */ + public static JavaClass[] getInterfaces(String class_name) + throws ClassNotFoundException { + return getInterfaces(lookupClass(class_name)); + } - /** - * Add clazz to repository if there isn't an equally named class already in there. - * - * @return old entry in repository - */ - public static JavaClass addClass( JavaClass clazz ) { - JavaClass old = _repository.findClass(clazz.getClassName()); - _repository.storeClass(clazz); - return old; - } + /** + * Equivalent to runtime "instanceof" operator. + * + * @return true, if clazz is an instance of super_class + * @throws ClassNotFoundException + * if any superclasses or superinterfaces of clazz can't be + * found + */ + public static boolean instanceOf(JavaClass clazz, JavaClass super_class) + throws ClassNotFoundException { + return clazz.instanceOf(super_class); + } + /** + * @return true, if clazz is an instance of super_class + * @throws ClassNotFoundException + * if either clazz or super_class can't be found + */ + public static boolean instanceOf(String clazz, String super_class) + throws ClassNotFoundException { + return instanceOf(lookupClass(clazz), lookupClass(super_class)); + } - /** - * Remove class with given (fully qualified) name from repository. - */ - public static void removeClass( String clazz ) { - _repository.removeClass(_repository.findClass(clazz)); - } + /** + * @return true, if clazz is an instance of super_class + * @throws ClassNotFoundException + * if super_class can't be found + */ + public static boolean instanceOf(JavaClass clazz, String super_class) + throws ClassNotFoundException { + return instanceOf(clazz, lookupClass(super_class)); + } + /** + * @return true, if clazz is an instance of super_class + * @throws ClassNotFoundException + * if clazz can't be found + */ + public static boolean instanceOf(String clazz, JavaClass super_class) + throws ClassNotFoundException { + return instanceOf(lookupClass(clazz), super_class); + } - /** - * Remove given class from repository. - */ - public static void removeClass( JavaClass clazz ) { - _repository.removeClass(clazz); - } + /** + * @return true, if clazz is an implementation of interface inter + * @throws ClassNotFoundException + * if any superclasses or superinterfaces of clazz can't be + * found + */ + public static boolean implementationOf(JavaClass clazz, JavaClass inter) + throws ClassNotFoundException { + return clazz.implementationOf(inter); + } + /** + * @return true, if clazz is an implementation of interface inter + * @throws ClassNotFoundException + * if clazz, inter, or any superclasses or superinterfaces of + * clazz can't be found + */ + public static boolean implementationOf(String clazz, String inter) + throws ClassNotFoundException { + return implementationOf(lookupClass(clazz), lookupClass(inter)); + } - /** - * @return list of super classes of clazz in ascending order, i.e., - * Object is always the last element - * @throws ClassNotFoundException if any of the superclasses can't be found - */ - public static JavaClass[] getSuperClasses( JavaClass clazz ) throws ClassNotFoundException { - return clazz.getSuperClasses(); - } + /** + * @return true, if clazz is an implementation of interface inter + * @throws ClassNotFoundException + * if inter or any superclasses or superinterfaces of clazz + * can't be found + */ + public static boolean implementationOf(JavaClass clazz, String inter) + throws ClassNotFoundException { + return implementationOf(clazz, lookupClass(inter)); + } - - /** - * @return list of super classes of clazz in ascending order, i.e., - * Object is always the last element. - * @throws ClassNotFoundException if the named class or any of its - * superclasses can't be found - */ - public static JavaClass[] getSuperClasses( String class_name ) throws ClassNotFoundException { - JavaClass jc = lookupClass(class_name); - return getSuperClasses(jc); - } - - - /** - * @return all interfaces implemented by class and its super - * classes and the interfaces that those interfaces extend, and so on. - * (Some people call this a transitive hull). - * @throws ClassNotFoundException if any of the class's - * superclasses or superinterfaces can't be found - */ - public static JavaClass[] getInterfaces( JavaClass clazz ) throws ClassNotFoundException { - return clazz.getAllInterfaces(); - } - - - /** - * @return all interfaces implemented by class and its super - * classes and the interfaces that extend those interfaces, and so on - * @throws ClassNotFoundException if the named class can't be found, - * or if any of its superclasses or superinterfaces can't be found - */ - public static JavaClass[] getInterfaces( String class_name ) throws ClassNotFoundException { - return getInterfaces(lookupClass(class_name)); - } - - - /** - * Equivalent to runtime "instanceof" operator. - * @return true, if clazz is an instance of super_class - * @throws ClassNotFoundException if any superclasses or superinterfaces - * of clazz can't be found - */ - public static boolean instanceOf( JavaClass clazz, JavaClass super_class ) - throws ClassNotFoundException { - return clazz.instanceOf(super_class); - } - - - /** - * @return true, if clazz is an instance of super_class - * @throws ClassNotFoundException if either clazz or super_class - * can't be found - */ - public static boolean instanceOf( String clazz, String super_class ) - throws ClassNotFoundException { - return instanceOf(lookupClass(clazz), lookupClass(super_class)); - } - - - /** - * @return true, if clazz is an instance of super_class - * @throws ClassNotFoundException if super_class can't be found - */ - public static boolean instanceOf( JavaClass clazz, String super_class ) - throws ClassNotFoundException { - return instanceOf(clazz, lookupClass(super_class)); - } - - - /** - * @return true, if clazz is an instance of super_class - * @throws ClassNotFoundException if clazz can't be found - */ - public static boolean instanceOf( String clazz, JavaClass super_class ) - throws ClassNotFoundException { - return instanceOf(lookupClass(clazz), super_class); - } - - - /** - * @return true, if clazz is an implementation of interface inter - * @throws ClassNotFoundException if any superclasses or superinterfaces - * of clazz can't be found - */ - public static boolean implementationOf( JavaClass clazz, JavaClass inter ) - throws ClassNotFoundException { - return clazz.implementationOf(inter); - } - - - /** - * @return true, if clazz is an implementation of interface inter - * @throws ClassNotFoundException if clazz, inter, or any superclasses - * or superinterfaces of clazz can't be found - */ - public static boolean implementationOf( String clazz, String inter ) - throws ClassNotFoundException { - return implementationOf(lookupClass(clazz), lookupClass(inter)); - } - - - /** - * @return true, if clazz is an implementation of interface inter - * @throws ClassNotFoundException if inter or any superclasses - * or superinterfaces of clazz can't be found - */ - public static boolean implementationOf( JavaClass clazz, String inter ) - throws ClassNotFoundException { - return implementationOf(clazz, lookupClass(inter)); - } - - - /** - * @return true, if clazz is an implementation of interface inter - * @throws ClassNotFoundException if clazz or any superclasses or - * superinterfaces of clazz can't be found - */ - public static boolean implementationOf( String clazz, JavaClass inter ) - throws ClassNotFoundException { - return implementationOf(lookupClass(clazz), inter); - } + /** + * @return true, if clazz is an implementation of interface inter + * @throws ClassNotFoundException + * if clazz or any superclasses or superinterfaces of clazz + * can't be found + */ + public static boolean implementationOf(String clazz, JavaClass inter) + throws ClassNotFoundException { + return implementationOf(lookupClass(clazz), inter); + } } diff --git a/src/org/apache/bcel/classfile/AccessFlags.java b/src/org/apache/bcel/classfile/AccessFlags.java index 981babc..006f318 100644 --- a/src/org/apache/bcel/classfile/AccessFlags.java +++ b/src/org/apache/bcel/classfile/AccessFlags.java @@ -19,220 +19,194 @@ package org.apache.bcel.classfile; import org.apache.bcel.Constants; /** - * Super class for all objects that have modifiers like private, final, ... - * I.e. classes, fields, and methods. - * + * Super class for all objects that have modifiers like private, final, ... I.e. + * classes, fields, and methods. + * * @version $Id: AccessFlags.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class AccessFlags implements java.io.Serializable { - protected int access_flags; + /** + * + */ + private static final long serialVersionUID = 1L; + protected int access_flags; + + public AccessFlags() { + } + + /** + * @param a + * inital access flags + */ + public AccessFlags(int a) { + access_flags = a; + } + + /** + * @return Access flags of the object aka. "modifiers". + */ + public final int getAccessFlags() { + return access_flags; + } + + /** + * @return Access flags of the object aka. "modifiers". + */ + public final int getModifiers() { + return access_flags; + } + + /** + * Set access flags aka "modifiers". + * + * @param access_flags + * Access flags of the object. + */ + public final void setAccessFlags(int access_flags) { + this.access_flags = access_flags; + } + + /** + * Set access flags aka "modifiers". + * + * @param access_flags + * Access flags of the object. + */ + public final void setModifiers(int access_flags) { + setAccessFlags(access_flags); + } + + private final void setFlag(int flag, boolean set) { + if ((access_flags & flag) != 0) { // Flag is set already + if (!set) { + access_flags ^= flag; + } + } else { // Flag not set + if (set) { + access_flags |= flag; + } + } + } + + public final void isPublic(boolean flag) { + setFlag(Constants.ACC_PUBLIC, flag); + } + + public final boolean isPublic() { + return (access_flags & Constants.ACC_PUBLIC) != 0; + } + + public final void isPrivate(boolean flag) { + setFlag(Constants.ACC_PRIVATE, flag); + } + + public final boolean isPrivate() { + return (access_flags & Constants.ACC_PRIVATE) != 0; + } + + public final void isProtected(boolean flag) { + setFlag(Constants.ACC_PROTECTED, flag); + } + + public final boolean isProtected() { + return (access_flags & Constants.ACC_PROTECTED) != 0; + } + + public final void isStatic(boolean flag) { + setFlag(Constants.ACC_STATIC, flag); + } + + public final boolean isStatic() { + return (access_flags & Constants.ACC_STATIC) != 0; + } + + public final void isFinal(boolean flag) { + setFlag(Constants.ACC_FINAL, flag); + } + + public final boolean isFinal() { + return (access_flags & Constants.ACC_FINAL) != 0; + } + + public final void isSynchronized(boolean flag) { + setFlag(Constants.ACC_SYNCHRONIZED, flag); + } + + public final boolean isSynchronized() { + return (access_flags & Constants.ACC_SYNCHRONIZED) != 0; + } + + public final void isVolatile(boolean flag) { + setFlag(Constants.ACC_VOLATILE, flag); + } + + public final boolean isVolatile() { + return (access_flags & Constants.ACC_VOLATILE) != 0; + } + + public final void isTransient(boolean flag) { + setFlag(Constants.ACC_TRANSIENT, flag); + } + + public final boolean isTransient() { + return (access_flags & Constants.ACC_TRANSIENT) != 0; + } + + public final void isNative(boolean flag) { + setFlag(Constants.ACC_NATIVE, flag); + } + + public final boolean isNative() { + return (access_flags & Constants.ACC_NATIVE) != 0; + } + + public final void isInterface(boolean flag) { + setFlag(Constants.ACC_INTERFACE, flag); + } + + public final boolean isInterface() { + return (access_flags & Constants.ACC_INTERFACE) != 0; + } + + public final void isAbstract(boolean flag) { + setFlag(Constants.ACC_ABSTRACT, flag); + } + + public final boolean isAbstract() { + return (access_flags & Constants.ACC_ABSTRACT) != 0; + } + + public final void isStrictfp(boolean flag) { + setFlag(Constants.ACC_STRICT, flag); + } + + public final boolean isStrictfp() { + return (access_flags & Constants.ACC_STRICT) != 0; + } + + public final void isSynthetic(boolean flag) { + setFlag(Constants.ACC_SYNTHETIC, flag); + } + public final boolean isSynthetic() { + return (access_flags & Constants.ACC_SYNTHETIC) != 0; + } - public AccessFlags() { - } + public final void isAnnotation(boolean flag) { + setFlag(Constants.ACC_ANNOTATION, flag); + } + public final boolean isAnnotation() { + return (access_flags & Constants.ACC_ANNOTATION) != 0; + } - /** - * @param a inital access flags - */ - public AccessFlags(int a) { - access_flags = a; - } + public final void isEnum(boolean flag) { + setFlag(Constants.ACC_ENUM, flag); + } - - /** - * @return Access flags of the object aka. "modifiers". - */ - public final int getAccessFlags() { - return access_flags; - } - - - /** - * @return Access flags of the object aka. "modifiers". - */ - public final int getModifiers() { - return access_flags; - } - - - /** Set access flags aka "modifiers". - * @param access_flags Access flags of the object. - */ - public final void setAccessFlags( int access_flags ) { - this.access_flags = access_flags; - } - - - /** Set access flags aka "modifiers". - * @param access_flags Access flags of the object. - */ - public final void setModifiers( int access_flags ) { - setAccessFlags(access_flags); - } - - - private final void setFlag( int flag, boolean set ) { - if ((access_flags & flag) != 0) { // Flag is set already - if (!set) { - access_flags ^= flag; - } - } else { // Flag not set - if (set) { - access_flags |= flag; - } - } - } - - - public final void isPublic( boolean flag ) { - setFlag(Constants.ACC_PUBLIC, flag); - } - - - public final boolean isPublic() { - return (access_flags & Constants.ACC_PUBLIC) != 0; - } - - - public final void isPrivate( boolean flag ) { - setFlag(Constants.ACC_PRIVATE, flag); - } - - - public final boolean isPrivate() { - return (access_flags & Constants.ACC_PRIVATE) != 0; - } - - - public final void isProtected( boolean flag ) { - setFlag(Constants.ACC_PROTECTED, flag); - } - - - public final boolean isProtected() { - return (access_flags & Constants.ACC_PROTECTED) != 0; - } - - - public final void isStatic( boolean flag ) { - setFlag(Constants.ACC_STATIC, flag); - } - - - public final boolean isStatic() { - return (access_flags & Constants.ACC_STATIC) != 0; - } - - - public final void isFinal( boolean flag ) { - setFlag(Constants.ACC_FINAL, flag); - } - - - public final boolean isFinal() { - return (access_flags & Constants.ACC_FINAL) != 0; - } - - - public final void isSynchronized( boolean flag ) { - setFlag(Constants.ACC_SYNCHRONIZED, flag); - } - - - public final boolean isSynchronized() { - return (access_flags & Constants.ACC_SYNCHRONIZED) != 0; - } - - - public final void isVolatile( boolean flag ) { - setFlag(Constants.ACC_VOLATILE, flag); - } - - - public final boolean isVolatile() { - return (access_flags & Constants.ACC_VOLATILE) != 0; - } - - - public final void isTransient( boolean flag ) { - setFlag(Constants.ACC_TRANSIENT, flag); - } - - - public final boolean isTransient() { - return (access_flags & Constants.ACC_TRANSIENT) != 0; - } - - - public final void isNative( boolean flag ) { - setFlag(Constants.ACC_NATIVE, flag); - } - - - public final boolean isNative() { - return (access_flags & Constants.ACC_NATIVE) != 0; - } - - - public final void isInterface( boolean flag ) { - setFlag(Constants.ACC_INTERFACE, flag); - } - - - public final boolean isInterface() { - return (access_flags & Constants.ACC_INTERFACE) != 0; - } - - - public final void isAbstract( boolean flag ) { - setFlag(Constants.ACC_ABSTRACT, flag); - } - - - public final boolean isAbstract() { - return (access_flags & Constants.ACC_ABSTRACT) != 0; - } - - - public final void isStrictfp( boolean flag ) { - setFlag(Constants.ACC_STRICT, flag); - } - - - public final boolean isStrictfp() { - return (access_flags & Constants.ACC_STRICT) != 0; - } - - - public final void isSynthetic( boolean flag ) { - setFlag(Constants.ACC_SYNTHETIC, flag); - } - - - public final boolean isSynthetic() { - return (access_flags & Constants.ACC_SYNTHETIC) != 0; - } - - - public final void isAnnotation( boolean flag ) { - setFlag(Constants.ACC_ANNOTATION, flag); - } - - - public final boolean isAnnotation() { - return (access_flags & Constants.ACC_ANNOTATION) != 0; - } - - - public final void isEnum( boolean flag ) { - setFlag(Constants.ACC_ENUM, flag); - } - - - public final boolean isEnum() { - return (access_flags & Constants.ACC_ENUM) != 0; - } + public final boolean isEnum() { + return (access_flags & Constants.ACC_ENUM) != 0; + } } diff --git a/src/org/apache/bcel/classfile/Attribute.java b/src/org/apache/bcel/classfile/Attribute.java index c34b097..5225814 100644 --- a/src/org/apache/bcel/classfile/Attribute.java +++ b/src/org/apache/bcel/classfile/Attribute.java @@ -22,257 +22,276 @@ import java.io.IOException; import java.io.Serializable; import java.util.HashMap; import java.util.Map; + import org.apache.bcel.Constants; /** * Abstract super class for Attribute objects. Currently the * ConstantValue, SourceFile, Code, - * Exceptiontable, LineNumberTable, - * LocalVariableTable, InnerClasses and - * Synthetic attributes are supported. The - * Unknown attribute stands for non-standard-attributes. - * + * Exceptiontable, LineNumberTable, + * LocalVariableTable, InnerClasses and Synthetic + * attributes are supported. The Unknown attribute stands for + * non-standard-attributes. + * * @version $Id: Attribute.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see ConstantValue - * @see SourceFile - * @see Code - * @see Unknown - * @see ExceptionTable - * @see LineNumberTable - * @see LocalVariableTable - * @see InnerClasses - * @see Synthetic - * @see Deprecated - * @see Signature + * @author M. Dahm + * @see ConstantValue + * @see SourceFile + * @see Code + * @see Unknown + * @see ExceptionTable + * @see LineNumberTable + * @see LocalVariableTable + * @see InnerClasses + * @see Synthetic + * @see Deprecated + * @see Signature */ public abstract class Attribute implements Cloneable, Node, Serializable { - protected int name_index; // Points to attribute name in constant pool - protected int length; // Content length of attribute field - protected byte tag; // Tag to distiguish subclasses - protected ConstantPool constant_pool; + /** + * + */ + private static final long serialVersionUID = 1L; + protected int name_index; // Points to attribute name in constant pool + protected int length; // Content length of attribute field + protected byte tag; // Tag to distiguish subclasses + protected ConstantPool constant_pool; + protected Attribute(byte tag, int name_index, int length, + ConstantPool constant_pool) { + this.tag = tag; + this.name_index = name_index; + this.length = length; + this.constant_pool = constant_pool; + } - protected Attribute(byte tag, int name_index, int length, ConstantPool constant_pool) { - this.tag = tag; - this.name_index = name_index; - this.length = length; - this.constant_pool = constant_pool; - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public abstract void accept(Visitor v); + /** + * Dump attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + public void dump(DataOutputStream file) throws IOException { + file.writeShort(name_index); + file.writeInt(length); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public abstract void accept( Visitor v ); + private static Map readers = new HashMap(); + /** + * Add an Attribute reader capable of parsing (user-defined) attributes + * named "name". You should not add readers for the standard attributes such + * as "LineNumberTable", because those are handled internally. + * + * @param name + * the name of the attribute as stored in the class file + * @param r + * the reader object + */ + public static void addAttributeReader(String name, AttributeReader r) { + readers.put(name, r); + } - /** - * Dump attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public void dump( DataOutputStream file ) throws IOException { - file.writeShort(name_index); - file.writeInt(length); - } + /** + * Remove attribute reader + * + * @param name + * the name of the attribute as stored in the class file + */ + public static void removeAttributeReader(String name) { + readers.remove(name); + } - private static Map readers = new HashMap(); + /* + * Class method reads one attribute from the input data stream. This method + * must not be accessible from the outside. It is called by the Field and + * Method constructor methods. + * + * @see Field + * + * @see Method + * + * @param file Input stream + * + * @param constant_pool Array of constants + * + * @return Attribute + * + * @throws IOException + * + * @throws ClassFormatException + */ + public static final Attribute readAttribute(DataInputStream file, + ConstantPool constant_pool) throws IOException, + ClassFormatException { + ConstantUtf8 c; + String name; + int name_index; + int length; + byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute + // Get class name from constant pool via `name_index' indirection + name_index = file.readUnsignedShort(); + c = (ConstantUtf8) constant_pool.getConstant(name_index, + Constants.CONSTANT_Utf8); + name = c.getBytes(); + // Length of data in bytes + length = file.readInt(); + // Compare strings to find known attribute + for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++) { + if (name.equals(Constants.ATTRIBUTE_NAMES[i])) { + tag = i; // found! + break; + } + } + // Call proper constructor, depending on `tag' + switch (tag) { + case Constants.ATTR_UNKNOWN: + AttributeReader r = readers.get(name); + if (r != null) { + return r.createAttribute(name_index, length, file, + constant_pool); + } + return new Unknown(name_index, length, file, constant_pool); + case Constants.ATTR_CONSTANT_VALUE: + return new ConstantValue(name_index, length, file, constant_pool); + case Constants.ATTR_SOURCE_FILE: + return new SourceFile(name_index, length, file, constant_pool); + case Constants.ATTR_CODE: + return new Code(name_index, length, file, constant_pool); + case Constants.ATTR_EXCEPTIONS: + return new ExceptionTable(name_index, length, file, constant_pool); + case Constants.ATTR_LINE_NUMBER_TABLE: + return new LineNumberTable(name_index, length, file, constant_pool); + case Constants.ATTR_LOCAL_VARIABLE_TABLE: + return new LocalVariableTable(name_index, length, file, + constant_pool); + case Constants.ATTR_INNER_CLASSES: + return new InnerClasses(name_index, length, file, constant_pool); + case Constants.ATTR_SYNTHETIC: + return new Synthetic(name_index, length, file, constant_pool); + case Constants.ATTR_DEPRECATED: + return new Deprecated(name_index, length, file, constant_pool); + case Constants.ATTR_PMG: + return new PMGClass(name_index, length, file, constant_pool); + case Constants.ATTR_SIGNATURE: + return new Signature(name_index, length, file, constant_pool); + case Constants.ATTR_STACK_MAP: + return new StackMap(name_index, length, file, constant_pool); + // case Constants.ATTR_RUNTIMEVISIBLE_ANNOTATIONS: + // return new RuntimeVisibleAnnotations(name_index, length, file, + // constant_pool); + // case Constants.ATTR_RUNTIMEINVISIBLE_ANNOTATIONS: + // return new RuntimeInvisibleAnnotations(name_index, length, file, + // constant_pool); + // case Constants.ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS: + // return new RuntimeVisibleParameterAnnotations(name_index, length, + // file, constant_pool); + // case Constants.ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS: + // return new RuntimeInvisibleParameterAnnotations(name_index, + // length, file, constant_pool); + // case Constants.ATTR_ANNOTATION_DEFAULT: + // return new AnnotationDefault(name_index, length, file, + // constant_pool); + default: // Never reached + throw new IllegalStateException("Ooops! default case reached."); + } + } + /** + * @return Length of attribute field in bytes. + */ + public final int getLength() { + return length; + } - /** Add an Attribute reader capable of parsing (user-defined) attributes - * named "name". You should not add readers for the standard attributes - * such as "LineNumberTable", because those are handled internally. - * - * @param name the name of the attribute as stored in the class file - * @param r the reader object - */ - public static void addAttributeReader( String name, AttributeReader r ) { - readers.put(name, r); - } + /** + * @param length + * length in bytes. + */ + public final void setLength(int length) { + this.length = length; + } + /** + * @param name_index + * of attribute. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } - /** Remove attribute reader - * - * @param name the name of the attribute as stored in the class file - */ - public static void removeAttributeReader( String name ) { - readers.remove(name); - } + /** + * @return Name index in constant pool of attribute name. + */ + public final int getNameIndex() { + return name_index; + } + /** + * @return Tag of attribute, i.e., its type. Value may not be altered, thus + * there is no setTag() method. + */ + public final byte getTag() { + return tag; + } - /* Class method reads one attribute from the input data stream. - * This method must not be accessible from the outside. It is - * called by the Field and Method constructor methods. - * - * @see Field - * @see Method - * @param file Input stream - * @param constant_pool Array of constants - * @return Attribute - * @throws IOException - * @throws ClassFormatException - */ - public static final Attribute readAttribute( DataInputStream file, ConstantPool constant_pool ) - throws IOException, ClassFormatException { - ConstantUtf8 c; - String name; - int name_index; - int length; - byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute - // Get class name from constant pool via `name_index' indirection - name_index = file.readUnsignedShort(); - c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8); - name = c.getBytes(); - // Length of data in bytes - length = file.readInt(); - // Compare strings to find known attribute - for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++) { - if (name.equals(Constants.ATTRIBUTE_NAMES[i])) { - tag = i; // found! - break; - } - } - // Call proper constructor, depending on `tag' - switch (tag) { - case Constants.ATTR_UNKNOWN: - AttributeReader r = (AttributeReader) readers.get(name); - if (r != null) { - return r.createAttribute(name_index, length, file, constant_pool); - } - return new Unknown(name_index, length, file, constant_pool); - case Constants.ATTR_CONSTANT_VALUE: - return new ConstantValue(name_index, length, file, constant_pool); - case Constants.ATTR_SOURCE_FILE: - return new SourceFile(name_index, length, file, constant_pool); - case Constants.ATTR_CODE: - return new Code(name_index, length, file, constant_pool); - case Constants.ATTR_EXCEPTIONS: - return new ExceptionTable(name_index, length, file, constant_pool); - case Constants.ATTR_LINE_NUMBER_TABLE: - return new LineNumberTable(name_index, length, file, constant_pool); - case Constants.ATTR_LOCAL_VARIABLE_TABLE: - return new LocalVariableTable(name_index, length, file, constant_pool); - case Constants.ATTR_INNER_CLASSES: - return new InnerClasses(name_index, length, file, constant_pool); - case Constants.ATTR_SYNTHETIC: - return new Synthetic(name_index, length, file, constant_pool); - case Constants.ATTR_DEPRECATED: - return new Deprecated(name_index, length, file, constant_pool); - case Constants.ATTR_PMG: - return new PMGClass(name_index, length, file, constant_pool); - case Constants.ATTR_SIGNATURE: - return new Signature(name_index, length, file, constant_pool); - case Constants.ATTR_STACK_MAP: - return new StackMap(name_index, length, file, constant_pool); - // case Constants.ATTR_RUNTIMEVISIBLE_ANNOTATIONS: - // return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool); - // case Constants.ATTR_RUNTIMEINVISIBLE_ANNOTATIONS: - // return new RuntimeInvisibleAnnotations(name_index, length, file, constant_pool); - // case Constants.ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS: - // return new RuntimeVisibleParameterAnnotations(name_index, length, file, constant_pool); - // case Constants.ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS: - // return new RuntimeInvisibleParameterAnnotations(name_index, length, file, constant_pool); - // case Constants.ATTR_ANNOTATION_DEFAULT: - // return new AnnotationDefault(name_index, length, file, constant_pool); - default: // Never reached - throw new IllegalStateException("Ooops! default case reached."); - } - } + /** + * @return Constant pool used by this object. + * @see ConstantPool + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } + /** + * @param constant_pool + * Constant pool to be used for this object. + * @see ConstantPool + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } - /** - * @return Length of attribute field in bytes. - */ - public final int getLength() { - return length; - } + /** + * Use copy() if you want to have a deep copy(), i.e., with all references + * copied correctly. + * + * @return shallow copy of this attribute + */ + @Override + public Object clone() { + Object o = null; + try { + o = super.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); // Never occurs + } + return o; + } + /** + * @return deep copy of this attribute + */ + public abstract Attribute copy(ConstantPool _constant_pool); - /** - * @param length length in bytes. - */ - public final void setLength( int length ) { - this.length = length; - } - - - /** - * @param name_index of attribute. - */ - public final void setNameIndex( int name_index ) { - this.name_index = name_index; - } - - - /** - * @return Name index in constant pool of attribute name. - */ - public final int getNameIndex() { - return name_index; - } - - - /** - * @return Tag of attribute, i.e., its type. Value may not be altered, thus - * there is no setTag() method. - */ - public final byte getTag() { - return tag; - } - - - /** - * @return Constant pool used by this object. - * @see ConstantPool - */ - public final ConstantPool getConstantPool() { - return constant_pool; - } - - - /** - * @param constant_pool Constant pool to be used for this object. - * @see ConstantPool - */ - public final void setConstantPool( ConstantPool constant_pool ) { - this.constant_pool = constant_pool; - } - - - /** - * Use copy() if you want to have a deep copy(), i.e., with all references - * copied correctly. - * - * @return shallow copy of this attribute - */ - public Object clone() { - Object o = null; - try { - o = super.clone(); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); // Never occurs - } - return o; - } - - - /** - * @return deep copy of this attribute - */ - public abstract Attribute copy( ConstantPool _constant_pool ); - - - /** - * @return attribute name. - */ - public String toString() { - return Constants.ATTRIBUTE_NAMES[tag]; - } + /** + * @return attribute name. + */ + @Override + public String toString() { + return Constants.ATTRIBUTE_NAMES[tag]; + } } diff --git a/src/org/apache/bcel/classfile/AttributeReader.java b/src/org/apache/bcel/classfile/AttributeReader.java index bd6c330..5f0770a 100644 --- a/src/org/apache/bcel/classfile/AttributeReader.java +++ b/src/org/apache/bcel/classfile/AttributeReader.java @@ -18,41 +18,39 @@ package org.apache.bcel.classfile; /** * Unknown (non-standard) attributes may be read via user-defined factory - * objects that can be registered with the Attribute.addAttributeReader - * method. These factory objects should implement this interface. - + * objects that can be registered with the Attribute.addAttributeReader method. + * These factory objects should implement this interface. + * * @see Attribute * @version $Id: AttributeReader.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface AttributeReader { - /** - When this attribute reader is added via the static method - Attribute.addAttributeReader, an attribute name is associated with it. - As the class file parser parses attributes, it will call various - AttributeReaders based on the name of the attributes it is - constructing. - - @param name_index An index into the constant pool, indexing a - ConstantUtf8 that represents the name of the attribute. - - @param length The length of the data contained in the attribute. This - is written into the constant pool and should agree with what the - factory expects the length to be. - - @param file This is the data input stream that the factory needs to read - its data from. - - @param constant_pool This is the constant pool associated with the - Attribute that we are constructing. - - @return The user-defined AttributeReader should take this data and use - it to construct an attribute. In the case of errors, a null can be - returned which will cause the parsing of the class file to fail. - - @see Attribute#addAttributeReader( String, AttributeReader ) - */ - public Attribute createAttribute( int name_index, int length, java.io.DataInputStream file, - ConstantPool constant_pool ); + /** + * When this attribute reader is added via the static method + * Attribute.addAttributeReader, an attribute name is associated with it. As + * the class file parser parses attributes, it will call various + * AttributeReaders based on the name of the attributes it is constructing. + * + * @param name_index + * An index into the constant pool, indexing a ConstantUtf8 that + * represents the name of the attribute. + * @param length + * The length of the data contained in the attribute. This is + * written into the constant pool and should agree with what the + * factory expects the length to be. + * @param file + * This is the data input stream that the factory needs to read + * its data from. + * @param constant_pool + * This is the constant pool associated with the Attribute that + * we are constructing. + * @return The user-defined AttributeReader should take this data and use it + * to construct an attribute. In the case of errors, a null can be + * returned which will cause the parsing of the class file to fail. + * @see Attribute#addAttributeReader(String, AttributeReader ) + */ + public Attribute createAttribute(int name_index, int length, + java.io.DataInputStream file, ConstantPool constant_pool); } diff --git a/src/org/apache/bcel/classfile/ClassFormatException.java b/src/org/apache/bcel/classfile/ClassFormatException.java index 1346419..ddc3fb6 100644 --- a/src/org/apache/bcel/classfile/ClassFormatException.java +++ b/src/org/apache/bcel/classfile/ClassFormatException.java @@ -16,22 +16,25 @@ */ package org.apache.bcel.classfile; -/** - * Thrown when the BCEL attempts to read a class file and determines - * that the file is malformed or otherwise cannot be interpreted as a - * class file. - * +/** + * Thrown when the BCEL attempts to read a class file and determines that the + * file is malformed or otherwise cannot be interpreted as a class file. + * * @version $Id: ClassFormatException.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ClassFormatException extends RuntimeException { - public ClassFormatException() { - super(); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public ClassFormatException() { + super(); + } - public ClassFormatException(String s) { - super(s); - } + public ClassFormatException(String s) { + super(s); + } } diff --git a/src/org/apache/bcel/classfile/ClassParser.java b/src/org/apache/bcel/classfile/ClassParser.java index df11e22..eda99ad 100644 --- a/src/org/apache/bcel/classfile/ClassParser.java +++ b/src/org/apache/bcel/classfile/ClassParser.java @@ -26,270 +26,283 @@ import java.util.zip.ZipFile; import org.apache.bcel.Constants; /** - * Wrapper class that parses a given Java .class file. The method parse returns a - * JavaClass object on success. When an I/O error or an - * inconsistency occurs an appropiate exception is propagated back to - * the caller. - * - * The structure and the names comply, except for a few conveniences, - * exactly with the - * JVM specification 1.0. See this paper for - * further details about the structure of a bytecode file. - * + * Wrapper class that parses a given Java .class file. The method parse returns a JavaClass object + * on success. When an I/O error or an inconsistency occurs an appropiate + * exception is propagated back to the caller. + * + * The structure and the names comply, except for a few conveniences, exactly + * with the JVM specification + * 1.0. See this paper for further details about the structure of a bytecode + * file. + * * @version $Id: ClassParser.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class ClassParser { - private DataInputStream file; - private boolean fileOwned; - private String file_name; - private String zip_file; - private int class_name_index, superclass_name_index; - private int major, minor; // Compiler version - private int access_flags; // Access rights of parsed class - private int[] interfaces; // Names of implemented interfaces - private ConstantPool constant_pool; // collection of constants - private Field[] fields; // class fields, i.e., its variables - private Method[] methods; // methods defined in the class - private Attribute[] attributes; // attributes defined in the class - private boolean is_zip; // Loaded from zip file - private static final int BUFSIZE = 8192; + private DataInputStream file; + private boolean fileOwned; + private String file_name; + private String zip_file; + private int class_name_index, superclass_name_index; + private int major, minor; // Compiler version + private int access_flags; // Access rights of parsed class + private int[] interfaces; // Names of implemented interfaces + private ConstantPool constant_pool; // collection of constants + private Field[] fields; // class fields, i.e., its variables + private Method[] methods; // methods defined in the class + private Attribute[] attributes; // attributes defined in the class + private boolean is_zip; // Loaded from zip file + private static final int BUFSIZE = 8192; + /** + * Parse class from the given stream. + * + * @param file + * Input stream + * @param file_name + * File name + */ + public ClassParser(InputStream file, String file_name) { + this.file_name = file_name; + fileOwned = false; + String clazz = file.getClass().getName(); // Not a very clean solution + // ... + is_zip = clazz.startsWith("java.util.zip.") + || clazz.startsWith("java.util.jar."); + if (file instanceof DataInputStream) { + this.file = (DataInputStream) file; + } else { + this.file = new DataInputStream(new BufferedInputStream(file, + BUFSIZE)); + } + } - /** - * Parse class from the given stream. - * - * @param file Input stream - * @param file_name File name - */ - public ClassParser(InputStream file, String file_name) { - this.file_name = file_name; - fileOwned = false; - String clazz = file.getClass().getName(); // Not a very clean solution ... - is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); - if (file instanceof DataInputStream) { - this.file = (DataInputStream) file; - } else { - this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE)); - } - } + /** + * Parse class from given .class file. + * + * @param file_name + * file name + */ + public ClassParser(String file_name) throws IOException { + is_zip = false; + this.file_name = file_name; + fileOwned = true; + } + /** + * Parse class from given .class file in a ZIP-archive + * + * @param zip_file + * zip file name + * @param file_name + * file name + */ + public ClassParser(String zip_file, String file_name) { + is_zip = true; + fileOwned = true; + this.zip_file = zip_file; + this.file_name = file_name; + } - /** Parse class from given .class file. - * - * @param file_name file name - */ - public ClassParser(String file_name) throws IOException { - is_zip = false; - this.file_name = file_name; - fileOwned = true; - } + /** + * Parse the given Java class file and return an object that represents the + * contained data, i.e., constants, methods, fields and commands. A + * ClassFormatException is raised, if the file is not a valid + * .class file. (This does not include verification of the byte code as it + * is performed by the java interpreter). + * + * @return Class object representing the parsed class file + * @throws IOException + * @throws ClassFormatException + */ + public JavaClass parse() throws IOException, ClassFormatException { + ZipFile zip = null; + try { + if (fileOwned) { + if (is_zip) { + zip = new ZipFile(zip_file); + ZipEntry entry = zip.getEntry(file_name); + file = new DataInputStream(new BufferedInputStream( + zip.getInputStream(entry), BUFSIZE)); + } else { + file = new DataInputStream(new BufferedInputStream( + new FileInputStream(file_name), BUFSIZE)); + } + } + /****************** Read headers ********************************/ + // Check magic tag of class file + readID(); + // Get compiler version + readVersion(); + /****************** Read constant pool and related **************/ + // Read constant pool entries + readConstantPool(); + // Get class information + readClassInfo(); + // Get interface information, i.e., implemented interfaces + readInterfaces(); + /****************** Read class fields and methods ***************/ + // Read class fields, i.e., the variables of the class + readFields(); + // Read class methods, i.e., the functions in the class + readMethods(); + // Read class attributes + readAttributes(); + // Check for unknown variables + // Unknown[] u = Unknown.getUnknownAttributes(); + // for(int i=0; i < u.length; i++) + // System.err.println("WARNING: " + u[i]); + // Everything should have been read now + // if(file.available() > 0) { + // int bytes = file.available(); + // byte[] buf = new byte[bytes]; + // file.read(buf); + // if(!(is_zip && (buf.length == 1))) { + // System.err.println("WARNING: Trailing garbage at end of " + + // file_name); + // System.err.println(bytes + " extra bytes: " + + // Utility.toHexString(buf)); + // } + // } + } finally { + // Read everything of interest, so close the file + if (fileOwned) { + file.close(); + if (zip != null) { + zip.close(); + } + } + } + // Return the information we have gathered in a new object + return new JavaClass(class_name_index, superclass_name_index, + file_name, major, minor, access_flags, constant_pool, + interfaces, fields, methods, attributes, is_zip ? JavaClass.ZIP + : JavaClass.FILE); + } + /** + * Read information about the attributes of the class. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readAttributes() throws IOException, + ClassFormatException { + int attributes_count; + attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + attributes[i] = Attribute.readAttribute(file, constant_pool); + } + } - /** Parse class from given .class file in a ZIP-archive - * - * @param zip_file zip file name - * @param file_name file name - */ - public ClassParser(String zip_file, String file_name) { - is_zip = true; - fileOwned = true; - this.zip_file = zip_file; - this.file_name = file_name; - } + /** + * Read information about the class and its super class. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readClassInfo() throws IOException, ClassFormatException { + access_flags = file.readUnsignedShort(); + /* + * Interfaces are implicitely abstract, the flag should be set according + * to the JVM specification. + */ + if ((access_flags & Constants.ACC_INTERFACE) != 0) { + access_flags |= Constants.ACC_ABSTRACT; + } + if (((access_flags & Constants.ACC_ABSTRACT) != 0) + && ((access_flags & Constants.ACC_FINAL) != 0)) { + throw new ClassFormatException( + "Class can't be both final and abstract"); + } + class_name_index = file.readUnsignedShort(); + superclass_name_index = file.readUnsignedShort(); + } + /** + * Read constant pool entries. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readConstantPool() throws IOException, + ClassFormatException { + constant_pool = new ConstantPool(file); + } - /** - * Parse the given Java class file and return an object that represents - * the contained data, i.e., constants, methods, fields and commands. - * A ClassFormatException is raised, if the file is not a valid - * .class file. (This does not include verification of the byte code as it - * is performed by the java interpreter). - * - * @return Class object representing the parsed class file - * @throws IOException - * @throws ClassFormatException - */ - public JavaClass parse() throws IOException, ClassFormatException { - ZipFile zip = null; - try { - if (fileOwned) { - if (is_zip) { - zip = new ZipFile(zip_file); - ZipEntry entry = zip.getEntry(file_name); - file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), - BUFSIZE)); - } else { - file = new DataInputStream(new BufferedInputStream(new FileInputStream( - file_name), BUFSIZE)); - } - } - /****************** Read headers ********************************/ - // Check magic tag of class file - readID(); - // Get compiler version - readVersion(); - /****************** Read constant pool and related **************/ - // Read constant pool entries - readConstantPool(); - // Get class information - readClassInfo(); - // Get interface information, i.e., implemented interfaces - readInterfaces(); - /****************** Read class fields and methods ***************/ - // Read class fields, i.e., the variables of the class - readFields(); - // Read class methods, i.e., the functions in the class - readMethods(); - // Read class attributes - readAttributes(); - // Check for unknown variables - //Unknown[] u = Unknown.getUnknownAttributes(); - //for(int i=0; i < u.length; i++) - // System.err.println("WARNING: " + u[i]); - // Everything should have been read now - // if(file.available() > 0) { - // int bytes = file.available(); - // byte[] buf = new byte[bytes]; - // file.read(buf); - // if(!(is_zip && (buf.length == 1))) { - // System.err.println("WARNING: Trailing garbage at end of " + file_name); - // System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf)); - // } - // } - } finally { - // Read everything of interest, so close the file - if (fileOwned) { - file.close(); - if (zip != null) { - zip.close(); - } - } - } - // Return the information we have gathered in a new object - return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, - access_flags, constant_pool, interfaces, fields, methods, attributes, is_zip - ? JavaClass.ZIP - : JavaClass.FILE); - } + /** + * Read information about the fields of the class, i.e., its variables. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readFields() throws IOException, ClassFormatException { + int fields_count; + fields_count = file.readUnsignedShort(); + fields = new Field[fields_count]; + for (int i = 0; i < fields_count; i++) { + fields[i] = new Field(file, constant_pool); + } + } + /******************** Private utility methods **********************/ + /** + * Check whether the header of the file is ok. Of course, this has to be the + * first action on successive file reads. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readID() throws IOException, ClassFormatException { + int magic = 0xCAFEBABE; + if (file.readInt() != magic) { + throw new ClassFormatException(file_name + + " is not a Java .class file"); + } + } - /** - * Read information about the attributes of the class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readAttributes() throws IOException, ClassFormatException { - int attributes_count; - attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { - attributes[i] = Attribute.readAttribute(file, constant_pool); - } - } + /** + * Read information about the interfaces implemented by this class. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readInterfaces() throws IOException, + ClassFormatException { + int interfaces_count; + interfaces_count = file.readUnsignedShort(); + interfaces = new int[interfaces_count]; + for (int i = 0; i < interfaces_count; i++) { + interfaces[i] = file.readUnsignedShort(); + } + } + /** + * Read information about the methods of the class. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readMethods() throws IOException, ClassFormatException { + int methods_count; + methods_count = file.readUnsignedShort(); + methods = new Method[methods_count]; + for (int i = 0; i < methods_count; i++) { + methods[i] = new Method(file, constant_pool); + } + } - /** - * Read information about the class and its super class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readClassInfo() throws IOException, ClassFormatException { - access_flags = file.readUnsignedShort(); - /* Interfaces are implicitely abstract, the flag should be set - * according to the JVM specification. - */ - if ((access_flags & Constants.ACC_INTERFACE) != 0) { - access_flags |= Constants.ACC_ABSTRACT; - } - if (((access_flags & Constants.ACC_ABSTRACT) != 0) - && ((access_flags & Constants.ACC_FINAL) != 0)) { - throw new ClassFormatException("Class can't be both final and abstract"); - } - class_name_index = file.readUnsignedShort(); - superclass_name_index = file.readUnsignedShort(); - } - - - /** - * Read constant pool entries. - * @throws IOException - * @throws ClassFormatException - */ - private final void readConstantPool() throws IOException, ClassFormatException { - constant_pool = new ConstantPool(file); - } - - - /** - * Read information about the fields of the class, i.e., its variables. - * @throws IOException - * @throws ClassFormatException - */ - private final void readFields() throws IOException, ClassFormatException { - int fields_count; - fields_count = file.readUnsignedShort(); - fields = new Field[fields_count]; - for (int i = 0; i < fields_count; i++) { - fields[i] = new Field(file, constant_pool); - } - } - - - /******************** Private utility methods **********************/ - /** - * Check whether the header of the file is ok. - * Of course, this has to be the first action on successive file reads. - * @throws IOException - * @throws ClassFormatException - */ - private final void readID() throws IOException, ClassFormatException { - int magic = 0xCAFEBABE; - if (file.readInt() != magic) { - throw new ClassFormatException(file_name + " is not a Java .class file"); - } - } - - - /** - * Read information about the interfaces implemented by this class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readInterfaces() throws IOException, ClassFormatException { - int interfaces_count; - interfaces_count = file.readUnsignedShort(); - interfaces = new int[interfaces_count]; - for (int i = 0; i < interfaces_count; i++) { - interfaces[i] = file.readUnsignedShort(); - } - } - - - /** - * Read information about the methods of the class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readMethods() throws IOException, ClassFormatException { - int methods_count; - methods_count = file.readUnsignedShort(); - methods = new Method[methods_count]; - for (int i = 0; i < methods_count; i++) { - methods[i] = new Method(file, constant_pool); - } - } - - - /** - * Read major and minor version of compiler which created the file. - * @throws IOException - * @throws ClassFormatException - */ - private final void readVersion() throws IOException, ClassFormatException { - minor = file.readUnsignedShort(); - major = file.readUnsignedShort(); - } + /** + * Read major and minor version of compiler which created the file. + * + * @throws IOException + * @throws ClassFormatException + */ + private final void readVersion() throws IOException, ClassFormatException { + minor = file.readUnsignedShort(); + major = file.readUnsignedShort(); + } } diff --git a/src/org/apache/bcel/classfile/Code.java b/src/org/apache/bcel/classfile/Code.java index e1b602e..772fb2b 100644 --- a/src/org/apache/bcel/classfile/Code.java +++ b/src/org/apache/bcel/classfile/Code.java @@ -21,332 +21,351 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class represents a chunk of Java byte code contained in a - * method. It is instantiated by the - * Attribute.readAttribute() method. A Code - * attribute contains informations about operand stack, local - * variables, byte code and the exceptions handled within this - * method. - * +/** + * This class represents a chunk of Java byte code contained in a method. It is + * instantiated by the Attribute.readAttribute() method. A + * Code attribute contains informations about operand stack, local + * variables, byte code and the exceptions handled within this method. + * * This attribute has attributes itself, namely LineNumberTable which - * is used for debugging purposes and LocalVariableTable which - * contains information about the local variables. - * + * is used for debugging purposes and LocalVariableTable which contains + * information about the local variables. + * * @version $Id: Code.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute - * @see CodeException - * @see LineNumberTable + * @author M. Dahm + * @see Attribute + * @see CodeException + * @see LineNumberTable * @see LocalVariableTable */ public final class Code extends Attribute { - private int max_stack; // Maximum size of stack used by this method - private int max_locals; // Number of local variables - private int code_length; // Length of code in bytes - private byte[] code; // Actual byte code - private int exception_table_length; - private CodeException[] exception_table; // Table of handled exceptions - private int attributes_count; // Attributes of code: LineNumber - private Attribute[] attributes; // or LocalVariable + /** + * + */ + private static final long serialVersionUID = 1L; + private int max_stack; // Maximum size of stack used by this method + private int max_locals; // Number of local variables + private int code_length; // Length of code in bytes + private byte[] code; // Actual byte code + private int exception_table_length; + private CodeException[] exception_table; // Table of handled exceptions + private int attributes_count; // Attributes of code: LineNumber + private Attribute[] attributes; // or LocalVariable + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public Code(Code c) { + this(c.getNameIndex(), c.getLength(), c.getMaxStack(), + c.getMaxLocals(), c.getCode(), c.getExceptionTable(), c + .getAttributes(), c.getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public Code(Code c) { - this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), c.getCode(), c - .getExceptionTable(), c.getAttributes(), c.getConstantPool()); - } + /** + * @param name_index + * Index pointing to the name Code + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + */ + Code(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + // Initialize with some default values which will be overwritten later + this(name_index, length, file.readUnsignedShort(), file + .readUnsignedShort(), (byte[]) null, (CodeException[]) null, + (Attribute[]) null, constant_pool); + code_length = file.readInt(); + code = new byte[code_length]; // Read byte code + file.readFully(code); + /* + * Read exception table that contains all regions where an exception + * handler is active, i.e., a try { ... } catch() block. + */ + exception_table_length = file.readUnsignedShort(); + exception_table = new CodeException[exception_table_length]; + for (int i = 0; i < exception_table_length; i++) { + exception_table[i] = new CodeException(file); + } + /* + * Read all attributes, currently `LineNumberTable' and + * `LocalVariableTable' + */ + attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + attributes[i] = Attribute.readAttribute(file, constant_pool); + } + /* + * Adjust length, because of setAttributes in this(), s.b. length is + * incorrect, because it didn't take the internal attributes into + * account yet! Very subtle bug, fixed in 3.1.1. + */ + this.length = length; + } + /** + * @param name_index + * Index pointing to the name Code + * @param length + * Content length in bytes + * @param max_stack + * Maximum size of stack + * @param max_locals + * Number of local variables + * @param code + * Actual byte code + * @param exception_table + * Table of handled exceptions + * @param attributes + * Attributes of code: LineNumber or LocalVariable + * @param constant_pool + * Array of constants + */ + public Code(int name_index, int length, int max_stack, int max_locals, + byte[] code, CodeException[] exception_table, + Attribute[] attributes, ConstantPool constant_pool) { + super(Constants.ATTR_CODE, name_index, length, constant_pool); + this.max_stack = max_stack; + this.max_locals = max_locals; + setCode(code); + setExceptionTable(exception_table); + setAttributes(attributes); // Overwrites length! + } - /** - * @param name_index Index pointing to the name Code - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - */ - Code(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - // Initialize with some default values which will be overwritten later - this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null, - (CodeException[]) null, (Attribute[]) null, constant_pool); - code_length = file.readInt(); - code = new byte[code_length]; // Read byte code - file.readFully(code); - /* Read exception table that contains all regions where an exception - * handler is active, i.e., a try { ... } catch() block. - */ - exception_table_length = file.readUnsignedShort(); - exception_table = new CodeException[exception_table_length]; - for (int i = 0; i < exception_table_length; i++) { - exception_table[i] = new CodeException(file); - } - /* Read all attributes, currently `LineNumberTable' and - * `LocalVariableTable' - */ - attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { - attributes[i] = Attribute.readAttribute(file, constant_pool); - } - /* Adjust length, because of setAttributes in this(), s.b. length - * is incorrect, because it didn't take the internal attributes - * into account yet! Very subtle bug, fixed in 3.1.1. - */ - this.length = length; - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitCode(this); + } + /** + * Dump code attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(max_stack); + file.writeShort(max_locals); + file.writeInt(code_length); + file.write(code, 0, code_length); + file.writeShort(exception_table_length); + for (int i = 0; i < exception_table_length; i++) { + exception_table[i].dump(file); + } + file.writeShort(attributes_count); + for (int i = 0; i < attributes_count; i++) { + attributes[i].dump(file); + } + } - /** - * @param name_index Index pointing to the name Code - * @param length Content length in bytes - * @param max_stack Maximum size of stack - * @param max_locals Number of local variables - * @param code Actual byte code - * @param exception_table Table of handled exceptions - * @param attributes Attributes of code: LineNumber or LocalVariable - * @param constant_pool Array of constants - */ - public Code(int name_index, int length, int max_stack, int max_locals, byte[] code, - CodeException[] exception_table, Attribute[] attributes, ConstantPool constant_pool) { - super(Constants.ATTR_CODE, name_index, length, constant_pool); - this.max_stack = max_stack; - this.max_locals = max_locals; - setCode(code); - setExceptionTable(exception_table); - setAttributes(attributes); // Overwrites length! - } + /** + * @return Collection of code attributes. + * @see Attribute + */ + public final Attribute[] getAttributes() { + return attributes; + } + /** + * @return LineNumberTable of Code, if it has one + */ + public LineNumberTable getLineNumberTable() { + for (int i = 0; i < attributes_count; i++) { + if (attributes[i] instanceof LineNumberTable) { + return (LineNumberTable) attributes[i]; + } + } + return null; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitCode(this); - } + /** + * @return LocalVariableTable of Code, if it has one + */ + public LocalVariableTable getLocalVariableTable() { + for (int i = 0; i < attributes_count; i++) { + if (attributes[i] instanceof LocalVariableTable) { + return (LocalVariableTable) attributes[i]; + } + } + return null; + } + /** + * @return Actual byte code of the method. + */ + public final byte[] getCode() { + return code; + } - /** - * Dump code attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(max_stack); - file.writeShort(max_locals); - file.writeInt(code_length); - file.write(code, 0, code_length); - file.writeShort(exception_table_length); - for (int i = 0; i < exception_table_length; i++) { - exception_table[i].dump(file); - } - file.writeShort(attributes_count); - for (int i = 0; i < attributes_count; i++) { - attributes[i].dump(file); - } - } + /** + * @return Table of handled exceptions. + * @see CodeException + */ + public final CodeException[] getExceptionTable() { + return exception_table; + } + /** + * @return Number of local variables. + */ + public final int getMaxLocals() { + return max_locals; + } - /** - * @return Collection of code attributes. - * @see Attribute - */ - public final Attribute[] getAttributes() { - return attributes; - } + /** + * @return Maximum size of stack used by this method. + */ + public final int getMaxStack() { + return max_stack; + } + /** + * @return the internal length of this code attribute (minus the first 6 + * bytes) and excluding all its attributes + */ + private final int getInternalLength() { + return 2 /* max_stack */+ 2 /* max_locals */+ 4 /* code length */ + + code_length /* byte-code */ + + 2 /* exception-table length */ + + 8 * exception_table_length /* exception table */ + + 2 /* attributes count */; + } - /** - * @return LineNumberTable of Code, if it has one - */ - public LineNumberTable getLineNumberTable() { - for (int i = 0; i < attributes_count; i++) { - if (attributes[i] instanceof LineNumberTable) { - return (LineNumberTable) attributes[i]; - } - } - return null; - } + /** + * @return the full size of this code attribute, minus its first 6 bytes, + * including the size of all its contained attributes + */ + private final int calculateLength() { + int len = 0; + for (int i = 0; i < attributes_count; i++) { + len += attributes[i].length + 6 /* attribute header size */; + } + return len + getInternalLength(); + } + /** + * @param attributes + * the attributes to set for this Code + */ + public final void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + attributes_count = (attributes == null) ? 0 : attributes.length; + length = calculateLength(); // Adjust length + } - /** - * @return LocalVariableTable of Code, if it has one - */ - public LocalVariableTable getLocalVariableTable() { - for (int i = 0; i < attributes_count; i++) { - if (attributes[i] instanceof LocalVariableTable) { - return (LocalVariableTable) attributes[i]; - } - } - return null; - } + /** + * @param code + * byte code + */ + public final void setCode(byte[] code) { + this.code = code; + code_length = (code == null) ? 0 : code.length; + } + /** + * @param exception_table + * exception table + */ + public final void setExceptionTable(CodeException[] exception_table) { + this.exception_table = exception_table; + exception_table_length = (exception_table == null) ? 0 + : exception_table.length; + } - /** - * @return Actual byte code of the method. - */ - public final byte[] getCode() { - return code; - } + /** + * @param max_locals + * maximum number of local variables + */ + public final void setMaxLocals(int max_locals) { + this.max_locals = max_locals; + } + /** + * @param max_stack + * maximum stack size + */ + public final void setMaxStack(int max_stack) { + this.max_stack = max_stack; + } - /** - * @return Table of handled exceptions. - * @see CodeException - */ - public final CodeException[] getExceptionTable() { - return exception_table; - } + /** + * @return String representation of code chunk. + */ + public final String toString(boolean verbose) { + StringBuffer buf; + buf = new StringBuffer(100); + buf.append("Code(max_stack = ") + .append(max_stack) + .append(", max_locals = ") + .append(max_locals) + .append(", code_length = ") + .append(code_length) + .append(")\n") + .append(Utility.codeToString(code, constant_pool, 0, -1, + verbose)); + if (exception_table_length > 0) { + buf.append("\nException handler(s) = \n").append( + "From\tTo\tHandler\tType\n"); + for (int i = 0; i < exception_table_length; i++) { + buf.append(exception_table[i].toString(constant_pool, verbose)) + .append("\n"); + } + } + if (attributes_count > 0) { + buf.append("\nAttribute(s) = \n"); + for (int i = 0; i < attributes_count; i++) { + buf.append(attributes[i].toString()).append("\n"); + } + } + return buf.toString(); + } + /** + * @return String representation of code chunk. + */ + @Override + public final String toString() { + return toString(true); + } - /** - * @return Number of local variables. - */ - public final int getMaxLocals() { - return max_locals; - } - - - /** - * @return Maximum size of stack used by this method. - */ - public final int getMaxStack() { - return max_stack; - } - - - /** - * @return the internal length of this code attribute (minus the first 6 bytes) - * and excluding all its attributes - */ - private final int getInternalLength() { - return 2 /*max_stack*/+ 2 /*max_locals*/+ 4 /*code length*/ - + code_length /*byte-code*/ - + 2 /*exception-table length*/ - + 8 * exception_table_length /* exception table */ - + 2 /* attributes count */; - } - - - /** - * @return the full size of this code attribute, minus its first 6 bytes, - * including the size of all its contained attributes - */ - private final int calculateLength() { - int len = 0; - for (int i = 0; i < attributes_count; i++) { - len += attributes[i].length + 6 /*attribute header size*/; - } - return len + getInternalLength(); - } - - - /** - * @param attributes the attributes to set for this Code - */ - public final void setAttributes( Attribute[] attributes ) { - this.attributes = attributes; - attributes_count = (attributes == null) ? 0 : attributes.length; - length = calculateLength(); // Adjust length - } - - - /** - * @param code byte code - */ - public final void setCode( byte[] code ) { - this.code = code; - code_length = (code == null) ? 0 : code.length; - } - - - /** - * @param exception_table exception table - */ - public final void setExceptionTable( CodeException[] exception_table ) { - this.exception_table = exception_table; - exception_table_length = (exception_table == null) ? 0 : exception_table.length; - } - - - /** - * @param max_locals maximum number of local variables - */ - public final void setMaxLocals( int max_locals ) { - this.max_locals = max_locals; - } - - - /** - * @param max_stack maximum stack size - */ - public final void setMaxStack( int max_stack ) { - this.max_stack = max_stack; - } - - - /** - * @return String representation of code chunk. - */ - public final String toString( boolean verbose ) { - StringBuffer buf; - buf = new StringBuffer(100); - buf.append("Code(max_stack = ").append(max_stack).append(", max_locals = ").append( - max_locals).append(", code_length = ").append(code_length).append(")\n").append( - Utility.codeToString(code, constant_pool, 0, -1, verbose)); - if (exception_table_length > 0) { - buf.append("\nException handler(s) = \n").append("From\tTo\tHandler\tType\n"); - for (int i = 0; i < exception_table_length; i++) { - buf.append(exception_table[i].toString(constant_pool, verbose)).append("\n"); - } - } - if (attributes_count > 0) { - buf.append("\nAttribute(s) = \n"); - for (int i = 0; i < attributes_count; i++) { - buf.append(attributes[i].toString()).append("\n"); - } - } - return buf.toString(); - } - - - /** - * @return String representation of code chunk. - */ - public final String toString() { - return toString(true); - } - - - /** - * @return deep copy of this attribute - * - * @param _constant_pool the constant pool to duplicate - */ - public Attribute copy( ConstantPool _constant_pool ) { - Code c = (Code) clone(); - if (code != null) { - c.code = new byte[code.length]; - System.arraycopy(code, 0, c.code, 0, code.length); - } - c.constant_pool = _constant_pool; - c.exception_table = new CodeException[exception_table_length]; - for (int i = 0; i < exception_table_length; i++) { - c.exception_table[i] = exception_table[i].copy(); - } - c.attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { - c.attributes[i] = attributes[i].copy(_constant_pool); - } - return c; - } + /** + * @return deep copy of this attribute + * + * @param _constant_pool + * the constant pool to duplicate + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + Code c = (Code) clone(); + if (code != null) { + c.code = new byte[code.length]; + System.arraycopy(code, 0, c.code, 0, code.length); + } + c.constant_pool = _constant_pool; + c.exception_table = new CodeException[exception_table_length]; + for (int i = 0; i < exception_table_length; i++) { + c.exception_table[i] = exception_table[i].copy(); + } + c.attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + c.attributes[i] = attributes[i].copy(_constant_pool); + } + return c; + } } diff --git a/src/org/apache/bcel/classfile/CodeException.java b/src/org/apache/bcel/classfile/CodeException.java index 1324450..c4a5f2f 100644 --- a/src/org/apache/bcel/classfile/CodeException.java +++ b/src/org/apache/bcel/classfile/CodeException.java @@ -24,191 +24,197 @@ import org.apache.bcel.Constants; /** * This class represents an entry in the exception table of the Code - * attribute and is used only there. It contains a range in which a - * particular exception handler is active. - * + * attribute and is used only there. It contains a range in which a particular + * exception handler is active. + * * @version $Id: CodeException.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Code + * @author M. Dahm + * @see Code */ -public final class CodeException implements Cloneable, Constants, Node, Serializable { +public final class CodeException implements Cloneable, Constants, Node, + Serializable { - private int start_pc; // Range in the code the exception handler is - private int end_pc; // active. start_pc is inclusive, end_pc exclusive - private int handler_pc; /* Starting address of exception handler, i.e., - * an offset from start of code. - */ - private int catch_type; /* If this is zero the handler catches any - * exception, otherwise it points to the - * exception class which is to be caught. - */ + /** + * + */ + private static final long serialVersionUID = 1L; + private int start_pc; // Range in the code the exception handler is + private int end_pc; // active. start_pc is inclusive, end_pc exclusive + private int handler_pc; /* + * Starting address of exception handler, i.e., an + * offset from start of code. + */ + private int catch_type; /* + * If this is zero the handler catches any + * exception, otherwise it points to the exception + * class which is to be caught. + */ + /** + * Initialize from another object. + */ + public CodeException(CodeException c) { + this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); + } - /** - * Initialize from another object. - */ - public CodeException(CodeException c) { - this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); - } + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + */ + CodeException(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort(), file.readUnsignedShort()); + } + /** + * @param start_pc + * Range in the code the exception handler is active, start_pc is + * inclusive while + * @param end_pc + * is exclusive + * @param handler_pc + * Starting address of exception handler, i.e., an offset from + * start of code. + * @param catch_type + * If zero the handler catches any exception, otherwise it points + * to the exception class which is to be caught. + */ + public CodeException(int start_pc, int end_pc, int handler_pc, + int catch_type) { + this.start_pc = start_pc; + this.end_pc = end_pc; + this.handler_pc = handler_pc; + this.catch_type = catch_type; + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - CodeException(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file - .readUnsignedShort()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitCodeException(this); + } + /** + * Dump code exception to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(start_pc); + file.writeShort(end_pc); + file.writeShort(handler_pc); + file.writeShort(catch_type); + } - /** - * @param start_pc Range in the code the exception handler is active, - * start_pc is inclusive while - * @param end_pc is exclusive - * @param handler_pc Starting address of exception handler, i.e., - * an offset from start of code. - * @param catch_type If zero the handler catches any - * exception, otherwise it points to the exception class which is - * to be caught. - */ - public CodeException(int start_pc, int end_pc, int handler_pc, int catch_type) { - this.start_pc = start_pc; - this.end_pc = end_pc; - this.handler_pc = handler_pc; - this.catch_type = catch_type; - } + /** + * @return 0, if the handler catches any exception, otherwise it points to + * the exception class which is to be caught. + */ + public final int getCatchType() { + return catch_type; + } + /** + * @return Exclusive end index of the region where the handler is active. + */ + public final int getEndPC() { + return end_pc; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitCodeException(this); - } + /** + * @return Starting address of exception handler, relative to the code. + */ + public final int getHandlerPC() { + return handler_pc; + } + /** + * @return Inclusive start index of the region where the handler is active. + */ + public final int getStartPC() { + return start_pc; + } - /** - * Dump code exception to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeShort(start_pc); - file.writeShort(end_pc); - file.writeShort(handler_pc); - file.writeShort(catch_type); - } + /** + * @param catch_type + * the type of exception that is caught + */ + public final void setCatchType(int catch_type) { + this.catch_type = catch_type; + } + /** + * @param end_pc + * end of handled block + */ + public final void setEndPC(int end_pc) { + this.end_pc = end_pc; + } - /** - * @return 0, if the handler catches any exception, otherwise it points to - * the exception class which is to be caught. - */ - public final int getCatchType() { - return catch_type; - } + /** + * @param handler_pc + * where the actual code is + */ + public final void setHandlerPC(int handler_pc) { + this.handler_pc = handler_pc; + } + /** + * @param start_pc + * start of handled block + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } - /** - * @return Exclusive end index of the region where the handler is active. - */ - public final int getEndPC() { - return end_pc; - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + + ", handler_pc = " + handler_pc + ", catch_type = " + + catch_type + ")"; + } + /** + * @return String representation. + */ + public final String toString(ConstantPool cp, boolean verbose) { + String str; + if (catch_type == 0) { + str = "(0)"; + } else { + str = Utility.compactClassName( + cp.getConstantString(catch_type, CONSTANT_Class), false) + + (verbose ? "(" + catch_type + ")" : ""); + } + return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; + } - /** - * @return Starting address of exception handler, relative to the code. - */ - public final int getHandlerPC() { - return handler_pc; - } + public final String toString(ConstantPool cp) { + return toString(cp, true); + } - - /** - * @return Inclusive start index of the region where the handler is active. - */ - public final int getStartPC() { - return start_pc; - } - - - /** - * @param catch_type the type of exception that is caught - */ - public final void setCatchType( int catch_type ) { - this.catch_type = catch_type; - } - - - /** - * @param end_pc end of handled block - */ - public final void setEndPC( int end_pc ) { - this.end_pc = end_pc; - } - - - /** - * @param handler_pc where the actual code is - */ - public final void setHandlerPC( int handler_pc ) { - this.handler_pc = handler_pc; - } - - - /** - * @param start_pc start of handled block - */ - public final void setStartPC( int start_pc ) { - this.start_pc = start_pc; - } - - - /** - * @return String representation. - */ - public final String toString() { - return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = " - + handler_pc + ", catch_type = " + catch_type + ")"; - } - - - /** - * @return String representation. - */ - public final String toString( ConstantPool cp, boolean verbose ) { - String str; - if (catch_type == 0) { - str = "(0)"; - } else { - str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false) - + (verbose ? "(" + catch_type + ")" : ""); - } - return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; - } - - - public final String toString( ConstantPool cp ) { - return toString(cp, true); - } - - - /** - * @return deep copy of this object - */ - public CodeException copy() { - try { - return (CodeException) clone(); - } catch (CloneNotSupportedException e) { - } - return null; - } + /** + * @return deep copy of this object + */ + public CodeException copy() { + try { + return (CodeException) clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } } diff --git a/src/org/apache/bcel/classfile/Constant.java b/src/org/apache/bcel/classfile/Constant.java index 5b0dda6..f2343a8 100644 --- a/src/org/apache/bcel/classfile/Constant.java +++ b/src/org/apache/bcel/classfile/Constant.java @@ -24,165 +24,168 @@ import org.apache.bcel.Constants; import org.apache.bcel.util.BCELComparator; /** - * Abstract superclass for classes to represent the different constant types - * in the constant pool of a class file. The classes keep closely to - * the JVM specification. - * + * Abstract superclass for classes to represent the different constant types in + * the constant pool of a class file. The classes keep closely to the JVM + * specification. + * * @version $Id: Constant.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class Constant implements Cloneable, Node, Serializable { - private static BCELComparator _cmp = new BCELComparator() { + /** + * + */ + private static final long serialVersionUID = 1L; + private static BCELComparator _cmp = new BCELComparator() { - public boolean equals( Object o1, Object o2 ) { - Constant THIS = (Constant) o1; - Constant THAT = (Constant) o2; - return THIS.toString().equals(THAT.toString()); - } + @Override + public boolean equals(Object o1, Object o2) { + Constant THIS = (Constant) o1; + Constant THAT = (Constant) o2; + return THIS.toString().equals(THAT.toString()); + } + @Override + public int hashCode(Object o) { + Constant THIS = (Constant) o; + return THIS.toString().hashCode(); + } + }; + /* + * In fact this tag is redundant since we can distinguish different + * `Constant' objects by their type, i.e., via `instanceof'. In some places + * we will use the tag for switch()es anyway. + * + * First, we want match the specification as closely as possible. Second we + * need the tag as an index to select the corresponding class name from the + * `CONSTANT_NAMES' array. + */ + protected byte tag; - public int hashCode( Object o ) { - Constant THIS = (Constant) o; - return THIS.toString().hashCode(); - } - }; - /* In fact this tag is redundant since we can distinguish different - * `Constant' objects by their type, i.e., via `instanceof'. In some - * places we will use the tag for switch()es anyway. - * - * First, we want match the specification as closely as possible. Second we - * need the tag as an index to select the corresponding class name from the - * `CONSTANT_NAMES' array. - */ - protected byte tag; + Constant(byte tag) { + this.tag = tag; + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public abstract void accept(Visitor v); - Constant(byte tag) { - this.tag = tag; - } + public abstract void dump(DataOutputStream file) throws IOException; + /** + * @return Tag of constant, i.e., its type. No setTag() method to avoid + * confusion. + */ + public final byte getTag() { + return tag; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public abstract void accept( Visitor v ); + /** + * @return String representation. + */ + @Override + public String toString() { + return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; + } + /** + * @return deep copy of this constant + */ + public Constant copy() { + try { + return (Constant) super.clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } - public abstract void dump( DataOutputStream file ) throws IOException; + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + /** + * Read one constant from the given file, the type depends on a tag byte. + * + * @param file + * Input stream + * @return Constant object + */ + static final Constant readConstant(DataInputStream file) + throws IOException, ClassFormatException { + byte b = file.readByte(); // Read tag byte + switch (b) { + case Constants.CONSTANT_Class: + return new ConstantClass(file); + case Constants.CONSTANT_Fieldref: + return new ConstantFieldref(file); + case Constants.CONSTANT_Methodref: + return new ConstantMethodref(file); + case Constants.CONSTANT_InterfaceMethodref: + return new ConstantInterfaceMethodref(file); + case Constants.CONSTANT_String: + return new ConstantString(file); + case Constants.CONSTANT_Integer: + return new ConstantInteger(file); + case Constants.CONSTANT_Float: + return new ConstantFloat(file); + case Constants.CONSTANT_Long: + return new ConstantLong(file); + case Constants.CONSTANT_Double: + return new ConstantDouble(file); + case Constants.CONSTANT_NameAndType: + return new ConstantNameAndType(file); + case Constants.CONSTANT_Utf8: + return new ConstantUtf8(file); + default: + throw new ClassFormatException( + "Invalid byte tag in constant pool: " + b); + } + } - /** - * @return Tag of constant, i.e., its type. No setTag() method to avoid - * confusion. - */ - public final byte getTag() { - return tag; - } + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + /** + * @param comparator + * Comparison strategy object + */ + public static void setComparator(BCELComparator comparator) { + _cmp = comparator; + } - /** - * @return String representation. - */ - public String toString() { - return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; - } + /** + * Return value as defined by given BCELComparator strategy. By default two + * Constant objects are said to be equal when the result of toString() is + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return _cmp.equals(this, obj); + } - - /** - * @return deep copy of this constant - */ - public Constant copy() { - try { - return (Constant) super.clone(); - } catch (CloneNotSupportedException e) { - } - return null; - } - - - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - - - /** - * Read one constant from the given file, the type depends on a tag byte. - * - * @param file Input stream - * @return Constant object - */ - static final Constant readConstant( DataInputStream file ) throws IOException, - ClassFormatException { - byte b = file.readByte(); // Read tag byte - switch (b) { - case Constants.CONSTANT_Class: - return new ConstantClass(file); - case Constants.CONSTANT_Fieldref: - return new ConstantFieldref(file); - case Constants.CONSTANT_Methodref: - return new ConstantMethodref(file); - case Constants.CONSTANT_InterfaceMethodref: - return new ConstantInterfaceMethodref(file); - case Constants.CONSTANT_String: - return new ConstantString(file); - case Constants.CONSTANT_Integer: - return new ConstantInteger(file); - case Constants.CONSTANT_Float: - return new ConstantFloat(file); - case Constants.CONSTANT_Long: - return new ConstantLong(file); - case Constants.CONSTANT_Double: - return new ConstantDouble(file); - case Constants.CONSTANT_NameAndType: - return new ConstantNameAndType(file); - case Constants.CONSTANT_Utf8: - return new ConstantUtf8(file); - default: - throw new ClassFormatException("Invalid byte tag in constant pool: " + b); - } - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return _cmp; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( BCELComparator comparator ) { - _cmp = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two Constant objects are said to be equal when - * the result of toString() is equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals( Object obj ) { - return _cmp.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the result of toString(). - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return _cmp.hashCode(this); - } + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the result of toString(). + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); + } } diff --git a/src/org/apache/bcel/classfile/ConstantCP.java b/src/org/apache/bcel/classfile/ConstantCP.java index 9f3377a..cfe7408 100644 --- a/src/org/apache/bcel/classfile/ConstantCP.java +++ b/src/org/apache/bcel/classfile/ConstantCP.java @@ -21,111 +21,115 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** +/** * Abstract super class for Fieldref and Methodref constants. - * + * * @version $Id: ConstantCP.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see ConstantFieldref - * @see ConstantMethodref - * @see ConstantInterfaceMethodref + * @author M. Dahm + * @see ConstantFieldref + * @see ConstantMethodref + * @see ConstantInterfaceMethodref */ public abstract class ConstantCP extends Constant { - /** References to the constants containing the class and the field signature - */ - protected int class_index, name_and_type_index; + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * References to the constants containing the class and the field signature + */ + protected int class_index, name_and_type_index; + /** + * Initialize from another object. + */ + public ConstantCP(ConstantCP c) { + this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); + } - /** - * Initialize from another object. - */ - public ConstantCP(ConstantCP c) { - this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); - } + /** + * Initialize instance from file data. + * + * @param tag + * Constant type tag + * @param file + * Input stream + * @throws IOException + */ + ConstantCP(byte tag, DataInputStream file) throws IOException { + this(tag, file.readUnsignedShort(), file.readUnsignedShort()); + } + /** + * @param class_index + * Reference to the class containing the field + * @param name_and_type_index + * and the field signature + */ + protected ConstantCP(byte tag, int class_index, int name_and_type_index) { + super(tag); + this.class_index = class_index; + this.name_and_type_index = name_and_type_index; + } - /** - * Initialize instance from file data. - * - * @param tag Constant type tag - * @param file Input stream - * @throws IOException - */ - ConstantCP(byte tag, DataInputStream file) throws IOException { - this(tag, file.readUnsignedShort(), file.readUnsignedShort()); - } + /** + * Dump constant field reference to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(class_index); + file.writeShort(name_and_type_index); + } + /** + * @return Reference (index) to class this field or method belongs to. + */ + public final int getClassIndex() { + return class_index; + } - /** - * @param class_index Reference to the class containing the field - * @param name_and_type_index and the field signature - */ - protected ConstantCP(byte tag, int class_index, int name_and_type_index) { - super(tag); - this.class_index = class_index; - this.name_and_type_index = name_and_type_index; - } + /** + * @return Reference (index) to signature of the field. + */ + public final int getNameAndTypeIndex() { + return name_and_type_index; + } + /** + * @param class_index + * points to Constant_class + */ + public final void setClassIndex(int class_index) { + this.class_index = class_index; + } - /** - * Dump constant field reference to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeShort(class_index); - file.writeShort(name_and_type_index); - } + /** + * @return Class this field belongs to. + */ + public String getClass(ConstantPool cp) { + return cp.constantToString(class_index, Constants.CONSTANT_Class); + } + /** + * @param name_and_type_index + * points to Constant_NameAndType + */ + public final void setNameAndTypeIndex(int name_and_type_index) { + this.name_and_type_index = name_and_type_index; + } - /** - * @return Reference (index) to class this field or method belongs to. - */ - public final int getClassIndex() { - return class_index; - } - - - /** - * @return Reference (index) to signature of the field. - */ - public final int getNameAndTypeIndex() { - return name_and_type_index; - } - - - /** - * @param class_index points to Constant_class - */ - public final void setClassIndex( int class_index ) { - this.class_index = class_index; - } - - - /** - * @return Class this field belongs to. - */ - public String getClass( ConstantPool cp ) { - return cp.constantToString(class_index, Constants.CONSTANT_Class); - } - - - /** - * @param name_and_type_index points to Constant_NameAndType - */ - public final void setNameAndTypeIndex( int name_and_type_index ) { - this.name_and_type_index = name_and_type_index; - } - - - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(class_index = " + class_index + ", name_and_type_index = " - + name_and_type_index + ")"; - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(class_index = " + class_index + + ", name_and_type_index = " + name_and_type_index + ")"; + } } diff --git a/src/org/apache/bcel/classfile/ConstantClass.java b/src/org/apache/bcel/classfile/ConstantClass.java index adddf3c..32d47e7 100644 --- a/src/org/apache/bcel/classfile/ConstantClass.java +++ b/src/org/apache/bcel/classfile/ConstantClass.java @@ -21,108 +21,112 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to a (external) class. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to a (external) class. + * * @version $Id: ConstantClass.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantClass extends Constant implements ConstantObject { - private int name_index; // Identical to ConstantString except for the name + /** + * + */ + private static final long serialVersionUID = 1L; + private int name_index; // Identical to ConstantString except for the name + /** + * Initialize from another object. + */ + public ConstantClass(ConstantClass c) { + this(c.getNameIndex()); + } - /** - * Initialize from another object. - */ - public ConstantClass(ConstantClass c) { - this(c.getNameIndex()); - } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantClass(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + /** + * @param name_index + * Name index in constant pool. Should refer to a ConstantUtf8. + */ + public ConstantClass(int name_index) { + super(Constants.CONSTANT_Class); + this.name_index = name_index; + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantClass(DataInputStream file) throws IOException { - this(file.readUnsignedShort()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantClass(this); + } + /** + * Dump constant class to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(name_index); + } - /** - * @param name_index Name index in constant pool. Should refer to a - * ConstantUtf8. - */ - public ConstantClass(int name_index) { - super(Constants.CONSTANT_Class); - this.name_index = name_index; - } + /** + * @return Name index in constant pool of class name. + */ + public final int getNameIndex() { + return name_index; + } + /** + * @param name_index + * the name index in the constant pool of this Constant Class + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantClass(this); - } + /** + * @return String object + */ + @Override + public Object getConstantValue(ConstantPool cp) { + Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getBytes(); + } + /** + * @return dereferenced string + */ + public String getBytes(ConstantPool cp) { + return (String) getConstantValue(cp); + } - /** - * Dump constant class to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeShort(name_index); - } - - - /** - * @return Name index in constant pool of class name. - */ - public final int getNameIndex() { - return name_index; - } - - - /** - * @param name_index the name index in the constant pool of this Constant Class - */ - public final void setNameIndex( int name_index ) { - this.name_index = name_index; - } - - - /** @return String object - */ - public Object getConstantValue( ConstantPool cp ) { - Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); - } - - - /** @return dereferenced string - */ - public String getBytes( ConstantPool cp ) { - return (String) getConstantValue(cp); - } - - - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(name_index = " + name_index + ")"; - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(name_index = " + name_index + ")"; + } } diff --git a/src/org/apache/bcel/classfile/ConstantDouble.java b/src/org/apache/bcel/classfile/ConstantDouble.java index 80e96e4..7874b49 100644 --- a/src/org/apache/bcel/classfile/ConstantDouble.java +++ b/src/org/apache/bcel/classfile/ConstantDouble.java @@ -21,99 +21,104 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to a Double object. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to a Double object. + * * @version $Id: ConstantDouble.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantDouble extends Constant implements ConstantObject { - private double bytes; + /** + * + */ + private static final long serialVersionUID = 1L; + private double bytes; + /** + * @param bytes + * Data + */ + public ConstantDouble(double bytes) { + super(Constants.CONSTANT_Double); + this.bytes = bytes; + } - /** - * @param bytes Data - */ - public ConstantDouble(double bytes) { - super(Constants.CONSTANT_Double); - this.bytes = bytes; - } + /** + * Initialize from another object. + */ + public ConstantDouble(ConstantDouble c) { + this(c.getBytes()); + } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantDouble(DataInputStream file) throws IOException { + this(file.readDouble()); + } - /** - * Initialize from another object. - */ - public ConstantDouble(ConstantDouble c) { - this(c.getBytes()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantDouble(this); + } + /** + * Dump constant double to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeDouble(bytes); + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantDouble(DataInputStream file) throws IOException { - this(file.readDouble()); - } + /** + * @return data, i.e., 8 bytes. + */ + public final double getBytes() { + return bytes; + } + /** + * @param bytes + * the raw bytes that represent the double value + */ + public final void setBytes(double bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantDouble(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } - - /** - * Dump constant double to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeDouble(bytes); - } - - - /** - * @return data, i.e., 8 bytes. - */ - public final double getBytes() { - return bytes; - } - - - /** - * @param bytes the raw bytes that represent the double value - */ - public final void setBytes( double bytes ) { - this.bytes = bytes; - } - - - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(bytes = " + bytes + ")"; - } - - - /** @return Double object - */ - public Object getConstantValue( ConstantPool cp ) { - return new Double(bytes); - } + /** + * @return Double object + */ + @Override + public Object getConstantValue(ConstantPool cp) { + return new Double(bytes); + } } diff --git a/src/org/apache/bcel/classfile/ConstantFieldref.java b/src/org/apache/bcel/classfile/ConstantFieldref.java index 71df99c..333c080 100644 --- a/src/org/apache/bcel/classfile/ConstantFieldref.java +++ b/src/org/apache/bcel/classfile/ConstantFieldref.java @@ -20,50 +20,58 @@ import java.io.DataInputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** +/** * This class represents a constant pool reference to a field. - * + * * @version $Id: ConstantFieldref.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class ConstantFieldref extends ConstantCP { - /** - * Initialize from another object. - */ - public ConstantFieldref(ConstantFieldref c) { - super(Constants.CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex()); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Initialize from another object. + */ + public ConstantFieldref(ConstantFieldref c) { + super(Constants.CONSTANT_Fieldref, c.getClassIndex(), c + .getNameAndTypeIndex()); + } - /** - * Initialize instance from file data. - * - * @param file input stream - * @throws IOException - */ - ConstantFieldref(DataInputStream file) throws IOException { - super(Constants.CONSTANT_Fieldref, file); - } + /** + * Initialize instance from file data. + * + * @param file + * input stream + * @throws IOException + */ + ConstantFieldref(DataInputStream file) throws IOException { + super(Constants.CONSTANT_Fieldref, file); + } + /** + * @param class_index + * Reference to the class containing the Field + * @param name_and_type_index + * and the Field signature + */ + public ConstantFieldref(int class_index, int name_and_type_index) { + super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index); + } - /** - * @param class_index Reference to the class containing the Field - * @param name_and_type_index and the Field signature - */ - public ConstantFieldref(int class_index, int name_and_type_index) { - super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index); - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of Fields, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantFieldref(this); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of Fields, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantFieldref(this); + } } diff --git a/src/org/apache/bcel/classfile/ConstantFloat.java b/src/org/apache/bcel/classfile/ConstantFloat.java index 8c18fef..0f94c96 100644 --- a/src/org/apache/bcel/classfile/ConstantFloat.java +++ b/src/org/apache/bcel/classfile/ConstantFloat.java @@ -21,100 +21,105 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to a float object. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to a float object. + * * @version $Id: ConstantFloat.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantFloat extends Constant implements ConstantObject { - private float bytes; + /** + * + */ + private static final long serialVersionUID = 1L; + private float bytes; + /** + * @param bytes + * Data + */ + public ConstantFloat(float bytes) { + super(Constants.CONSTANT_Float); + this.bytes = bytes; + } - /** - * @param bytes Data - */ - public ConstantFloat(float bytes) { - super(Constants.CONSTANT_Float); - this.bytes = bytes; - } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public ConstantFloat(ConstantFloat c) { + this(c.getBytes()); + } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantFloat(DataInputStream file) throws IOException { + this(file.readFloat()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public ConstantFloat(ConstantFloat c) { - this(c.getBytes()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantFloat(this); + } + /** + * Dump constant float to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeFloat(bytes); + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantFloat(DataInputStream file) throws IOException { - this(file.readFloat()); - } + /** + * @return data, i.e., 4 bytes. + */ + public final float getBytes() { + return bytes; + } + /** + * @param bytes + * the raw bytes that represent this float + */ + public final void setBytes(float bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantFloat(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } - - /** - * Dump constant float to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeFloat(bytes); - } - - - /** - * @return data, i.e., 4 bytes. - */ - public final float getBytes() { - return bytes; - } - - - /** - * @param bytes the raw bytes that represent this float - */ - public final void setBytes( float bytes ) { - this.bytes = bytes; - } - - - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(bytes = " + bytes + ")"; - } - - - /** @return Float object - */ - public Object getConstantValue( ConstantPool cp ) { - return new Float(bytes); - } + /** + * @return Float object + */ + @Override + public Object getConstantValue(ConstantPool cp) { + return new Float(bytes); + } } diff --git a/src/org/apache/bcel/classfile/ConstantInteger.java b/src/org/apache/bcel/classfile/ConstantInteger.java index bdd21e2..b24f552 100644 --- a/src/org/apache/bcel/classfile/ConstantInteger.java +++ b/src/org/apache/bcel/classfile/ConstantInteger.java @@ -21,99 +21,104 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to an int object. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to an int object. + * * @version $Id: ConstantInteger.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantInteger extends Constant implements ConstantObject { - private int bytes; + /** + * + */ + private static final long serialVersionUID = 1L; + private int bytes; + /** + * @param bytes + * Data + */ + public ConstantInteger(int bytes) { + super(Constants.CONSTANT_Integer); + this.bytes = bytes; + } - /** - * @param bytes Data - */ - public ConstantInteger(int bytes) { - super(Constants.CONSTANT_Integer); - this.bytes = bytes; - } + /** + * Initialize from another object. + */ + public ConstantInteger(ConstantInteger c) { + this(c.getBytes()); + } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantInteger(DataInputStream file) throws IOException { + this(file.readInt()); + } - /** - * Initialize from another object. - */ - public ConstantInteger(ConstantInteger c) { - this(c.getBytes()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantInteger(this); + } + /** + * Dump constant integer to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeInt(bytes); + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantInteger(DataInputStream file) throws IOException { - this(file.readInt()); - } + /** + * @return data, i.e., 4 bytes. + */ + public final int getBytes() { + return bytes; + } + /** + * @param bytes + * the raw bytes that represent this integer + */ + public final void setBytes(int bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantInteger(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } - - /** - * Dump constant integer to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeInt(bytes); - } - - - /** - * @return data, i.e., 4 bytes. - */ - public final int getBytes() { - return bytes; - } - - - /** - * @param bytes the raw bytes that represent this integer - */ - public final void setBytes( int bytes ) { - this.bytes = bytes; - } - - - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(bytes = " + bytes + ")"; - } - - - /** @return Integer object - */ - public Object getConstantValue( ConstantPool cp ) { - return new Integer(bytes); - } + /** + * @return Integer object + */ + @Override + public Object getConstantValue(ConstantPool cp) { + return new Integer(bytes); + } } diff --git a/src/org/apache/bcel/classfile/ConstantInterfaceMethodref.java b/src/org/apache/bcel/classfile/ConstantInterfaceMethodref.java index ba3a96a..4d05ed7 100644 --- a/src/org/apache/bcel/classfile/ConstantInterfaceMethodref.java +++ b/src/org/apache/bcel/classfile/ConstantInterfaceMethodref.java @@ -20,50 +20,60 @@ import java.io.DataInputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** +/** * This class represents a constant pool reference to an interface method. - * - * @version $Id: ConstantInterfaceMethodref.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * + * @version $Id: ConstantInterfaceMethodref.java 386056 2006-03-15 11:31:56Z + * tcurdt $ + * @author M. Dahm */ public final class ConstantInterfaceMethodref extends ConstantCP { - /** - * Initialize from another object. - */ - public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) { - super(Constants.CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex()); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Initialize from another object. + */ + public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) { + super(Constants.CONSTANT_InterfaceMethodref, c.getClassIndex(), c + .getNameAndTypeIndex()); + } - /** - * Initialize instance from file data. - * - * @param file input stream - * @throws IOException - */ - ConstantInterfaceMethodref(DataInputStream file) throws IOException { - super(Constants.CONSTANT_InterfaceMethodref, file); - } + /** + * Initialize instance from file data. + * + * @param file + * input stream + * @throws IOException + */ + ConstantInterfaceMethodref(DataInputStream file) throws IOException { + super(Constants.CONSTANT_InterfaceMethodref, file); + } + /** + * @param class_index + * Reference to the class containing the method + * @param name_and_type_index + * and the method signature + */ + public ConstantInterfaceMethodref(int class_index, int name_and_type_index) { + super(Constants.CONSTANT_InterfaceMethodref, class_index, + name_and_type_index); + } - /** - * @param class_index Reference to the class containing the method - * @param name_and_type_index and the method signature - */ - public ConstantInterfaceMethodref(int class_index, int name_and_type_index) { - super(Constants.CONSTANT_InterfaceMethodref, class_index, name_and_type_index); - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantInterfaceMethodref(this); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantInterfaceMethodref(this); + } } diff --git a/src/org/apache/bcel/classfile/ConstantLong.java b/src/org/apache/bcel/classfile/ConstantLong.java index e0d475d..8a6f0f1 100644 --- a/src/org/apache/bcel/classfile/ConstantLong.java +++ b/src/org/apache/bcel/classfile/ConstantLong.java @@ -21,99 +21,104 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to a long object. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to a long object. + * * @version $Id: ConstantLong.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantLong extends Constant implements ConstantObject { - private long bytes; + /** + * + */ + private static final long serialVersionUID = 1L; + private long bytes; + /** + * @param bytes + * Data + */ + public ConstantLong(long bytes) { + super(Constants.CONSTANT_Long); + this.bytes = bytes; + } - /** - * @param bytes Data - */ - public ConstantLong(long bytes) { - super(Constants.CONSTANT_Long); - this.bytes = bytes; - } + /** + * Initialize from another object. + */ + public ConstantLong(ConstantLong c) { + this(c.getBytes()); + } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantLong(DataInputStream file) throws IOException { + this(file.readLong()); + } - /** - * Initialize from another object. - */ - public ConstantLong(ConstantLong c) { - this(c.getBytes()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantLong(this); + } + /** + * Dump constant long to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeLong(bytes); + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantLong(DataInputStream file) throws IOException { - this(file.readLong()); - } + /** + * @return data, i.e., 8 bytes. + */ + public final long getBytes() { + return bytes; + } + /** + * @param bytes + * thr raw bytes that represent this long + */ + public final void setBytes(long bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantLong(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } - - /** - * Dump constant long to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeLong(bytes); - } - - - /** - * @return data, i.e., 8 bytes. - */ - public final long getBytes() { - return bytes; - } - - - /** - * @param bytes thr raw bytes that represent this long - */ - public final void setBytes( long bytes ) { - this.bytes = bytes; - } - - - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(bytes = " + bytes + ")"; - } - - - /** @return Long object - */ - public Object getConstantValue( ConstantPool cp ) { - return new Long(bytes); - } + /** + * @return Long object + */ + @Override + public Object getConstantValue(ConstantPool cp) { + return new Long(bytes); + } } diff --git a/src/org/apache/bcel/classfile/ConstantMethodref.java b/src/org/apache/bcel/classfile/ConstantMethodref.java index 0991238..ebd001a 100644 --- a/src/org/apache/bcel/classfile/ConstantMethodref.java +++ b/src/org/apache/bcel/classfile/ConstantMethodref.java @@ -20,50 +20,58 @@ import java.io.DataInputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** +/** * This class represents a constant pool reference to a method. - * + * * @version $Id: ConstantMethodref.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class ConstantMethodref extends ConstantCP { - /** - * Initialize from another object. - */ - public ConstantMethodref(ConstantMethodref c) { - super(Constants.CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex()); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Initialize from another object. + */ + public ConstantMethodref(ConstantMethodref c) { + super(Constants.CONSTANT_Methodref, c.getClassIndex(), c + .getNameAndTypeIndex()); + } - /** - * Initialize instance from file data. - * - * @param file input stream - * @throws IOException - */ - ConstantMethodref(DataInputStream file) throws IOException { - super(Constants.CONSTANT_Methodref, file); - } + /** + * Initialize instance from file data. + * + * @param file + * input stream + * @throws IOException + */ + ConstantMethodref(DataInputStream file) throws IOException { + super(Constants.CONSTANT_Methodref, file); + } + /** + * @param class_index + * Reference to the class containing the method + * @param name_and_type_index + * and the method signature + */ + public ConstantMethodref(int class_index, int name_and_type_index) { + super(Constants.CONSTANT_Methodref, class_index, name_and_type_index); + } - /** - * @param class_index Reference to the class containing the method - * @param name_and_type_index and the method signature - */ - public ConstantMethodref(int class_index, int name_and_type_index) { - super(Constants.CONSTANT_Methodref, class_index, name_and_type_index); - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantMethodref(this); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantMethodref(this); + } } diff --git a/src/org/apache/bcel/classfile/ConstantNameAndType.java b/src/org/apache/bcel/classfile/ConstantNameAndType.java index 01a833e..ea182e5 100644 --- a/src/org/apache/bcel/classfile/ConstantNameAndType.java +++ b/src/org/apache/bcel/classfile/ConstantNameAndType.java @@ -21,128 +21,132 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to the name and signature - * of a field or method. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to the name and signature of a field or method. + * * @version $Id: ConstantNameAndType.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantNameAndType extends Constant { - private int name_index; // Name of field/method - private int signature_index; // and its signature. + /** + * + */ + private static final long serialVersionUID = 1L; + private int name_index; // Name of field/method + private int signature_index; // and its signature. + /** + * Initialize from another object. + */ + public ConstantNameAndType(ConstantNameAndType c) { + this(c.getNameIndex(), c.getSignatureIndex()); + } - /** - * Initialize from another object. - */ - public ConstantNameAndType(ConstantNameAndType c) { - this(c.getNameIndex(), c.getSignatureIndex()); - } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantNameAndType(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } + /** + * @param name_index + * Name of field/method + * @param signature_index + * and its signature + */ + public ConstantNameAndType(int name_index, int signature_index) { + super(Constants.CONSTANT_NameAndType); + this.name_index = name_index; + this.signature_index = signature_index; + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantNameAndType(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantNameAndType(this); + } + /** + * Dump name and signature index to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(name_index); + file.writeShort(signature_index); + } - /** - * @param name_index Name of field/method - * @param signature_index and its signature - */ - public ConstantNameAndType(int name_index, int signature_index) { - super(Constants.CONSTANT_NameAndType); - this.name_index = name_index; - this.signature_index = signature_index; - } + /** + * @return Name index in constant pool of field/method name. + */ + public final int getNameIndex() { + return name_index; + } + /** + * @return name + */ + public final String getName(ConstantPool cp) { + return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantNameAndType(this); - } + /** + * @return Index in constant pool of field/method signature. + */ + public final int getSignatureIndex() { + return signature_index; + } + /** + * @return signature + */ + public final String getSignature(ConstantPool cp) { + return cp + .constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); + } - /** - * Dump name and signature index to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeShort(name_index); - file.writeShort(signature_index); - } + /** + * @param name_index + * the name index of this constant + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + /** + * @param signature_index + * the signature index in the constant pool of this type + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } - /** - * @return Name index in constant pool of field/method name. - */ - public final int getNameIndex() { - return name_index; - } - - - /** @return name - */ - public final String getName( ConstantPool cp ) { - return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); - } - - - /** - * @return Index in constant pool of field/method signature. - */ - public final int getSignatureIndex() { - return signature_index; - } - - - /** @return signature - */ - public final String getSignature( ConstantPool cp ) { - return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); - } - - - /** - * @param name_index the name index of this constant - */ - public final void setNameIndex( int name_index ) { - this.name_index = name_index; - } - - - /** - * @param signature_index the signature index in the constant pool of this type - */ - public final void setSignatureIndex( int signature_index ) { - this.signature_index = signature_index; - } - - - /** - * @return String representation - */ - public final String toString() { - return super.toString() + "(name_index = " + name_index + ", signature_index = " - + signature_index + ")"; - } + /** + * @return String representation + */ + @Override + public final String toString() { + return super.toString() + "(name_index = " + name_index + + ", signature_index = " + signature_index + ")"; + } } diff --git a/src/org/apache/bcel/classfile/ConstantObject.java b/src/org/apache/bcel/classfile/ConstantObject.java index 38917af..cded347 100644 --- a/src/org/apache/bcel/classfile/ConstantObject.java +++ b/src/org/apache/bcel/classfile/ConstantObject.java @@ -16,17 +16,18 @@ */ package org.apache.bcel.classfile; -/** - * This interface denotes those constants that have a "natural" value, - * such as ConstantLong, ConstantString, etc.. - * +/** + * This interface denotes those constants that have a "natural" value, such as + * ConstantLong, ConstantString, etc.. + * * @version $Id: ConstantObject.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public interface ConstantObject { - /** @return object representing the constant, e.g., Long for ConstantLong - */ - public abstract Object getConstantValue( ConstantPool cp ); + /** + * @return object representing the constant, e.g., Long for ConstantLong + */ + public abstract Object getConstantValue(ConstantPool cp); } diff --git a/src/org/apache/bcel/classfile/ConstantPool.java b/src/org/apache/bcel/classfile/ConstantPool.java index 9b92d63..e7cd240 100644 --- a/src/org/apache/bcel/classfile/ConstantPool.java +++ b/src/org/apache/bcel/classfile/ConstantPool.java @@ -23,331 +23,346 @@ import java.io.Serializable; import org.apache.bcel.Constants; /** - * This class represents the constant pool, i.e., a table of constants, of - * a parsed classfile. It may contain null references, due to the JVM - * specification that skips an entry after an 8-byte constant (double, - * long) entry. Those interested in generating constant pools - * programatically should see - * ConstantPoolGen. - + * This class represents the constant pool, i.e., a table of constants, of a + * parsed classfile. It may contain null references, due to the JVM + * specification that skips an entry after an 8-byte constant (double, long) + * entry. Those interested in generating constant pools programatically should + * see ConstantPoolGen. + * * @version $Id: ConstantPool.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @see Constant - * @see org.apache.bcel.generic.ConstantPoolGen + * @see Constant + * @see org.apache.bcel.generic.ConstantPoolGen * @author M. Dahm */ public class ConstantPool implements Cloneable, Node, Serializable { - private int constant_pool_count; - private Constant[] constant_pool; + /** + * + */ + private static final long serialVersionUID = 1L; + private int constant_pool_count; + private Constant[] constant_pool; + /** + * @param constant_pool + * Array of constants + */ + public ConstantPool(Constant[] constant_pool) { + setConstantPool(constant_pool); + } - /** - * @param constant_pool Array of constants - */ - public ConstantPool(Constant[] constant_pool) { - setConstantPool(constant_pool); - } + /** + * Read constants from given file stream. + * + * @param file + * Input stream + * @throws IOException + * @throws ClassFormatException + */ + ConstantPool(DataInputStream file) throws IOException, ClassFormatException { + byte tag; + constant_pool_count = file.readUnsignedShort(); + constant_pool = new Constant[constant_pool_count]; + /* + * constant_pool[0] is unused by the compiler and may be used freely by + * the implementation. + */ + for (int i = 1; i < constant_pool_count; i++) { + constant_pool[i] = Constant.readConstant(file); + /* + * Quote from the JVM specification: "All eight byte constants take + * up two spots in the constant pool. If this is the n'th byte in + * the constant pool, then the next item will be numbered n+2" + * + * Thus we have to increment the index counter. + */ + tag = constant_pool[i].getTag(); + if ((tag == Constants.CONSTANT_Double) + || (tag == Constants.CONSTANT_Long)) { + i++; + } + } + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantPool(this); + } - /** - * Read constants from given file stream. - * - * @param file Input stream - * @throws IOException - * @throws ClassFormatException - */ - ConstantPool(DataInputStream file) throws IOException, ClassFormatException { - byte tag; - constant_pool_count = file.readUnsignedShort(); - constant_pool = new Constant[constant_pool_count]; - /* constant_pool[0] is unused by the compiler and may be used freely - * by the implementation. - */ - for (int i = 1; i < constant_pool_count; i++) { - constant_pool[i] = Constant.readConstant(file); - /* Quote from the JVM specification: - * "All eight byte constants take up two spots in the constant pool. - * If this is the n'th byte in the constant pool, then the next item - * will be numbered n+2" - * - * Thus we have to increment the index counter. - */ - tag = constant_pool[i].getTag(); - if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) { - i++; - } - } - } + /** + * Resolve constant to a string representation. + * + * @param c + * Constant to be printed + * @return String representation + */ + public String constantToString(Constant c) throws ClassFormatException { + String str; + int i; + byte tag = c.getTag(); + switch (tag) { + case Constants.CONSTANT_Class: + i = ((ConstantClass) c).getNameIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = Utility + .compactClassName(((ConstantUtf8) c).getBytes(), false); + break; + case Constants.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\""; + break; + case Constants.CONSTANT_Utf8: + str = ((ConstantUtf8) c).getBytes(); + break; + case Constants.CONSTANT_Double: + str = "" + ((ConstantDouble) c).getBytes(); + break; + case Constants.CONSTANT_Float: + str = "" + ((ConstantFloat) c).getBytes(); + break; + case Constants.CONSTANT_Long: + str = "" + ((ConstantLong) c).getBytes(); + break; + case Constants.CONSTANT_Integer: + str = "" + ((ConstantInteger) c).getBytes(); + break; + case Constants.CONSTANT_NameAndType: + str = (constantToString(((ConstantNameAndType) c).getNameIndex(), + Constants.CONSTANT_Utf8) + " " + constantToString( + ((ConstantNameAndType) c).getSignatureIndex(), + Constants.CONSTANT_Utf8)); + break; + case Constants.CONSTANT_InterfaceMethodref: + case Constants.CONSTANT_Methodref: + case Constants.CONSTANT_Fieldref: + str = (constantToString(((ConstantCP) c).getClassIndex(), + Constants.CONSTANT_Class) + "." + constantToString( + ((ConstantCP) c).getNameAndTypeIndex(), + Constants.CONSTANT_NameAndType)); + break; + default: // Never reached + throw new RuntimeException("Unknown constant type " + tag); + } + return str; + } + private static final String escape(String str) { + int len = str.length(); + StringBuffer buf = new StringBuffer(len + 5); + char[] ch = str.toCharArray(); + for (int i = 0; i < len; i++) { + switch (ch[i]) { + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + case '\t': + buf.append("\\t"); + break; + case '\b': + buf.append("\\b"); + break; + case '"': + buf.append("\\\""); + break; + default: + buf.append(ch[i]); + } + } + return buf.toString(); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantPool(this); - } + /** + * Retrieve constant at `index' from constant pool and resolve it to a + * string representation. + * + * @param index + * of constant in constant pool + * @param tag + * expected type + * @return String representation + */ + public String constantToString(int index, byte tag) + throws ClassFormatException { + Constant c = getConstant(index, tag); + return constantToString(c); + } + /** + * Dump constant pool to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + public void dump(DataOutputStream file) throws IOException { + file.writeShort(constant_pool_count); + for (int i = 1; i < constant_pool_count; i++) { + if (constant_pool[i] != null) { + constant_pool[i].dump(file); + } + } + } - /** - * Resolve constant to a string representation. - * - * @param c Constant to be printed - * @return String representation - */ - public String constantToString( Constant c ) throws ClassFormatException { - String str; - int i; - byte tag = c.getTag(); - switch (tag) { - case Constants.CONSTANT_Class: - i = ((ConstantClass) c).getNameIndex(); - c = getConstant(i, Constants.CONSTANT_Utf8); - str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); - break; - case Constants.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - c = getConstant(i, Constants.CONSTANT_Utf8); - str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\""; - break; - case Constants.CONSTANT_Utf8: - str = ((ConstantUtf8) c).getBytes(); - break; - case Constants.CONSTANT_Double: - str = "" + ((ConstantDouble) c).getBytes(); - break; - case Constants.CONSTANT_Float: - str = "" + ((ConstantFloat) c).getBytes(); - break; - case Constants.CONSTANT_Long: - str = "" + ((ConstantLong) c).getBytes(); - break; - case Constants.CONSTANT_Integer: - str = "" + ((ConstantInteger) c).getBytes(); - break; - case Constants.CONSTANT_NameAndType: - str = (constantToString(((ConstantNameAndType) c).getNameIndex(), - Constants.CONSTANT_Utf8) - + " " + constantToString(((ConstantNameAndType) c).getSignatureIndex(), - Constants.CONSTANT_Utf8)); - break; - case Constants.CONSTANT_InterfaceMethodref: - case Constants.CONSTANT_Methodref: - case Constants.CONSTANT_Fieldref: - str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class) - + "." + constantToString(((ConstantCP) c).getNameAndTypeIndex(), - Constants.CONSTANT_NameAndType)); - break; - default: // Never reached - throw new RuntimeException("Unknown constant type " + tag); - } - return str; - } + /** + * Get constant from constant pool. + * + * @param index + * Index in constant pool + * @return Constant value + * @see Constant + */ + public Constant getConstant(int index) { + if (index >= constant_pool.length || index < 0) { + throw new ClassFormatException("Invalid constant pool reference: " + + index + ". Constant pool size is: " + + constant_pool.length); + } + return constant_pool[index]; + } + /** + * Get constant from constant pool and check whether it has the expected + * type. + * + * @param index + * Index in constant pool + * @param tag + * Tag of expected constant, i.e., its type + * @return Constant value + * @see Constant + * @throws ClassFormatException + */ + public Constant getConstant(int index, byte tag) + throws ClassFormatException { + Constant c; + c = getConstant(index); + if (c == null) { + throw new ClassFormatException("Constant pool at index " + index + + " is null."); + } + if (c.getTag() != tag) { + throw new ClassFormatException("Expected class `" + + Constants.CONSTANT_NAMES[tag] + "' at index " + index + + " and got " + c); + } + return c; + } - private static final String escape( String str ) { - int len = str.length(); - StringBuffer buf = new StringBuffer(len + 5); - char[] ch = str.toCharArray(); - for (int i = 0; i < len; i++) { - switch (ch[i]) { - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - case '\t': - buf.append("\\t"); - break; - case '\b': - buf.append("\\b"); - break; - case '"': - buf.append("\\\""); - break; - default: - buf.append(ch[i]); - } - } - return buf.toString(); - } + /** + * @return Array of constants. + * @see Constant + */ + public Constant[] getConstantPool() { + return constant_pool; + } + /** + * Get string from constant pool and bypass the indirection of + * `ConstantClass' and `ConstantString' objects. I.e. these classes have an + * index field that points to another entry of the constant pool of type + * `ConstantUtf8' which contains the real data. + * + * @param index + * Index in constant pool + * @param tag + * Tag of expected constant, either ConstantClass or + * ConstantString + * @return Contents of string reference + * @see ConstantClass + * @see ConstantString + * @throws ClassFormatException + */ + public String getConstantString(int index, byte tag) + throws ClassFormatException { + Constant c; + int i; + c = getConstant(index, tag); + /* + * This switch() is not that elegant, since the two classes have the + * same contents, they just differ in the name of the index field + * variable. But we want to stick to the JVM naming conventions closely + * though we could have solved these more elegantly by using the same + * variable name or by subclassing. + */ + switch (tag) { + case Constants.CONSTANT_Class: + i = ((ConstantClass) c).getNameIndex(); + break; + case Constants.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + break; + default: + throw new RuntimeException( + "getConstantString called with illegal tag " + tag); + } + // Finally get the string from the constant pool + c = getConstant(i, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getBytes(); + } - /** - * Retrieve constant at `index' from constant pool and resolve it to - * a string representation. - * - * @param index of constant in constant pool - * @param tag expected type - * @return String representation - */ - public String constantToString( int index, byte tag ) throws ClassFormatException { - Constant c = getConstant(index, tag); - return constantToString(c); - } + /** + * @return Length of constant pool. + */ + public int getLength() { + return constant_pool_count; + } + /** + * @param constant + * Constant to set + */ + public void setConstant(int index, Constant constant) { + constant_pool[index] = constant; + } - /** - * Dump constant pool to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public void dump( DataOutputStream file ) throws IOException { - file.writeShort(constant_pool_count); - for (int i = 1; i < constant_pool_count; i++) { - if (constant_pool[i] != null) { - constant_pool[i].dump(file); - } - } - } + /** + * @param constant_pool + */ + public void setConstantPool(Constant[] constant_pool) { + this.constant_pool = constant_pool; + constant_pool_count = (constant_pool == null) ? 0 + : constant_pool.length; + } + /** + * @return String representation. + */ + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 1; i < constant_pool_count; i++) { + buf.append(i).append(")").append(constant_pool[i]).append("\n"); + } + return buf.toString(); + } - /** - * Get constant from constant pool. - * - * @param index Index in constant pool - * @return Constant value - * @see Constant - */ - public Constant getConstant( int index ) { - if (index >= constant_pool.length || index < 0) { - throw new ClassFormatException("Invalid constant pool reference: " + index - + ". Constant pool size is: " + constant_pool.length); - } - return constant_pool[index]; - } - - - /** - * Get constant from constant pool and check whether it has the - * expected type. - * - * @param index Index in constant pool - * @param tag Tag of expected constant, i.e., its type - * @return Constant value - * @see Constant - * @throws ClassFormatException - */ - public Constant getConstant( int index, byte tag ) throws ClassFormatException { - Constant c; - c = getConstant(index); - if (c == null) { - throw new ClassFormatException("Constant pool at index " + index + " is null."); - } - if (c.getTag() != tag) { - throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag] - + "' at index " + index + " and got " + c); - } - return c; - } - - - /** - * @return Array of constants. - * @see Constant - */ - public Constant[] getConstantPool() { - return constant_pool; - } - - - /** - * Get string from constant pool and bypass the indirection of - * `ConstantClass' and `ConstantString' objects. I.e. these classes have - * an index field that points to another entry of the constant pool of - * type `ConstantUtf8' which contains the real data. - * - * @param index Index in constant pool - * @param tag Tag of expected constant, either ConstantClass or ConstantString - * @return Contents of string reference - * @see ConstantClass - * @see ConstantString - * @throws ClassFormatException - */ - public String getConstantString( int index, byte tag ) throws ClassFormatException { - Constant c; - int i; - c = getConstant(index, tag); - /* This switch() is not that elegant, since the two classes have the - * same contents, they just differ in the name of the index - * field variable. - * But we want to stick to the JVM naming conventions closely though - * we could have solved these more elegantly by using the same - * variable name or by subclassing. - */ - switch (tag) { - case Constants.CONSTANT_Class: - i = ((ConstantClass) c).getNameIndex(); - break; - case Constants.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - break; - default: - throw new RuntimeException("getConstantString called with illegal tag " + tag); - } - // Finally get the string from the constant pool - c = getConstant(i, Constants.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); - } - - - /** - * @return Length of constant pool. - */ - public int getLength() { - return constant_pool_count; - } - - - /** - * @param constant Constant to set - */ - public void setConstant( int index, Constant constant ) { - constant_pool[index] = constant; - } - - - /** - * @param constant_pool - */ - public void setConstantPool( Constant[] constant_pool ) { - this.constant_pool = constant_pool; - constant_pool_count = (constant_pool == null) ? 0 : constant_pool.length; - } - - - /** - * @return String representation. - */ - public String toString() { - StringBuffer buf = new StringBuffer(); - for (int i = 1; i < constant_pool_count; i++) { - buf.append(i).append(")").append(constant_pool[i]).append("\n"); - } - return buf.toString(); - } - - - /** - * @return deep copy of this constant pool - */ - public ConstantPool copy() { - ConstantPool c = null; - try { - c = (ConstantPool) clone(); - c.constant_pool = new Constant[constant_pool_count]; - for (int i = 1; i < constant_pool_count; i++) { - if (constant_pool[i] != null) { - c.constant_pool[i] = constant_pool[i].copy(); - } - } - } catch (CloneNotSupportedException e) { - } - return c; - } + /** + * @return deep copy of this constant pool + */ + public ConstantPool copy() { + ConstantPool c = null; + try { + c = (ConstantPool) clone(); + c.constant_pool = new Constant[constant_pool_count]; + for (int i = 1; i < constant_pool_count; i++) { + if (constant_pool[i] != null) { + c.constant_pool[i] = constant_pool[i].copy(); + } + } + } catch (CloneNotSupportedException e) { + } + return c; + } } diff --git a/src/org/apache/bcel/classfile/ConstantString.java b/src/org/apache/bcel/classfile/ConstantString.java index c9474dd..ff38c9e 100644 --- a/src/org/apache/bcel/classfile/ConstantString.java +++ b/src/org/apache/bcel/classfile/ConstantString.java @@ -21,107 +21,112 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to a String object. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to a String object. + * * @version $Id: ConstantString.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantString extends Constant implements ConstantObject { - private int string_index; // Identical to ConstantClass except for this name + /** + * + */ + private static final long serialVersionUID = 1L; + private int string_index; // Identical to ConstantClass except for this name + /** + * Initialize from another object. + */ + public ConstantString(ConstantString c) { + this(c.getStringIndex()); + } - /** - * Initialize from another object. - */ - public ConstantString(ConstantString c) { - this(c.getStringIndex()); - } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantString(DataInputStream file) throws IOException { + this(file.readUnsignedShort()); + } + /** + * @param string_index + * Index of Constant_Utf8 in constant pool + */ + public ConstantString(int string_index) { + super(Constants.CONSTANT_String); + this.string_index = string_index; + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantString(DataInputStream file) throws IOException { - this(file.readUnsignedShort()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantString(this); + } + /** + * Dump constant field reference to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeShort(string_index); + } - /** - * @param string_index Index of Constant_Utf8 in constant pool - */ - public ConstantString(int string_index) { - super(Constants.CONSTANT_String); - this.string_index = string_index; - } + /** + * @return Index in constant pool of the string (ConstantUtf8). + */ + public final int getStringIndex() { + return string_index; + } + /** + * @param string_index + * the index into the constant of the string value + */ + public final void setStringIndex(int string_index) { + this.string_index = string_index; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantString(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(string_index = " + string_index + ")"; + } + /** + * @return String object + */ + @Override + public Object getConstantValue(ConstantPool cp) { + Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8); + return ((ConstantUtf8) c).getBytes(); + } - /** - * Dump constant field reference to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeShort(string_index); - } - - - /** - * @return Index in constant pool of the string (ConstantUtf8). - */ - public final int getStringIndex() { - return string_index; - } - - - /** - * @param string_index the index into the constant of the string value - */ - public final void setStringIndex( int string_index ) { - this.string_index = string_index; - } - - - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(string_index = " + string_index + ")"; - } - - - /** @return String object - */ - public Object getConstantValue( ConstantPool cp ) { - Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); - } - - - /** @return dereferenced string - */ - public String getBytes( ConstantPool cp ) { - return (String) getConstantValue(cp); - } + /** + * @return dereferenced string + */ + public String getBytes(ConstantPool cp) { + return (String) getConstantValue(cp); + } } diff --git a/src/org/apache/bcel/classfile/ConstantUtf8.java b/src/org/apache/bcel/classfile/ConstantUtf8.java index f30e0d4..a4df998 100644 --- a/src/org/apache/bcel/classfile/ConstantUtf8.java +++ b/src/org/apache/bcel/classfile/ConstantUtf8.java @@ -21,96 +21,101 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class is derived from the abstract - * Constant class - * and represents a reference to a Utf8 encoded string. - * +/** + * This class is derived from the abstract Constant class and + * represents a reference to a Utf8 encoded string. + * * @version $Id: ConstantUtf8.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Constant + * @author M. Dahm + * @see Constant */ public final class ConstantUtf8 extends Constant { - private String bytes; + /** + * + */ + private static final long serialVersionUID = 1L; + private String bytes; + /** + * Initialize from another object. + */ + public ConstantUtf8(ConstantUtf8 c) { + this(c.getBytes()); + } - /** - * Initialize from another object. - */ - public ConstantUtf8(ConstantUtf8 c) { - this(c.getBytes()); - } + /** + * Initialize instance from file data. + * + * @param file + * Input stream + * @throws IOException + */ + ConstantUtf8(DataInputStream file) throws IOException { + super(Constants.CONSTANT_Utf8); + bytes = file.readUTF(); + } + /** + * @param bytes + * Data + */ + public ConstantUtf8(String bytes) { + super(Constants.CONSTANT_Utf8); + if (bytes == null) { + throw new IllegalArgumentException("bytes must not be null!"); + } + this.bytes = bytes; + } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantUtf8(DataInputStream file) throws IOException { - super(Constants.CONSTANT_Utf8); - bytes = file.readUTF(); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantUtf8(this); + } + /** + * Dump String in Utf8 format to file stream. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(tag); + file.writeUTF(bytes); + } - /** - * @param bytes Data - */ - public ConstantUtf8(String bytes) { - super(Constants.CONSTANT_Utf8); - if (bytes == null) { - throw new IllegalArgumentException("bytes must not be null!"); - } - this.bytes = bytes; - } + /** + * @return Data converted to string. + */ + public final String getBytes() { + return bytes; + } + /** + * @param bytes + * the raw bytes of this Utf-8 + */ + public final void setBytes(String bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantUtf8(this); - } - - - /** - * Dump String in Utf8 format to file stream. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeUTF(bytes); - } - - - /** - * @return Data converted to string. - */ - public final String getBytes() { - return bytes; - } - - - /** - * @param bytes the raw bytes of this Utf-8 - */ - public final void setBytes( String bytes ) { - this.bytes = bytes; - } - - - /** - * @return String representation - */ - public final String toString() { - return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")"; - } + /** + * @return String representation + */ + @Override + public final String toString() { + return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + + "\")"; + } } diff --git a/src/org/apache/bcel/classfile/ConstantValue.java b/src/org/apache/bcel/classfile/ConstantValue.java index b0d89da..dbb41e3 100644 --- a/src/org/apache/bcel/classfile/ConstantValue.java +++ b/src/org/apache/bcel/classfile/ConstantValue.java @@ -22,134 +22,147 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class is derived from Attribute and represents a constant - * value, i.e., a default value for initializing a class field. - * This class is instantiated by the Attribute.readAttribute() method. - * + * This class is derived from Attribute and represents a constant + * value, i.e., a default value for initializing a class field. This class is + * instantiated by the Attribute.readAttribute() method. + * * @version $Id: ConstantValue.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute + * @author M. Dahm + * @see Attribute */ public final class ConstantValue extends Attribute { - private int constantvalue_index; + /** + * + */ + private static final long serialVersionUID = 1L; + private int constantvalue_index; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public ConstantValue(ConstantValue c) { + this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c + .getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public ConstantValue(ConstantValue c) { - this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool()); - } + /** + * Construct object from file stream. + * + * @param name_index + * Name index in constant pool + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + ConstantValue(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + /** + * @param name_index + * Name index in constant pool + * @param length + * Content length in bytes + * @param constantvalue_index + * Index in constant pool + * @param constant_pool + * Array of constants + */ + public ConstantValue(int name_index, int length, int constantvalue_index, + ConstantPool constant_pool) { + super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); + this.constantvalue_index = constantvalue_index; + } - /** - * Construct object from file stream. - * @param name_index Name index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - ConstantValue(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitConstantValue(this); + } + /** + * Dump constant value attribute to file stream on binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(constantvalue_index); + } - /** - * @param name_index Name index in constant pool - * @param length Content length in bytes - * @param constantvalue_index Index in constant pool - * @param constant_pool Array of constants - */ - public ConstantValue(int name_index, int length, int constantvalue_index, - ConstantPool constant_pool) { - super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); - this.constantvalue_index = constantvalue_index; - } + /** + * @return Index in constant pool of constant value. + */ + public final int getConstantValueIndex() { + return constantvalue_index; + } + /** + * @param constantvalue_index + * the index info the constant pool of this constant value + */ + public final void setConstantValueIndex(int constantvalue_index) { + this.constantvalue_index = constantvalue_index; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitConstantValue(this); - } + /** + * @return String representation of constant value. + */ + @Override + public final String toString() { + Constant c = constant_pool.getConstant(constantvalue_index); + String buf; + int i; + // Print constant to string depending on its type + switch (c.getTag()) { + case Constants.CONSTANT_Long: + buf = "" + ((ConstantLong) c).getBytes(); + break; + case Constants.CONSTANT_Float: + buf = "" + ((ConstantFloat) c).getBytes(); + break; + case Constants.CONSTANT_Double: + buf = "" + ((ConstantDouble) c).getBytes(); + break; + case Constants.CONSTANT_Integer: + buf = "" + ((ConstantInteger) c).getBytes(); + break; + case Constants.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = constant_pool.getConstant(i, Constants.CONSTANT_Utf8); + buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + + "\""; + break; + default: + throw new IllegalStateException("Type of ConstValue invalid: " + c); + } + return buf; + } - - /** - * Dump constant value attribute to file stream on binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(constantvalue_index); - } - - - /** - * @return Index in constant pool of constant value. - */ - public final int getConstantValueIndex() { - return constantvalue_index; - } - - - /** - * @param constantvalue_index the index info the constant pool of this constant value - */ - public final void setConstantValueIndex( int constantvalue_index ) { - this.constantvalue_index = constantvalue_index; - } - - - /** - * @return String representation of constant value. - */ - public final String toString() { - Constant c = constant_pool.getConstant(constantvalue_index); - String buf; - int i; - // Print constant to string depending on its type - switch (c.getTag()) { - case Constants.CONSTANT_Long: - buf = "" + ((ConstantLong) c).getBytes(); - break; - case Constants.CONSTANT_Float: - buf = "" + ((ConstantFloat) c).getBytes(); - break; - case Constants.CONSTANT_Double: - buf = "" + ((ConstantDouble) c).getBytes(); - break; - case Constants.CONSTANT_Integer: - buf = "" + ((ConstantInteger) c).getBytes(); - break; - case Constants.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - c = constant_pool.getConstant(i, Constants.CONSTANT_Utf8); - buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\""; - break; - default: - throw new IllegalStateException("Type of ConstValue invalid: " + c); - } - return buf; - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - ConstantValue c = (ConstantValue) clone(); - c.constant_pool = _constant_pool; - return c; - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + ConstantValue c = (ConstantValue) clone(); + c.constant_pool = _constant_pool; + return c; + } } diff --git a/src/org/apache/bcel/classfile/Deprecated.java b/src/org/apache/bcel/classfile/Deprecated.java index 50529fb..17531cd 100644 --- a/src/org/apache/bcel/classfile/Deprecated.java +++ b/src/org/apache/bcel/classfile/Deprecated.java @@ -23,118 +23,130 @@ import org.apache.bcel.Constants; /** * This class is derived from Attribute and denotes that this is a - * deprecated method. - * It is instantiated from the Attribute.readAttribute() method. - * + * deprecated method. It is instantiated from the + * Attribute.readAttribute() method. + * * @version $Id: Deprecated.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute + * @author M. Dahm + * @see Attribute */ public final class Deprecated extends Attribute { - private byte[] bytes; + /** + * + */ + private static final long serialVersionUID = 1L; + private byte[] bytes; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Deprecated(Deprecated c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Deprecated(Deprecated c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } + /** + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param bytes + * Attribute contents + * @param constant_pool + * Array of constants + */ + public Deprecated(int name_index, int length, byte[] bytes, + ConstantPool constant_pool) { + super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool); + this.bytes = bytes; + } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + Deprecated(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + if (length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + System.err.println("Deprecated attribute with length > 0"); + } + } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param bytes Attribute contents - * @param constant_pool Array of constants - */ - public Deprecated(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { - super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool); - this.bytes = bytes; - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitDeprecated(this); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (length > 0) { + file.write(bytes, 0, length); + } + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Deprecated(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (byte[]) null, constant_pool); - if (length > 0) { - bytes = new byte[length]; - file.readFully(bytes); - System.err.println("Deprecated attribute with length > 0"); - } - } + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } + /** + * @param bytes + * the raw bytes that represents this byte array + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitDeprecated(this); - } + /** + * @return attribute name + */ + @Override + public final String toString() { + return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED]; + } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - if (length > 0) { - file.write(bytes, 0, length); - } - } - - - /** - * @return data bytes. - */ - public final byte[] getBytes() { - return bytes; - } - - - /** - * @param bytes the raw bytes that represents this byte array - */ - public final void setBytes( byte[] bytes ) { - this.bytes = bytes; - } - - - /** - * @return attribute name - */ - public final String toString() { - return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED]; - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - Deprecated c = (Deprecated) clone(); - if (bytes != null) { - c.bytes = new byte[bytes.length]; - System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); - } - c.constant_pool = _constant_pool; - return c; - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + Deprecated c = (Deprecated) clone(); + if (bytes != null) { + c.bytes = new byte[bytes.length]; + System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); + } + c.constant_pool = _constant_pool; + return c; + } } diff --git a/src/org/apache/bcel/classfile/DescendingVisitor.java b/src/org/apache/bcel/classfile/DescendingVisitor.java index dae5111..cef7cac 100644 --- a/src/org/apache/bcel/classfile/DescendingVisitor.java +++ b/src/org/apache/bcel/classfile/DescendingVisitor.java @@ -19,338 +19,338 @@ package org.apache.bcel.classfile; import java.util.Stack; /** - * Traverses a JavaClass with another Visitor object 'piggy-backed' - * that is applied to all components of a JavaClass object. I.e. this - * class supplies the traversal strategy, other classes can make use - * of it. - * + * Traverses a JavaClass with another Visitor object 'piggy-backed' that is + * applied to all components of a JavaClass object. I.e. this class supplies the + * traversal strategy, other classes can make use of it. + * * @version $Id: DescendingVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DescendingVisitor implements Visitor { - private JavaClass clazz; - private Visitor visitor; - private Stack stack = new Stack(); - - - /** @return container of current entitity, i.e., predecessor during traversal - */ - public Object predecessor() { - return predecessor(0); - } - - - /** - * @param level nesting level, i.e., 0 returns the direct predecessor - * @return container of current entitity, i.e., predecessor during traversal - */ - public Object predecessor( int level ) { - int size = stack.size(); - if ((size < 2) || (level < 0)) { - return null; - } else { - return stack.elementAt(size - (level + 2)); // size - 1 == current - } - } - - - /** @return current object - */ - public Object current() { - return stack.peek(); - } - - - /** - * @param clazz Class to traverse - * @param visitor visitor object to apply to all components - */ - public DescendingVisitor(JavaClass clazz, Visitor visitor) { - this.clazz = clazz; - this.visitor = visitor; - } - - - /** - * Start traversal. - */ - public void visit() { - clazz.accept(this); - } - - - public void visitJavaClass( JavaClass _clazz ) { - stack.push(_clazz); - _clazz.accept(visitor); - Field[] fields = _clazz.getFields(); - for (int i = 0; i < fields.length; i++) { - fields[i].accept(this); - } - Method[] methods = _clazz.getMethods(); - for (int i = 0; i < methods.length; i++) { - methods[i].accept(this); - } - Attribute[] attributes = _clazz.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - attributes[i].accept(this); - } - _clazz.getConstantPool().accept(this); - stack.pop(); - } - - - public void visitField( Field field ) { - stack.push(field); - field.accept(visitor); - Attribute[] attributes = field.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - attributes[i].accept(this); - } - stack.pop(); - } - - - public void visitConstantValue( ConstantValue cv ) { - stack.push(cv); - cv.accept(visitor); - stack.pop(); - } - - - public void visitMethod( Method method ) { - stack.push(method); - method.accept(visitor); - Attribute[] attributes = method.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - attributes[i].accept(this); - } - stack.pop(); - } - - - public void visitExceptionTable( ExceptionTable table ) { - stack.push(table); - table.accept(visitor); - stack.pop(); - } - - - public void visitCode( Code code ) { - stack.push(code); - code.accept(visitor); - CodeException[] table = code.getExceptionTable(); - for (int i = 0; i < table.length; i++) { - table[i].accept(this); - } - Attribute[] attributes = code.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - attributes[i].accept(this); - } - stack.pop(); - } - - - public void visitCodeException( CodeException ce ) { - stack.push(ce); - ce.accept(visitor); - stack.pop(); - } - - - public void visitLineNumberTable( LineNumberTable table ) { - stack.push(table); - table.accept(visitor); - LineNumber[] numbers = table.getLineNumberTable(); - for (int i = 0; i < numbers.length; i++) { - numbers[i].accept(this); - } - stack.pop(); - } - - - public void visitLineNumber( LineNumber number ) { - stack.push(number); - number.accept(visitor); - stack.pop(); - } - - - public void visitLocalVariableTable( LocalVariableTable table ) { - stack.push(table); - table.accept(visitor); - LocalVariable[] vars = table.getLocalVariableTable(); - for (int i = 0; i < vars.length; i++) { - vars[i].accept(this); - } - stack.pop(); - } - - - public void visitStackMap( StackMap table ) { - stack.push(table); - table.accept(visitor); - StackMapEntry[] vars = table.getStackMap(); - for (int i = 0; i < vars.length; i++) { - vars[i].accept(this); - } - stack.pop(); - } - - - public void visitStackMapEntry( StackMapEntry var ) { - stack.push(var); - var.accept(visitor); - stack.pop(); - } - - - public void visitLocalVariable( LocalVariable var ) { - stack.push(var); - var.accept(visitor); - stack.pop(); - } - - - public void visitConstantPool( ConstantPool cp ) { - stack.push(cp); - cp.accept(visitor); - Constant[] constants = cp.getConstantPool(); - for (int i = 1; i < constants.length; i++) { - if (constants[i] != null) { - constants[i].accept(this); - } - } - stack.pop(); - } - - - public void visitConstantClass( ConstantClass constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantDouble( ConstantDouble constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantFieldref( ConstantFieldref constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantFloat( ConstantFloat constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantInteger( ConstantInteger constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantLong( ConstantLong constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantMethodref( ConstantMethodref constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantNameAndType( ConstantNameAndType constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantString( ConstantString constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitConstantUtf8( ConstantUtf8 constant ) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } - - - public void visitInnerClasses( InnerClasses ic ) { - stack.push(ic); - ic.accept(visitor); - InnerClass[] ics = ic.getInnerClasses(); - for (int i = 0; i < ics.length; i++) { - ics[i].accept(this); - } - stack.pop(); - } - - - public void visitInnerClass( InnerClass inner ) { - stack.push(inner); - inner.accept(visitor); - stack.pop(); - } - - - public void visitDeprecated( Deprecated attribute ) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - - public void visitSignature( Signature attribute ) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - - public void visitSourceFile( SourceFile attribute ) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - - public void visitSynthetic( Synthetic attribute ) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } - - - public void visitUnknown( Unknown attribute ) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } + private JavaClass clazz; + private Visitor visitor; + private Stack stack = new Stack(); + + /** + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor() { + return predecessor(0); + } + + /** + * @param level + * nesting level, i.e., 0 returns the direct predecessor + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor(int level) { + int size = stack.size(); + if ((size < 2) || (level < 0)) { + return null; + } else { + return stack.elementAt(size - (level + 2)); // size - 1 == current + } + } + + /** + * @return current object + */ + public Object current() { + return stack.peek(); + } + + /** + * @param clazz + * Class to traverse + * @param visitor + * visitor object to apply to all components + */ + public DescendingVisitor(JavaClass clazz, Visitor visitor) { + this.clazz = clazz; + this.visitor = visitor; + } + + /** + * Start traversal. + */ + public void visit() { + clazz.accept(this); + } + + @Override + public void visitJavaClass(JavaClass _clazz) { + stack.push(_clazz); + _clazz.accept(visitor); + Field[] fields = _clazz.getFields(); + for (int i = 0; i < fields.length; i++) { + fields[i].accept(this); + } + Method[] methods = _clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + methods[i].accept(this); + } + Attribute[] attributes = _clazz.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + attributes[i].accept(this); + } + _clazz.getConstantPool().accept(this); + stack.pop(); + } + + @Override + public void visitField(Field field) { + stack.push(field); + field.accept(visitor); + Attribute[] attributes = field.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + attributes[i].accept(this); + } + stack.pop(); + } + + @Override + public void visitConstantValue(ConstantValue cv) { + stack.push(cv); + cv.accept(visitor); + stack.pop(); + } + + @Override + public void visitMethod(Method method) { + stack.push(method); + method.accept(visitor); + Attribute[] attributes = method.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + attributes[i].accept(this); + } + stack.pop(); + } + + @Override + public void visitExceptionTable(ExceptionTable table) { + stack.push(table); + table.accept(visitor); + stack.pop(); + } + + @Override + public void visitCode(Code code) { + stack.push(code); + code.accept(visitor); + CodeException[] table = code.getExceptionTable(); + for (int i = 0; i < table.length; i++) { + table[i].accept(this); + } + Attribute[] attributes = code.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + attributes[i].accept(this); + } + stack.pop(); + } + + @Override + public void visitCodeException(CodeException ce) { + stack.push(ce); + ce.accept(visitor); + stack.pop(); + } + + @Override + public void visitLineNumberTable(LineNumberTable table) { + stack.push(table); + table.accept(visitor); + LineNumber[] numbers = table.getLineNumberTable(); + for (int i = 0; i < numbers.length; i++) { + numbers[i].accept(this); + } + stack.pop(); + } + + @Override + public void visitLineNumber(LineNumber number) { + stack.push(number); + number.accept(visitor); + stack.pop(); + } + + @Override + public void visitLocalVariableTable(LocalVariableTable table) { + stack.push(table); + table.accept(visitor); + LocalVariable[] vars = table.getLocalVariableTable(); + for (int i = 0; i < vars.length; i++) { + vars[i].accept(this); + } + stack.pop(); + } + + @Override + public void visitStackMap(StackMap table) { + stack.push(table); + table.accept(visitor); + StackMapEntry[] vars = table.getStackMap(); + for (int i = 0; i < vars.length; i++) { + vars[i].accept(this); + } + stack.pop(); + } + + @Override + public void visitStackMapEntry(StackMapEntry var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } + + @Override + public void visitLocalVariable(LocalVariable var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantPool(ConstantPool cp) { + stack.push(cp); + cp.accept(visitor); + Constant[] constants = cp.getConstantPool(); + for (int i = 1; i < constants.length; i++) { + if (constants[i] != null) { + constants[i].accept(this); + } + } + stack.pop(); + } + + @Override + public void visitConstantClass(ConstantClass constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantDouble(ConstantDouble constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantFieldref(ConstantFieldref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantFloat(ConstantFloat constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantInteger(ConstantInteger constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantInterfaceMethodref( + ConstantInterfaceMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantLong(ConstantLong constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantMethodref(ConstantMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantNameAndType(ConstantNameAndType constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantString(ConstantString constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantUtf8(ConstantUtf8 constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitInnerClasses(InnerClasses ic) { + stack.push(ic); + ic.accept(visitor); + InnerClass[] ics = ic.getInnerClasses(); + for (int i = 0; i < ics.length; i++) { + ics[i].accept(this); + } + stack.pop(); + } + + @Override + public void visitInnerClass(InnerClass inner) { + stack.push(inner); + inner.accept(visitor); + stack.pop(); + } + + @Override + public void visitDeprecated(Deprecated attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitSignature(Signature attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitSourceFile(SourceFile attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitSynthetic(Synthetic attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitUnknown(Unknown attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } } diff --git a/src/org/apache/bcel/classfile/EmptyVisitor.java b/src/org/apache/bcel/classfile/EmptyVisitor.java index 8652507..23e1794 100644 --- a/src/org/apache/bcel/classfile/EmptyVisitor.java +++ b/src/org/apache/bcel/classfile/EmptyVisitor.java @@ -17,145 +17,145 @@ package org.apache.bcel.classfile; /** - * Visitor with empty method bodies, can be extended and used in conjunction with the - * DescendingVisitor class, e.g. - * + * Visitor with empty method bodies, can be extended and used in conjunction + * with the DescendingVisitor class, e.g. + * * By courtesy of David Spencer. - * + * * @see DescendingVisitor * @version $Id: EmptyVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $ * */ public class EmptyVisitor implements Visitor { - protected EmptyVisitor() { - } + protected EmptyVisitor() { + } + @Override + public void visitCode(Code obj) { + } - public void visitCode( Code obj ) { - } + @Override + public void visitCodeException(CodeException obj) { + } + @Override + public void visitConstantClass(ConstantClass obj) { + } - public void visitCodeException( CodeException obj ) { - } + @Override + public void visitConstantDouble(ConstantDouble obj) { + } + @Override + public void visitConstantFieldref(ConstantFieldref obj) { + } - public void visitConstantClass( ConstantClass obj ) { - } + @Override + public void visitConstantFloat(ConstantFloat obj) { + } + @Override + public void visitConstantInteger(ConstantInteger obj) { + } - public void visitConstantDouble( ConstantDouble obj ) { - } + @Override + public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) { + } + @Override + public void visitConstantLong(ConstantLong obj) { + } - public void visitConstantFieldref( ConstantFieldref obj ) { - } + @Override + public void visitConstantMethodref(ConstantMethodref obj) { + } + @Override + public void visitConstantNameAndType(ConstantNameAndType obj) { + } - public void visitConstantFloat( ConstantFloat obj ) { - } + @Override + public void visitConstantPool(ConstantPool obj) { + } + @Override + public void visitConstantString(ConstantString obj) { + } - public void visitConstantInteger( ConstantInteger obj ) { - } + @Override + public void visitConstantUtf8(ConstantUtf8 obj) { + } + @Override + public void visitConstantValue(ConstantValue obj) { + } - public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref obj ) { - } + @Override + public void visitDeprecated(Deprecated obj) { + } + @Override + public void visitExceptionTable(ExceptionTable obj) { + } - public void visitConstantLong( ConstantLong obj ) { - } + @Override + public void visitField(Field obj) { + } + @Override + public void visitInnerClass(InnerClass obj) { + } - public void visitConstantMethodref( ConstantMethodref obj ) { - } + @Override + public void visitInnerClasses(InnerClasses obj) { + } + @Override + public void visitJavaClass(JavaClass obj) { + } - public void visitConstantNameAndType( ConstantNameAndType obj ) { - } + @Override + public void visitLineNumber(LineNumber obj) { + } + @Override + public void visitLineNumberTable(LineNumberTable obj) { + } - public void visitConstantPool( ConstantPool obj ) { - } + @Override + public void visitLocalVariable(LocalVariable obj) { + } + @Override + public void visitLocalVariableTable(LocalVariableTable obj) { + } - public void visitConstantString( ConstantString obj ) { - } + @Override + public void visitMethod(Method obj) { + } + @Override + public void visitSignature(Signature obj) { + } - public void visitConstantUtf8( ConstantUtf8 obj ) { - } + @Override + public void visitSourceFile(SourceFile obj) { + } + @Override + public void visitSynthetic(Synthetic obj) { + } - public void visitConstantValue( ConstantValue obj ) { - } + @Override + public void visitUnknown(Unknown obj) { + } + @Override + public void visitStackMap(StackMap obj) { + } - public void visitDeprecated( Deprecated obj ) { - } - - - public void visitExceptionTable( ExceptionTable obj ) { - } - - - public void visitField( Field obj ) { - } - - - public void visitInnerClass( InnerClass obj ) { - } - - - public void visitInnerClasses( InnerClasses obj ) { - } - - - public void visitJavaClass( JavaClass obj ) { - } - - - public void visitLineNumber( LineNumber obj ) { - } - - - public void visitLineNumberTable( LineNumberTable obj ) { - } - - - public void visitLocalVariable( LocalVariable obj ) { - } - - - public void visitLocalVariableTable( LocalVariableTable obj ) { - } - - - public void visitMethod( Method obj ) { - } - - - public void visitSignature( Signature obj ) { - } - - - public void visitSourceFile( SourceFile obj ) { - } - - - public void visitSynthetic( Synthetic obj ) { - } - - - public void visitUnknown( Unknown obj ) { - } - - - public void visitStackMap( StackMap obj ) { - } - - - public void visitStackMapEntry( StackMapEntry obj ) { - } + @Override + public void visitStackMapEntry(StackMapEntry obj) { + } } diff --git a/src/org/apache/bcel/classfile/ExceptionTable.java b/src/org/apache/bcel/classfile/ExceptionTable.java index b68bdc8..59a08ff 100644 --- a/src/org/apache/bcel/classfile/ExceptionTable.java +++ b/src/org/apache/bcel/classfile/ExceptionTable.java @@ -21,160 +21,171 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** - * This class represents the table of exceptions that are thrown by a - * method. This attribute may be used once per method. The name of - * this class is ExceptionTable for historical reasons; The - * Java Virtual Machine Specification, Second Edition defines this - * attribute using the name Exceptions (which is inconsistent - * with the other classes). - * +/** + * This class represents the table of exceptions that are thrown by a method. + * This attribute may be used once per method. The name of this class is + * ExceptionTable for historical reasons; The Java Virtual Machine + * Specification, Second Edition defines this attribute using the name + * Exceptions (which is inconsistent with the other classes). + * * @version $Id: ExceptionTable.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Code + * @author M. Dahm + * @see Code */ public final class ExceptionTable extends Attribute { - private int number_of_exceptions; // Table of indices into - private int[] exception_index_table; // constant pool + /** + * + */ + private static final long serialVersionUID = 1L; + private int number_of_exceptions; // Table of indices into + private int[] exception_index_table; // constant pool + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public ExceptionTable(ExceptionTable c) { + this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c + .getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public ExceptionTable(ExceptionTable c) { - this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c.getConstantPool()); - } + /** + * @param name_index + * Index in constant pool + * @param length + * Content length in bytes + * @param exception_index_table + * Table of indices in constant pool + * @param constant_pool + * Array of constants + */ + public ExceptionTable(int name_index, int length, + int[] exception_index_table, ConstantPool constant_pool) { + super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool); + setExceptionIndexTable(exception_index_table); + } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + ExceptionTable(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (int[]) null, constant_pool); + number_of_exceptions = file.readUnsignedShort(); + exception_index_table = new int[number_of_exceptions]; + for (int i = 0; i < number_of_exceptions; i++) { + exception_index_table[i] = file.readUnsignedShort(); + } + } - /** - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param exception_index_table Table of indices in constant pool - * @param constant_pool Array of constants - */ - public ExceptionTable(int name_index, int length, int[] exception_index_table, - ConstantPool constant_pool) { - super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool); - setExceptionIndexTable(exception_index_table); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionTable(this); + } + /** + * Dump exceptions attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(number_of_exceptions); + for (int i = 0; i < number_of_exceptions; i++) { + file.writeShort(exception_index_table[i]); + } + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - ExceptionTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (int[]) null, constant_pool); - number_of_exceptions = file.readUnsignedShort(); - exception_index_table = new int[number_of_exceptions]; - for (int i = 0; i < number_of_exceptions; i++) { - exception_index_table[i] = file.readUnsignedShort(); - } - } + /** + * @return Array of indices into constant pool of thrown exceptions. + */ + public final int[] getExceptionIndexTable() { + return exception_index_table; + } + /** + * @return Length of exception table. + */ + public final int getNumberOfExceptions() { + return number_of_exceptions; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionTable(this); - } + /** + * @return class names of thrown exceptions + */ + public final String[] getExceptionNames() { + String[] names = new String[number_of_exceptions]; + for (int i = 0; i < number_of_exceptions; i++) { + names[i] = constant_pool.getConstantString( + exception_index_table[i], Constants.CONSTANT_Class) + .replace('/', '.'); + } + return names; + } + /** + * @param exception_index_table + * the list of exception indexes Also redefines + * number_of_exceptions according to table length. + */ + public final void setExceptionIndexTable(int[] exception_index_table) { + this.exception_index_table = exception_index_table; + number_of_exceptions = (exception_index_table == null) ? 0 + : exception_index_table.length; + } - /** - * Dump exceptions attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(number_of_exceptions); - for (int i = 0; i < number_of_exceptions; i++) { - file.writeShort(exception_index_table[i]); - } - } + /** + * @return String representation, i.e., a list of thrown exceptions. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(""); + String str; + for (int i = 0; i < number_of_exceptions; i++) { + str = constant_pool.getConstantString(exception_index_table[i], + Constants.CONSTANT_Class); + buf.append(Utility.compactClassName(str, false)); + if (i < number_of_exceptions - 1) { + buf.append(", "); + } + } + return buf.toString(); + } - - /** - * @return Array of indices into constant pool of thrown exceptions. - */ - public final int[] getExceptionIndexTable() { - return exception_index_table; - } - - - /** - * @return Length of exception table. - */ - public final int getNumberOfExceptions() { - return number_of_exceptions; - } - - - /** - * @return class names of thrown exceptions - */ - public final String[] getExceptionNames() { - String[] names = new String[number_of_exceptions]; - for (int i = 0; i < number_of_exceptions; i++) { - names[i] = constant_pool.getConstantString(exception_index_table[i], - Constants.CONSTANT_Class).replace('/', '.'); - } - return names; - } - - - /** - * @param exception_index_table the list of exception indexes - * Also redefines number_of_exceptions according to table length. - */ - public final void setExceptionIndexTable( int[] exception_index_table ) { - this.exception_index_table = exception_index_table; - number_of_exceptions = (exception_index_table == null) ? 0 : exception_index_table.length; - } - - - /** - * @return String representation, i.e., a list of thrown exceptions. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(""); - String str; - for (int i = 0; i < number_of_exceptions; i++) { - str = constant_pool.getConstantString(exception_index_table[i], - Constants.CONSTANT_Class); - buf.append(Utility.compactClassName(str, false)); - if (i < number_of_exceptions - 1) { - buf.append(", "); - } - } - return buf.toString(); - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - ExceptionTable c = (ExceptionTable) clone(); - if (exception_index_table != null) { - c.exception_index_table = new int[exception_index_table.length]; - System.arraycopy(exception_index_table, 0, c.exception_index_table, 0, - exception_index_table.length); - } - c.constant_pool = _constant_pool; - return c; - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + ExceptionTable c = (ExceptionTable) clone(); + if (exception_index_table != null) { + c.exception_index_table = new int[exception_index_table.length]; + System.arraycopy(exception_index_table, 0, c.exception_index_table, + 0, exception_index_table.length); + } + c.constant_pool = _constant_pool; + return c; + } } diff --git a/src/org/apache/bcel/classfile/Field.java b/src/org/apache/bcel/classfile/Field.java index 7cbffdd..4ed0777 100644 --- a/src/org/apache/bcel/classfile/Field.java +++ b/src/org/apache/bcel/classfile/Field.java @@ -23,168 +23,175 @@ import org.apache.bcel.generic.Type; import org.apache.bcel.util.BCELComparator; /** - * This class represents the field info structure, i.e., the representation - * for a variable in the class. See JVM specification for details. - * + * This class represents the field info structure, i.e., the representation for + * a variable in the class. See JVM specification for details. + * * @version $Id: Field.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class Field extends FieldOrMethod { - private static BCELComparator _cmp = new BCELComparator() { + /** + * + */ + private static final long serialVersionUID = 1L; + private static BCELComparator _cmp = new BCELComparator() { - public boolean equals( Object o1, Object o2 ) { - Field THIS = (Field) o1; - Field THAT = (Field) o2; - return THIS.getName().equals(THAT.getName()) - && THIS.getSignature().equals(THAT.getSignature()); - } + @Override + public boolean equals(Object o1, Object o2) { + Field THIS = (Field) o1; + Field THAT = (Field) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } + @Override + public int hashCode(Object o) { + Field THIS = (Field) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; - public int hashCode( Object o ) { - Field THIS = (Field) o; - return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); - } - }; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Field(Field c) { + super(c); + } + /** + * Construct object from file stream. + * + * @param file + * Input stream + */ + Field(DataInputStream file, ConstantPool constant_pool) throws IOException, + ClassFormatException { + super(file, constant_pool); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Field(Field c) { - super(c); - } + /** + * @param access_flags + * Access rights of field + * @param name_index + * Points to field name in constant pool + * @param signature_index + * Points to encoded signature + * @param attributes + * Collection of attributes + * @param constant_pool + * Array of constants + */ + public Field(int access_flags, int name_index, int signature_index, + Attribute[] attributes, ConstantPool constant_pool) { + super(access_flags, name_index, signature_index, attributes, + constant_pool); + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitField(this); + } - /** - * Construct object from file stream. - * @param file Input stream - */ - Field(DataInputStream file, ConstantPool constant_pool) throws IOException, - ClassFormatException { - super(file, constant_pool); - } + /** + * @return constant value associated with this field (may be null) + */ + public final ConstantValue getConstantValue() { + for (int i = 0; i < attributes_count; i++) { + if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) { + return (ConstantValue) attributes[i]; + } + } + return null; + } + /** + * Return string representation close to declaration format, `public static + * final short MAX = 100', e.g.. + * + * @return String representation of field, including the signature. + */ + @Override + public final String toString() { + String name, signature, access; // Short cuts to constant pool + // Get names from constant pool + access = Utility.accessToString(access_flags); + access = access.equals("") ? "" : (access + " "); + signature = Utility.signatureToString(getSignature()); + name = getName(); + StringBuffer buf = new StringBuffer(64); + buf.append(access).append(signature).append(" ").append(name); + ConstantValue cv = getConstantValue(); + if (cv != null) { + buf.append(" = ").append(cv); + } + for (int i = 0; i < attributes_count; i++) { + Attribute a = attributes[i]; + if (!(a instanceof ConstantValue)) { + buf.append(" [").append(a.toString()).append("]"); + } + } + return buf.toString(); + } - /** - * @param access_flags Access rights of field - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature - * @param attributes Collection of attributes - * @param constant_pool Array of constants - */ - public Field(int access_flags, int name_index, int signature_index, Attribute[] attributes, - ConstantPool constant_pool) { - super(access_flags, name_index, signature_index, attributes, constant_pool); - } + /** + * @return deep copy of this field + */ + public final Field copy(ConstantPool _constant_pool) { + return (Field) copy_(_constant_pool); + } + /** + * @return type of field + */ + public Type getType() { + return Type.getReturnType(getSignature()); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitField(this); - } + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + /** + * @param comparator + * Comparison strategy object + */ + public static void setComparator(BCELComparator comparator) { + _cmp = comparator; + } - /** - * @return constant value associated with this field (may be null) - */ - public final ConstantValue getConstantValue() { - for (int i = 0; i < attributes_count; i++) { - if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) { - return (ConstantValue) attributes[i]; - } - } - return null; - } + /** + * Return value as defined by given BCELComparator strategy. By default two + * Field objects are said to be equal when their names and signatures are + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return _cmp.equals(this, obj); + } - - /** - * Return string representation close to declaration format, - * `public static final short MAX = 100', e.g.. - * - * @return String representation of field, including the signature. - */ - public final String toString() { - String name, signature, access; // Short cuts to constant pool - // Get names from constant pool - access = Utility.accessToString(access_flags); - access = access.equals("") ? "" : (access + " "); - signature = Utility.signatureToString(getSignature()); - name = getName(); - StringBuffer buf = new StringBuffer(64); - buf.append(access).append(signature).append(" ").append(name); - ConstantValue cv = getConstantValue(); - if (cv != null) { - buf.append(" = ").append(cv); - } - for (int i = 0; i < attributes_count; i++) { - Attribute a = attributes[i]; - if (!(a instanceof ConstantValue)) { - buf.append(" [").append(a.toString()).append("]"); - } - } - return buf.toString(); - } - - - /** - * @return deep copy of this field - */ - public final Field copy( ConstantPool _constant_pool ) { - return (Field) copy_(_constant_pool); - } - - - /** - * @return type of field - */ - public Type getType() { - return Type.getReturnType(getSignature()); - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return _cmp; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( BCELComparator comparator ) { - _cmp = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two Field objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals( Object obj ) { - return _cmp.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the field's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return _cmp.hashCode(this); - } + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the field's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); + } } diff --git a/src/org/apache/bcel/classfile/FieldOrMethod.java b/src/org/apache/bcel/classfile/FieldOrMethod.java index 885164b..03b0fff 100644 --- a/src/org/apache/bcel/classfile/FieldOrMethod.java +++ b/src/org/apache/bcel/classfile/FieldOrMethod.java @@ -21,186 +21,190 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; -/** +/** * Abstract super class for fields and methods. - * + * * @version $Id: FieldOrMethod.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node { +public abstract class FieldOrMethod extends AccessFlags implements Cloneable, + Node { - protected int name_index; // Points to field name in constant pool - protected int signature_index; // Points to encoded signature - protected int attributes_count; // No. of attributes - protected Attribute[] attributes; // Collection of attributes - protected ConstantPool constant_pool; + /** + * + */ + private static final long serialVersionUID = 1L; + protected int name_index; // Points to field name in constant pool + protected int signature_index; // Points to encoded signature + protected int attributes_count; // No. of attributes + protected Attribute[] attributes; // Collection of attributes + protected ConstantPool constant_pool; + FieldOrMethod() { + } - FieldOrMethod() { - } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + protected FieldOrMethod(FieldOrMethod c) { + this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c + .getAttributes(), c.getConstantPool()); + } + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + * @throws ClassFormatException + */ + protected FieldOrMethod(DataInputStream file, ConstantPool constant_pool) + throws IOException, ClassFormatException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort(), null, constant_pool); + attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + attributes[i] = Attribute.readAttribute(file, constant_pool); + } + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - protected FieldOrMethod(FieldOrMethod c) { - this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c - .getConstantPool()); - } + /** + * @param access_flags + * Access rights of method + * @param name_index + * Points to field name in constant pool + * @param signature_index + * Points to encoded signature + * @param attributes + * Collection of attributes + * @param constant_pool + * Array of constants + */ + protected FieldOrMethod(int access_flags, int name_index, + int signature_index, Attribute[] attributes, + ConstantPool constant_pool) { + this.access_flags = access_flags; + this.name_index = name_index; + this.signature_index = signature_index; + this.constant_pool = constant_pool; + setAttributes(attributes); + } + /** + * Dump object to file stream on binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(access_flags); + file.writeShort(name_index); + file.writeShort(signature_index); + file.writeShort(attributes_count); + for (int i = 0; i < attributes_count; i++) { + attributes[i].dump(file); + } + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - * @throws ClassFormatException - */ - protected FieldOrMethod(DataInputStream file, ConstantPool constant_pool) throws IOException, - ClassFormatException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, - constant_pool); - attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { - attributes[i] = Attribute.readAttribute(file, constant_pool); - } - } + /** + * @return Collection of object attributes. + */ + public final Attribute[] getAttributes() { + return attributes; + } + /** + * @param attributes + * Collection of object attributes. + */ + public final void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + attributes_count = (attributes == null) ? 0 : attributes.length; + } - /** - * @param access_flags Access rights of method - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature - * @param attributes Collection of attributes - * @param constant_pool Array of constants - */ - protected FieldOrMethod(int access_flags, int name_index, int signature_index, - Attribute[] attributes, ConstantPool constant_pool) { - this.access_flags = access_flags; - this.name_index = name_index; - this.signature_index = signature_index; - this.constant_pool = constant_pool; - setAttributes(attributes); - } + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } + /** + * @param constant_pool + * Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } - /** - * Dump object to file stream on binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeShort(access_flags); - file.writeShort(name_index); - file.writeShort(signature_index); - file.writeShort(attributes_count); - for (int i = 0; i < attributes_count; i++) { - attributes[i].dump(file); - } - } + /** + * @return Index in constant pool of object's name. + */ + public final int getNameIndex() { + return name_index; + } + /** + * @param name_index + * Index in constant pool of object's name. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } - /** - * @return Collection of object attributes. - */ - public final Attribute[] getAttributes() { - return attributes; - } + /** + * @return Index in constant pool of field signature. + */ + public final int getSignatureIndex() { + return signature_index; + } + /** + * @param signature_index + * Index in constant pool of field signature. + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } - /** - * @param attributes Collection of object attributes. - */ - public final void setAttributes( Attribute[] attributes ) { - this.attributes = attributes; - attributes_count = (attributes == null) ? 0 : attributes.length; - } + /** + * @return Name of object, i.e., method name or field name + */ + public final String getName() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(name_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + /** + * @return String representation of object's type signature (java style) + */ + public final String getSignature() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(signature_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { - return constant_pool; - } - - - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool( ConstantPool constant_pool ) { - this.constant_pool = constant_pool; - } - - - /** - * @return Index in constant pool of object's name. - */ - public final int getNameIndex() { - return name_index; - } - - - /** - * @param name_index Index in constant pool of object's name. - */ - public final void setNameIndex( int name_index ) { - this.name_index = name_index; - } - - - /** - * @return Index in constant pool of field signature. - */ - public final int getSignatureIndex() { - return signature_index; - } - - - /** - * @param signature_index Index in constant pool of field signature. - */ - public final void setSignatureIndex( int signature_index ) { - this.signature_index = signature_index; - } - - - /** - * @return Name of object, i.e., method name or field name - */ - public final String getName() { - ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8); - return c.getBytes(); - } - - - /** - * @return String representation of object's type signature (java style) - */ - public final String getSignature() { - ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8); - return c.getBytes(); - } - - - /** - * @return deep copy of this field - */ - protected FieldOrMethod copy_( ConstantPool _constant_pool ) { - try { - FieldOrMethod c = (FieldOrMethod) clone(); - c.constant_pool = _constant_pool; - c.attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { - c.attributes[i] = attributes[i].copy(_constant_pool); - } - return c; - } catch (CloneNotSupportedException e) { - return null; - } - } + /** + * @return deep copy of this field + */ + protected FieldOrMethod copy_(ConstantPool _constant_pool) { + try { + FieldOrMethod c = (FieldOrMethod) clone(); + c.constant_pool = _constant_pool; + c.attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + c.attributes[i] = attributes[i].copy(_constant_pool); + } + return c; + } catch (CloneNotSupportedException e) { + return null; + } + } } diff --git a/src/org/apache/bcel/classfile/InnerClass.java b/src/org/apache/bcel/classfile/InnerClass.java index 794ade5..52cbf32 100644 --- a/src/org/apache/bcel/classfile/InnerClass.java +++ b/src/org/apache/bcel/classfile/InnerClass.java @@ -22,193 +22,194 @@ import java.io.IOException; import java.io.Serializable; import org.apache.bcel.Constants; -/** - * This class represents a inner class attribute, i.e., the class - * indices of the inner and outer classes, the name and the attributes - * of the inner class. - * +/** + * This class represents a inner class attribute, i.e., the class indices of the + * inner and outer classes, the name and the attributes of the inner class. + * * @version $Id: InnerClass.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see InnerClasses */ public final class InnerClass implements Cloneable, Node, Serializable { - private int inner_class_index; - private int outer_class_index; - private int inner_name_index; - private int inner_access_flags; + /** + * + */ + private static final long serialVersionUID = 1L; + private int inner_class_index; + private int outer_class_index; + private int inner_name_index; + private int inner_access_flags; + /** + * Initialize from another object. + */ + public InnerClass(InnerClass c) { + this(c.getInnerClassIndex(), c.getOuterClassIndex(), c + .getInnerNameIndex(), c.getInnerAccessFlags()); + } - /** - * Initialize from another object. - */ - public InnerClass(InnerClass c) { - this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c - .getInnerAccessFlags()); - } + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + */ + InnerClass(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort(), file.readUnsignedShort()); + } + /** + * @param inner_class_index + * Class index in constant pool of inner class + * @param outer_class_index + * Class index in constant pool of outer class + * @param inner_name_index + * Name index in constant pool of inner class + * @param inner_access_flags + * Access flags of inner class + */ + public InnerClass(int inner_class_index, int outer_class_index, + int inner_name_index, int inner_access_flags) { + this.inner_class_index = inner_class_index; + this.outer_class_index = outer_class_index; + this.inner_name_index = inner_name_index; + this.inner_access_flags = inner_access_flags; + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - InnerClass(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file - .readUnsignedShort()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitInnerClass(this); + } + /** + * Dump inner class attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(inner_class_index); + file.writeShort(outer_class_index); + file.writeShort(inner_name_index); + file.writeShort(inner_access_flags); + } - /** - * @param inner_class_index Class index in constant pool of inner class - * @param outer_class_index Class index in constant pool of outer class - * @param inner_name_index Name index in constant pool of inner class - * @param inner_access_flags Access flags of inner class - */ - public InnerClass(int inner_class_index, int outer_class_index, int inner_name_index, - int inner_access_flags) { - this.inner_class_index = inner_class_index; - this.outer_class_index = outer_class_index; - this.inner_name_index = inner_name_index; - this.inner_access_flags = inner_access_flags; - } + /** + * @return access flags of inner class. + */ + public final int getInnerAccessFlags() { + return inner_access_flags; + } + /** + * @return class index of inner class. + */ + public final int getInnerClassIndex() { + return inner_class_index; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitInnerClass(this); - } + /** + * @return name index of inner class. + */ + public final int getInnerNameIndex() { + return inner_name_index; + } + /** + * @return class index of outer class. + */ + public final int getOuterClassIndex() { + return outer_class_index; + } - /** - * Dump inner class attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeShort(inner_class_index); - file.writeShort(outer_class_index); - file.writeShort(inner_name_index); - file.writeShort(inner_access_flags); - } + /** + * @param inner_access_flags + * access flags for this inner class + */ + public final void setInnerAccessFlags(int inner_access_flags) { + this.inner_access_flags = inner_access_flags; + } + /** + * @param inner_class_index + * index into the constant pool for this class + */ + public final void setInnerClassIndex(int inner_class_index) { + this.inner_class_index = inner_class_index; + } - /** - * @return access flags of inner class. - */ - public final int getInnerAccessFlags() { - return inner_access_flags; - } + /** + * @param inner_name_index + * index into the constant pool for this class's name + */ + public final void setInnerNameIndex(int inner_name_index) { + this.inner_name_index = inner_name_index; + } + /** + * @param outer_class_index + * index into the constant pool for the owning class + */ + public final void setOuterClassIndex(int outer_class_index) { + this.outer_class_index = outer_class_index; + } - /** - * @return class index of inner class. - */ - public final int getInnerClassIndex() { - return inner_class_index; - } + /** + * @return String representation. + */ + @Override + public final String toString() { + return "InnerClass(" + inner_class_index + ", " + outer_class_index + + ", " + inner_name_index + ", " + inner_access_flags + ")"; + } + /** + * @return Resolved string representation + */ + public final String toString(ConstantPool constant_pool) { + String inner_class_name, outer_class_name, inner_name, access; + inner_class_name = constant_pool.getConstantString(inner_class_index, + Constants.CONSTANT_Class); + inner_class_name = Utility.compactClassName(inner_class_name); + if (outer_class_index != 0) { + outer_class_name = constant_pool.getConstantString( + outer_class_index, Constants.CONSTANT_Class); + outer_class_name = Utility.compactClassName(outer_class_name); + } else { + outer_class_name = ""; + } + if (inner_name_index != 0) { + inner_name = ((ConstantUtf8) constant_pool.getConstant( + inner_name_index, Constants.CONSTANT_Utf8)).getBytes(); + } else { + inner_name = ""; + } + access = Utility.accessToString(inner_access_flags, true); + access = access.equals("") ? "" : (access + " "); + return "InnerClass:" + access + inner_class_name + "(\"" + + outer_class_name + "\", \"" + inner_name + "\")"; + } - /** - * @return name index of inner class. - */ - public final int getInnerNameIndex() { - return inner_name_index; - } - - - /** - * @return class index of outer class. - */ - public final int getOuterClassIndex() { - return outer_class_index; - } - - - /** - * @param inner_access_flags access flags for this inner class - */ - public final void setInnerAccessFlags( int inner_access_flags ) { - this.inner_access_flags = inner_access_flags; - } - - - /** - * @param inner_class_index index into the constant pool for this class - */ - public final void setInnerClassIndex( int inner_class_index ) { - this.inner_class_index = inner_class_index; - } - - - /** - * @param inner_name_index index into the constant pool for this class's name - */ - public final void setInnerNameIndex( int inner_name_index ) { - this.inner_name_index = inner_name_index; - } - - - /** - * @param outer_class_index index into the constant pool for the owning class - */ - public final void setOuterClassIndex( int outer_class_index ) { - this.outer_class_index = outer_class_index; - } - - - /** - * @return String representation. - */ - public final String toString() { - return "InnerClass(" + inner_class_index + ", " + outer_class_index + ", " - + inner_name_index + ", " + inner_access_flags + ")"; - } - - - /** - * @return Resolved string representation - */ - public final String toString( ConstantPool constant_pool ) { - String inner_class_name, outer_class_name, inner_name, access; - inner_class_name = constant_pool.getConstantString(inner_class_index, - Constants.CONSTANT_Class); - inner_class_name = Utility.compactClassName(inner_class_name); - if (outer_class_index != 0) { - outer_class_name = constant_pool.getConstantString(outer_class_index, - Constants.CONSTANT_Class); - outer_class_name = Utility.compactClassName(outer_class_name); - } else { - outer_class_name = ""; - } - if (inner_name_index != 0) { - inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index, - Constants.CONSTANT_Utf8)).getBytes(); - } else { - inner_name = ""; - } - access = Utility.accessToString(inner_access_flags, true); - access = access.equals("") ? "" : (access + " "); - return "InnerClass:" + access + inner_class_name + "(\"" + outer_class_name + "\", \"" - + inner_name + "\")"; - } - - - /** - * @return deep copy of this object - */ - public InnerClass copy() { - try { - return (InnerClass) clone(); - } catch (CloneNotSupportedException e) { - } - return null; - } + /** + * @return deep copy of this object + */ + public InnerClass copy() { + try { + return (InnerClass) clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } } diff --git a/src/org/apache/bcel/classfile/InnerClasses.java b/src/org/apache/bcel/classfile/InnerClasses.java index dd63e9b..d47e3ed 100644 --- a/src/org/apache/bcel/classfile/InnerClasses.java +++ b/src/org/apache/bcel/classfile/InnerClasses.java @@ -22,129 +22,139 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class is derived from Attribute and denotes that this class - * is an Inner class of another. - * to the source file of this class. - * It is instantiated from the Attribute.readAttribute() method. - * + * This class is derived from Attribute and denotes that this class is + * an Inner class of another. to the source file of this class. It is + * instantiated from the Attribute.readAttribute() method. + * * @version $Id: InnerClasses.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute + * @author M. Dahm + * @see Attribute */ public final class InnerClasses extends Attribute { - private InnerClass[] inner_classes; - private int number_of_classes; + /** + * + */ + private static final long serialVersionUID = 1L; + private InnerClass[] inner_classes; + private int number_of_classes; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public InnerClasses(InnerClasses c) { + this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c + .getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public InnerClasses(InnerClasses c) { - this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool()); - } + /** + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param inner_classes + * array of inner classes attributes + * @param constant_pool + * Array of constants + */ + public InnerClasses(int name_index, int length, InnerClass[] inner_classes, + ConstantPool constant_pool) { + super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool); + setInnerClasses(inner_classes); + } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + InnerClasses(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (InnerClass[]) null, constant_pool); + number_of_classes = file.readUnsignedShort(); + inner_classes = new InnerClass[number_of_classes]; + for (int i = 0; i < number_of_classes; i++) { + inner_classes[i] = new InnerClass(file); + } + } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param inner_classes array of inner classes attributes - * @param constant_pool Array of constants - */ - public InnerClasses(int name_index, int length, InnerClass[] inner_classes, - ConstantPool constant_pool) { - super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool); - setInnerClasses(inner_classes); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitInnerClasses(this); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(number_of_classes); + for (int i = 0; i < number_of_classes; i++) { + inner_classes[i].dump(file); + } + } - /** - * Construct object from file stream. - * - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - InnerClasses(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (InnerClass[]) null, constant_pool); - number_of_classes = file.readUnsignedShort(); - inner_classes = new InnerClass[number_of_classes]; - for (int i = 0; i < number_of_classes; i++) { - inner_classes[i] = new InnerClass(file); - } - } + /** + * @return array of inner class "records" + */ + public final InnerClass[] getInnerClasses() { + return inner_classes; + } + /** + * @param inner_classes + * the array of inner classes + */ + public final void setInnerClasses(InnerClass[] inner_classes) { + this.inner_classes = inner_classes; + number_of_classes = (inner_classes == null) ? 0 : inner_classes.length; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitInnerClasses(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < number_of_classes; i++) { + buf.append(inner_classes[i].toString(constant_pool)).append("\n"); + } + return buf.toString(); + } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(number_of_classes); - for (int i = 0; i < number_of_classes; i++) { - inner_classes[i].dump(file); - } - } - - - /** - * @return array of inner class "records" - */ - public final InnerClass[] getInnerClasses() { - return inner_classes; - } - - - /** - * @param inner_classes the array of inner classes - */ - public final void setInnerClasses( InnerClass[] inner_classes ) { - this.inner_classes = inner_classes; - number_of_classes = (inner_classes == null) ? 0 : inner_classes.length; - } - - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < number_of_classes; i++) { - buf.append(inner_classes[i].toString(constant_pool)).append("\n"); - } - return buf.toString(); - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - InnerClasses c = (InnerClasses) clone(); - c.inner_classes = new InnerClass[number_of_classes]; - for (int i = 0; i < number_of_classes; i++) { - c.inner_classes[i] = inner_classes[i].copy(); - } - c.constant_pool = _constant_pool; - return c; - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + InnerClasses c = (InnerClasses) clone(); + c.inner_classes = new InnerClass[number_of_classes]; + for (int i = 0; i < number_of_classes; i++) { + c.inner_classes[i] = inner_classes[i].copy(); + } + c.constant_pool = _constant_pool; + return c; + } } diff --git a/src/org/apache/bcel/classfile/JavaClass.java b/src/org/apache/bcel/classfile/JavaClass.java index de8d91d..faf2a08 100644 --- a/src/org/apache/bcel/classfile/JavaClass.java +++ b/src/org/apache/bcel/classfile/JavaClass.java @@ -35,837 +35,847 @@ import org.apache.bcel.util.ClassQueue; import org.apache.bcel.util.SyntheticRepository; /** - * Represents a Java class, i.e., the data structures, constant pool, - * fields, methods and commands contained in a Java .class file. - * See JVM specification for details. - * The intent of this class is to represent a parsed or otherwise existing - * class file. Those interested in programatically generating classes - * should see the ClassGen class. - + * Represents a Java class, i.e., the data structures, constant pool, fields, + * methods and commands contained in a Java .class file. See JVM specification for details. The + * intent of this class is to represent a parsed or otherwise existing class + * file. Those interested in programatically generating classes should see the + * ClassGen class. + * * @version $Id: JavaClass.java 386056 2006-03-15 11:31:56Z tcurdt $ * @see org.apache.bcel.generic.ClassGen - * @author M. Dahm + * @author M. Dahm */ -public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable { +public class JavaClass extends AccessFlags implements Cloneable, Node, + Comparable { /** * */ private static final long serialVersionUID = 1L; private String file_name; - private String package_name; - private String source_file_name = ""; - private int class_name_index; - private int superclass_name_index; - private String class_name; - private String superclass_name; - private int major, minor; // Compiler version - private ConstantPool constant_pool; // Constant pool - private int[] interfaces; // implemented interfaces - private String[] interface_names; - private Field[] fields; // Fields, i.e., variables of class - private Method[] methods; // methods defined in the class - private Attribute[] attributes; // attributes defined in the class - private byte source = HEAP; // Generated in memory - public static final byte HEAP = 1; - public static final byte FILE = 2; - public static final byte ZIP = 3; - static boolean debug = false; // Debugging on/off - static char sep = '/'; // directory separator - private static BCELComparator _cmp = new BCELComparator() { - - public boolean equals( Object o1, Object o2 ) { - JavaClass THIS = (JavaClass) o1; - JavaClass THAT = (JavaClass) o2; - return THIS.getClassName().equals(THAT.getClassName()); - } - - - public int hashCode( Object o ) { - JavaClass THIS = (JavaClass) o; - return THIS.getClassName().hashCode(); - } - }; - /** - * In cases where we go ahead and create something, - * use the default SyntheticRepository, because we - * don't know any better. - */ - private transient org.apache.bcel.util.Repository repository = SyntheticRepository - .getInstance(); - - - /** - * Constructor gets all contents as arguments. - * - * @param class_name_index Index into constant pool referencing a - * ConstantClass that represents this class. - * @param superclass_name_index Index into constant pool referencing a - * ConstantClass that represents this class's superclass. - * @param file_name File name - * @param major Major compiler version - * @param minor Minor compiler version - * @param access_flags Access rights defined by bit flags - * @param constant_pool Array of constants - * @param interfaces Implemented interfaces - * @param fields Class fields - * @param methods Class methods - * @param attributes Class attributes - * @param source Read from file or generated in memory? - */ - public JavaClass(int class_name_index, int superclass_name_index, String file_name, int major, - int minor, int access_flags, ConstantPool constant_pool, int[] interfaces, - Field[] fields, Method[] methods, Attribute[] attributes, byte source) { - if (interfaces == null) { - interfaces = new int[0]; - } - if (attributes == null) { - attributes = new Attribute[0]; - } - if (fields == null) { - fields = new Field[0]; - } - if (methods == null) { - methods = new Method[0]; - } - this.class_name_index = class_name_index; - this.superclass_name_index = superclass_name_index; - this.file_name = file_name; - this.major = major; - this.minor = minor; - this.access_flags = access_flags; - this.constant_pool = constant_pool; - this.interfaces = interfaces; - this.fields = fields; - this.methods = methods; - this.attributes = attributes; - this.source = source; - // Get source file name if available - for (int i = 0; i < attributes.length; i++) { - if (attributes[i] instanceof SourceFile) { - source_file_name = ((SourceFile) attributes[i]).getSourceFileName(); - break; - } - } - /* According to the specification the following entries must be of type - * `ConstantClass' but we check that anyway via the - * `ConstPool.getConstant' method. - */ - class_name = constant_pool.getConstantString(class_name_index, Constants.CONSTANT_Class); - class_name = Utility.compactClassName(class_name, false); - int index = class_name.lastIndexOf('.'); - if (index < 0) { - package_name = ""; - } else { - package_name = class_name.substring(0, index); - } - if (superclass_name_index > 0) { - // May be zero -> class is java.lang.Object - superclass_name = constant_pool.getConstantString(superclass_name_index, - Constants.CONSTANT_Class); - superclass_name = Utility.compactClassName(superclass_name, false); - } else { - superclass_name = "java.lang.Object"; - } - interface_names = new String[interfaces.length]; - for (int i = 0; i < interfaces.length; i++) { - String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class); - interface_names[i] = Utility.compactClassName(str, false); - } - } - - - /** - * Constructor gets all contents as arguments. - * - * @param class_name_index Class name - * @param superclass_name_index Superclass name - * @param file_name File name - * @param major Major compiler version - * @param minor Minor compiler version - * @param access_flags Access rights defined by bit flags - * @param constant_pool Array of constants - * @param interfaces Implemented interfaces - * @param fields Class fields - * @param methods Class methods - * @param attributes Class attributes - */ - public JavaClass(int class_name_index, int superclass_name_index, String file_name, int major, - int minor, int access_flags, ConstantPool constant_pool, int[] interfaces, - Field[] fields, Method[] methods, Attribute[] attributes) { - this(class_name_index, superclass_name_index, file_name, major, minor, access_flags, - constant_pool, interfaces, fields, methods, attributes, HEAP); - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitJavaClass(this); - } - - - /* Print debug information depending on `JavaClass.debug' - */ - static final void Debug( String str ) { - if (debug) { - System.out.println(str); - } - } - - - /** - * Dump class to a file. - * - * @param file Output file - * @throws IOException - */ - public void dump( File file ) throws IOException { - String parent = file.getParent(); - if (parent != null) { - File dir = new File(parent); - dir.mkdirs(); - } - DataOutputStream dos = null; - try { - dos = new DataOutputStream(new FileOutputStream(file)); - dump(dos); - } finally { - if (dos != null) { - dos.close(); - } - } - } - - - /** - * Dump class to a file named file_name. - * - * @param _file_name Output file name - * @exception IOException - */ - public void dump( String _file_name ) throws IOException { - dump(new File(_file_name)); - } - - - /** - * @return class in binary format - */ - public byte[] getBytes() { - ByteArrayOutputStream s = new ByteArrayOutputStream(); - DataOutputStream ds = new DataOutputStream(s); - try { - dump(ds); - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - ds.close(); - } catch (IOException e2) { - e2.printStackTrace(); - } - } - return s.toByteArray(); - } - - - /** - * Dump Java class to output stream in binary format. - * - * @param file Output stream - * @exception IOException - */ - public void dump( OutputStream file ) throws IOException { - dump(new DataOutputStream(file)); - } - - - /** - * Dump Java class to output stream in binary format. - * - * @param file Output stream - * @exception IOException - */ - public void dump( DataOutputStream file ) throws IOException { - file.writeInt(0xcafebabe); - file.writeShort(minor); - file.writeShort(major); - constant_pool.dump(file); - file.writeShort(access_flags); - file.writeShort(class_name_index); - file.writeShort(superclass_name_index); - file.writeShort(interfaces.length); - for (int i = 0; i < interfaces.length; i++) { - file.writeShort(interfaces[i]); - } - file.writeShort(fields.length); - for (int i = 0; i < fields.length; i++) { - fields[i].dump(file); - } - file.writeShort(methods.length); - for (int i = 0; i < methods.length; i++) { - methods[i].dump(file); - } - if (attributes != null) { - file.writeShort(attributes.length); - for (int i = 0; i < attributes.length; i++) { - attributes[i].dump(file); - } - } else { - file.writeShort(0); - } - file.flush(); - } - - - /** - * @return Attributes of the class. - */ - public Attribute[] getAttributes() { - return attributes; - } - - - /** - * @return Class name. - */ - public String getClassName() { - return class_name; - } - - - /** - * @return Package name. - */ - public String getPackageName() { - return package_name; - } - - - /** - * @return Class name index. - */ - public int getClassNameIndex() { - return class_name_index; - } - - - /** - * @return Constant pool. - */ - public ConstantPool getConstantPool() { - return constant_pool; - } - - - /** - * @return Fields, i.e., variables of the class. Like the JVM spec - * mandates for the classfile format, these fields are those specific to - * this class, and not those of the superclass or superinterfaces. - */ - public Field[] getFields() { - return fields; - } - - - /** - * @return File name of class, aka SourceFile attribute value - */ - public String getFileName() { - return file_name; - } - - - /** - * @return Names of implemented interfaces. - */ - public String[] getInterfaceNames() { - return interface_names; - } - - - /** - * @return Indices in constant pool of implemented interfaces. - */ - public int[] getInterfaceIndices() { - return interfaces; - } - - - /** - * @return Major number of class file version. - */ - public int getMajor() { - return major; - } - - - /** - * @return Methods of the class. - */ - public Method[] getMethods() { - return methods; - } - - - /** - * @return A org.apache.bcel.classfile.Method corresponding to - * java.lang.reflect.Method if any - */ - public Method getMethod( java.lang.reflect.Method m ) { - for (int i = 0; i < methods.length; i++) { - Method method = methods[i]; - if (m.getName().equals(method.getName()) && (m.getModifiers() == method.getModifiers()) - && Type.getSignature(m).equals(method.getSignature())) { - return method; - } - } - return null; - } - - - /** - * @return Minor number of class file version. - */ - public int getMinor() { - return minor; - } - - - /** - * @return sbsolute path to file where this class was read from - */ - public String getSourceFileName() { - return source_file_name; - } - - - /** - * @return Superclass name. - */ - public String getSuperclassName() { - return superclass_name; - } - - - /** - * @return Class name index. - */ - public int getSuperclassNameIndex() { - return superclass_name_index; - } - - static { - // Debugging ... on/off - debug = Boolean.getBoolean("JavaClass.debug"); - // Get path separator either / or \ usually - String _sep = System.getProperty("file.separator"); - if (_sep != null) { - try { - JavaClass.sep = _sep.charAt(0); - } catch (StringIndexOutOfBoundsException e) { - } // Never reached - } - } - - - /** - * @param attributes . - */ - public void setAttributes( Attribute[] attributes ) { - this.attributes = attributes; - } - - - /** - * @param class_name . - */ - public void setClassName( String class_name ) { - this.class_name = class_name; - } - - - /** - * @param class_name_index . - */ - public void setClassNameIndex( int class_name_index ) { - this.class_name_index = class_name_index; - } - - - /** - * @param constant_pool . - */ - public void setConstantPool( ConstantPool constant_pool ) { - this.constant_pool = constant_pool; - } - - - /** - * @param fields . - */ - public void setFields( Field[] fields ) { - this.fields = fields; - } - - - /** - * Set File name of class, aka SourceFile attribute value - */ - public void setFileName( String file_name ) { - this.file_name = file_name; - } - - - /** - * @param interface_names . - */ - public void setInterfaceNames( String[] interface_names ) { - this.interface_names = interface_names; - } - - - /** - * @param interfaces . - */ - public void setInterfaces( int[] interfaces ) { - this.interfaces = interfaces; - } - - - /** - * @param major . - */ - public void setMajor( int major ) { - this.major = major; - } - - - /** - * @param methods . - */ - public void setMethods( Method[] methods ) { - this.methods = methods; - } - - - /** - * @param minor . - */ - public void setMinor( int minor ) { - this.minor = minor; - } - - - /** - * Set absolute path to file this class was read from. - */ - public void setSourceFileName( String source_file_name ) { - this.source_file_name = source_file_name; - } - - - /** - * @param superclass_name . - */ - public void setSuperclassName( String superclass_name ) { - this.superclass_name = superclass_name; - } - - - /** - * @param superclass_name_index . - */ - public void setSuperclassNameIndex( int superclass_name_index ) { - this.superclass_name_index = superclass_name_index; - } - - - /** - * @return String representing class contents. - */ - public String toString() { - String access = Utility.accessToString(access_flags, true); - access = access.equals("") ? "" : (access + " "); - StringBuffer buf = new StringBuffer(128); - buf.append(access).append(Utility.classOrInterface(access_flags)).append(" ").append( - class_name).append(" extends ").append( - Utility.compactClassName(superclass_name, false)).append('\n'); - int size = interfaces.length; - if (size > 0) { - buf.append("implements\t\t"); - for (int i = 0; i < size; i++) { - buf.append(interface_names[i]); - if (i < size - 1) { - buf.append(", "); - } - } - buf.append('\n'); - } - buf.append("filename\t\t").append(file_name).append('\n'); - buf.append("compiled from\t\t").append(source_file_name).append('\n'); - buf.append("compiler version\t").append(major).append(".").append(minor).append('\n'); - buf.append("access flags\t\t").append(access_flags).append('\n'); - buf.append("constant pool\t\t").append(constant_pool.getLength()).append(" entries\n"); - buf.append("ACC_SUPER flag\t\t").append(isSuper()).append("\n"); - if (attributes.length > 0) { - buf.append("\nAttribute(s):\n"); - for (int i = 0; i < attributes.length; i++) { - buf.append(indent(attributes[i])); - } - } - if (fields.length > 0) { - buf.append("\n").append(fields.length).append(" fields:\n"); - for (int i = 0; i < fields.length; i++) { - buf.append("\t").append(fields[i]).append('\n'); - } - } - if (methods.length > 0) { - buf.append("\n").append(methods.length).append(" methods:\n"); - for (int i = 0; i < methods.length; i++) { - buf.append("\t").append(methods[i]).append('\n'); - } - } - return buf.toString(); - } - - - private static final String indent( Object obj ) { - StringTokenizer tok = new StringTokenizer(obj.toString(), "\n"); - StringBuffer buf = new StringBuffer(); - while (tok.hasMoreTokens()) { - buf.append("\t").append(tok.nextToken()).append("\n"); - } - return buf.toString(); - } - - - /** - * @return deep copy of this class - */ - public JavaClass copy() { - JavaClass c = null; - try { - c = (JavaClass) clone(); - c.constant_pool = constant_pool.copy(); - c.interfaces = (int[]) interfaces.clone(); - c.interface_names = (String[]) interface_names.clone(); - c.fields = new Field[fields.length]; - for (int i = 0; i < fields.length; i++) { - c.fields[i] = fields[i].copy(c.constant_pool); - } - c.methods = new Method[methods.length]; - for (int i = 0; i < methods.length; i++) { - c.methods[i] = methods[i].copy(c.constant_pool); - } - c.attributes = new Attribute[attributes.length]; - for (int i = 0; i < attributes.length; i++) { - c.attributes[i] = attributes[i].copy(c.constant_pool); - } - } catch (CloneNotSupportedException e) { - } - return c; - } - - - public final boolean isSuper() { - return (access_flags & Constants.ACC_SUPER) != 0; - } - - - public final boolean isClass() { - return (access_flags & Constants.ACC_INTERFACE) == 0; - } - - - /** @return returns either HEAP (generated), FILE, or ZIP - */ - public final byte getSource() { - return source; - } - - - /********************* New repository functionality *********************/ - /** - * Gets the ClassRepository which holds its definition. By default - * this is the same as SyntheticRepository.getInstance(); - */ - public org.apache.bcel.util.Repository getRepository() { - return repository; - } - - - /** - * Sets the ClassRepository which loaded the JavaClass. - * Should be called immediately after parsing is done. - */ - public void setRepository( org.apache.bcel.util.Repository repository ) { - this.repository = repository; - } - - - /** Equivalent to runtime "instanceof" operator. - * - * @return true if this JavaClass is derived from the super class - * @throws ClassNotFoundException if superclasses or superinterfaces - * of this object can't be found - */ - public final boolean instanceOf( JavaClass super_class ) throws ClassNotFoundException { - if (this.equals(super_class)) { - return true; - } - JavaClass[] super_classes = getSuperClasses(); - for (int i = 0; i < super_classes.length; i++) { - if (super_classes[i].equals(super_class)) { - return true; - } - } - if (super_class.isInterface()) { - return implementationOf(super_class); - } - return false; - } - - - /** - * @return true, if this class is an implementation of interface inter - * @throws ClassNotFoundException if superclasses or superinterfaces - * of this class can't be found - */ - public boolean implementationOf( JavaClass inter ) throws ClassNotFoundException { - if (!inter.isInterface()) { - throw new IllegalArgumentException(inter.getClassName() + " is no interface"); - } - if (this.equals(inter)) { - return true; - } - JavaClass[] super_interfaces = getAllInterfaces(); - for (int i = 0; i < super_interfaces.length; i++) { - if (super_interfaces[i].equals(inter)) { - return true; - } - } - return false; - } - - - /** - * @return the superclass for this JavaClass object, or null if this - * is java.lang.Object - * @throws ClassNotFoundException if the superclass can't be found - */ - public JavaClass getSuperClass() throws ClassNotFoundException { - if ("java.lang.Object".equals(getClassName())) { - return null; - } - return repository.loadClass(getSuperclassName()); - } - - - /** - * @return list of super classes of this class in ascending order, i.e., - * java.lang.Object is always the last element - * @throws ClassNotFoundException if any of the superclasses can't be found - */ - public JavaClass[] getSuperClasses() throws ClassNotFoundException { - JavaClass clazz = this; - List allSuperClasses = new ArrayList(); - for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { - allSuperClasses.add(clazz); - } - return (JavaClass[]) allSuperClasses.toArray(new JavaClass[allSuperClasses.size()]); - } - - - /** - * Get interfaces directly implemented by this JavaClass. - */ - public JavaClass[] getInterfaces() throws ClassNotFoundException { - String[] _interfaces = getInterfaceNames(); - JavaClass[] classes = new JavaClass[_interfaces.length]; - for (int i = 0; i < _interfaces.length; i++) { - classes[i] = repository.loadClass(_interfaces[i]); - } - return classes; - } - - - /** - * Get all interfaces implemented by this JavaClass (transitively). - */ - public JavaClass[] getAllInterfaces() throws ClassNotFoundException { - ClassQueue queue = new ClassQueue(); - Set allInterfaces = new TreeSet(); - queue.enqueue(this); - while (!queue.empty()) { - JavaClass clazz = queue.dequeue(); - JavaClass souper = clazz.getSuperClass(); - JavaClass[] _interfaces = clazz.getInterfaces(); - if (clazz.isInterface()) { - allInterfaces.add(clazz); - } else { - if (souper != null) { - queue.enqueue(souper); - } - } - for (int i = 0; i < _interfaces.length; i++) { - queue.enqueue(_interfaces[i]); - } - } - return (JavaClass[]) allInterfaces.toArray(new JavaClass[allInterfaces.size()]); - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return _cmp; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( BCELComparator comparator ) { - _cmp = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two JavaClass objects are said to be equal when - * their class names are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals( Object obj ) { - return _cmp.equals(this, obj); - } - - - /** - * Return the natural ordering of two JavaClasses. - * This ordering is based on the class name - */ - public int compareTo( Object obj ) { - return getClassName().compareTo(((JavaClass) obj).getClassName()); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the class name. - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return _cmp.hashCode(this); - } + private String package_name; + private String source_file_name = ""; + private int class_name_index; + private int superclass_name_index; + private String class_name; + private String superclass_name; + private int major, minor; // Compiler version + private ConstantPool constant_pool; // Constant pool + private int[] interfaces; // implemented interfaces + private String[] interface_names; + private Field[] fields; // Fields, i.e., variables of class + private Method[] methods; // methods defined in the class + private Attribute[] attributes; // attributes defined in the class + private byte source = HEAP; // Generated in memory + public static final byte HEAP = 1; + public static final byte FILE = 2; + public static final byte ZIP = 3; + static boolean debug = false; // Debugging on/off + static char sep = '/'; // directory separator + private static BCELComparator _cmp = new BCELComparator() { + + @Override + public boolean equals(Object o1, Object o2) { + JavaClass THIS = (JavaClass) o1; + JavaClass THAT = (JavaClass) o2; + return THIS.getClassName().equals(THAT.getClassName()); + } + + @Override + public int hashCode(Object o) { + JavaClass THIS = (JavaClass) o; + return THIS.getClassName().hashCode(); + } + }; + /** + * In cases where we go ahead and create something, use the default + * SyntheticRepository, because we don't know any better. + */ + private transient org.apache.bcel.util.Repository repository = SyntheticRepository + .getInstance(); + + /** + * Constructor gets all contents as arguments. + * + * @param class_name_index + * Index into constant pool referencing a ConstantClass that + * represents this class. + * @param superclass_name_index + * Index into constant pool referencing a ConstantClass that + * represents this class's superclass. + * @param file_name + * File name + * @param major + * Major compiler version + * @param minor + * Minor compiler version + * @param access_flags + * Access rights defined by bit flags + * @param constant_pool + * Array of constants + * @param interfaces + * Implemented interfaces + * @param fields + * Class fields + * @param methods + * Class methods + * @param attributes + * Class attributes + * @param source + * Read from file or generated in memory? + */ + public JavaClass(int class_name_index, int superclass_name_index, + String file_name, int major, int minor, int access_flags, + ConstantPool constant_pool, int[] interfaces, Field[] fields, + Method[] methods, Attribute[] attributes, byte source) { + if (interfaces == null) { + interfaces = new int[0]; + } + if (attributes == null) { + attributes = new Attribute[0]; + } + if (fields == null) { + fields = new Field[0]; + } + if (methods == null) { + methods = new Method[0]; + } + this.class_name_index = class_name_index; + this.superclass_name_index = superclass_name_index; + this.file_name = file_name; + this.major = major; + this.minor = minor; + this.access_flags = access_flags; + this.constant_pool = constant_pool; + this.interfaces = interfaces; + this.fields = fields; + this.methods = methods; + this.attributes = attributes; + this.source = source; + // Get source file name if available + for (int i = 0; i < attributes.length; i++) { + if (attributes[i] instanceof SourceFile) { + source_file_name = ((SourceFile) attributes[i]) + .getSourceFileName(); + break; + } + } + /* + * According to the specification the following entries must be of type + * `ConstantClass' but we check that anyway via the + * `ConstPool.getConstant' method. + */ + class_name = constant_pool.getConstantString(class_name_index, + Constants.CONSTANT_Class); + class_name = Utility.compactClassName(class_name, false); + int index = class_name.lastIndexOf('.'); + if (index < 0) { + package_name = ""; + } else { + package_name = class_name.substring(0, index); + } + if (superclass_name_index > 0) { + // May be zero -> class is java.lang.Object + superclass_name = constant_pool.getConstantString( + superclass_name_index, Constants.CONSTANT_Class); + superclass_name = Utility.compactClassName(superclass_name, false); + } else { + superclass_name = "java.lang.Object"; + } + interface_names = new String[interfaces.length]; + for (int i = 0; i < interfaces.length; i++) { + String str = constant_pool.getConstantString(interfaces[i], + Constants.CONSTANT_Class); + interface_names[i] = Utility.compactClassName(str, false); + } + } + + /** + * Constructor gets all contents as arguments. + * + * @param class_name_index + * Class name + * @param superclass_name_index + * Superclass name + * @param file_name + * File name + * @param major + * Major compiler version + * @param minor + * Minor compiler version + * @param access_flags + * Access rights defined by bit flags + * @param constant_pool + * Array of constants + * @param interfaces + * Implemented interfaces + * @param fields + * Class fields + * @param methods + * Class methods + * @param attributes + * Class attributes + */ + public JavaClass(int class_name_index, int superclass_name_index, + String file_name, int major, int minor, int access_flags, + ConstantPool constant_pool, int[] interfaces, Field[] fields, + Method[] methods, Attribute[] attributes) { + this(class_name_index, superclass_name_index, file_name, major, minor, + access_flags, constant_pool, interfaces, fields, methods, + attributes, HEAP); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitJavaClass(this); + } + + /* + * Print debug information depending on `JavaClass.debug' + */ + static final void Debug(String str) { + if (debug) { + System.out.println(str); + } + } + + /** + * Dump class to a file. + * + * @param file + * Output file + * @throws IOException + */ + public void dump(File file) throws IOException { + String parent = file.getParent(); + if (parent != null) { + File dir = new File(parent); + dir.mkdirs(); + } + DataOutputStream dos = null; + try { + dos = new DataOutputStream(new FileOutputStream(file)); + dump(dos); + } finally { + if (dos != null) { + dos.close(); + } + } + } + + /** + * Dump class to a file named file_name. + * + * @param _file_name + * Output file name + * @exception IOException + */ + public void dump(String _file_name) throws IOException { + dump(new File(_file_name)); + } + + /** + * @return class in binary format + */ + public byte[] getBytes() { + ByteArrayOutputStream s = new ByteArrayOutputStream(); + DataOutputStream ds = new DataOutputStream(s); + try { + dump(ds); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + ds.close(); + } catch (IOException e2) { + e2.printStackTrace(); + } + } + return s.toByteArray(); + } + + /** + * Dump Java class to output stream in binary format. + * + * @param file + * Output stream + * @exception IOException + */ + public void dump(OutputStream file) throws IOException { + dump(new DataOutputStream(file)); + } + + /** + * Dump Java class to output stream in binary format. + * + * @param file + * Output stream + * @exception IOException + */ + public void dump(DataOutputStream file) throws IOException { + file.writeInt(0xcafebabe); + file.writeShort(minor); + file.writeShort(major); + constant_pool.dump(file); + file.writeShort(access_flags); + file.writeShort(class_name_index); + file.writeShort(superclass_name_index); + file.writeShort(interfaces.length); + for (int i = 0; i < interfaces.length; i++) { + file.writeShort(interfaces[i]); + } + file.writeShort(fields.length); + for (int i = 0; i < fields.length; i++) { + fields[i].dump(file); + } + file.writeShort(methods.length); + for (int i = 0; i < methods.length; i++) { + methods[i].dump(file); + } + if (attributes != null) { + file.writeShort(attributes.length); + for (int i = 0; i < attributes.length; i++) { + attributes[i].dump(file); + } + } else { + file.writeShort(0); + } + file.flush(); + } + + /** + * @return Attributes of the class. + */ + public Attribute[] getAttributes() { + return attributes; + } + + /** + * @return Class name. + */ + public String getClassName() { + return class_name; + } + + /** + * @return Package name. + */ + public String getPackageName() { + return package_name; + } + + /** + * @return Class name index. + */ + public int getClassNameIndex() { + return class_name_index; + } + + /** + * @return Constant pool. + */ + public ConstantPool getConstantPool() { + return constant_pool; + } + + /** + * @return Fields, i.e., variables of the class. Like the JVM spec mandates + * for the classfile format, these fields are those specific to this + * class, and not those of the superclass or superinterfaces. + */ + public Field[] getFields() { + return fields; + } + + /** + * @return File name of class, aka SourceFile attribute value + */ + public String getFileName() { + return file_name; + } + + /** + * @return Names of implemented interfaces. + */ + public String[] getInterfaceNames() { + return interface_names; + } + + /** + * @return Indices in constant pool of implemented interfaces. + */ + public int[] getInterfaceIndices() { + return interfaces; + } + + /** + * @return Major number of class file version. + */ + public int getMajor() { + return major; + } + + /** + * @return Methods of the class. + */ + public Method[] getMethods() { + return methods; + } + + /** + * @return A org.apache.bcel.classfile.Method corresponding to + * java.lang.reflect.Method if any + */ + public Method getMethod(java.lang.reflect.Method m) { + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + if (m.getName().equals(method.getName()) + && (m.getModifiers() == method.getModifiers()) + && Type.getSignature(m).equals(method.getSignature())) { + return method; + } + } + return null; + } + + /** + * @return Minor number of class file version. + */ + public int getMinor() { + return minor; + } + + /** + * @return sbsolute path to file where this class was read from + */ + public String getSourceFileName() { + return source_file_name; + } + + /** + * @return Superclass name. + */ + public String getSuperclassName() { + return superclass_name; + } + + /** + * @return Class name index. + */ + public int getSuperclassNameIndex() { + return superclass_name_index; + } + + static { + // Debugging ... on/off + debug = Boolean.getBoolean("JavaClass.debug"); + // Get path separator either / or \ usually + String _sep = System.getProperty("file.separator"); + if (_sep != null) { + try { + JavaClass.sep = _sep.charAt(0); + } catch (StringIndexOutOfBoundsException e) { + } // Never reached + } + } + + /** + * @param attributes + * . + */ + public void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + } + + /** + * @param class_name + * . + */ + public void setClassName(String class_name) { + this.class_name = class_name; + } + + /** + * @param class_name_index + * . + */ + public void setClassNameIndex(int class_name_index) { + this.class_name_index = class_name_index; + } + + /** + * @param constant_pool + * . + */ + public void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * @param fields + * . + */ + public void setFields(Field[] fields) { + this.fields = fields; + } + + /** + * Set File name of class, aka SourceFile attribute value + */ + public void setFileName(String file_name) { + this.file_name = file_name; + } + + /** + * @param interface_names + * . + */ + public void setInterfaceNames(String[] interface_names) { + this.interface_names = interface_names; + } + + /** + * @param interfaces + * . + */ + public void setInterfaces(int[] interfaces) { + this.interfaces = interfaces; + } + + /** + * @param major + * . + */ + public void setMajor(int major) { + this.major = major; + } + + /** + * @param methods + * . + */ + public void setMethods(Method[] methods) { + this.methods = methods; + } + + /** + * @param minor + * . + */ + public void setMinor(int minor) { + this.minor = minor; + } + + /** + * Set absolute path to file this class was read from. + */ + public void setSourceFileName(String source_file_name) { + this.source_file_name = source_file_name; + } + + /** + * @param superclass_name + * . + */ + public void setSuperclassName(String superclass_name) { + this.superclass_name = superclass_name; + } + + /** + * @param superclass_name_index + * . + */ + public void setSuperclassNameIndex(int superclass_name_index) { + this.superclass_name_index = superclass_name_index; + } + + /** + * @return String representing class contents. + */ + @Override + public String toString() { + String access = Utility.accessToString(access_flags, true); + access = access.equals("") ? "" : (access + " "); + StringBuffer buf = new StringBuffer(128); + buf.append(access).append(Utility.classOrInterface(access_flags)) + .append(" ").append(class_name).append(" extends ") + .append(Utility.compactClassName(superclass_name, false)) + .append('\n'); + int size = interfaces.length; + if (size > 0) { + buf.append("implements\t\t"); + for (int i = 0; i < size; i++) { + buf.append(interface_names[i]); + if (i < size - 1) { + buf.append(", "); + } + } + buf.append('\n'); + } + buf.append("filename\t\t").append(file_name).append('\n'); + buf.append("compiled from\t\t").append(source_file_name).append('\n'); + buf.append("compiler version\t").append(major).append(".") + .append(minor).append('\n'); + buf.append("access flags\t\t").append(access_flags).append('\n'); + buf.append("constant pool\t\t").append(constant_pool.getLength()) + .append(" entries\n"); + buf.append("ACC_SUPER flag\t\t").append(isSuper()).append("\n"); + if (attributes.length > 0) { + buf.append("\nAttribute(s):\n"); + for (int i = 0; i < attributes.length; i++) { + buf.append(indent(attributes[i])); + } + } + if (fields.length > 0) { + buf.append("\n").append(fields.length).append(" fields:\n"); + for (int i = 0; i < fields.length; i++) { + buf.append("\t").append(fields[i]).append('\n'); + } + } + if (methods.length > 0) { + buf.append("\n").append(methods.length).append(" methods:\n"); + for (int i = 0; i < methods.length; i++) { + buf.append("\t").append(methods[i]).append('\n'); + } + } + return buf.toString(); + } + + private static final String indent(Object obj) { + StringTokenizer tok = new StringTokenizer(obj.toString(), "\n"); + StringBuffer buf = new StringBuffer(); + while (tok.hasMoreTokens()) { + buf.append("\t").append(tok.nextToken()).append("\n"); + } + return buf.toString(); + } + + /** + * @return deep copy of this class + */ + public JavaClass copy() { + JavaClass c = null; + try { + c = (JavaClass) clone(); + c.constant_pool = constant_pool.copy(); + c.interfaces = interfaces.clone(); + c.interface_names = interface_names.clone(); + c.fields = new Field[fields.length]; + for (int i = 0; i < fields.length; i++) { + c.fields[i] = fields[i].copy(c.constant_pool); + } + c.methods = new Method[methods.length]; + for (int i = 0; i < methods.length; i++) { + c.methods[i] = methods[i].copy(c.constant_pool); + } + c.attributes = new Attribute[attributes.length]; + for (int i = 0; i < attributes.length; i++) { + c.attributes[i] = attributes[i].copy(c.constant_pool); + } + } catch (CloneNotSupportedException e) { + } + return c; + } + + public final boolean isSuper() { + return (access_flags & Constants.ACC_SUPER) != 0; + } + + public final boolean isClass() { + return (access_flags & Constants.ACC_INTERFACE) == 0; + } + + /** + * @return returns either HEAP (generated), FILE, or ZIP + */ + public final byte getSource() { + return source; + } + + /********************* New repository functionality *********************/ + /** + * Gets the ClassRepository which holds its definition. By default this is + * the same as SyntheticRepository.getInstance(); + */ + public org.apache.bcel.util.Repository getRepository() { + return repository; + } + + /** + * Sets the ClassRepository which loaded the JavaClass. Should be called + * immediately after parsing is done. + */ + public void setRepository(org.apache.bcel.util.Repository repository) { + this.repository = repository; + } + + /** + * Equivalent to runtime "instanceof" operator. + * + * @return true if this JavaClass is derived from the super class + * @throws ClassNotFoundException + * if superclasses or superinterfaces of this object can't be + * found + */ + public final boolean instanceOf(JavaClass super_class) + throws ClassNotFoundException { + if (this.equals(super_class)) { + return true; + } + JavaClass[] super_classes = getSuperClasses(); + for (int i = 0; i < super_classes.length; i++) { + if (super_classes[i].equals(super_class)) { + return true; + } + } + if (super_class.isInterface()) { + return implementationOf(super_class); + } + return false; + } + + /** + * @return true, if this class is an implementation of interface inter + * @throws ClassNotFoundException + * if superclasses or superinterfaces of this class can't be + * found + */ + public boolean implementationOf(JavaClass inter) + throws ClassNotFoundException { + if (!inter.isInterface()) { + throw new IllegalArgumentException(inter.getClassName() + + " is no interface"); + } + if (this.equals(inter)) { + return true; + } + JavaClass[] super_interfaces = getAllInterfaces(); + for (int i = 0; i < super_interfaces.length; i++) { + if (super_interfaces[i].equals(inter)) { + return true; + } + } + return false; + } + + /** + * @return the superclass for this JavaClass object, or null if this is + * java.lang.Object + * @throws ClassNotFoundException + * if the superclass can't be found + */ + public JavaClass getSuperClass() throws ClassNotFoundException { + if ("java.lang.Object".equals(getClassName())) { + return null; + } + return repository.loadClass(getSuperclassName()); + } + + /** + * @return list of super classes of this class in ascending order, i.e., + * java.lang.Object is always the last element + * @throws ClassNotFoundException + * if any of the superclasses can't be found + */ + public JavaClass[] getSuperClasses() throws ClassNotFoundException { + JavaClass clazz = this; + List allSuperClasses = new ArrayList(); + for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz + .getSuperClass()) { + allSuperClasses.add(clazz); + } + return allSuperClasses.toArray(new JavaClass[allSuperClasses.size()]); + } + + /** + * Get interfaces directly implemented by this JavaClass. + */ + public JavaClass[] getInterfaces() throws ClassNotFoundException { + String[] _interfaces = getInterfaceNames(); + JavaClass[] classes = new JavaClass[_interfaces.length]; + for (int i = 0; i < _interfaces.length; i++) { + classes[i] = repository.loadClass(_interfaces[i]); + } + return classes; + } + + /** + * Get all interfaces implemented by this JavaClass (transitively). + */ + public JavaClass[] getAllInterfaces() throws ClassNotFoundException { + ClassQueue queue = new ClassQueue(); + Set allInterfaces = new TreeSet(); + queue.enqueue(this); + while (!queue.empty()) { + JavaClass clazz = queue.dequeue(); + JavaClass souper = clazz.getSuperClass(); + JavaClass[] _interfaces = clazz.getInterfaces(); + if (clazz.isInterface()) { + allInterfaces.add(clazz); + } else { + if (souper != null) { + queue.enqueue(souper); + } + } + for (int i = 0; i < _interfaces.length; i++) { + queue.enqueue(_interfaces[i]); + } + } + return allInterfaces.toArray(new JavaClass[allInterfaces.size()]); + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + + /** + * @param comparator + * Comparison strategy object + */ + public static void setComparator(BCELComparator comparator) { + _cmp = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * JavaClass objects are said to be equal when their class names are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return _cmp.equals(this, obj); + } + + /** + * Return the natural ordering of two JavaClasses. This ordering is based on + * the class name + */ + @Override + public int compareTo(Object obj) { + return getClassName().compareTo(((JavaClass) obj).getClassName()); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the class name. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); + } } diff --git a/src/org/apache/bcel/classfile/LineNumber.java b/src/org/apache/bcel/classfile/LineNumber.java index 954aa33..e9081b7 100644 --- a/src/org/apache/bcel/classfile/LineNumber.java +++ b/src/org/apache/bcel/classfile/LineNumber.java @@ -23,119 +23,122 @@ import java.io.Serializable; /** * This class represents a (PC offset, line number) pair, i.e., a line number in - * the source that corresponds to a relative address in the byte code. This - * is used for debugging purposes. - * + * the source that corresponds to a relative address in the byte code. This is + * used for debugging purposes. + * * @version $Id: LineNumber.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see LineNumberTable + * @author M. Dahm + * @see LineNumberTable */ public final class LineNumber implements Cloneable, Node, Serializable { - private int start_pc; // Program Counter (PC) corresponds to line - private int line_number; // number in source file + /** + * + */ + private static final long serialVersionUID = 1L; + private int start_pc; // Program Counter (PC) corresponds to line + private int line_number; // number in source file + /** + * Initialize from another object. + */ + public LineNumber(LineNumber c) { + this(c.getStartPC(), c.getLineNumber()); + } - /** - * Initialize from another object. - */ - public LineNumber(LineNumber c) { - this(c.getStartPC(), c.getLineNumber()); - } + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + */ + LineNumber(DataInputStream file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } + /** + * @param start_pc + * Program Counter (PC) corresponds to + * @param line_number + * line number in source file + */ + public LineNumber(int start_pc, int line_number) { + this.start_pc = start_pc; + this.line_number = line_number; + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - LineNumber(DataInputStream file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLineNumber(this); + } + /** + * Dump line number/pc pair to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(start_pc); + file.writeShort(line_number); + } - /** - * @param start_pc Program Counter (PC) corresponds to - * @param line_number line number in source file - */ - public LineNumber(int start_pc, int line_number) { - this.start_pc = start_pc; - this.line_number = line_number; - } + /** + * @return Corresponding source line + */ + public final int getLineNumber() { + return line_number; + } + /** + * @return PC in code + */ + public final int getStartPC() { + return start_pc; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLineNumber(this); - } + /** + * @param line_number + * the source line number + */ + public final void setLineNumber(int line_number) { + this.line_number = line_number; + } + /** + * @param start_pc + * the pc for this line number + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } - /** - * Dump line number/pc pair to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeShort(start_pc); - file.writeShort(line_number); - } + /** + * @return String representation + */ + @Override + public final String toString() { + return "LineNumber(" + start_pc + ", " + line_number + ")"; + } - - /** - * @return Corresponding source line - */ - public final int getLineNumber() { - return line_number; - } - - - /** - * @return PC in code - */ - public final int getStartPC() { - return start_pc; - } - - - /** - * @param line_number the source line number - */ - public final void setLineNumber( int line_number ) { - this.line_number = line_number; - } - - - /** - * @param start_pc the pc for this line number - */ - public final void setStartPC( int start_pc ) { - this.start_pc = start_pc; - } - - - /** - * @return String representation - */ - public final String toString() { - return "LineNumber(" + start_pc + ", " + line_number + ")"; - } - - - /** - * @return deep copy of this object - */ - public LineNumber copy() { - try { - return (LineNumber) clone(); - } catch (CloneNotSupportedException e) { - } - return null; - } + /** + * @return deep copy of this object + */ + public LineNumber copy() { + try { + return (LineNumber) clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } } diff --git a/src/org/apache/bcel/classfile/LineNumberTable.java b/src/org/apache/bcel/classfile/LineNumberTable.java index 33e93ed..da11faf 100644 --- a/src/org/apache/bcel/classfile/LineNumberTable.java +++ b/src/org/apache/bcel/classfile/LineNumberTable.java @@ -22,187 +22,202 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class represents a table of line numbers for debugging - * purposes. This attribute is used by the Code attribute. It - * contains pairs of PCs and line numbers. - * + * This class represents a table of line numbers for debugging purposes. This + * attribute is used by the Code attribute. It contains pairs of PCs + * and line numbers. + * * @version $Id: LineNumberTable.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Code + * @author M. Dahm + * @see Code * @see LineNumber */ public final class LineNumberTable extends Attribute { - private int line_number_table_length; - private LineNumber[] line_number_table; // Table of line/numbers pairs + /** + * + */ + private static final long serialVersionUID = 1L; + private int line_number_table_length; + private LineNumber[] line_number_table; // Table of line/numbers pairs + /* + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LineNumberTable(LineNumberTable c) { + this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c + .getConstantPool()); + } - /* - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public LineNumberTable(LineNumberTable c) { - this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); - } + /* + * @param name_index Index of name + * + * @param length Content length in bytes + * + * @param line_number_table Table of line/numbers pairs + * + * @param constant_pool Array of constants + */ + public LineNumberTable(int name_index, int length, + LineNumber[] line_number_table, ConstantPool constant_pool) { + super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, + constant_pool); + setLineNumberTable(line_number_table); + } + /** + * Construct object from file stream. + * + * @param name_index + * Index of name + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + LineNumberTable(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (LineNumber[]) null, constant_pool); + line_number_table_length = (file.readUnsignedShort()); + line_number_table = new LineNumber[line_number_table_length]; + for (int i = 0; i < line_number_table_length; i++) { + line_number_table[i] = new LineNumber(file); + } + } - /* - * @param name_index Index of name - * @param length Content length in bytes - * @param line_number_table Table of line/numbers pairs - * @param constant_pool Array of constants - */ - public LineNumberTable(int name_index, int length, LineNumber[] line_number_table, - ConstantPool constant_pool) { - super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); - setLineNumberTable(line_number_table); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLineNumberTable(this); + } + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(line_number_table_length); + for (int i = 0; i < line_number_table_length; i++) { + line_number_table[i].dump(file); + } + } - /** - * Construct object from file stream. - * @param name_index Index of name - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (LineNumber[]) null, constant_pool); - line_number_table_length = (file.readUnsignedShort()); - line_number_table = new LineNumber[line_number_table_length]; - for (int i = 0; i < line_number_table_length; i++) { - line_number_table[i] = new LineNumber(file); - } - } + /** + * @return Array of (pc offset, line number) pairs. + */ + public final LineNumber[] getLineNumberTable() { + return line_number_table; + } + /** + * @param line_number_table + * the line number entries for this table + */ + public final void setLineNumberTable(LineNumber[] line_number_table) { + this.line_number_table = line_number_table; + line_number_table_length = (line_number_table == null) ? 0 + : line_number_table.length; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLineNumberTable(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(); + StringBuffer line = new StringBuffer(); + String newLine = System.getProperty("line.separator", "\n"); + for (int i = 0; i < line_number_table_length; i++) { + line.append(line_number_table[i].toString()); + if (i < line_number_table_length - 1) { + line.append(", "); + } + if (line.length() > 72) { + line.append(newLine); + buf.append(line.toString()); + line.setLength(0); + } + } + buf.append(line); + return buf.toString(); + } + /** + * Map byte code positions to source code lines. + * + * @param pos + * byte code offset + * @return corresponding line in source code + */ + public int getSourceLine(int pos) { + int l = 0, r = line_number_table_length - 1; + if (r < 0) { + return -1; + } + int min_index = -1, min = -1; + /* + * Do a binary search since the array is ordered. + */ + do { + int i = (l + r) / 2; + int j = line_number_table[i].getStartPC(); + if (j == pos) { + return line_number_table[i].getLineNumber(); + } else if (pos < j) { + r = i - 1; + } else { + l = i + 1; + } + /* + * If exact match can't be found (which is the most common case) + * return the line number that corresponds to the greatest index + * less than pos. + */ + if (j < pos && j > min) { + min = j; + min_index = i; + } + } while (l <= r); + /* + * It's possible that we did not find any valid entry for the bytecode + * offset we were looking for. + */ + if (min_index < 0) { + return -1; + } + return line_number_table[min_index].getLineNumber(); + } - /** - * Dump line number table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(line_number_table_length); - for (int i = 0; i < line_number_table_length; i++) { - line_number_table[i].dump(file); - } - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + LineNumberTable c = (LineNumberTable) clone(); + c.line_number_table = new LineNumber[line_number_table_length]; + for (int i = 0; i < line_number_table_length; i++) { + c.line_number_table[i] = line_number_table[i].copy(); + } + c.constant_pool = _constant_pool; + return c; + } - - /** - * @return Array of (pc offset, line number) pairs. - */ - public final LineNumber[] getLineNumberTable() { - return line_number_table; - } - - - /** - * @param line_number_table the line number entries for this table - */ - public final void setLineNumberTable( LineNumber[] line_number_table ) { - this.line_number_table = line_number_table; - line_number_table_length = (line_number_table == null) ? 0 : line_number_table.length; - } - - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(); - StringBuffer line = new StringBuffer(); - String newLine = System.getProperty("line.separator", "\n"); - for (int i = 0; i < line_number_table_length; i++) { - line.append(line_number_table[i].toString()); - if (i < line_number_table_length - 1) { - line.append(", "); - } - if (line.length() > 72) { - line.append(newLine); - buf.append(line.toString()); - line.setLength(0); - } - } - buf.append(line); - return buf.toString(); - } - - - /** - * Map byte code positions to source code lines. - * - * @param pos byte code offset - * @return corresponding line in source code - */ - public int getSourceLine( int pos ) { - int l = 0, r = line_number_table_length - 1; - if (r < 0) { - return -1; - } - int min_index = -1, min = -1; - /* Do a binary search since the array is ordered. - */ - do { - int i = (l + r) / 2; - int j = line_number_table[i].getStartPC(); - if (j == pos) { - return line_number_table[i].getLineNumber(); - } else if (pos < j) { - r = i - 1; - } else { - l = i + 1; - } - /* If exact match can't be found (which is the most common case) - * return the line number that corresponds to the greatest index less - * than pos. - */ - if (j < pos && j > min) { - min = j; - min_index = i; - } - } while (l <= r); - /* It's possible that we did not find any valid entry for the bytecode - * offset we were looking for. - */ - if (min_index < 0) { - return -1; - } - return line_number_table[min_index].getLineNumber(); - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - LineNumberTable c = (LineNumberTable) clone(); - c.line_number_table = new LineNumber[line_number_table_length]; - for (int i = 0; i < line_number_table_length; i++) { - c.line_number_table[i] = line_number_table[i].copy(); - } - c.constant_pool = _constant_pool; - return c; - } - - - public final int getTableLength() { - return line_number_table_length; - } + public final int getTableLength() { + return line_number_table_length; + } } diff --git a/src/org/apache/bcel/classfile/LocalVariable.java b/src/org/apache/bcel/classfile/LocalVariable.java index 8de890b..2f5cb16 100644 --- a/src/org/apache/bcel/classfile/LocalVariable.java +++ b/src/org/apache/bcel/classfile/LocalVariable.java @@ -25,224 +25,232 @@ import org.apache.bcel.Constants; /** * This class represents a local variable within a method. It contains its * scope, name, signature and index on the method's frame. - * + * * @version $Id: LocalVariable.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see LocalVariableTable + * @author M. Dahm + * @see LocalVariableTable */ -public final class LocalVariable implements Constants, Cloneable, Node, Serializable { +public final class LocalVariable implements Constants, Cloneable, Node, + Serializable { - private int start_pc; // Range in which the variable is valid - private int length; - private int name_index; // Index in constant pool of variable name - private int signature_index; // Index of variable signature - private int index; /* Variable is `index'th local variable on - * this method's frame. - */ - private ConstantPool constant_pool; + /** + * + */ + private static final long serialVersionUID = 1L; + private int start_pc; // Range in which the variable is valid + private int length; + private int name_index; // Index in constant pool of variable name + private int signature_index; // Index of variable signature + private int index; /* + * Variable is `index'th local variable on this method's + * frame. + */ + private ConstantPool constant_pool; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LocalVariable(LocalVariable c) { + this(c.getStartPC(), c.getLength(), c.getNameIndex(), c + .getSignatureIndex(), c.getIndex(), c.getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public LocalVariable(LocalVariable c) { - this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(), - c.getConstantPool()); - } + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + */ + LocalVariable(DataInputStream file, ConstantPool constant_pool) + throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort(), constant_pool); + } + /** + * @param start_pc + * Range in which the variable + * @param length + * ... is valid + * @param name_index + * Index in constant pool of variable name + * @param signature_index + * Index of variable's signature + * @param index + * Variable is `index'th local variable on the method's frame + * @param constant_pool + * Array of constants + */ + public LocalVariable(int start_pc, int length, int name_index, + int signature_index, int index, ConstantPool constant_pool) { + this.start_pc = start_pc; + this.length = length; + this.name_index = name_index; + this.signature_index = signature_index; + this.index = index; + this.constant_pool = constant_pool; + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - LocalVariable(DataInputStream file, ConstantPool constant_pool) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file - .readUnsignedShort(), file.readUnsignedShort(), constant_pool); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLocalVariable(this); + } + /** + * Dump local variable to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(start_pc); + file.writeShort(length); + file.writeShort(name_index); + file.writeShort(signature_index); + file.writeShort(index); + } - /** - * @param start_pc Range in which the variable - * @param length ... is valid - * @param name_index Index in constant pool of variable name - * @param signature_index Index of variable's signature - * @param index Variable is `index'th local variable on the method's frame - * @param constant_pool Array of constants - */ - public LocalVariable(int start_pc, int length, int name_index, int signature_index, int index, - ConstantPool constant_pool) { - this.start_pc = start_pc; - this.length = length; - this.name_index = name_index; - this.signature_index = signature_index; - this.index = index; - this.constant_pool = constant_pool; - } + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } + /** + * @return Variable is valid within getStartPC() .. getStartPC()+getLength() + */ + public final int getLength() { + return length; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLocalVariable(this); - } + /** + * @return Variable name. + */ + public final String getName() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8); + return c.getBytes(); + } + /** + * @return Index in constant pool of variable name. + */ + public final int getNameIndex() { + return name_index; + } - /** - * Dump local variable to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeShort(start_pc); - file.writeShort(length); - file.writeShort(name_index); - file.writeShort(signature_index); - file.writeShort(index); - } + /** + * @return Signature. + */ + public final String getSignature() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(signature_index, + CONSTANT_Utf8); + return c.getBytes(); + } + /** + * @return Index in constant pool of variable signature. + */ + public final int getSignatureIndex() { + return signature_index; + } - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { - return constant_pool; - } + /** + * @return index of register where variable is stored + */ + public final int getIndex() { + return index; + } + /** + * @return Start of range where he variable is valid + */ + public final int getStartPC() { + return start_pc; + } - /** - * @return Variable is valid within getStartPC() .. getStartPC()+getLength() - */ - public final int getLength() { - return length; - } + /** + * @param constant_pool + * Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + /** + * @param length + * the length of this local variable + */ + public final void setLength(int length) { + this.length = length; + } - /** - * @return Variable name. - */ - public final String getName() { - ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8); - return c.getBytes(); - } + /** + * @param name_index + * the index into the constant pool for the name of this variable + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + /** + * @param signature_index + * the index into the constant pool for the signature of this + * variable + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } - /** - * @return Index in constant pool of variable name. - */ - public final int getNameIndex() { - return name_index; - } + /** + * @param index + * the index in the local variable table of this variable + */ + public final void setIndex(int index) { + this.index = index; + } + /** + * @param start_pc + * Specify range where the local variable is valid. + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } - /** - * @return Signature. - */ - public final String getSignature() { - ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8); - return c.getBytes(); - } + /** + * @return string representation. + */ + @Override + public final String toString() { + String name = getName(), signature = Utility + .signatureToString(getSignature()); + return "LocalVariable(start_pc = " + start_pc + ", length = " + length + + ", index = " + index + ":" + signature + " " + name + ")"; + } - - /** - * @return Index in constant pool of variable signature. - */ - public final int getSignatureIndex() { - return signature_index; - } - - - /** - * @return index of register where variable is stored - */ - public final int getIndex() { - return index; - } - - - /** - * @return Start of range where he variable is valid - */ - public final int getStartPC() { - return start_pc; - } - - - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool( ConstantPool constant_pool ) { - this.constant_pool = constant_pool; - } - - - /** - * @param length the length of this local variable - */ - public final void setLength( int length ) { - this.length = length; - } - - - /** - * @param name_index the index into the constant pool for the name of this variable - */ - public final void setNameIndex( int name_index ) { - this.name_index = name_index; - } - - - /** - * @param signature_index the index into the constant pool for the signature of this variable - */ - public final void setSignatureIndex( int signature_index ) { - this.signature_index = signature_index; - } - - - /** - * @param index the index in the local variable table of this variable - */ - public final void setIndex( int index ) { - this.index = index; - } - - - /** - * @param start_pc Specify range where the local variable is valid. - */ - public final void setStartPC( int start_pc ) { - this.start_pc = start_pc; - } - - - /** - * @return string representation. - */ - public final String toString() { - String name = getName(), signature = Utility.signatureToString(getSignature()); - return "LocalVariable(start_pc = " + start_pc + ", length = " + length + ", index = " - + index + ":" + signature + " " + name + ")"; - } - - - /** - * @return deep copy of this object - */ - public LocalVariable copy() { - try { - return (LocalVariable) clone(); - } catch (CloneNotSupportedException e) { - } - return null; - } + /** + * @return deep copy of this object + */ + public LocalVariable copy() { + try { + return (LocalVariable) clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } } diff --git a/src/org/apache/bcel/classfile/LocalVariableTable.java b/src/org/apache/bcel/classfile/LocalVariableTable.java index cbdc36c..1211614 100644 --- a/src/org/apache/bcel/classfile/LocalVariableTable.java +++ b/src/org/apache/bcel/classfile/LocalVariableTable.java @@ -22,176 +22,187 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class represents colection of local variables in a - * method. This attribute is contained in the Code attribute. - * + * This class represents colection of local variables in a method. This + * attribute is contained in the Code attribute. + * * @version $Id: LocalVariableTable.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Code + * @author M. Dahm + * @see Code * @see LocalVariable */ public class LocalVariableTable extends Attribute { - private int local_variable_table_length; // Table of local - private LocalVariable[] local_variable_table; // variables + /** + * + */ + private static final long serialVersionUID = 1L; + private int local_variable_table_length; // Table of local + private LocalVariable[] local_variable_table; // variables + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LocalVariableTable(LocalVariableTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c + .getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public LocalVariableTable(LocalVariableTable c) { - this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool()); - } + /** + * @param name_index + * Index in constant pool to `LocalVariableTable' + * @param length + * Content length in bytes + * @param local_variable_table + * Table of local variables + * @param constant_pool + * Array of constants + */ + public LocalVariableTable(int name_index, int length, + LocalVariable[] local_variable_table, ConstantPool constant_pool) { + super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, + constant_pool); + setLocalVariableTable(local_variable_table); + } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + LocalVariableTable(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (LocalVariable[]) null, constant_pool); + local_variable_table_length = (file.readUnsignedShort()); + local_variable_table = new LocalVariable[local_variable_table_length]; + for (int i = 0; i < local_variable_table_length; i++) { + local_variable_table[i] = new LocalVariable(file, constant_pool); + } + } - /** - * @param name_index Index in constant pool to `LocalVariableTable' - * @param length Content length in bytes - * @param local_variable_table Table of local variables - * @param constant_pool Array of constants - */ - public LocalVariableTable(int name_index, int length, LocalVariable[] local_variable_table, - ConstantPool constant_pool) { - super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); - setLocalVariableTable(local_variable_table); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLocalVariableTable(this); + } + /** + * Dump local variable table attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(local_variable_table_length); + for (int i = 0; i < local_variable_table_length; i++) { + local_variable_table[i].dump(file); + } + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - LocalVariableTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (LocalVariable[]) null, constant_pool); - local_variable_table_length = (file.readUnsignedShort()); - local_variable_table = new LocalVariable[local_variable_table_length]; - for (int i = 0; i < local_variable_table_length; i++) { - local_variable_table[i] = new LocalVariable(file, constant_pool); - } - } + /** + * @return Array of local variables of method. + */ + public final LocalVariable[] getLocalVariableTable() { + return local_variable_table; + } + /** + * @return first matching variable using index + * + * @param index + * the variable slot + * + * @return the first LocalVariable that matches the slot or null if not + * found + * + */ + public final LocalVariable getLocalVariable(int index) { + for (int i = 0; i < local_variable_table_length; i++) { + if (local_variable_table[i].getIndex() == index) { + return local_variable_table[i]; + } + } + return null; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLocalVariableTable(this); - } + /** + * @return matching variable using index when variable is used at supplied + * pc + * + * @param index + * the variable slot + * @param pc + * the current pc that this variable is alive + * + * @return the LocalVariable that matches or null if not found + */ + public final LocalVariable getLocalVariable(int index, int pc) { + for (int i = 0; i < local_variable_table_length; i++) { + if (local_variable_table[i].getIndex() == index) { + int start_pc = local_variable_table[i].getStartPC(); + int end_pc = start_pc + local_variable_table[i].getLength(); + if ((pc >= start_pc) && (pc < end_pc)) { + return local_variable_table[i]; + } + } + } + return null; + } + public final void setLocalVariableTable(LocalVariable[] local_variable_table) { + this.local_variable_table = local_variable_table; + local_variable_table_length = (local_variable_table == null) ? 0 + : local_variable_table.length; + } - /** - * Dump local variable table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(local_variable_table_length); - for (int i = 0; i < local_variable_table_length; i++) { - local_variable_table[i].dump(file); - } - } + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(""); + for (int i = 0; i < local_variable_table_length; i++) { + buf.append(local_variable_table[i].toString()); + if (i < local_variable_table_length - 1) { + buf.append('\n'); + } + } + return buf.toString(); + } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + LocalVariableTable c = (LocalVariableTable) clone(); + c.local_variable_table = new LocalVariable[local_variable_table_length]; + for (int i = 0; i < local_variable_table_length; i++) { + c.local_variable_table[i] = local_variable_table[i].copy(); + } + c.constant_pool = _constant_pool; + return c; + } - /** - * @return Array of local variables of method. - */ - public final LocalVariable[] getLocalVariableTable() { - return local_variable_table; - } - - - /** - * @return first matching variable using index - * - * @param index the variable slot - * - * @return the first LocalVariable that matches the slot or null if not found - * - * @deprecated since 5.2 because multiple variables can share the - * same slot, use getLocalVariable(int index, int pc) instead. - */ - public final LocalVariable getLocalVariable( int index ) { - for (int i = 0; i < local_variable_table_length; i++) { - if (local_variable_table[i].getIndex() == index) { - return local_variable_table[i]; - } - } - return null; - } - - - /** - * @return matching variable using index when variable is used at supplied pc - * - * @param index the variable slot - * @param pc the current pc that this variable is alive - * - * @return the LocalVariable that matches or null if not found - */ - public final LocalVariable getLocalVariable( int index, int pc ) { - for (int i = 0; i < local_variable_table_length; i++) { - if (local_variable_table[i].getIndex() == index) { - int start_pc = local_variable_table[i].getStartPC(); - int end_pc = start_pc + local_variable_table[i].getLength(); - if ((pc >= start_pc) && (pc < end_pc)) { - return local_variable_table[i]; - } - } - } - return null; - } - - - public final void setLocalVariableTable( LocalVariable[] local_variable_table ) { - this.local_variable_table = local_variable_table; - local_variable_table_length = (local_variable_table == null) - ? 0 - : local_variable_table.length; - } - - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(""); - for (int i = 0; i < local_variable_table_length; i++) { - buf.append(local_variable_table[i].toString()); - if (i < local_variable_table_length - 1) { - buf.append('\n'); - } - } - return buf.toString(); - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - LocalVariableTable c = (LocalVariableTable) clone(); - c.local_variable_table = new LocalVariable[local_variable_table_length]; - for (int i = 0; i < local_variable_table_length; i++) { - c.local_variable_table[i] = local_variable_table[i].copy(); - } - c.constant_pool = _constant_pool; - return c; - } - - - public final int getTableLength() { - return local_variable_table_length; - } + public final int getTableLength() { + return local_variable_table_length; + } } diff --git a/src/org/apache/bcel/classfile/Method.java b/src/org/apache/bcel/classfile/Method.java index 51b38ba..7dfc57b 100644 --- a/src/org/apache/bcel/classfile/Method.java +++ b/src/org/apache/bcel/classfile/Method.java @@ -23,232 +23,238 @@ import org.apache.bcel.generic.Type; import org.apache.bcel.util.BCELComparator; /** - * This class represents the method info structure, i.e., the representation - * for a method in the class. See JVM specification for details. - * A method has access flags, a name, a signature and a number of attributes. - * + * This class represents the method info structure, i.e., the representation for + * a method in the class. See JVM specification for details. A method has access + * flags, a name, a signature and a number of attributes. + * * @version $Id: Method.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class Method extends FieldOrMethod { - private static BCELComparator _cmp = new BCELComparator() { + /** + * + */ + private static final long serialVersionUID = 1L; + private static BCELComparator _cmp = new BCELComparator() { - public boolean equals( Object o1, Object o2 ) { - Method THIS = (Method) o1; - Method THAT = (Method) o2; - return THIS.getName().equals(THAT.getName()) - && THIS.getSignature().equals(THAT.getSignature()); - } + @Override + public boolean equals(Object o1, Object o2) { + Method THIS = (Method) o1; + Method THAT = (Method) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } + @Override + public int hashCode(Object o) { + Method THIS = (Method) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; - public int hashCode( Object o ) { - Method THIS = (Method) o; - return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); - } - }; + /** + * Empty constructor, all attributes have to be defined via `setXXX' + * methods. Use at your own risk. + */ + public Method() { + } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Method(Method c) { + super(c); + } - /** - * Empty constructor, all attributes have to be defined via `setXXX' - * methods. Use at your own risk. - */ - public Method() { - } + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + * @throws ClassFormatException + */ + Method(DataInputStream file, ConstantPool constant_pool) + throws IOException, ClassFormatException { + super(file, constant_pool); + } + /** + * @param access_flags + * Access rights of method + * @param name_index + * Points to field name in constant pool + * @param signature_index + * Points to encoded signature + * @param attributes + * Collection of attributes + * @param constant_pool + * Array of constants + */ + public Method(int access_flags, int name_index, int signature_index, + Attribute[] attributes, ConstantPool constant_pool) { + super(access_flags, name_index, signature_index, attributes, + constant_pool); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Method(Method c) { - super(c); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitMethod(this); + } + /** + * @return Code attribute of method, if any + */ + public final Code getCode() { + for (int i = 0; i < attributes_count; i++) { + if (attributes[i] instanceof Code) { + return (Code) attributes[i]; + } + } + return null; + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - * @throws ClassFormatException - */ - Method(DataInputStream file, ConstantPool constant_pool) throws IOException, - ClassFormatException { - super(file, constant_pool); - } + /** + * @return ExceptionTable attribute of method, if any, i.e., list all + * exceptions the method may throw not exception handlers! + */ + public final ExceptionTable getExceptionTable() { + for (int i = 0; i < attributes_count; i++) { + if (attributes[i] instanceof ExceptionTable) { + return (ExceptionTable) attributes[i]; + } + } + return null; + } + /** + * @return LocalVariableTable of code attribute if any, i.e. the call is + * forwarded to the Code atribute. + */ + public final LocalVariableTable getLocalVariableTable() { + Code code = getCode(); + if (code == null) { + return null; + } + return code.getLocalVariableTable(); + } - /** - * @param access_flags Access rights of method - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature - * @param attributes Collection of attributes - * @param constant_pool Array of constants - */ - public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes, - ConstantPool constant_pool) { - super(access_flags, name_index, signature_index, attributes, constant_pool); - } + /** + * @return LineNumberTable of code attribute if any, i.e. the call is + * forwarded to the Code atribute. + */ + public final LineNumberTable getLineNumberTable() { + Code code = getCode(); + if (code == null) { + return null; + } + return code.getLineNumberTable(); + } + /** + * Return string representation close to declaration format, `public static + * void main(String[] args) throws IOException', e.g. + * + * @return String representation of the method. + */ + @Override + public final String toString() { + ConstantUtf8 c; + String name, signature, access; // Short cuts to constant pool + StringBuffer buf; + access = Utility.accessToString(access_flags); + // Get name and signature from constant pool + c = (ConstantUtf8) constant_pool.getConstant(signature_index, + Constants.CONSTANT_Utf8); + signature = c.getBytes(); + c = (ConstantUtf8) constant_pool.getConstant(name_index, + Constants.CONSTANT_Utf8); + name = c.getBytes(); + signature = Utility.methodSignatureToString(signature, name, access, + true, getLocalVariableTable()); + buf = new StringBuffer(signature); + for (int i = 0; i < attributes_count; i++) { + Attribute a = attributes[i]; + if (!((a instanceof Code) || (a instanceof ExceptionTable))) { + buf.append(" [").append(a.toString()).append("]"); + } + } + ExceptionTable e = getExceptionTable(); + if (e != null) { + String str = e.toString(); + if (!str.equals("")) { + buf.append("\n\t\tthrows ").append(str); + } + } + return buf.toString(); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitMethod(this); - } + /** + * @return deep copy of this method + */ + public final Method copy(ConstantPool _constant_pool) { + return (Method) copy_(_constant_pool); + } + /** + * @return return type of method + */ + public Type getReturnType() { + return Type.getReturnType(getSignature()); + } - /** - * @return Code attribute of method, if any - */ - public final Code getCode() { - for (int i = 0; i < attributes_count; i++) { - if (attributes[i] instanceof Code) { - return (Code) attributes[i]; - } - } - return null; - } + /** + * @return array of method argument types + */ + public Type[] getArgumentTypes() { + return Type.getArgumentTypes(getSignature()); + } + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } - /** - * @return ExceptionTable attribute of method, if any, i.e., list all - * exceptions the method may throw not exception handlers! - */ - public final ExceptionTable getExceptionTable() { - for (int i = 0; i < attributes_count; i++) { - if (attributes[i] instanceof ExceptionTable) { - return (ExceptionTable) attributes[i]; - } - } - return null; - } + /** + * @param comparator + * Comparison strategy object + */ + public static void setComparator(BCELComparator comparator) { + _cmp = comparator; + } + /** + * Return value as defined by given BCELComparator strategy. By default two + * method objects are said to be equal when their names and signatures are + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return _cmp.equals(this, obj); + } - /** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded - * to the Code atribute. - */ - public final LocalVariableTable getLocalVariableTable() { - Code code = getCode(); - if (code == null) { - return null; - } - return code.getLocalVariableTable(); - } - - - /** @return LineNumberTable of code attribute if any, i.e. the call is forwarded - * to the Code atribute. - */ - public final LineNumberTable getLineNumberTable() { - Code code = getCode(); - if (code == null) { - return null; - } - return code.getLineNumberTable(); - } - - - /** - * Return string representation close to declaration format, - * `public static void main(String[] args) throws IOException', e.g. - * - * @return String representation of the method. - */ - public final String toString() { - ConstantUtf8 c; - String name, signature, access; // Short cuts to constant pool - StringBuffer buf; - access = Utility.accessToString(access_flags); - // Get name and signature from constant pool - c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8); - signature = c.getBytes(); - c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8); - name = c.getBytes(); - signature = Utility.methodSignatureToString(signature, name, access, true, - getLocalVariableTable()); - buf = new StringBuffer(signature); - for (int i = 0; i < attributes_count; i++) { - Attribute a = attributes[i]; - if (!((a instanceof Code) || (a instanceof ExceptionTable))) { - buf.append(" [").append(a.toString()).append("]"); - } - } - ExceptionTable e = getExceptionTable(); - if (e != null) { - String str = e.toString(); - if (!str.equals("")) { - buf.append("\n\t\tthrows ").append(str); - } - } - return buf.toString(); - } - - - /** - * @return deep copy of this method - */ - public final Method copy( ConstantPool _constant_pool ) { - return (Method) copy_(_constant_pool); - } - - - /** - * @return return type of method - */ - public Type getReturnType() { - return Type.getReturnType(getSignature()); - } - - - /** - * @return array of method argument types - */ - public Type[] getArgumentTypes() { - return Type.getArgumentTypes(getSignature()); - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return _cmp; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( BCELComparator comparator ) { - _cmp = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two method objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals( Object obj ) { - return _cmp.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the method's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return _cmp.hashCode(this); - } + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the method's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); + } } diff --git a/src/org/apache/bcel/classfile/Node.java b/src/org/apache/bcel/classfile/Node.java index f105b7c..0c4f63d 100644 --- a/src/org/apache/bcel/classfile/Node.java +++ b/src/org/apache/bcel/classfile/Node.java @@ -18,11 +18,11 @@ package org.apache.bcel.classfile; /** * Denote class to have an accept method(); - * + * * @version $Id: Node.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface Node { - public void accept( Visitor obj ); + public void accept(Visitor obj); } diff --git a/src/org/apache/bcel/classfile/PMGClass.java b/src/org/apache/bcel/classfile/PMGClass.java index 9511871..5fcb92f 100644 --- a/src/org/apache/bcel/classfile/PMGClass.java +++ b/src/org/apache/bcel/classfile/PMGClass.java @@ -22,146 +22,154 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class is derived from Attribute and represents a reference - * to a PMG attribute. - * + * This class is derived from Attribute and represents a reference to a + * PMG attribute. + * * @version $Id: PMGClass.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute + * @author M. Dahm + * @see Attribute */ public final class PMGClass extends Attribute { - private int pmg_class_index, pmg_index; + /** + * + */ + private static final long serialVersionUID = 1L; + private int pmg_class_index, pmg_index; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public PMGClass(PMGClass c) { + this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c + .getPMGClassIndex(), c.getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public PMGClass(PMGClass c) { - this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(), c - .getConstantPool()); - } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + PMGClass(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, file.readUnsignedShort(), file + .readUnsignedShort(), constant_pool); + } + /** + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param pmg_index + * index in constant pool for source file name + * @param pmg_class_index + * Index in constant pool to CONSTANT_Utf8 + * @param constant_pool + * Array of constants + */ + public PMGClass(int name_index, int length, int pmg_index, + int pmg_class_index, ConstantPool constant_pool) { + super(Constants.ATTR_PMG, name_index, length, constant_pool); + this.pmg_index = pmg_index; + this.pmg_class_index = pmg_class_index; + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - PMGClass(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), constant_pool); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + System.err.println("Visiting non-standard PMGClass object"); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(pmg_index); + file.writeShort(pmg_class_index); + } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param pmg_index index in constant pool for source file name - * @param pmg_class_index Index in constant pool to CONSTANT_Utf8 - * @param constant_pool Array of constants - */ - public PMGClass(int name_index, int length, int pmg_index, int pmg_class_index, - ConstantPool constant_pool) { - super(Constants.ATTR_PMG, name_index, length, constant_pool); - this.pmg_index = pmg_index; - this.pmg_class_index = pmg_class_index; - } + /** + * @return Index in constant pool of source file name. + */ + public final int getPMGClassIndex() { + return pmg_class_index; + } + /** + * @param pmg_class_index + */ + public final void setPMGClassIndex(int pmg_class_index) { + this.pmg_class_index = pmg_class_index; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - System.err.println("Visiting non-standard PMGClass object"); - } + /** + * @return Index in constant pool of source file name. + */ + public final int getPMGIndex() { + return pmg_index; + } + /** + * @param pmg_index + */ + public final void setPMGIndex(int pmg_index) { + this.pmg_index = pmg_index; + } - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(pmg_index); - file.writeShort(pmg_class_index); - } + /** + * @return PMG name. + */ + public final String getPMGName() { + ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + /** + * @return PMG class name. + */ + public final String getPMGClassName() { + ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant( + pmg_class_index, Constants.CONSTANT_Utf8); + return c.getBytes(); + } - /** - * @return Index in constant pool of source file name. - */ - public final int getPMGClassIndex() { - return pmg_class_index; - } + /** + * @return String representation + */ + @Override + public final String toString() { + return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")"; + } - - /** - * @param pmg_class_index - */ - public final void setPMGClassIndex( int pmg_class_index ) { - this.pmg_class_index = pmg_class_index; - } - - - /** - * @return Index in constant pool of source file name. - */ - public final int getPMGIndex() { - return pmg_index; - } - - - /** - * @param pmg_index - */ - public final void setPMGIndex( int pmg_index ) { - this.pmg_index = pmg_index; - } - - - /** - * @return PMG name. - */ - public final String getPMGName() { - ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } - - - /** - * @return PMG class name. - */ - public final String getPMGClassName() { - ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_class_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } - - - /** - * @return String representation - */ - public final String toString() { - return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")"; - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - return (PMGClass) clone(); - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + return (PMGClass) clone(); + } } diff --git a/src/org/apache/bcel/classfile/Signature.java b/src/org/apache/bcel/classfile/Signature.java index 49c03d4..602aff5 100644 --- a/src/org/apache/bcel/classfile/Signature.java +++ b/src/org/apache/bcel/classfile/Signature.java @@ -23,251 +23,251 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class is derived from Attribute and represents a reference - * to a GJ attribute. - * + * This class is derived from Attribute and represents a reference to a + * GJ attribute. + * * @version $Id: Signature.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute + * @author M. Dahm + * @see Attribute */ public final class Signature extends Attribute { - private int signature_index; + /** + * + */ + private static final long serialVersionUID = 1L; + private int signature_index; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Signature(Signature c) { + this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c + .getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Signature(Signature c) { - this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); - } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + Signature(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + /** + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param signature_index + * Index in constant pool to CONSTANT_Utf8 + * @param constant_pool + * Array of constants + */ + public Signature(int name_index, int length, int signature_index, + ConstantPool constant_pool) { + super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool); + this.signature_index = signature_index; + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Signature(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + // System.err.println("Visiting non-standard Signature object"); + v.visitSignature(this); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(signature_index); + } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param signature_index Index in constant pool to CONSTANT_Utf8 - * @param constant_pool Array of constants - */ - public Signature(int name_index, int length, int signature_index, ConstantPool constant_pool) { - super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool); - this.signature_index = signature_index; - } + /** + * @return Index in constant pool of source file name. + */ + public final int getSignatureIndex() { + return signature_index; + } + /** + * @param signature_index + * the index info the constant pool of this signature + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - //System.err.println("Visiting non-standard Signature object"); - v.visitSignature(this); - } + /** + * @return GJ signature. + */ + public final String getSignature() { + ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant( + signature_index, Constants.CONSTANT_Utf8); + return c.getBytes(); + } + /** + * Extends ByteArrayInputStream to make 'unreading' chars possible. + */ + private static final class MyByteArrayInputStream extends + ByteArrayInputStream { - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(signature_index); - } + MyByteArrayInputStream(String data) { + super(data.getBytes()); + } + final String getData() { + return new String(buf); + } - /** - * @return Index in constant pool of source file name. - */ - public final int getSignatureIndex() { - return signature_index; - } + final void unread() { + if (pos > 0) { + pos--; + } + } + } + private static boolean identStart(int ch) { + return ch == 'T' || ch == 'L'; + } - /** - * @param signature_index the index info the constant pool of this signature - */ - public final void setSignatureIndex( int signature_index ) { - this.signature_index = signature_index; - } + private static final void matchIdent(MyByteArrayInputStream in, + StringBuffer buf) { + int ch; + if ((ch = in.read()) == -1) { + throw new RuntimeException("Illegal signature: " + in.getData() + + " no ident, reaching EOF"); + } + // System.out.println("return from ident:" + (char)ch); + if (!identStart(ch)) { + StringBuffer buf2 = new StringBuffer(); + int count = 1; + while (Character.isJavaIdentifierPart((char) ch)) { + buf2.append((char) ch); + count++; + ch = in.read(); + } + if (ch == ':') { // Ok, formal parameter + in.skip("Ljava/lang/Object".length()); + buf.append(buf2); + ch = in.read(); + in.unread(); + // System.out.println("so far:" + buf2 + ":next:" +(char)ch); + } else { + for (int i = 0; i < count; i++) { + in.unread(); + } + } + return; + } + StringBuffer buf2 = new StringBuffer(); + ch = in.read(); + do { + buf2.append((char) ch); + ch = in.read(); + // System.out.println("within ident:"+ (char)ch); + } while ((ch != -1) + && (Character.isJavaIdentifierPart((char) ch) || (ch == '/'))); + buf.append(buf2.toString().replace('/', '.')); + // System.out.println("regular return ident:"+ (char)ch + ":" + buf2); + if (ch != -1) { + in.unread(); + } + } + private static final void matchGJIdent(MyByteArrayInputStream in, + StringBuffer buf) { + int ch; + matchIdent(in, buf); + ch = in.read(); + if ((ch == '<') || ch == '(') { // Parameterized or method + // System.out.println("Enter <"); + buf.append((char) ch); + matchGJIdent(in, buf); + while (((ch = in.read()) != '>') && (ch != ')')) { // List of + // parameters + if (ch == -1) { + throw new RuntimeException("Illegal signature: " + + in.getData() + " reaching EOF"); + } + // System.out.println("Still no >"); + buf.append(", "); + in.unread(); + matchGJIdent(in, buf); // Recursive call + } + // System.out.println("Exit >"); + buf.append((char) ch); + } else { + in.unread(); + } + ch = in.read(); + if (identStart(ch)) { + in.unread(); + matchGJIdent(in, buf); + } else if (ch == ')') { + in.unread(); + return; + } else if (ch != ';') { + throw new RuntimeException("Illegal signature: " + in.getData() + + " read " + (char) ch); + } + } - /** - * @return GJ signature. - */ - public final String getSignature() { - ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(signature_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } + public static String translate(String s) { + // System.out.println("Sig:" + s); + StringBuffer buf = new StringBuffer(); + matchGJIdent(new MyByteArrayInputStream(s), buf); + return buf.toString(); + } - /** - * Extends ByteArrayInputStream to make 'unreading' chars possible. - */ - private static final class MyByteArrayInputStream extends ByteArrayInputStream { + public static final boolean isFormalParameterList(String s) { + return s.startsWith("<") && (s.indexOf(':') > 0); + } - MyByteArrayInputStream(String data) { - super(data.getBytes()); - } + public static final boolean isActualParameterList(String s) { + return s.startsWith("L") && s.endsWith(">;"); + } + /** + * @return String representation + */ + @Override + public final String toString() { + String s = getSignature(); + return "Signature(" + s + ")"; + } - final int mark() { - return pos; - } - - - final String getData() { - return new String(buf); - } - - - final void reset( int p ) { - pos = p; - } - - - final void unread() { - if (pos > 0) { - pos--; - } - } - } - - - private static boolean identStart( int ch ) { - return ch == 'T' || ch == 'L'; - } - - - private static final void matchIdent( MyByteArrayInputStream in, StringBuffer buf ) { - int ch; - if ((ch = in.read()) == -1) { - throw new RuntimeException("Illegal signature: " + in.getData() - + " no ident, reaching EOF"); - } - //System.out.println("return from ident:" + (char)ch); - if (!identStart(ch)) { - StringBuffer buf2 = new StringBuffer(); - int count = 1; - while (Character.isJavaIdentifierPart((char) ch)) { - buf2.append((char) ch); - count++; - ch = in.read(); - } - if (ch == ':') { // Ok, formal parameter - in.skip("Ljava/lang/Object".length()); - buf.append(buf2); - ch = in.read(); - in.unread(); - //System.out.println("so far:" + buf2 + ":next:" +(char)ch); - } else { - for (int i = 0; i < count; i++) { - in.unread(); - } - } - return; - } - StringBuffer buf2 = new StringBuffer(); - ch = in.read(); - do { - buf2.append((char) ch); - ch = in.read(); - //System.out.println("within ident:"+ (char)ch); - } while ((ch != -1) && (Character.isJavaIdentifierPart((char) ch) || (ch == '/'))); - buf.append(buf2.toString().replace('/', '.')); - //System.out.println("regular return ident:"+ (char)ch + ":" + buf2); - if (ch != -1) { - in.unread(); - } - } - - - private static final void matchGJIdent( MyByteArrayInputStream in, StringBuffer buf ) { - int ch; - matchIdent(in, buf); - ch = in.read(); - if ((ch == '<') || ch == '(') { // Parameterized or method - //System.out.println("Enter <"); - buf.append((char) ch); - matchGJIdent(in, buf); - while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters - if (ch == -1) { - throw new RuntimeException("Illegal signature: " + in.getData() - + " reaching EOF"); - } - //System.out.println("Still no >"); - buf.append(", "); - in.unread(); - matchGJIdent(in, buf); // Recursive call - } - //System.out.println("Exit >"); - buf.append((char) ch); - } else { - in.unread(); - } - ch = in.read(); - if (identStart(ch)) { - in.unread(); - matchGJIdent(in, buf); - } else if (ch == ')') { - in.unread(); - return; - } else if (ch != ';') { - throw new RuntimeException("Illegal signature: " + in.getData() + " read " + (char) ch); - } - } - - - public static String translate( String s ) { - //System.out.println("Sig:" + s); - StringBuffer buf = new StringBuffer(); - matchGJIdent(new MyByteArrayInputStream(s), buf); - return buf.toString(); - } - - - public static final boolean isFormalParameterList( String s ) { - return s.startsWith("<") && (s.indexOf(':') > 0); - } - - - public static final boolean isActualParameterList( String s ) { - return s.startsWith("L") && s.endsWith(">;"); - } - - - /** - * @return String representation - */ - public final String toString() { - String s = getSignature(); - return "Signature(" + s + ")"; - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - return (Signature) clone(); - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + return (Signature) clone(); + } } diff --git a/src/org/apache/bcel/classfile/SourceFile.java b/src/org/apache/bcel/classfile/SourceFile.java index da391b4..9f98400 100644 --- a/src/org/apache/bcel/classfile/SourceFile.java +++ b/src/org/apache/bcel/classfile/SourceFile.java @@ -22,124 +22,134 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class is derived from Attribute and represents a reference - * to the source file of this class. At most one SourceFile attribute - * should appear per classfile. The intention of this class is that it is - * instantiated from the Attribute.readAttribute() method. - * + * This class is derived from Attribute and represents a reference to + * the source file of this class. At most one SourceFile attribute should appear + * per classfile. The intention of this class is that it is instantiated from + * the Attribute.readAttribute() method. + * * @version $Id: SourceFile.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute + * @author M. Dahm + * @see Attribute */ public final class SourceFile extends Attribute { - private int sourcefile_index; + /** + * + */ + private static final long serialVersionUID = 1L; + private int sourcefile_index; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public SourceFile(SourceFile c) { + this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c + .getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public SourceFile(SourceFile c) { - this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool()); - } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + SourceFile(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + /** + * @param name_index + * Index in constant pool to CONSTANT_Utf8, which should + * represent the string "SourceFile". + * @param length + * Content length in bytes, the value should be 2. + * @param constant_pool + * The constant pool that this attribute is associated with. + * @param sourcefile_index + * Index in constant pool to CONSTANT_Utf8. This string will be + * interpreted as the name of the file from which this class was + * compiled. It will not be interpreted as indicating the name of + * the directory contqining the file or an absolute path; this + * information has to be supplied the consumer of this attribute + * - in many cases, the JVM. + */ + public SourceFile(int name_index, int length, int sourcefile_index, + ConstantPool constant_pool) { + super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool); + this.sourcefile_index = sourcefile_index; + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - SourceFile(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitSourceFile(this); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(sourcefile_index); + } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8, which - * should represent the string "SourceFile". - * @param length Content length in bytes, the value should be 2. - * @param constant_pool The constant pool that this attribute is - * associated with. - * @param sourcefile_index Index in constant pool to CONSTANT_Utf8. This - * string will be interpreted as the name of the file from which this - * class was compiled. It will not be interpreted as indicating the name - * of the directory contqining the file or an absolute path; this - * information has to be supplied the consumer of this attribute - in - * many cases, the JVM. - */ - public SourceFile(int name_index, int length, int sourcefile_index, ConstantPool constant_pool) { - super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool); - this.sourcefile_index = sourcefile_index; - } + /** + * @return Index in constant pool of source file name. + */ + public final int getSourceFileIndex() { + return sourcefile_index; + } + /** + * @param sourcefile_index + */ + public final void setSourceFileIndex(int sourcefile_index) { + this.sourcefile_index = sourcefile_index; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitSourceFile(this); - } + /** + * @return Source file name. + */ + public final String getSourceFileName() { + ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant( + sourcefile_index, Constants.CONSTANT_Utf8); + return c.getBytes(); + } + /** + * @return String representation + */ + @Override + public final String toString() { + return "SourceFile(" + getSourceFileName() + ")"; + } - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(sourcefile_index); - } - - - /** - * @return Index in constant pool of source file name. - */ - public final int getSourceFileIndex() { - return sourcefile_index; - } - - - /** - * @param sourcefile_index - */ - public final void setSourceFileIndex( int sourcefile_index ) { - this.sourcefile_index = sourcefile_index; - } - - - /** - * @return Source file name. - */ - public final String getSourceFileName() { - ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(sourcefile_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } - - - /** - * @return String representation - */ - public final String toString() { - return "SourceFile(" + getSourceFileName() + ")"; - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - return (SourceFile) clone(); - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + return (SourceFile) clone(); + } } diff --git a/src/org/apache/bcel/classfile/StackMap.java b/src/org/apache/bcel/classfile/StackMap.java index 75e695a..0daa12f 100644 --- a/src/org/apache/bcel/classfile/StackMap.java +++ b/src/org/apache/bcel/classfile/StackMap.java @@ -22,132 +22,141 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class represents a stack map attribute used for - * preverification of Java classes for the Java 2 Micro Edition + * This class represents a stack map attribute used for preverification of Java + * classes for the Java 2 Micro Edition * (J2ME). This attribute is used by the KVM and contained - * within the Code attribute of a method. See CLDC specification - * 5.3.1.2 - * + * href="http://java.sun.com/products/cldc/">KVM and contained within the + * Code attribute of a method. See CLDC specification 5.3.1.2 + * * @version $Id: StackMap.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Code - * @see StackMapEntry - * @see StackMapType + * @author M. Dahm + * @see Code + * @see StackMapEntry + * @see StackMapType */ public final class StackMap extends Attribute implements Node { - private int map_length; - private StackMapEntry[] map; // Table of stack map entries + /** + * + */ + private static final long serialVersionUID = 1L; + private int map_length; + private StackMapEntry[] map; // Table of stack map entries + /* + * @param name_index Index of name + * + * @param length Content length in bytes + * + * @param map Table of stack map entries + * + * @param constant_pool Array of constants + */ + public StackMap(int name_index, int length, StackMapEntry[] map, + ConstantPool constant_pool) { + super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool); + setStackMap(map); + } - /* - * @param name_index Index of name - * @param length Content length in bytes - * @param map Table of stack map entries - * @param constant_pool Array of constants - */ - public StackMap(int name_index, int length, StackMapEntry[] map, ConstantPool constant_pool) { - super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool); - setStackMap(map); - } + /** + * Construct object from file stream. + * + * @param name_index + * Index of name + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + StackMap(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (StackMapEntry[]) null, constant_pool); + map_length = file.readUnsignedShort(); + map = new StackMapEntry[map_length]; + for (int i = 0; i < map_length; i++) { + map[i] = new StackMapEntry(file, constant_pool); + } + } + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(map_length); + for (int i = 0; i < map_length; i++) { + map[i].dump(file); + } + } - /** - * Construct object from file stream. - * @param name_index Index of name - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - StackMap(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (StackMapEntry[]) null, constant_pool); - map_length = file.readUnsignedShort(); - map = new StackMapEntry[map_length]; - for (int i = 0; i < map_length; i++) { - map[i] = new StackMapEntry(file, constant_pool); - } - } + /** + * @return Array of stack map entries + */ + public final StackMapEntry[] getStackMap() { + return map; + } + /** + * @param map + * Array of stack map entries + */ + public final void setStackMap(StackMapEntry[] map) { + this.map = map; + map_length = (map == null) ? 0 : map.length; + } - /** - * Dump line number table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(map_length); - for (int i = 0; i < map_length; i++) { - map[i].dump(file); - } - } + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer("StackMap("); + for (int i = 0; i < map_length; i++) { + buf.append(map[i].toString()); + if (i < map_length - 1) { + buf.append(", "); + } + } + buf.append(')'); + return buf.toString(); + } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + StackMap c = (StackMap) clone(); + c.map = new StackMapEntry[map_length]; + for (int i = 0; i < map_length; i++) { + c.map[i] = map[i].copy(); + } + c.constant_pool = _constant_pool; + return c; + } - /** - * @return Array of stack map entries - */ - public final StackMapEntry[] getStackMap() { - return map; - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackMap(this); + } - - /** - * @param map Array of stack map entries - */ - public final void setStackMap( StackMapEntry[] map ) { - this.map = map; - map_length = (map == null) ? 0 : map.length; - } - - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer("StackMap("); - for (int i = 0; i < map_length; i++) { - buf.append(map[i].toString()); - if (i < map_length - 1) { - buf.append(", "); - } - } - buf.append(')'); - return buf.toString(); - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - StackMap c = (StackMap) clone(); - c.map = new StackMapEntry[map_length]; - for (int i = 0; i < map_length; i++) { - c.map[i] = map[i].copy(); - } - c.constant_pool = _constant_pool; - return c; - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackMap(this); - } - - - public final int getMapLength() { - return map_length; - } + public final int getMapLength() { + return map_length; + } } diff --git a/src/org/apache/bcel/classfile/StackMapEntry.java b/src/org/apache/bcel/classfile/StackMapEntry.java index 2d53152..61df151 100644 --- a/src/org/apache/bcel/classfile/StackMapEntry.java +++ b/src/org/apache/bcel/classfile/StackMapEntry.java @@ -21,192 +21,181 @@ import java.io.DataOutputStream; import java.io.IOException; /** - * This class represents a stack map entry recording the types of - * local variables and the the of stack items at a given byte code offset. - * See CLDC specification 5.3.1.2 - * + * This class represents a stack map entry recording the types of local + * variables and the the of stack items at a given byte code offset. See CLDC + * specification 5.3.1.2 + * * @version $Id: StackMapEntry.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see StackMap - * @see StackMapType + * @author M. Dahm + * @see StackMap + * @see StackMapType */ public final class StackMapEntry implements Cloneable { - private int byte_code_offset; - private int number_of_locals; - private StackMapType[] types_of_locals; - private int number_of_stack_items; - private StackMapType[] types_of_stack_items; - private ConstantPool constant_pool; + private int byte_code_offset; + private int number_of_locals; + private StackMapType[] types_of_locals; + private int number_of_stack_items; + private StackMapType[] types_of_stack_items; + private ConstantPool constant_pool; + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + */ + StackMapEntry(DataInputStream file, ConstantPool constant_pool) + throws IOException { + this(file.readShort(), file.readShort(), null, -1, null, constant_pool); + types_of_locals = new StackMapType[number_of_locals]; + for (int i = 0; i < number_of_locals; i++) { + types_of_locals[i] = new StackMapType(file, constant_pool); + } + number_of_stack_items = file.readShort(); + types_of_stack_items = new StackMapType[number_of_stack_items]; + for (int i = 0; i < number_of_stack_items; i++) { + types_of_stack_items[i] = new StackMapType(file, constant_pool); + } + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException { - this(file.readShort(), file.readShort(), null, -1, null, constant_pool); - types_of_locals = new StackMapType[number_of_locals]; - for (int i = 0; i < number_of_locals; i++) { - types_of_locals[i] = new StackMapType(file, constant_pool); - } - number_of_stack_items = file.readShort(); - types_of_stack_items = new StackMapType[number_of_stack_items]; - for (int i = 0; i < number_of_stack_items; i++) { - types_of_stack_items[i] = new StackMapType(file, constant_pool); - } - } + public StackMapEntry(int byte_code_offset, int number_of_locals, + StackMapType[] types_of_locals, int number_of_stack_items, + StackMapType[] types_of_stack_items, ConstantPool constant_pool) { + this.byte_code_offset = byte_code_offset; + this.number_of_locals = number_of_locals; + this.types_of_locals = types_of_locals; + this.number_of_stack_items = number_of_stack_items; + this.types_of_stack_items = types_of_stack_items; + this.constant_pool = constant_pool; + } + /** + * Dump stack map entry + * + * @param file + * Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeShort(byte_code_offset); + file.writeShort(number_of_locals); + for (int i = 0; i < number_of_locals; i++) { + types_of_locals[i].dump(file); + } + file.writeShort(number_of_stack_items); + for (int i = 0; i < number_of_stack_items; i++) { + types_of_stack_items[i].dump(file); + } + } - public StackMapEntry(int byte_code_offset, int number_of_locals, - StackMapType[] types_of_locals, int number_of_stack_items, - StackMapType[] types_of_stack_items, ConstantPool constant_pool) { - this.byte_code_offset = byte_code_offset; - this.number_of_locals = number_of_locals; - this.types_of_locals = types_of_locals; - this.number_of_stack_items = number_of_stack_items; - this.types_of_stack_items = types_of_stack_items; - this.constant_pool = constant_pool; - } + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer(64); + buf.append("(offset=").append(byte_code_offset); + if (number_of_locals > 0) { + buf.append(", locals={"); + for (int i = 0; i < number_of_locals; i++) { + buf.append(types_of_locals[i]); + if (i < number_of_locals - 1) { + buf.append(", "); + } + } + buf.append("}"); + } + if (number_of_stack_items > 0) { + buf.append(", stack items={"); + for (int i = 0; i < number_of_stack_items; i++) { + buf.append(types_of_stack_items[i]); + if (i < number_of_stack_items - 1) { + buf.append(", "); + } + } + buf.append("}"); + } + buf.append(")"); + return buf.toString(); + } + public void setByteCodeOffset(int b) { + byte_code_offset = b; + } - /** - * Dump stack map entry - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeShort(byte_code_offset); - file.writeShort(number_of_locals); - for (int i = 0; i < number_of_locals; i++) { - types_of_locals[i].dump(file); - } - file.writeShort(number_of_stack_items); - for (int i = 0; i < number_of_stack_items; i++) { - types_of_stack_items[i].dump(file); - } - } + public int getByteCodeOffset() { + return byte_code_offset; + } + public void setNumberOfLocals(int n) { + number_of_locals = n; + } - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(64); - buf.append("(offset=").append(byte_code_offset); - if (number_of_locals > 0) { - buf.append(", locals={"); - for (int i = 0; i < number_of_locals; i++) { - buf.append(types_of_locals[i]); - if (i < number_of_locals - 1) { - buf.append(", "); - } - } - buf.append("}"); - } - if (number_of_stack_items > 0) { - buf.append(", stack items={"); - for (int i = 0; i < number_of_stack_items; i++) { - buf.append(types_of_stack_items[i]); - if (i < number_of_stack_items - 1) { - buf.append(", "); - } - } - buf.append("}"); - } - buf.append(")"); - return buf.toString(); - } + public int getNumberOfLocals() { + return number_of_locals; + } + public void setTypesOfLocals(StackMapType[] t) { + types_of_locals = t; + } - public void setByteCodeOffset( int b ) { - byte_code_offset = b; - } + public StackMapType[] getTypesOfLocals() { + return types_of_locals; + } + public void setNumberOfStackItems(int n) { + number_of_stack_items = n; + } - public int getByteCodeOffset() { - return byte_code_offset; - } + public int getNumberOfStackItems() { + return number_of_stack_items; + } + public void setTypesOfStackItems(StackMapType[] t) { + types_of_stack_items = t; + } - public void setNumberOfLocals( int n ) { - number_of_locals = n; - } + public StackMapType[] getTypesOfStackItems() { + return types_of_stack_items; + } + /** + * @return deep copy of this object + */ + public StackMapEntry copy() { + try { + return (StackMapEntry) clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } - public int getNumberOfLocals() { - return number_of_locals; - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + public void accept(Visitor v) { + v.visitStackMapEntry(this); + } + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } - public void setTypesOfLocals( StackMapType[] t ) { - types_of_locals = t; - } - - - public StackMapType[] getTypesOfLocals() { - return types_of_locals; - } - - - public void setNumberOfStackItems( int n ) { - number_of_stack_items = n; - } - - - public int getNumberOfStackItems() { - return number_of_stack_items; - } - - - public void setTypesOfStackItems( StackMapType[] t ) { - types_of_stack_items = t; - } - - - public StackMapType[] getTypesOfStackItems() { - return types_of_stack_items; - } - - - /** - * @return deep copy of this object - */ - public StackMapEntry copy() { - try { - return (StackMapEntry) clone(); - } catch (CloneNotSupportedException e) { - } - return null; - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackMapEntry(this); - } - - - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { - return constant_pool; - } - - - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool( ConstantPool constant_pool ) { - this.constant_pool = constant_pool; - } + /** + * @param constant_pool + * Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } } diff --git a/src/org/apache/bcel/classfile/StackMapType.java b/src/org/apache/bcel/classfile/StackMapType.java index df6555e..1276b4f 100644 --- a/src/org/apache/bcel/classfile/StackMapType.java +++ b/src/org/apache/bcel/classfile/StackMapType.java @@ -22,140 +22,139 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * This class represents the type of a local variable or item on stack - * used in the StackMap entries. - * + * This class represents the type of a local variable or item on stack used in + * the StackMap entries. + * * @version $Id: StackMapType.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see StackMapEntry - * @see StackMap - * @see Constants + * @author M. Dahm + * @see StackMapEntry + * @see StackMap + * @see Constants */ public final class StackMapType implements Cloneable { - private byte type; - private int index = -1; // Index to CONSTANT_Class or offset - private ConstantPool constant_pool; + private byte type; + private int index = -1; // Index to CONSTANT_Class or offset + private ConstantPool constant_pool; + /** + * Construct object from file stream. + * + * @param file + * Input stream + * @throws IOException + */ + StackMapType(DataInputStream file, ConstantPool constant_pool) + throws IOException { + this(file.readByte(), -1, constant_pool); + if (hasIndex()) { + setIndex(file.readShort()); + } + setConstantPool(constant_pool); + } - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - StackMapType(DataInputStream file, ConstantPool constant_pool) throws IOException { - this(file.readByte(), -1, constant_pool); - if (hasIndex()) { - setIndex(file.readShort()); - } - setConstantPool(constant_pool); - } + /** + * @param type + * type tag as defined in the Constants interface + * @param index + * index to constant pool, or byte code offset + */ + public StackMapType(byte type, int index, ConstantPool constant_pool) { + setType(type); + setIndex(index); + setConstantPool(constant_pool); + } + public void setType(byte t) { + if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) { + throw new RuntimeException("Illegal type for StackMapType: " + t); + } + type = t; + } - /** - * @param type type tag as defined in the Constants interface - * @param index index to constant pool, or byte code offset - */ - public StackMapType(byte type, int index, ConstantPool constant_pool) { - setType(type); - setIndex(index); - setConstantPool(constant_pool); - } + public byte getType() { + return type; + } + public void setIndex(int t) { + index = t; + } - public void setType( byte t ) { - if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) { - throw new RuntimeException("Illegal type for StackMapType: " + t); - } - type = t; - } + /** + * @return index to constant pool if type == ITEM_Object, or offset in byte + * code, if type == ITEM_NewObject, and -1 otherwise + */ + public int getIndex() { + return index; + } + /** + * Dump type entries to file. + * + * @param file + * Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException { + file.writeByte(type); + if (hasIndex()) { + file.writeShort(getIndex()); + } + } - public byte getType() { - return type; - } + /** + * @return true, if type is either ITEM_Object or ITEM_NewObject + */ + public final boolean hasIndex() { + return ((type == Constants.ITEM_Object) || (type == Constants.ITEM_NewObject)); + } + private String printIndex() { + if (type == Constants.ITEM_Object) { + if (index < 0) { + return ", class="; + } + return ", class=" + + constant_pool.constantToString(index, + Constants.CONSTANT_Class); + } else if (type == Constants.ITEM_NewObject) { + return ", offset=" + index; + } else { + return ""; + } + } - public void setIndex( int t ) { - index = t; - } + /** + * @return String representation + */ + @Override + public final String toString() { + return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")"; + } + /** + * @return deep copy of this object + */ + public StackMapType copy() { + try { + return (StackMapType) clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } - /** @return index to constant pool if type == ITEM_Object, or offset - * in byte code, if type == ITEM_NewObject, and -1 otherwise - */ - public int getIndex() { - return index; - } + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } - - /** - * Dump type entries to file. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(type); - if (hasIndex()) { - file.writeShort(getIndex()); - } - } - - - /** @return true, if type is either ITEM_Object or ITEM_NewObject - */ - public final boolean hasIndex() { - return ((type == Constants.ITEM_Object) || (type == Constants.ITEM_NewObject)); - } - - - private String printIndex() { - if (type == Constants.ITEM_Object) { - if (index < 0) { - return ", class="; - } - return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class); - } else if (type == Constants.ITEM_NewObject) { - return ", offset=" + index; - } else { - return ""; - } - } - - - /** - * @return String representation - */ - public final String toString() { - return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")"; - } - - - /** - * @return deep copy of this object - */ - public StackMapType copy() { - try { - return (StackMapType) clone(); - } catch (CloneNotSupportedException e) { - } - return null; - } - - - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { - return constant_pool; - } - - - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool( ConstantPool constant_pool ) { - this.constant_pool = constant_pool; - } + /** + * @param constant_pool + * Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } } diff --git a/src/org/apache/bcel/classfile/Synthetic.java b/src/org/apache/bcel/classfile/Synthetic.java index a7ce252..1f2c784 100644 --- a/src/org/apache/bcel/classfile/Synthetic.java +++ b/src/org/apache/bcel/classfile/Synthetic.java @@ -23,128 +23,137 @@ import org.apache.bcel.Constants; /** * This class is derived from Attribute and declares this class as - * `synthetic', i.e., it needs special handling. The JVM specification - * states "A class member that does not appear in the source code must be - * marked using a Synthetic attribute." It may appear in the ClassFile - * attribute table, a field_info table or a method_info table. This class - * is intended to be instantiated from the - * Attribute.readAttribute() method. - * + * `synthetic', i.e., it needs special handling. The JVM specification states "A + * class member that does not appear in the source code must be marked using a + * Synthetic attribute." It may appear in the ClassFile attribute table, a + * field_info table or a method_info table. This class is intended to be + * instantiated from the Attribute.readAttribute() method. + * * @version $Id: Synthetic.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Attribute + * @author M. Dahm + * @see Attribute */ public final class Synthetic extends Attribute { - private byte[] bytes; + /** + * + */ + private static final long serialVersionUID = 1L; + private byte[] bytes; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public Synthetic(Synthetic c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public Synthetic(Synthetic c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } + /** + * @param name_index + * Index in constant pool to CONSTANT_Utf8, which should + * represent the string "Synthetic". + * @param length + * Content length in bytes - should be zero. + * @param bytes + * Attribute contents + * @param constant_pool + * The constant pool this attribute is associated with. + */ + public Synthetic(int name_index, int length, byte[] bytes, + ConstantPool constant_pool) { + super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool); + this.bytes = bytes; + } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool to CONSTANT_Utf8 + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + Synthetic(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + if (length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + System.err.println("Synthetic attribute with length > 0"); + } + } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8, which - * should represent the string "Synthetic". - * @param length Content length in bytes - should be zero. - * @param bytes Attribute contents - * @param constant_pool The constant pool this attribute is associated - * with. - */ - public Synthetic(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { - super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool); - this.bytes = bytes; - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitSynthetic(this); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (length > 0) { + file.write(bytes, 0, length); + } + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Synthetic(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (byte[]) null, constant_pool); - if (length > 0) { - bytes = new byte[length]; - file.readFully(bytes); - System.err.println("Synthetic attribute with length > 0"); - } - } + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } + /** + * @param bytes + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitSynthetic(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuffer buf = new StringBuffer("Synthetic"); + if (length > 0) { + buf.append(" ").append(Utility.toHexString(bytes)); + } + return buf.toString(); + } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - if (length > 0) { - file.write(bytes, 0, length); - } - } - - - /** - * @return data bytes. - */ - public final byte[] getBytes() { - return bytes; - } - - - /** - * @param bytes - */ - public final void setBytes( byte[] bytes ) { - this.bytes = bytes; - } - - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer("Synthetic"); - if (length > 0) { - buf.append(" ").append(Utility.toHexString(bytes)); - } - return buf.toString(); - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - Synthetic c = (Synthetic) clone(); - if (bytes != null) { - c.bytes = new byte[bytes.length]; - System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); - } - c.constant_pool = _constant_pool; - return c; - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + Synthetic c = (Synthetic) clone(); + if (bytes != null) { + c.bytes = new byte[bytes.length]; + System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); + } + c.constant_pool = _constant_pool; + return c; + } } diff --git a/src/org/apache/bcel/classfile/Unknown.java b/src/org/apache/bcel/classfile/Unknown.java index d7e333e..d4ce2f4 100644 --- a/src/org/apache/bcel/classfile/Unknown.java +++ b/src/org/apache/bcel/classfile/Unknown.java @@ -22,167 +22,178 @@ import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; + import org.apache.bcel.Constants; /** - * This class represents a reference to an unknown (i.e., - * application-specific) attribute of a class. It is instantiated from the - * Attribute.readAttribute() method. Applications that need to - * read in application-specific attributes should create an AttributeReader implementation and - * attach it via AttributeReader implementation and attach + * it via Attribute.addAttributeReader. - - * + * + * * @version $Id: Unknown.java 386056 2006-03-15 11:31:56Z tcurdt $ * @see org.apache.bcel.classfile.Attribute * @see org.apache.bcel.classfile.AttributeReader - * @author M. Dahm + * @author M. Dahm */ public final class Unknown extends Attribute { - private byte[] bytes; - private String name; - private static Map unknown_attributes = new HashMap(); + /** + * + */ + private static final long serialVersionUID = 1L; + private byte[] bytes; + private String name; + private static Map unknown_attributes = new HashMap(); + /** + * @return array of unknown attributes, but just one for each kind. + */ + static Unknown[] getUnknownAttributes() { + Unknown[] unknowns = new Unknown[unknown_attributes.size()]; + Iterator entries = unknown_attributes.values().iterator(); + for (int i = 0; entries.hasNext(); i++) { + unknowns[i] = entries.next(); + } + unknown_attributes.clear(); + return unknowns; + } - /** @return array of unknown attributes, but just one for each kind. - */ - static Unknown[] getUnknownAttributes() { - Unknown[] unknowns = new Unknown[unknown_attributes.size()]; - Iterator entries = unknown_attributes.values().iterator(); - for (int i = 0; entries.hasNext(); i++) { - unknowns[i] = (Unknown) entries.next(); - } - unknown_attributes.clear(); - return unknowns; - } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Unknown(Unknown c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } + /** + * Create a non-standard attribute. + * + * @param name_index + * Index in constant pool + * @param length + * Content length in bytes + * @param bytes + * Attribute contents + * @param constant_pool + * Array of constants + */ + public Unknown(int name_index, int length, byte[] bytes, + ConstantPool constant_pool) { + super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); + this.bytes = bytes; + name = ((ConstantUtf8) constant_pool.getConstant(name_index, + Constants.CONSTANT_Utf8)).getBytes(); + unknown_attributes.put(name, this); + } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Unknown(Unknown c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } + /** + * Construct object from file stream. + * + * @param name_index + * Index in constant pool + * @param length + * Content length in bytes + * @param file + * Input stream + * @param constant_pool + * Array of constants + * @throws IOException + */ + Unknown(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + if (length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + } + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitUnknown(this); + } - /** - * Create a non-standard attribute. - * - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param bytes Attribute contents - * @param constant_pool Array of constants - */ - public Unknown(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { - super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); - this.bytes = bytes; - name = ((ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8)) - .getBytes(); - unknown_attributes.put(name, this); - } + /** + * Dump unknown bytes to file stream. + * + * @param file + * Output file stream + * @throws IOException + */ + @Override + public final void dump(DataOutputStream file) throws IOException { + super.dump(file); + if (length > 0) { + file.write(bytes, 0, length); + } + } + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } - /** - * Construct object from file stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Unknown(int name_index, int length, DataInputStream file, ConstantPool constant_pool) - throws IOException { - this(name_index, length, (byte[]) null, constant_pool); - if (length > 0) { - bytes = new byte[length]; - file.readFully(bytes); - } - } + /** + * @return name of attribute. + */ + public final String getName() { + return name; + } + /** + * @param bytes + * the bytes to set + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitUnknown(this); - } + /** + * @return String representation. + */ + @Override + public final String toString() { + if (length == 0 || bytes == null) { + return "(Unknown attribute " + name + ")"; + } + String hex; + if (length > 10) { + byte[] tmp = new byte[10]; + System.arraycopy(bytes, 0, tmp, 0, 10); + hex = Utility.toHexString(tmp) + "... (truncated)"; + } else { + hex = Utility.toHexString(bytes); + } + return "(Unknown attribute " + name + ": " + hex + ")"; + } - - /** - * Dump unknown bytes to file stream. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump( DataOutputStream file ) throws IOException { - super.dump(file); - if (length > 0) { - file.write(bytes, 0, length); - } - } - - - /** - * @return data bytes. - */ - public final byte[] getBytes() { - return bytes; - } - - - /** - * @return name of attribute. - */ - public final String getName() { - return name; - } - - - /** - * @param bytes the bytes to set - */ - public final void setBytes( byte[] bytes ) { - this.bytes = bytes; - } - - - /** - * @return String representation. - */ - public final String toString() { - if (length == 0 || bytes == null) { - return "(Unknown attribute " + name + ")"; - } - String hex; - if (length > 10) { - byte[] tmp = new byte[10]; - System.arraycopy(bytes, 0, tmp, 0, 10); - hex = Utility.toHexString(tmp) + "... (truncated)"; - } else { - hex = Utility.toHexString(bytes); - } - return "(Unknown attribute " + name + ": " + hex + ")"; - } - - - /** - * @return deep copy of this attribute - */ - public Attribute copy( ConstantPool _constant_pool ) { - Unknown c = (Unknown) clone(); - if (bytes != null) { - c.bytes = new byte[bytes.length]; - System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); - } - c.constant_pool = _constant_pool; - return c; - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(ConstantPool _constant_pool) { + Unknown c = (Unknown) clone(); + if (bytes != null) { + c.bytes = new byte[bytes.length]; + System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); + } + c.constant_pool = _constant_pool; + return c; + } } diff --git a/src/org/apache/bcel/classfile/Utility.java b/src/org/apache/bcel/classfile/Utility.java index d9b79c1..86d8c71 100644 --- a/src/org/apache/bcel/classfile/Utility.java +++ b/src/org/apache/bcel/classfile/Utility.java @@ -32,1311 +32,1402 @@ import java.util.List; import java.util.Locale; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; + import org.apache.bcel.Constants; import org.apache.bcel.util.ByteSequence; /** * Utility functions that do not really belong to any class in particular. - * + * * @version $Id: Utility.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class Utility { - private static int unwrap( ThreadLocal tl ) { - return ((Integer) tl.get()).intValue(); - } - - - private static void wrap( ThreadLocal tl, int value ) { - tl.set(new Integer(value)); - } - - private static ThreadLocal consumed_chars = new ThreadLocal() { - - protected Object initialValue() { - return new Integer(0); - } - };/* How many chars have been consumed - * during parsing in signatureToString(). - * Read by methodSignatureToString(). - * Set by side effect,but only internally. - */ - private static boolean wide = false; /* The `WIDE' instruction is used in the - * byte code to allow 16-bit wide indices - * for local variables. This opcode - * precedes an `ILOAD', e.g.. The opcode - * immediately following takes an extra - * byte which is combined with the - * following byte to form a - * 16-bit value. - */ - - - /** - * Convert bit field of flags into string such as `static final'. - * - * @param access_flags Access flags - * @return String representation of flags - */ - public static final String accessToString( int access_flags ) { - return accessToString(access_flags, false); - } - - - /** - * Convert bit field of flags into string such as `static final'. - * - * Special case: Classes compiled with new compilers and with the - * `ACC_SUPER' flag would be said to be "synchronized". This is - * because SUN used the same value for the flags `ACC_SUPER' and - * `ACC_SYNCHRONIZED'. - * - * @param access_flags Access flags - * @param for_class access flags are for class qualifiers ? - * @return String representation of flags - */ - public static final String accessToString( int access_flags, boolean for_class ) { - StringBuffer buf = new StringBuffer(); - int p = 0; - for (int i = 0; p < Constants.MAX_ACC_FLAG; i++) { // Loop through known flags - p = pow2(i); - if ((access_flags & p) != 0) { - /* Special case: Classes compiled with new compilers and with the - * `ACC_SUPER' flag would be said to be "synchronized". This is - * because SUN used the same value for the flags `ACC_SUPER' and - * `ACC_SYNCHRONIZED'. - */ - if (for_class && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE))) { - continue; - } - buf.append(Constants.ACCESS_NAMES[i]).append(" "); - } - } - return buf.toString().trim(); - } - - - /** - * @return "class" or "interface", depending on the ACC_INTERFACE flag - */ - public static final String classOrInterface( int access_flags ) { - return ((access_flags & Constants.ACC_INTERFACE) != 0) ? "interface" : "class"; - } - - - /** - * Disassemble a byte array of JVM byte codes starting from code line - * `index' and return the disassembled string representation. Decode only - * `num' opcodes (including their operands), use -1 if you want to - * decompile everything. - * - * @param code byte code array - * @param constant_pool Array of constants - * @param index offset in `code' array - * (number of opcodes, not bytes!) - * @param length number of opcodes to decompile, -1 for all - * @param verbose be verbose, e.g. print constant pool index - * @return String representation of byte codes - */ - public static final String codeToString( byte[] code, ConstantPool constant_pool, int index, - int length, boolean verbose ) { - StringBuffer buf = new StringBuffer(code.length * 20); // Should be sufficient - ByteSequence stream = new ByteSequence(code); - try { - for (int i = 0; i < index; i++) { - codeToString(stream, constant_pool, verbose); - } - for (int i = 0; stream.available() > 0; i++) { - if ((length < 0) || (i < length)) { - String indices = fillup(stream.getIndex() + ":", 6, true, ' '); - buf.append(indices).append(codeToString(stream, constant_pool, verbose)) - .append('\n'); - } - } - } catch (IOException e) { - System.out.println(buf.toString()); - e.printStackTrace(); - throw new ClassFormatException("Byte code error: " + e); - } - return buf.toString(); - } - - - public static final String codeToString( byte[] code, ConstantPool constant_pool, int index, - int length ) { - return codeToString(code, constant_pool, index, length, true); - } - - - /** - * Disassemble a stream of byte codes and return the - * string representation. - * - * @param bytes stream of bytes - * @param constant_pool Array of constants - * @param verbose be verbose, e.g. print constant pool index - * @return String representation of byte code - */ - public static final String codeToString( ByteSequence bytes, ConstantPool constant_pool, - boolean verbose ) throws IOException { - short opcode = (short) bytes.readUnsignedByte(); - int default_offset = 0, low, high, npairs; - int index, vindex, constant; - int[] match, jump_table; - int no_pad_bytes = 0, offset; - StringBuffer buf = new StringBuffer(Constants.OPCODE_NAMES[opcode]); - /* Special case: Skip (0-3) padding bytes, i.e., the - * following bytes are 4-byte-aligned - */ - if ((opcode == Constants.TABLESWITCH) || (opcode == Constants.LOOKUPSWITCH)) { - int remainder = bytes.getIndex() % 4; - no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; - for (int i = 0; i < no_pad_bytes; i++) { - byte b; - if ((b = bytes.readByte()) != 0) { - System.err.println("Warning: Padding byte != 0 in " - + Constants.OPCODE_NAMES[opcode] + ":" + b); - } - } - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); - } - switch (opcode) { - /* Table switch has variable length arguments. - */ - case Constants.TABLESWITCH: - low = bytes.readInt(); - high = bytes.readInt(); - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - buf.append("\tdefault = ").append(default_offset).append(", low = ").append(low) - .append(", high = ").append(high).append("("); - jump_table = new int[high - low + 1]; - for (int i = 0; i < jump_table.length; i++) { - jump_table[i] = offset + bytes.readInt(); - buf.append(jump_table[i]); - if (i < jump_table.length - 1) { - buf.append(", "); - } - } - buf.append(")"); - break; - /* Lookup switch has variable length arguments. - */ - case Constants.LOOKUPSWITCH: { - npairs = bytes.readInt(); - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - match = new int[npairs]; - jump_table = new int[npairs]; - default_offset += offset; - buf.append("\tdefault = ").append(default_offset).append(", npairs = ").append( - npairs).append(" ("); - for (int i = 0; i < npairs; i++) { - match[i] = bytes.readInt(); - jump_table[i] = offset + bytes.readInt(); - buf.append("(").append(match[i]).append(", ").append(jump_table[i]).append(")"); - if (i < npairs - 1) { - buf.append(", "); - } - } - buf.append(")"); - } - break; - /* Two address bytes + offset from start of byte stream form the - * jump target - */ - case Constants.GOTO: - case Constants.IFEQ: - case Constants.IFGE: - case Constants.IFGT: - case Constants.IFLE: - case Constants.IFLT: - case Constants.JSR: - case Constants.IFNE: - case Constants.IFNONNULL: - case Constants.IFNULL: - case Constants.IF_ACMPEQ: - case Constants.IF_ACMPNE: - case Constants.IF_ICMPEQ: - case Constants.IF_ICMPGE: - case Constants.IF_ICMPGT: - case Constants.IF_ICMPLE: - case Constants.IF_ICMPLT: - case Constants.IF_ICMPNE: - buf.append("\t\t#").append((bytes.getIndex() - 1) + bytes.readShort()); - break; - /* 32-bit wide jumps - */ - case Constants.GOTO_W: - case Constants.JSR_W: - buf.append("\t\t#").append(((bytes.getIndex() - 1) + bytes.readInt())); - break; - /* Index byte references local variable (register) - */ - case Constants.ALOAD: - case Constants.ASTORE: - case Constants.DLOAD: - case Constants.DSTORE: - case Constants.FLOAD: - case Constants.FSTORE: - case Constants.ILOAD: - case Constants.ISTORE: - case Constants.LLOAD: - case Constants.LSTORE: - case Constants.RET: - if (wide) { - vindex = bytes.readUnsignedShort(); - wide = false; // Clear flag - } else { - vindex = bytes.readUnsignedByte(); - } - buf.append("\t\t%").append(vindex); - break; - /* - * Remember wide byte which is used to form a 16-bit address in the - * following instruction. Relies on that the method is called again with - * the following opcode. - */ - case Constants.WIDE: - wide = true; - buf.append("\t(wide)"); - break; - /* Array of basic type. - */ - case Constants.NEWARRAY: - buf.append("\t\t<").append(Constants.TYPE_NAMES[bytes.readByte()]).append(">"); - break; - /* Access object/class fields. - */ - case Constants.GETFIELD: - case Constants.GETSTATIC: - case Constants.PUTFIELD: - case Constants.PUTSTATIC: - index = bytes.readUnsignedShort(); - buf.append("\t\t").append( - constant_pool.constantToString(index, Constants.CONSTANT_Fieldref)).append( - (verbose ? " (" + index + ")" : "")); - break; - /* Operands are references to classes in constant pool - */ - case Constants.NEW: - case Constants.CHECKCAST: - buf.append("\t"); - case Constants.INSTANCEOF: - index = bytes.readUnsignedShort(); - buf.append("\t<").append( - constant_pool.constantToString(index, Constants.CONSTANT_Class)) - .append(">").append((verbose ? " (" + index + ")" : "")); - break; - /* Operands are references to methods in constant pool - */ - case Constants.INVOKESPECIAL: - case Constants.INVOKESTATIC: - case Constants.INVOKEVIRTUAL: - index = bytes.readUnsignedShort(); - buf.append("\t").append( - constant_pool.constantToString(index, Constants.CONSTANT_Methodref)) - .append((verbose ? " (" + index + ")" : "")); - break; - case Constants.INVOKEINTERFACE: - index = bytes.readUnsignedShort(); - int nargs = bytes.readUnsignedByte(); // historical, redundant - buf.append("\t").append( - constant_pool - .constantToString(index, Constants.CONSTANT_InterfaceMethodref)) - .append(verbose ? " (" + index + ")\t" : "").append(nargs).append("\t") - .append(bytes.readUnsignedByte()); // Last byte is a reserved space - break; - /* Operands are references to items in constant pool - */ - case Constants.LDC_W: - case Constants.LDC2_W: - index = bytes.readUnsignedShort(); - buf.append("\t\t").append( - constant_pool.constantToString(index, constant_pool.getConstant(index) - .getTag())).append((verbose ? " (" + index + ")" : "")); - break; - case Constants.LDC: - index = bytes.readUnsignedByte(); - buf.append("\t\t").append( - constant_pool.constantToString(index, constant_pool.getConstant(index) - .getTag())).append((verbose ? " (" + index + ")" : "")); - break; - /* Array of references. - */ - case Constants.ANEWARRAY: - index = bytes.readUnsignedShort(); - buf.append("\t\t<").append( - compactClassName(constant_pool.getConstantString(index, - Constants.CONSTANT_Class), false)).append(">").append( - (verbose ? " (" + index + ")" : "")); - break; - /* Multidimensional array of references. - */ - case Constants.MULTIANEWARRAY: { - index = bytes.readUnsignedShort(); - int dimensions = bytes.readUnsignedByte(); - buf.append("\t<").append( - compactClassName(constant_pool.getConstantString(index, - Constants.CONSTANT_Class), false)).append(">\t").append(dimensions) - .append((verbose ? " (" + index + ")" : "")); - } - break; - /* Increment local variable. - */ - case Constants.IINC: - if (wide) { - vindex = bytes.readUnsignedShort(); - constant = bytes.readShort(); - wide = false; - } else { - vindex = bytes.readUnsignedByte(); - constant = bytes.readByte(); - } - buf.append("\t\t%").append(vindex).append("\t").append(constant); - break; - default: - if (Constants.NO_OF_OPERANDS[opcode] > 0) { - for (int i = 0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) { - buf.append("\t\t"); - switch (Constants.TYPE_OF_OPERANDS[opcode][i]) { - case Constants.T_BYTE: - buf.append(bytes.readByte()); - break; - case Constants.T_SHORT: - buf.append(bytes.readShort()); - break; - case Constants.T_INT: - buf.append(bytes.readInt()); - break; - default: // Never reached - System.err.println("Unreachable default case reached!"); - System.exit(-1); - } - } - } - } - return buf.toString(); - } - - - public static final String codeToString( ByteSequence bytes, ConstantPool constant_pool ) - throws IOException { - return codeToString(bytes, constant_pool, true); - } - - - /** - * Shorten long class names, java/lang/String becomes - * String. - * - * @param str The long class name - * @return Compacted class name - */ - public static final String compactClassName( String str ) { - return compactClassName(str, true); - } - - - /** - * Shorten long class name str, i.e., chop off the prefix, - * if the - * class name starts with this string and the flag chopit is true. - * Slashes / are converted to dots .. - * - * @param str The long class name - * @param prefix The prefix the get rid off - * @param chopit Flag that determines whether chopping is executed or not - * @return Compacted class name - */ - public static final String compactClassName( String str, String prefix, boolean chopit ) { - int len = prefix.length(); - str = str.replace('/', '.'); // Is `/' on all systems, even DOS - if (chopit) { - // If string starts with `prefix' and contains no further dots - if (str.startsWith(prefix) && (str.substring(len).indexOf('.') == -1)) { - str = str.substring(len); - } - } - return str; - } - - - /** - * Shorten long class names, java/lang/String becomes - * java.lang.String, - * e.g.. If chopit is true the prefix java.lang - * is also removed. - * - * @param str The long class name - * @param chopit Flag that determines whether chopping is executed or not - * @return Compacted class name - */ - public static final String compactClassName( String str, boolean chopit ) { - return compactClassName(str, "java.lang.", chopit); - } - - - /** - * @return `flag' with bit `i' set to 1 - */ - public static final int setBit( int flag, int i ) { - return flag | pow2(i); - } - - - /** - * @return `flag' with bit `i' set to 0 - */ - public static final int clearBit( int flag, int i ) { - int bit = pow2(i); - return (flag & bit) == 0 ? flag : flag ^ bit; - } - - - /** - * @return true, if bit `i' in `flag' is set - */ - public static final boolean isSet( int flag, int i ) { - return (flag & pow2(i)) != 0; - } - - - /** - * Converts string containing the method return and argument types - * to a byte code method signature. - * - * @param ret Return type of method - * @param argv Types of method arguments - * @return Byte code representation of method signature - */ - public final static String methodTypeToSignature( String ret, String[] argv ) - throws ClassFormatException { - StringBuffer buf = new StringBuffer("("); - String str; - if (argv != null) { - for (int i = 0; i < argv.length; i++) { - str = getSignature(argv[i]); - if (str.endsWith("V")) { - throw new ClassFormatException("Invalid type: " + argv[i]); - } - buf.append(str); - } - } - str = getSignature(ret); - buf.append(")").append(str); - return buf.toString(); - } - - - /** - * @param signature Method signature - * @return Array of argument types - * @throws ClassFormatException - */ - public static final String[] methodSignatureArgumentTypes( String signature ) - throws ClassFormatException { - return methodSignatureArgumentTypes(signature, true); - } - - - /** - * @param signature Method signature - * @param chopit Shorten class names ? - * @return Array of argument types - * @throws ClassFormatException - */ - public static final String[] methodSignatureArgumentTypes( String signature, boolean chopit ) - throws ClassFormatException { - List vec = new ArrayList(); - int index; - try { // Read all declarations between for `(' and `)' - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - index = 1; // current string position - while (signature.charAt(index) != ')') { - vec.add(signatureToString(signature.substring(index), chopit)); - //corrected concurrent private static field acess - index += unwrap(consumed_chars); // update position - } - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - return (String[]) vec.toArray(new String[vec.size()]); - } - - - /** - * @param signature Method signature - * @return return type of method - * @throws ClassFormatException - */ - public static final String methodSignatureReturnType( String signature ) - throws ClassFormatException { - return methodSignatureReturnType(signature, true); - } - - - /** - * @param signature Method signature - * @param chopit Shorten class names ? - * @return return type of method - * @throws ClassFormatException - */ - public static final String methodSignatureReturnType( String signature, boolean chopit ) - throws ClassFormatException { - int index; - String type; - try { - // Read return type after `)' - index = signature.lastIndexOf(')') + 1; - type = signatureToString(signature.substring(index), chopit); - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - return type; - } - - - /** - * Converts method signature to string with all class names compacted. - * - * @param signature to convert - * @param name of method - * @param access flags of method - * @return Human readable signature - */ - public static final String methodSignatureToString( String signature, String name, String access ) { - return methodSignatureToString(signature, name, access, true); - } - - - public static final String methodSignatureToString( String signature, String name, - String access, boolean chopit ) { - return methodSignatureToString(signature, name, access, chopit, null); - } - - - /** - * A return type signature represents the return value from a method. - * It is a series of bytes in the following grammar: - * - * ::= | V - * - * The character V indicates that the method returns no value. Otherwise, the - * signature indicates the type of the return value. - * An argument signature represents an argument passed to a method: - * - * ::= - * - * A method signature represents the arguments that the method expects, and - * the value that it returns. - * ::= () - * ::= * - * - * This method converts such a string into a Java type declaration like - * `void main(String[])' and throws a `ClassFormatException' when the parsed - * type is invalid. - * - * @param signature Method signature - * @param name Method name - * @param access Method access rights - * @return Java type declaration - * @throws ClassFormatException - */ - public static final String methodSignatureToString( String signature, String name, - String access, boolean chopit, LocalVariableTable vars ) throws ClassFormatException { - StringBuffer buf = new StringBuffer("("); - String type; - int index; - int var_index = (access.indexOf("static") >= 0) ? 0 : 1; - try { // Read all declarations between for `(' and `)' - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - index = 1; // current string position - while (signature.charAt(index) != ')') { - String param_type = signatureToString(signature.substring(index), chopit); - buf.append(param_type); - if (vars != null) { - LocalVariable l = vars.getLocalVariable(var_index); - if (l != null) { - buf.append(" ").append(l.getName()); - } - } else { - buf.append(" arg").append(var_index); - } - if ("double".equals(param_type) || "long".equals(param_type)) { - var_index += 2; - } else { - var_index++; - } - buf.append(", "); - //corrected concurrent private static field acess - index += unwrap(consumed_chars); // update position - } - index++; // update position - // Read return type after `)' - type = signatureToString(signature.substring(index), chopit); - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - if (buf.length() > 1) { - buf.setLength(buf.length() - 2); - } - buf.append(")"); - return access + ((access.length() > 0) ? " " : "") + // May be an empty string - type + " " + name + buf.toString(); - } - - - // Guess what this does - private static final int pow2( int n ) { - return 1 << n; - } - - - /** - * Replace all occurences of old in str with new. - * - * @param str String to permute - * @param old String to be replaced - * @param new_ Replacement string - * @return new String object - */ - public static final String replace( String str, String old, String new_ ) { - int index, old_index; - StringBuffer buf = new StringBuffer(); - try { - if ((index = str.indexOf(old)) != -1) { // `old' found in str - old_index = 0; // String start offset - // While we have something to replace - while ((index = str.indexOf(old, old_index)) != -1) { - buf.append(str.substring(old_index, index)); // append prefix - buf.append(new_); // append replacement - old_index = index + old.length(); // Skip `old'.length chars - } - buf.append(str.substring(old_index)); // append rest of string - str = buf.toString(); - } - } catch (StringIndexOutOfBoundsException e) { // Should not occur - System.err.println(e); - } - return str; - } - - - /** - * Converts signature to string with all class names compacted. - * - * @param signature to convert - * @return Human readable signature - */ - public static final String signatureToString( String signature ) { - return signatureToString(signature, true); - } - - - /** - * The field signature represents the value of an argument to a function or - * the value of a variable. It is a series of bytes generated by the - * following grammar: - * - *
-     *  ::= 
-     *       ::= ||
-     *        ::= B|C|D|F|I|J|S|Z
-     *      ::= L;
-     *       ::= [
-     *
-     * The meaning of the base types is as follows:
-     * B byte signed byte
-     * C char character
-     * D double double precision IEEE float
-     * F float single precision IEEE float
-     * I int integer
-     * J long long integer
-     * L; ... an object of the given class
-     * S short signed short
-     * Z boolean true or false
-     * [ ... array
-     * 
- * - * This method converts this string into a Java type declaration such as - * `String[]' and throws a `ClassFormatException' when the parsed type is - * invalid. - * - * @param signature Class signature - * @param chopit Flag that determines whether chopping is executed or not - * @return Java type declaration - * @throws ClassFormatException - */ - public static final String signatureToString( String signature, boolean chopit ) { - //corrected concurrent private static field acess - wrap(consumed_chars, 1); // This is the default, read just one char like `B' - try { - switch (signature.charAt(0)) { - case 'B': - return "byte"; - case 'C': - return "char"; - case 'D': - return "double"; - case 'F': - return "float"; - case 'I': - return "int"; - case 'J': - return "long"; - case 'L': { // Full class name - int index = signature.indexOf(';'); // Look for closing `;' - if (index < 0) { - throw new ClassFormatException("Invalid signature: " + signature); - } - //corrected concurrent private static field acess - wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed - return compactClassName(signature.substring(1, index), chopit); - } - case 'S': - return "short"; - case 'Z': - return "boolean"; - case '[': { // Array declaration - int n; - StringBuffer brackets; - String type; - int consumed_chars; // Shadows global var - brackets = new StringBuffer(); // Accumulate []'s - // Count opening brackets and look for optional size argument - for (n = 0; signature.charAt(n) == '['; n++) { - brackets.append("[]"); - } - consumed_chars = n; // Remember value - // The rest of the string denotes a `' - type = signatureToString(signature.substring(n), chopit); - //corrected concurrent private static field acess - //Utility.consumed_chars += consumed_chars; is replaced by: - int _temp = unwrap(Utility.consumed_chars) + consumed_chars; - wrap(Utility.consumed_chars, _temp); - return type + brackets.toString(); - } - case 'V': - return "void"; - default: - throw new ClassFormatException("Invalid signature: `" + signature + "'"); - } - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid signature: " + e + ":" + signature); - } - } - - - /** Parse Java type such as "char", or "java.lang.String[]" and return the - * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" respectively. - * - * @param type Java type - * @return byte code signature - */ - public static String getSignature( String type ) { - StringBuffer buf = new StringBuffer(); - char[] chars = type.toCharArray(); - boolean char_found = false, delim = false; - int index = -1; - loop: for (int i = 0; i < chars.length; i++) { - switch (chars[i]) { - case ' ': - case '\t': - case '\n': - case '\r': - case '\f': - if (char_found) { - delim = true; - } - break; - case '[': - if (!char_found) { - throw new RuntimeException("Illegal type: " + type); - } - index = i; - break loop; - default: - char_found = true; - if (!delim) { - buf.append(chars[i]); - } - } - } - int brackets = 0; - if (index > 0) { - brackets = countBrackets(type.substring(index)); - } - type = buf.toString(); - buf.setLength(0); - for (int i = 0; i < brackets; i++) { - buf.append('['); - } - boolean found = false; - for (int i = Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) { - if (Constants.TYPE_NAMES[i].equals(type)) { - found = true; - buf.append(Constants.SHORT_TYPE_NAMES[i]); - } - } - if (!found) { - buf.append('L').append(type.replace('.', '/')).append(';'); - } - return buf.toString(); - } - - - private static int countBrackets( String brackets ) { - char[] chars = brackets.toCharArray(); - int count = 0; - boolean open = false; - for (int i = 0; i < chars.length; i++) { - switch (chars[i]) { - case '[': - if (open) { - throw new RuntimeException("Illegally nested brackets:" + brackets); - } - open = true; - break; - case ']': - if (!open) { - throw new RuntimeException("Illegally nested brackets:" + brackets); - } - open = false; - count++; - break; - default: - // Don't care - } - } - if (open) { - throw new RuntimeException("Illegally nested brackets:" + brackets); - } - return count; - } - - - /** - * Return type of method signature as a byte value as defined in Constants - * - * @param signature in format described above - * @return type of method signature - * @see Constants - */ - public static final byte typeOfMethodSignature( String signature ) throws ClassFormatException { - int index; - try { - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - index = signature.lastIndexOf(')') + 1; - return typeOfSignature(signature.substring(index)); - } catch (StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - - /** - * Return type of signature as a byte value as defined in Constants - * - * @param signature in format described above - * @return type of signature - * @see Constants - */ - public static final byte typeOfSignature( String signature ) throws ClassFormatException { - try { - switch (signature.charAt(0)) { - case 'B': - return Constants.T_BYTE; - case 'C': - return Constants.T_CHAR; - case 'D': - return Constants.T_DOUBLE; - case 'F': - return Constants.T_FLOAT; - case 'I': - return Constants.T_INT; - case 'J': - return Constants.T_LONG; - case 'L': - return Constants.T_REFERENCE; - case '[': - return Constants.T_ARRAY; - case 'V': - return Constants.T_VOID; - case 'Z': - return Constants.T_BOOLEAN; - case 'S': - return Constants.T_SHORT; - default: - throw new ClassFormatException("Invalid method signature: " + signature); - } - } catch (StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - - /** Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload" - */ - public static short searchOpcode( String name ) { - name = name.toLowerCase(Locale.ENGLISH); - for (short i = 0; i < Constants.OPCODE_NAMES.length; i++) { - if (Constants.OPCODE_NAMES[i].equals(name)) { - return i; - } - } - return -1; - } - - - /** - * Convert (signed) byte to (unsigned) short value, i.e., all negative - * values become positive. - */ - private static final short byteToShort( byte b ) { - return (b < 0) ? (short) (256 + b) : (short) b; - } - - - /** Convert bytes into hexidecimal string - * - * @return bytes as hexidecimal string, e.g. 00 FA 12 ... - */ - public static final String toHexString( byte[] bytes ) { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < bytes.length; i++) { - short b = byteToShort(bytes[i]); - String hex = Integer.toString(b, 0x10); - if (b < 0x10) { - buf.append('0'); - } - buf.append(hex); - if (i < bytes.length - 1) { - buf.append(' '); - } - } - return buf.toString(); - } - - - /** - * Return a string for an integer justified left or right and filled up with - * `fill' characters if necessary. - * - * @param i integer to format - * @param length length of desired string - * @param left_justify format left or right - * @param fill fill character - * @return formatted int - */ - public static final String format( int i, int length, boolean left_justify, char fill ) { - return fillup(Integer.toString(i), length, left_justify, fill); - } - - - /** - * Fillup char with up to length characters with char `fill' and justify it left or right. - * - * @param str string to format - * @param length length of desired string - * @param left_justify format left or right - * @param fill fill character - * @return formatted string - */ - public static final String fillup( String str, int length, boolean left_justify, char fill ) { - int len = length - str.length(); - char[] buf = new char[(len < 0) ? 0 : len]; - for (int j = 0; j < buf.length; j++) { - buf[j] = fill; - } - if (left_justify) { - return str + new String(buf); - } - return new String(buf) + str; - } - - - static final boolean equals( byte[] a, byte[] b ) { - int size; - if ((size = a.length) != b.length) { - return false; - } - for (int i = 0; i < size; i++) { - if (a[i] != b[i]) { - return false; - } - } - return true; - } - - - public static final void printArray( PrintStream out, Object[] obj ) { - out.println(printArray(obj, true)); - } - - - public static final void printArray( PrintWriter out, Object[] obj ) { - out.println(printArray(obj, true)); - } - - - public static final String printArray( Object[] obj ) { - return printArray(obj, true); - } - - - public static final String printArray( Object[] obj, boolean braces ) { - return printArray(obj, braces, false); - } - - - public static final String printArray( Object[] obj, boolean braces, boolean quote ) { - if (obj == null) { - return null; - } - StringBuffer buf = new StringBuffer(); - if (braces) { - buf.append('{'); - } - for (int i = 0; i < obj.length; i++) { - if (obj[i] != null) { - buf.append((quote ? "\"" : "")).append(obj[i].toString()).append( - (quote ? "\"" : "")); - } else { - buf.append("null"); - } - if (i < obj.length - 1) { - buf.append(", "); - } - } - if (braces) { - buf.append('}'); - } - return buf.toString(); - } - - - /** @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _) - */ - public static boolean isJavaIdentifierPart( char ch ) { - return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) - || ((ch >= '0') && (ch <= '9')) || (ch == '_'); - } - - - /** Encode byte array it into Java identifier string, i.e., a string - * that only contains the following characters: (a, ... z, A, ... Z, - * 0, ... 9, _, $). The encoding algorithm itself is not too - * clever: if the current byte's ASCII value already is a valid Java - * identifier part, leave it as it is. Otherwise it writes the - * escape character($) followed by

  • the ASCII value as a - * hexadecimal string, if the value is not in the range - * 200..247
  • a Java identifier char not used in a lowercase - * hexadecimal string, if the value is in the range - * 200..247
    • - * - *

      This operation inflates the original byte array by roughly 40-50%

      - * - * @param bytes the byte array to convert - * @param compress use gzip to minimize string - */ - public static String encode( byte[] bytes, boolean compress ) throws IOException { - if (compress) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - GZIPOutputStream gos = new GZIPOutputStream(baos); - gos.write(bytes, 0, bytes.length); - gos.close(); - baos.close(); - bytes = baos.toByteArray(); - } - CharArrayWriter caw = new CharArrayWriter(); - JavaWriter jw = new JavaWriter(caw); - for (int i = 0; i < bytes.length; i++) { - int in = bytes[i] & 0x000000ff; // Normalize to unsigned - jw.write(in); - } - return caw.toString(); - } - - - /** Decode a string back to a byte array. - * - * @param s the string to convert - * @param uncompress use gzip to uncompress the stream of bytes - */ - public static byte[] decode( String s, boolean uncompress ) throws IOException { - char[] chars = s.toCharArray(); - CharArrayReader car = new CharArrayReader(chars); - JavaReader jr = new JavaReader(car); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - int ch; - while ((ch = jr.read()) >= 0) { - bos.write(ch); - } - bos.close(); - car.close(); - jr.close(); - byte[] bytes = bos.toByteArray(); - if (uncompress) { - GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); - byte[] tmp = new byte[bytes.length * 3]; // Rough estimate - int count = 0; - int b; - while ((b = gis.read()) >= 0) { - tmp[count++] = (byte) b; - } - bytes = new byte[count]; - System.arraycopy(tmp, 0, bytes, 0, count); - } - return bytes; - } - - // A-Z, g-z, _, $ - private static final int FREE_CHARS = 48; - static int[] CHAR_MAP = new int[FREE_CHARS]; - static int[] MAP_CHAR = new int[256]; // Reverse map - private static final char ESCAPE_CHAR = '$'; - static { - int j = 0; - for (int i = 'A'; i <= 'Z'; i++) { - CHAR_MAP[j] = i; - MAP_CHAR[i] = j; - j++; - } - for (int i = 'g'; i <= 'z'; i++) { - CHAR_MAP[j] = i; - MAP_CHAR[i] = j; - j++; - } - CHAR_MAP[j] = '$'; - MAP_CHAR['$'] = j; - j++; - CHAR_MAP[j] = '_'; - MAP_CHAR['_'] = j; - } - - /** Decode characters into bytes. - * Used by decode() - */ - private static class JavaReader extends FilterReader { - - public JavaReader(Reader in) { - super(in); - } - - - public int read() throws IOException { - int b = in.read(); - if (b != ESCAPE_CHAR) { - return b; - } - int i = in.read(); - if (i < 0) { - return -1; - } - if (((i >= '0') && (i <= '9')) || ((i >= 'a') && (i <= 'f'))) { // Normal escape - int j = in.read(); - if (j < 0) { - return -1; - } - char[] tmp = { - (char) i, (char) j - }; - int s = Integer.parseInt(new String(tmp), 16); - return s; - } - return MAP_CHAR[i]; - } - - - public int read( char[] cbuf, int off, int len ) throws IOException { - for (int i = 0; i < len; i++) { - cbuf[off + i] = (char) read(); - } - return len; - } - } - - /** Encode bytes into valid java identifier characters. - * Used by encode() - */ - private static class JavaWriter extends FilterWriter { - - public JavaWriter(Writer out) { - super(out); - } - - - public void write( int b ) throws IOException { - if (isJavaIdentifierPart((char) b) && (b != ESCAPE_CHAR)) { - out.write(b); - } else { - out.write(ESCAPE_CHAR); // Escape character - // Special escape - if (b >= 0 && b < FREE_CHARS) { - out.write(CHAR_MAP[b]); - } else { // Normal escape - char[] tmp = Integer.toHexString(b).toCharArray(); - if (tmp.length == 1) { - out.write('0'); - out.write(tmp[0]); - } else { - out.write(tmp[0]); - out.write(tmp[1]); - } - } - } - } - - - public void write( char[] cbuf, int off, int len ) throws IOException { - for (int i = 0; i < len; i++) { - write(cbuf[off + i]); - } - } - - - public void write( String str, int off, int len ) throws IOException { - write(str.toCharArray(), off, len); - } - } - - - /** - * Escape all occurences of newline chars '\n', quotes \", etc. - */ - public static final String convertString( String label ) { - char[] ch = label.toCharArray(); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < ch.length; i++) { - switch (ch[i]) { - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - case '\"': - buf.append("\\\""); - break; - case '\'': - buf.append("\\'"); - break; - case '\\': - buf.append("\\\\"); - break; - default: - buf.append(ch[i]); - break; - } - } - return buf.toString(); - } + private static int unwrap(ThreadLocal tl) { + return tl.get().intValue(); + } + + private static void wrap(ThreadLocal tl, int value) { + tl.set(new Integer(value)); + } + + private static ThreadLocal consumed_chars = new ThreadLocal() { + + @Override + protected Integer initialValue() { + return new Integer(0); + } + };/* + * How many chars have been consumed during parsing in signatureToString(). + * Read by methodSignatureToString(). Set by side effect,but only + * internally. + */ + private static boolean wide = false; /* + * The `WIDE' instruction is used in the + * byte code to allow 16-bit wide + * indices for local variables. This + * opcode precedes an `ILOAD', e.g.. The + * opcode immediately following takes an + * extra byte which is combined with the + * following byte to form a 16-bit + * value. + */ + + /** + * Convert bit field of flags into string such as `static final'. + * + * @param access_flags + * Access flags + * @return String representation of flags + */ + public static final String accessToString(int access_flags) { + return accessToString(access_flags, false); + } + + /** + * Convert bit field of flags into string such as `static final'. + * + * Special case: Classes compiled with new compilers and with the + * `ACC_SUPER' flag would be said to be "synchronized". This is because SUN + * used the same value for the flags `ACC_SUPER' and `ACC_SYNCHRONIZED'. + * + * @param access_flags + * Access flags + * @param for_class + * access flags are for class qualifiers ? + * @return String representation of flags + */ + public static final String accessToString(int access_flags, + boolean for_class) { + StringBuffer buf = new StringBuffer(); + int p = 0; + for (int i = 0; p < Constants.MAX_ACC_FLAG; i++) { // Loop through known + // flags + p = pow2(i); + if ((access_flags & p) != 0) { + /* + * Special case: Classes compiled with new compilers and with + * the `ACC_SUPER' flag would be said to be "synchronized". This + * is because SUN used the same value for the flags `ACC_SUPER' + * and `ACC_SYNCHRONIZED'. + */ + if (for_class + && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE))) { + continue; + } + buf.append(Constants.ACCESS_NAMES[i]).append(" "); + } + } + return buf.toString().trim(); + } + + /** + * @return "class" or "interface", depending on the ACC_INTERFACE flag + */ + public static final String classOrInterface(int access_flags) { + return ((access_flags & Constants.ACC_INTERFACE) != 0) ? "interface" + : "class"; + } + + /** + * Disassemble a byte array of JVM byte codes starting from code line + * `index' and return the disassembled string representation. Decode only + * `num' opcodes (including their operands), use -1 if you want to decompile + * everything. + * + * @param code + * byte code array + * @param constant_pool + * Array of constants + * @param index + * offset in `code' array + * (number of opcodes, not bytes!) + * @param length + * number of opcodes to decompile, -1 for all + * @param verbose + * be verbose, e.g. print constant pool index + * @return String representation of byte codes + */ + public static final String codeToString(byte[] code, + ConstantPool constant_pool, int index, int length, boolean verbose) { + StringBuffer buf = new StringBuffer(code.length * 20); // Should be + // sufficient + ByteSequence stream = new ByteSequence(code); + try { + for (int i = 0; i < index; i++) { + codeToString(stream, constant_pool, verbose); + } + for (int i = 0; stream.available() > 0; i++) { + if ((length < 0) || (i < length)) { + String indices = fillup(stream.getIndex() + ":", 6, true, + ' '); + buf.append(indices) + .append(codeToString(stream, constant_pool, verbose)) + .append('\n'); + } + } + } catch (IOException e) { + System.out.println(buf.toString()); + e.printStackTrace(); + throw new ClassFormatException("Byte code error: " + e); + } + return buf.toString(); + } + + public static final String codeToString(byte[] code, + ConstantPool constant_pool, int index, int length) { + return codeToString(code, constant_pool, index, length, true); + } + + /** + * Disassemble a stream of byte codes and return the string representation. + * + * @param bytes + * stream of bytes + * @param constant_pool + * Array of constants + * @param verbose + * be verbose, e.g. print constant pool index + * @return String representation of byte code + */ + public static final String codeToString(ByteSequence bytes, + ConstantPool constant_pool, boolean verbose) throws IOException { + short opcode = (short) bytes.readUnsignedByte(); + int default_offset = 0, low, high, npairs; + int index, vindex, constant; + int[] match, jump_table; + int no_pad_bytes = 0, offset; + StringBuffer buf = new StringBuffer(Constants.OPCODE_NAMES[opcode]); + /* + * Special case: Skip (0-3) padding bytes, i.e., the following bytes are + * 4-byte-aligned + */ + if ((opcode == Constants.TABLESWITCH) + || (opcode == Constants.LOOKUPSWITCH)) { + int remainder = bytes.getIndex() % 4; + no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; + for (int i = 0; i < no_pad_bytes; i++) { + byte b; + if ((b = bytes.readByte()) != 0) { + System.err.println("Warning: Padding byte != 0 in " + + Constants.OPCODE_NAMES[opcode] + ":" + b); + } + } + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); + } + switch (opcode) { + /* + * Table switch has variable length arguments. + */ + case Constants.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + buf.append("\tdefault = ").append(default_offset) + .append(", low = ").append(low).append(", high = ") + .append(high).append("("); + jump_table = new int[high - low + 1]; + for (int i = 0; i < jump_table.length; i++) { + jump_table[i] = offset + bytes.readInt(); + buf.append(jump_table[i]); + if (i < jump_table.length - 1) { + buf.append(", "); + } + } + buf.append(")"); + break; + /* + * Lookup switch has variable length arguments. + */ + case Constants.LOOKUPSWITCH: { + npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + match = new int[npairs]; + jump_table = new int[npairs]; + default_offset += offset; + buf.append("\tdefault = ").append(default_offset) + .append(", npairs = ").append(npairs).append(" ("); + for (int i = 0; i < npairs; i++) { + match[i] = bytes.readInt(); + jump_table[i] = offset + bytes.readInt(); + buf.append("(").append(match[i]).append(", ") + .append(jump_table[i]).append(")"); + if (i < npairs - 1) { + buf.append(", "); + } + } + buf.append(")"); + } + break; + /* + * Two address bytes + offset from start of byte stream form the jump + * target + */ + case Constants.GOTO: + case Constants.IFEQ: + case Constants.IFGE: + case Constants.IFGT: + case Constants.IFLE: + case Constants.IFLT: + case Constants.JSR: + case Constants.IFNE: + case Constants.IFNONNULL: + case Constants.IFNULL: + case Constants.IF_ACMPEQ: + case Constants.IF_ACMPNE: + case Constants.IF_ICMPEQ: + case Constants.IF_ICMPGE: + case Constants.IF_ICMPGT: + case Constants.IF_ICMPLE: + case Constants.IF_ICMPLT: + case Constants.IF_ICMPNE: + buf.append("\t\t#").append( + (bytes.getIndex() - 1) + bytes.readShort()); + break; + /* + * 32-bit wide jumps + */ + case Constants.GOTO_W: + case Constants.JSR_W: + buf.append("\t\t#").append( + ((bytes.getIndex() - 1) + bytes.readInt())); + break; + /* + * Index byte references local variable (register) + */ + case Constants.ALOAD: + case Constants.ASTORE: + case Constants.DLOAD: + case Constants.DSTORE: + case Constants.FLOAD: + case Constants.FSTORE: + case Constants.ILOAD: + case Constants.ISTORE: + case Constants.LLOAD: + case Constants.LSTORE: + case Constants.RET: + if (wide) { + vindex = bytes.readUnsignedShort(); + wide = false; // Clear flag + } else { + vindex = bytes.readUnsignedByte(); + } + buf.append("\t\t%").append(vindex); + break; + /* + * Remember wide byte which is used to form a 16-bit address in the + * following instruction. Relies on that the method is called again with + * the following opcode. + */ + case Constants.WIDE: + wide = true; + buf.append("\t(wide)"); + break; + /* + * Array of basic type. + */ + case Constants.NEWARRAY: + buf.append("\t\t<").append(Constants.TYPE_NAMES[bytes.readByte()]) + .append(">"); + break; + /* + * Access object/class fields. + */ + case Constants.GETFIELD: + case Constants.GETSTATIC: + case Constants.PUTFIELD: + case Constants.PUTSTATIC: + index = bytes.readUnsignedShort(); + buf.append("\t\t") + .append(constant_pool.constantToString(index, + Constants.CONSTANT_Fieldref)) + .append((verbose ? " (" + index + ")" : "")); + break; + /* + * Operands are references to classes in constant pool + */ + case Constants.NEW: + case Constants.CHECKCAST: + buf.append("\t"); + case Constants.INSTANCEOF: + index = bytes.readUnsignedShort(); + buf.append("\t<") + .append(constant_pool.constantToString(index, + Constants.CONSTANT_Class)).append(">") + .append((verbose ? " (" + index + ")" : "")); + break; + /* + * Operands are references to methods in constant pool + */ + case Constants.INVOKESPECIAL: + case Constants.INVOKESTATIC: + case Constants.INVOKEVIRTUAL: + index = bytes.readUnsignedShort(); + buf.append("\t") + .append(constant_pool.constantToString(index, + Constants.CONSTANT_Methodref)) + .append((verbose ? " (" + index + ")" : "")); + break; + case Constants.INVOKEINTERFACE: + index = bytes.readUnsignedShort(); + int nargs = bytes.readUnsignedByte(); // historical, redundant + buf.append("\t") + .append(constant_pool.constantToString(index, + Constants.CONSTANT_InterfaceMethodref)) + .append(verbose ? " (" + index + ")\t" : "").append(nargs) + .append("\t").append(bytes.readUnsignedByte()); // Last byte + // is a + // reserved + // space + break; + /* + * Operands are references to items in constant pool + */ + case Constants.LDC_W: + case Constants.LDC2_W: + index = bytes.readUnsignedShort(); + buf.append("\t\t") + .append(constant_pool.constantToString(index, constant_pool + .getConstant(index).getTag())) + .append((verbose ? " (" + index + ")" : "")); + break; + case Constants.LDC: + index = bytes.readUnsignedByte(); + buf.append("\t\t") + .append(constant_pool.constantToString(index, constant_pool + .getConstant(index).getTag())) + .append((verbose ? " (" + index + ")" : "")); + break; + /* + * Array of references. + */ + case Constants.ANEWARRAY: + index = bytes.readUnsignedShort(); + buf.append("\t\t<") + .append(compactClassName(constant_pool.getConstantString( + index, Constants.CONSTANT_Class), false)) + .append(">").append((verbose ? " (" + index + ")" : "")); + break; + /* + * Multidimensional array of references. + */ + case Constants.MULTIANEWARRAY: { + index = bytes.readUnsignedShort(); + int dimensions = bytes.readUnsignedByte(); + buf.append("\t<") + .append(compactClassName(constant_pool.getConstantString( + index, Constants.CONSTANT_Class), false)) + .append(">\t").append(dimensions) + .append((verbose ? " (" + index + ")" : "")); + } + break; + /* + * Increment local variable. + */ + case Constants.IINC: + if (wide) { + vindex = bytes.readUnsignedShort(); + constant = bytes.readShort(); + wide = false; + } else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("\t\t%").append(vindex).append("\t").append(constant); + break; + default: + if (Constants.NO_OF_OPERANDS[opcode] > 0) { + for (int i = 0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) { + buf.append("\t\t"); + switch (Constants.TYPE_OF_OPERANDS[opcode][i]) { + case Constants.T_BYTE: + buf.append(bytes.readByte()); + break; + case Constants.T_SHORT: + buf.append(bytes.readShort()); + break; + case Constants.T_INT: + buf.append(bytes.readInt()); + break; + default: // Never reached + System.err.println("Unreachable default case reached!"); + System.exit(-1); + } + } + } + } + return buf.toString(); + } + + public static final String codeToString(ByteSequence bytes, + ConstantPool constant_pool) throws IOException { + return codeToString(bytes, constant_pool, true); + } + + /** + * Shorten long class names, java/lang/String becomes + * String. + * + * @param str + * The long class name + * @return Compacted class name + */ + public static final String compactClassName(String str) { + return compactClassName(str, true); + } + + /** + * Shorten long class name str, i.e., chop off the prefix, + * if the class name starts with this string and the flag chopit is + * true. Slashes / are converted to dots .. + * + * @param str + * The long class name + * @param prefix + * The prefix the get rid off + * @param chopit + * Flag that determines whether chopping is executed or not + * @return Compacted class name + */ + public static final String compactClassName(String str, String prefix, + boolean chopit) { + int len = prefix.length(); + str = str.replace('/', '.'); // Is `/' on all systems, even DOS + if (chopit) { + // If string starts with `prefix' and contains no further dots + if (str.startsWith(prefix) + && (str.substring(len).indexOf('.') == -1)) { + str = str.substring(len); + } + } + return str; + } + + /** + * Shorten long class names, java/lang/String becomes + * java.lang.String, e.g.. If chopit is true the + * prefix java.lang is also removed. + * + * @param str + * The long class name + * @param chopit + * Flag that determines whether chopping is executed or not + * @return Compacted class name + */ + public static final String compactClassName(String str, boolean chopit) { + return compactClassName(str, "java.lang.", chopit); + } + + /** + * @return `flag' with bit `i' set to 1 + */ + public static final int setBit(int flag, int i) { + return flag | pow2(i); + } + + /** + * @return `flag' with bit `i' set to 0 + */ + public static final int clearBit(int flag, int i) { + int bit = pow2(i); + return (flag & bit) == 0 ? flag : flag ^ bit; + } + + /** + * @return true, if bit `i' in `flag' is set + */ + public static final boolean isSet(int flag, int i) { + return (flag & pow2(i)) != 0; + } + + /** + * Converts string containing the method return and argument types to a byte + * code method signature. + * + * @param ret + * Return type of method + * @param argv + * Types of method arguments + * @return Byte code representation of method signature + */ + public final static String methodTypeToSignature(String ret, String[] argv) + throws ClassFormatException { + StringBuffer buf = new StringBuffer("("); + String str; + if (argv != null) { + for (int i = 0; i < argv.length; i++) { + str = getSignature(argv[i]); + if (str.endsWith("V")) { + throw new ClassFormatException("Invalid type: " + argv[i]); + } + buf.append(str); + } + } + str = getSignature(ret); + buf.append(")").append(str); + return buf.toString(); + } + + /** + * @param signature + * Method signature + * @return Array of argument types + * @throws ClassFormatException + */ + public static final String[] methodSignatureArgumentTypes(String signature) + throws ClassFormatException { + return methodSignatureArgumentTypes(signature, true); + } + + /** + * @param signature + * Method signature + * @param chopit + * Shorten class names ? + * @return Array of argument types + * @throws ClassFormatException + */ + public static final String[] methodSignatureArgumentTypes(String signature, + boolean chopit) throws ClassFormatException { + List vec = new ArrayList(); + int index; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + vec.add(signatureToString(signature.substring(index), chopit)); + // corrected concurrent private static field acess + index += unwrap(consumed_chars); // update position + } + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + + signature); + } + return vec.toArray(new String[vec.size()]); + } + + /** + * @param signature + * Method signature + * @return return type of method + * @throws ClassFormatException + */ + public static final String methodSignatureReturnType(String signature) + throws ClassFormatException { + return methodSignatureReturnType(signature, true); + } + + /** + * @param signature + * Method signature + * @param chopit + * Shorten class names ? + * @return return type of method + * @throws ClassFormatException + */ + public static final String methodSignatureReturnType(String signature, + boolean chopit) throws ClassFormatException { + int index; + String type; + try { + // Read return type after `)' + index = signature.lastIndexOf(')') + 1; + type = signatureToString(signature.substring(index), chopit); + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + + signature); + } + return type; + } + + /** + * Converts method signature to string with all class names compacted. + * + * @param signature + * to convert + * @param name + * of method + * @param access + * flags of method + * @return Human readable signature + */ + public static final String methodSignatureToString(String signature, + String name, String access) { + return methodSignatureToString(signature, name, access, true); + } + + public static final String methodSignatureToString(String signature, + String name, String access, boolean chopit) { + return methodSignatureToString(signature, name, access, chopit, null); + } + + /** + * A return type signature represents the return value from a method. It is + * a series of bytes in the following grammar: + * + * ::= | V + * + * The character V indicates that the method returns no value. Otherwise, + * the signature indicates the type of the return value. An argument + * signature represents an argument passed to a method: + * + * ::= + * + * A method signature represents the arguments that the method expects, and + * the value that it returns. ::= () + * ::= * + * + * This method converts such a string into a Java type declaration like + * `void main(String[])' and throws a `ClassFormatException' when the parsed + * type is invalid. + * + * @param signature + * Method signature + * @param name + * Method name + * @param access + * Method access rights + * @return Java type declaration + * @throws ClassFormatException + */ + public static final String methodSignatureToString(String signature, + String name, String access, boolean chopit, LocalVariableTable vars) + throws ClassFormatException { + StringBuffer buf = new StringBuffer("("); + String type; + int index; + int var_index = (access.indexOf("static") >= 0) ? 0 : 1; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + String param_type = signatureToString( + signature.substring(index), chopit); + buf.append(param_type); + if (vars != null) { + LocalVariable l = vars.getLocalVariable(var_index); + if (l != null) { + buf.append(" ").append(l.getName()); + } + } else { + buf.append(" arg").append(var_index); + } + if ("double".equals(param_type) || "long".equals(param_type)) { + var_index += 2; + } else { + var_index++; + } + buf.append(", "); + // corrected concurrent private static field acess + index += unwrap(consumed_chars); // update position + } + index++; // update position + // Read return type after `)' + type = signatureToString(signature.substring(index), chopit); + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + + signature); + } + if (buf.length() > 1) { + buf.setLength(buf.length() - 2); + } + buf.append(")"); + return access + ((access.length() > 0) ? " " : "") + // May be an empty + // string + type + " " + name + buf.toString(); + } + + // Guess what this does + private static final int pow2(int n) { + return 1 << n; + } + + /** + * Replace all occurences of old in str with new. + * + * @param str + * String to permute + * @param old + * String to be replaced + * @param new_ + * Replacement string + * @return new String object + */ + public static final String replace(String str, String old, String new_) { + int index, old_index; + StringBuffer buf = new StringBuffer(); + try { + if ((index = str.indexOf(old)) != -1) { // `old' found in str + old_index = 0; // String start offset + // While we have something to replace + while ((index = str.indexOf(old, old_index)) != -1) { + buf.append(str.substring(old_index, index)); // append + // prefix + buf.append(new_); // append replacement + old_index = index + old.length(); // Skip `old'.length chars + } + buf.append(str.substring(old_index)); // append rest of string + str = buf.toString(); + } + } catch (StringIndexOutOfBoundsException e) { // Should not occur + System.err.println(e); + } + return str; + } + + /** + * Converts signature to string with all class names compacted. + * + * @param signature + * to convert + * @return Human readable signature + */ + public static final String signatureToString(String signature) { + return signatureToString(signature, true); + } + + /** + * The field signature represents the value of an argument to a function or + * the value of a variable. It is a series of bytes generated by the + * following grammar: + * + *
      +	 *  ::= 
      +	 *       ::= ||
      +	 *        ::= B|C|D|F|I|J|S|Z
      +	 *      ::= L;
      +	 *       ::= [
      +	 * 
      +	 * The meaning of the base types is as follows:
      +	 * B byte signed byte
      +	 * C char character
      +	 * D double double precision IEEE float
      +	 * F float single precision IEEE float
      +	 * I int integer
      +	 * J long long integer
      +	 * L; ... an object of the given class
      +	 * S short signed short
      +	 * Z boolean true or false
      +	 * [ ... array
      +	 * 
      + * + * This method converts this string into a Java type declaration such as + * `String[]' and throws a `ClassFormatException' when the parsed type is + * invalid. + * + * @param signature + * Class signature + * @param chopit + * Flag that determines whether chopping is executed or not + * @return Java type declaration + * @throws ClassFormatException + */ + public static final String signatureToString(String signature, + boolean chopit) { + // corrected concurrent private static field acess + wrap(consumed_chars, 1); // This is the default, read just one char like + // `B' + try { + switch (signature.charAt(0)) { + case 'B': + return "byte"; + case 'C': + return "char"; + case 'D': + return "double"; + case 'F': + return "float"; + case 'I': + return "int"; + case 'J': + return "long"; + case 'L': { // Full class name + int index = signature.indexOf(';'); // Look for closing `;' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + + signature); + } + // corrected concurrent private static field acess + wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are + // removed + return compactClassName(signature.substring(1, index), chopit); + } + case 'S': + return "short"; + case 'Z': + return "boolean"; + case '[': { // Array declaration + int n; + StringBuffer brackets; + String type; + int consumed_chars; // Shadows global var + brackets = new StringBuffer(); // Accumulate []'s + // Count opening brackets and look for optional size argument + for (n = 0; signature.charAt(n) == '['; n++) { + brackets.append("[]"); + } + consumed_chars = n; // Remember value + // The rest of the string denotes a `' + type = signatureToString(signature.substring(n), chopit); + // corrected concurrent private static field acess + // Utility.consumed_chars += consumed_chars; is replaced by: + int _temp = unwrap(Utility.consumed_chars) + consumed_chars; + wrap(Utility.consumed_chars, _temp); + return type + brackets.toString(); + } + case 'V': + return "void"; + default: + throw new ClassFormatException("Invalid signature: `" + + signature + "'"); + } + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid signature: " + e + ":" + + signature); + } + } + + /** + * Parse Java type such as "char", or "java.lang.String[]" and return the + * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" + * respectively. + * + * @param type + * Java type + * @return byte code signature + */ + public static String getSignature(String type) { + StringBuffer buf = new StringBuffer(); + char[] chars = type.toCharArray(); + boolean char_found = false, delim = false; + int index = -1; + loop: for (int i = 0; i < chars.length; i++) { + switch (chars[i]) { + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + if (char_found) { + delim = true; + } + break; + case '[': + if (!char_found) { + throw new RuntimeException("Illegal type: " + type); + } + index = i; + break loop; + default: + char_found = true; + if (!delim) { + buf.append(chars[i]); + } + } + } + int brackets = 0; + if (index > 0) { + brackets = countBrackets(type.substring(index)); + } + type = buf.toString(); + buf.setLength(0); + for (int i = 0; i < brackets; i++) { + buf.append('['); + } + boolean found = false; + for (int i = Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) { + if (Constants.TYPE_NAMES[i].equals(type)) { + found = true; + buf.append(Constants.SHORT_TYPE_NAMES[i]); + } + } + if (!found) { + buf.append('L').append(type.replace('.', '/')).append(';'); + } + return buf.toString(); + } + + private static int countBrackets(String brackets) { + char[] chars = brackets.toCharArray(); + int count = 0; + boolean open = false; + for (int i = 0; i < chars.length; i++) { + switch (chars[i]) { + case '[': + if (open) { + throw new RuntimeException("Illegally nested brackets:" + + brackets); + } + open = true; + break; + case ']': + if (!open) { + throw new RuntimeException("Illegally nested brackets:" + + brackets); + } + open = false; + count++; + break; + default: + // Don't care + } + } + if (open) { + throw new RuntimeException("Illegally nested brackets:" + brackets); + } + return count; + } + + /** + * Return type of method signature as a byte value as defined in + * Constants + * + * @param signature + * in format described above + * @return type of method signature + * @see Constants + */ + public static final byte typeOfMethodSignature(String signature) + throws ClassFormatException { + int index; + try { + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + + signature); + } + index = signature.lastIndexOf(')') + 1; + return typeOfSignature(signature.substring(index)); + } catch (StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + + signature); + } + } + + /** + * Return type of signature as a byte value as defined in Constants + * + * @param signature + * in format described above + * @return type of signature + * @see Constants + */ + public static final byte typeOfSignature(String signature) + throws ClassFormatException { + try { + switch (signature.charAt(0)) { + case 'B': + return Constants.T_BYTE; + case 'C': + return Constants.T_CHAR; + case 'D': + return Constants.T_DOUBLE; + case 'F': + return Constants.T_FLOAT; + case 'I': + return Constants.T_INT; + case 'J': + return Constants.T_LONG; + case 'L': + return Constants.T_REFERENCE; + case '[': + return Constants.T_ARRAY; + case 'V': + return Constants.T_VOID; + case 'Z': + return Constants.T_BOOLEAN; + case 'S': + return Constants.T_SHORT; + default: + throw new ClassFormatException("Invalid method signature: " + + signature); + } + } catch (StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + + signature); + } + } + + /** + * Map opcode names to opcode numbers. E.g., return Constants.ALOAD for + * "aload" + */ + public static short searchOpcode(String name) { + name = name.toLowerCase(Locale.ENGLISH); + for (short i = 0; i < Constants.OPCODE_NAMES.length; i++) { + if (Constants.OPCODE_NAMES[i].equals(name)) { + return i; + } + } + return -1; + } + + /** + * Convert (signed) byte to (unsigned) short value, i.e., all negative + * values become positive. + */ + private static final short byteToShort(byte b) { + return (b < 0) ? (short) (256 + b) : (short) b; + } + + /** + * Convert bytes into hexidecimal string + * + * @return bytes as hexidecimal string, e.g. 00 FA 12 ... + */ + public static final String toHexString(byte[] bytes) { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < bytes.length; i++) { + short b = byteToShort(bytes[i]); + String hex = Integer.toString(b, 0x10); + if (b < 0x10) { + buf.append('0'); + } + buf.append(hex); + if (i < bytes.length - 1) { + buf.append(' '); + } + } + return buf.toString(); + } + + /** + * Return a string for an integer justified left or right and filled up with + * `fill' characters if necessary. + * + * @param i + * integer to format + * @param length + * length of desired string + * @param left_justify + * format left or right + * @param fill + * fill character + * @return formatted int + */ + public static final String format(int i, int length, boolean left_justify, + char fill) { + return fillup(Integer.toString(i), length, left_justify, fill); + } + + /** + * Fillup char with up to length characters with char `fill' and justify it + * left or right. + * + * @param str + * string to format + * @param length + * length of desired string + * @param left_justify + * format left or right + * @param fill + * fill character + * @return formatted string + */ + public static final String fillup(String str, int length, + boolean left_justify, char fill) { + int len = length - str.length(); + char[] buf = new char[(len < 0) ? 0 : len]; + for (int j = 0; j < buf.length; j++) { + buf[j] = fill; + } + if (left_justify) { + return str + new String(buf); + } + return new String(buf) + str; + } + + static final boolean equals(byte[] a, byte[] b) { + int size; + if ((size = a.length) != b.length) { + return false; + } + for (int i = 0; i < size; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + public static final void printArray(PrintStream out, Object[] obj) { + out.println(printArray(obj, true)); + } + + public static final void printArray(PrintWriter out, Object[] obj) { + out.println(printArray(obj, true)); + } + + public static final String printArray(Object[] obj) { + return printArray(obj, true); + } + + public static final String printArray(Object[] obj, boolean braces) { + return printArray(obj, braces, false); + } + + public static final String printArray(Object[] obj, boolean braces, + boolean quote) { + if (obj == null) { + return null; + } + StringBuffer buf = new StringBuffer(); + if (braces) { + buf.append('{'); + } + for (int i = 0; i < obj.length; i++) { + if (obj[i] != null) { + buf.append((quote ? "\"" : "")).append(obj[i].toString()) + .append((quote ? "\"" : "")); + } else { + buf.append("null"); + } + if (i < obj.length - 1) { + buf.append(", "); + } + } + if (braces) { + buf.append('}'); + } + return buf.toString(); + } + + /** + * @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _) + */ + public static boolean isJavaIdentifierPart(char ch) { + return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) + || ((ch >= '0') && (ch <= '9')) || (ch == '_'); + } + + /** + * Encode byte array it into Java identifier string, i.e., a string that + * only contains the following characters: (a, ... z, A, ... Z, 0, ... 9, _, + * $). The encoding algorithm itself is not too clever: if the current + * byte's ASCII value already is a valid Java identifier part, leave it as + * it is. Otherwise it writes the escape character($) followed by + *

      + *

        + *
      • the ASCII value as a hexadecimal string, if the value is not in the + * range 200..247
      • + *
      • a Java identifier char not used in a lowercase hexadecimal string, if + * the value is in the range 200..247
      • + *
          + *

          + * + *

          + * This operation inflates the original byte array by roughly 40-50% + *

          + * + * @param bytes + * the byte array to convert + * @param compress + * use gzip to minimize string + */ + public static String encode(byte[] bytes, boolean compress) + throws IOException { + if (compress) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + GZIPOutputStream gos = new GZIPOutputStream(baos); + gos.write(bytes, 0, bytes.length); + gos.close(); + baos.close(); + bytes = baos.toByteArray(); + } + CharArrayWriter caw = new CharArrayWriter(); + JavaWriter jw = new JavaWriter(caw); + for (int i = 0; i < bytes.length; i++) { + int in = bytes[i] & 0x000000ff; // Normalize to unsigned + jw.write(in); + } + jw.close(); + return caw.toString(); + } + + /** + * Decode a string back to a byte array. + * + * @param s + * the string to convert + * @param uncompress + * use gzip to uncompress the stream of bytes + */ + public static byte[] decode(String s, boolean uncompress) + throws IOException { + char[] chars = s.toCharArray(); + CharArrayReader car = new CharArrayReader(chars); + JavaReader jr = new JavaReader(car); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int ch; + while ((ch = jr.read()) >= 0) { + bos.write(ch); + } + bos.close(); + car.close(); + jr.close(); + byte[] bytes = bos.toByteArray(); + if (uncompress) { + GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream( + bytes)); + byte[] tmp = new byte[bytes.length * 3]; // Rough estimate + int count = 0; + int b; + while ((b = gis.read()) >= 0) { + tmp[count++] = (byte) b; + } + bytes = new byte[count]; + System.arraycopy(tmp, 0, bytes, 0, count); + } + return bytes; + } + + // A-Z, g-z, _, $ + private static final int FREE_CHARS = 48; + static int[] CHAR_MAP = new int[FREE_CHARS]; + static int[] MAP_CHAR = new int[256]; // Reverse map + private static final char ESCAPE_CHAR = '$'; + static { + int j = 0; + for (int i = 'A'; i <= 'Z'; i++) { + CHAR_MAP[j] = i; + MAP_CHAR[i] = j; + j++; + } + for (int i = 'g'; i <= 'z'; i++) { + CHAR_MAP[j] = i; + MAP_CHAR[i] = j; + j++; + } + CHAR_MAP[j] = '$'; + MAP_CHAR['$'] = j; + j++; + CHAR_MAP[j] = '_'; + MAP_CHAR['_'] = j; + } + + /** + * Decode characters into bytes. Used by decode() + */ + private static class JavaReader extends FilterReader { + + public JavaReader(Reader in) { + super(in); + } + + @Override + public int read() throws IOException { + int b = in.read(); + if (b != ESCAPE_CHAR) { + return b; + } + int i = in.read(); + if (i < 0) { + return -1; + } + if (((i >= '0') && (i <= '9')) || ((i >= 'a') && (i <= 'f'))) { // Normal + // escape + int j = in.read(); + if (j < 0) { + return -1; + } + char[] tmp = { (char) i, (char) j }; + int s = Integer.parseInt(new String(tmp), 16); + return s; + } + return MAP_CHAR[i]; + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + for (int i = 0; i < len; i++) { + cbuf[off + i] = (char) read(); + } + return len; + } + } + + /** + * Encode bytes into valid java identifier characters. Used by encode() + */ + private static class JavaWriter extends FilterWriter { + + public JavaWriter(Writer out) { + super(out); + } + + @Override + public void write(int b) throws IOException { + if (isJavaIdentifierPart((char) b) && (b != ESCAPE_CHAR)) { + out.write(b); + } else { + out.write(ESCAPE_CHAR); // Escape character + // Special escape + if (b >= 0 && b < FREE_CHARS) { + out.write(CHAR_MAP[b]); + } else { // Normal escape + char[] tmp = Integer.toHexString(b).toCharArray(); + if (tmp.length == 1) { + out.write('0'); + out.write(tmp[0]); + } else { + out.write(tmp[0]); + out.write(tmp[1]); + } + } + } + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + for (int i = 0; i < len; i++) { + write(cbuf[off + i]); + } + } + + @Override + public void write(String str, int off, int len) throws IOException { + write(str.toCharArray(), off, len); + } + } + + /** + * Escape all occurences of newline chars '\n', quotes \", etc. + */ + public static final String convertString(String label) { + char[] ch = label.toCharArray(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < ch.length; i++) { + switch (ch[i]) { + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + case '\"': + buf.append("\\\""); + break; + case '\'': + buf.append("\\'"); + break; + case '\\': + buf.append("\\\\"); + break; + default: + buf.append(ch[i]); + break; + } + } + return buf.toString(); + } } diff --git a/src/org/apache/bcel/classfile/Visitor.java b/src/org/apache/bcel/classfile/Visitor.java index 4eda18b..cdf0e74 100644 --- a/src/org/apache/bcel/classfile/Visitor.java +++ b/src/org/apache/bcel/classfile/Visitor.java @@ -17,111 +17,80 @@ package org.apache.bcel.classfile; /** - * Interface to make use of the Visitor pattern programming style. - * I.e. a class that implements this interface can traverse the contents of - * a Java class just by calling the `accept' method which all classes have. - * + * Interface to make use of the Visitor pattern programming style. I.e. a class + * that implements this interface can traverse the contents of a Java class just + * by calling the `accept' method which all classes have. + * * @version $Id: Visitor.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface Visitor { - //public void visitAnnotation(Annotations obj); - //public void visitParameterAnnotation(ParameterAnnotations obj); - //public void visitAnnotationEntry(AnnotationEntry obj); - //public void visitAnnotationDefault(AnnotationDefault obj); - public void visitCode( Code obj ); + // public void visitAnnotation(Annotations obj); + // public void visitParameterAnnotation(ParameterAnnotations obj); + // public void visitAnnotationEntry(AnnotationEntry obj); + // public void visitAnnotationDefault(AnnotationDefault obj); + public void visitCode(Code obj); + public void visitCodeException(CodeException obj); - public void visitCodeException( CodeException obj ); + public void visitConstantClass(ConstantClass obj); + public void visitConstantDouble(ConstantDouble obj); - public void visitConstantClass( ConstantClass obj ); + public void visitConstantFieldref(ConstantFieldref obj); + public void visitConstantFloat(ConstantFloat obj); - public void visitConstantDouble( ConstantDouble obj ); + public void visitConstantInteger(ConstantInteger obj); + public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj); - public void visitConstantFieldref( ConstantFieldref obj ); + public void visitConstantLong(ConstantLong obj); + public void visitConstantMethodref(ConstantMethodref obj); - public void visitConstantFloat( ConstantFloat obj ); + public void visitConstantNameAndType(ConstantNameAndType obj); + public void visitConstantPool(ConstantPool obj); - public void visitConstantInteger( ConstantInteger obj ); + public void visitConstantString(ConstantString obj); + public void visitConstantUtf8(ConstantUtf8 obj); - public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref obj ); + public void visitConstantValue(ConstantValue obj); + public void visitDeprecated(Deprecated obj); - public void visitConstantLong( ConstantLong obj ); + public void visitExceptionTable(ExceptionTable obj); + public void visitField(Field obj); - public void visitConstantMethodref( ConstantMethodref obj ); + public void visitInnerClass(InnerClass obj); + public void visitInnerClasses(InnerClasses obj); - public void visitConstantNameAndType( ConstantNameAndType obj ); + public void visitJavaClass(JavaClass obj); + public void visitLineNumber(LineNumber obj); - public void visitConstantPool( ConstantPool obj ); + public void visitLineNumberTable(LineNumberTable obj); + public void visitLocalVariable(LocalVariable obj); - public void visitConstantString( ConstantString obj ); + public void visitLocalVariableTable(LocalVariableTable obj); + public void visitMethod(Method obj); - public void visitConstantUtf8( ConstantUtf8 obj ); + public void visitSignature(Signature obj); + public void visitSourceFile(SourceFile obj); - public void visitConstantValue( ConstantValue obj ); + public void visitSynthetic(Synthetic obj); + public void visitUnknown(Unknown obj); - public void visitDeprecated( Deprecated obj ); + public void visitStackMap(StackMap obj); - - public void visitExceptionTable( ExceptionTable obj ); - - - public void visitField( Field obj ); - - - public void visitInnerClass( InnerClass obj ); - - - public void visitInnerClasses( InnerClasses obj ); - - - public void visitJavaClass( JavaClass obj ); - - - public void visitLineNumber( LineNumber obj ); - - - public void visitLineNumberTable( LineNumberTable obj ); - - - public void visitLocalVariable( LocalVariable obj ); - - - public void visitLocalVariableTable( LocalVariableTable obj ); - - - public void visitMethod( Method obj ); - - - public void visitSignature( Signature obj ); - - - public void visitSourceFile( SourceFile obj ); - - - public void visitSynthetic( Synthetic obj ); - - - public void visitUnknown( Unknown obj ); - - - public void visitStackMap( StackMap obj ); - - - public void visitStackMapEntry( StackMapEntry obj ); + public void visitStackMapEntry(StackMapEntry obj); } diff --git a/src/org/apache/bcel/generic/AALOAD.java b/src/org/apache/bcel/generic/AALOAD.java index 7668759..b8ecd6c 100644 --- a/src/org/apache/bcel/generic/AALOAD.java +++ b/src/org/apache/bcel/generic/AALOAD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * AALOAD - Load reference from array - *
          Stack: ..., arrayref, index -> value
          - * + * + *
          + * Stack: ..., arrayref, index -> value
          + * 
          + * * @version $Id: AALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class AALOAD extends ArrayInstruction implements StackProducer { - /** Load reference from array - */ - public AALOAD() { - super(org.apache.bcel.Constants.AALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Load reference from array + */ + public AALOAD() { + super(org.apache.bcel.Constants.AALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitAALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitAALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/AASTORE.java b/src/org/apache/bcel/generic/AASTORE.java index e445189..8bc1792 100644 --- a/src/org/apache/bcel/generic/AASTORE.java +++ b/src/org/apache/bcel/generic/AASTORE.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * AASTORE - Store into reference array - *
          Stack: ..., arrayref, index, value -> ...
          - * +/** + * AASTORE - Store into reference array + * + *
          + * Stack: ..., arrayref, index, value -> ...
          + * 
          + * * @version $Id: AASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class AASTORE extends ArrayInstruction implements StackConsumer { - /** Store into reference array - */ - public AASTORE() { - super(org.apache.bcel.Constants.AASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Store into reference array + */ + public AASTORE() { + super(org.apache.bcel.Constants.AASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitAASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitAASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/ACONST_NULL.java b/src/org/apache/bcel/generic/ACONST_NULL.java index d62d483..d996cf0 100644 --- a/src/org/apache/bcel/generic/ACONST_NULL.java +++ b/src/org/apache/bcel/generic/ACONST_NULL.java @@ -16,42 +16,53 @@ */ package org.apache.bcel.generic; -/** +/** * ACONST_NULL - Push null reference - *
          Stack: ... -> ..., null
          - * + * + *
          + * Stack: ... -> ..., null
          + * 
          + * * @version $Id: ACONST_NULL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class ACONST_NULL extends Instruction implements PushInstruction, TypedInstruction { +public class ACONST_NULL extends Instruction implements PushInstruction, + TypedInstruction { - /** - * Push null reference - */ - public ACONST_NULL() { - super(org.apache.bcel.Constants.ACONST_NULL, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Push null reference + */ + public ACONST_NULL() { + super(org.apache.bcel.Constants.ACONST_NULL, (short) 1); + } - /** @return Type.NULL - */ - public Type getType( ConstantPoolGen cp ) { - return Type.NULL; - } + /** + * @return Type.NULL + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.NULL; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitACONST_NULL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitACONST_NULL(this); + } } diff --git a/src/org/apache/bcel/generic/ALOAD.java b/src/org/apache/bcel/generic/ALOAD.java index c093f5d..7abea0e 100644 --- a/src/org/apache/bcel/generic/ALOAD.java +++ b/src/org/apache/bcel/generic/ALOAD.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * ALOAD - Load reference from local variable - *
          Stack: ... -> ..., objectref
          - * + * + *
          + * Stack: ... -> ..., objectref
          + * 
          + * * @version $Id: ALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ALOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ALOAD() { - super(org.apache.bcel.Constants.ALOAD, org.apache.bcel.Constants.ALOAD_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ALOAD() { + super(org.apache.bcel.Constants.ALOAD, + org.apache.bcel.Constants.ALOAD_0); + } - /** Load reference from local variable - * @param n index of local variable - */ - public ALOAD(int n) { - super(org.apache.bcel.Constants.ALOAD, org.apache.bcel.Constants.ALOAD_0, n); - } + /** + * Load reference from local variable + * + * @param n + * index of local variable + */ + public ALOAD(int n) { + super(org.apache.bcel.Constants.ALOAD, + org.apache.bcel.Constants.ALOAD_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/ANEWARRAY.java b/src/org/apache/bcel/generic/ANEWARRAY.java index 0d1d46a..f7e4953 100644 --- a/src/org/apache/bcel/generic/ANEWARRAY.java +++ b/src/org/apache/bcel/generic/ANEWARRAY.java @@ -18,62 +18,72 @@ package org.apache.bcel.generic; import org.apache.bcel.ExceptionConstants; -/** - * ANEWARRAY - Create new array of references - *
          Stack: ..., count -> ..., arrayref
          - * +/** + * ANEWARRAY - Create new array of references + * + *
          + * Stack: ..., count -> ..., arrayref
          + * 
          + * * @version $Id: ANEWARRAY.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, - ExceptionThrower, StackConsumer, StackProducer { +public class ANEWARRAY extends CPInstruction implements LoadClass, + AllocationInstruction, ExceptionThrower, StackConsumer, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ANEWARRAY() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ANEWARRAY() { + } - public ANEWARRAY(int index) { - super(org.apache.bcel.Constants.ANEWARRAY, index); - } + public ANEWARRAY(int index) { + super(org.apache.bcel.Constants.ANEWARRAY, index); + } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; + System.arraycopy( + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, + 0, + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; + return cs; + } - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; - return cs; - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitANEWARRAY(this); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitANEWARRAY(this); - } - - - public ObjectType getLoadClassType( ConstantPoolGen cpg ) { - Type t = getType(cpg); - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - return (t instanceof ObjectType) ? (ObjectType) t : null; - } + @Override + public ObjectType getLoadClassType(ConstantPoolGen cpg) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } } diff --git a/src/org/apache/bcel/generic/ARETURN.java b/src/org/apache/bcel/generic/ARETURN.java index 40dcee7..dc47ddc 100644 --- a/src/org/apache/bcel/generic/ARETURN.java +++ b/src/org/apache/bcel/generic/ARETURN.java @@ -16,36 +16,45 @@ */ package org.apache.bcel.generic; -/** - * ARETURN - Return reference from method - *
          Stack: ..., objectref -> <empty>
          - * +/** + * ARETURN - Return reference from method + * + *
          + * Stack: ..., objectref -> <empty>
          + * 
          + * * @version $Id: ARETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ARETURN extends ReturnInstruction { - /** - * Return reference from method - */ - public ARETURN() { - super(org.apache.bcel.Constants.ARETURN); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Return reference from method + */ + public ARETURN() { + super(org.apache.bcel.Constants.ARETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitARETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitARETURN(this); + } } diff --git a/src/org/apache/bcel/generic/ARRAYLENGTH.java b/src/org/apache/bcel/generic/ARRAYLENGTH.java index 9c7ed7b..819f252 100644 --- a/src/org/apache/bcel/generic/ARRAYLENGTH.java +++ b/src/org/apache/bcel/generic/ARRAYLENGTH.java @@ -16,42 +16,52 @@ */ package org.apache.bcel.generic; -/** - * ARRAYLENGTH - Get length of array - *
          Stack: ..., arrayref -> ..., length
          - * +/** + * ARRAYLENGTH - Get length of array + * + *
          + * Stack: ..., arrayref -> ..., length
          + * 
          + * * @version $Id: ARRAYLENGTH.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class ARRAYLENGTH extends Instruction implements ExceptionThrower, StackProducer { +public class ARRAYLENGTH extends Instruction implements ExceptionThrower, + StackProducer { - /** Get length of array - */ - public ARRAYLENGTH() { - super(org.apache.bcel.Constants.ARRAYLENGTH, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Get length of array + */ + public ARRAYLENGTH() { + super(org.apache.bcel.Constants.ARRAYLENGTH, (short) 1); + } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION - }; - } + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitARRAYLENGTH(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitARRAYLENGTH(this); + } } diff --git a/src/org/apache/bcel/generic/ASTORE.java b/src/org/apache/bcel/generic/ASTORE.java index 351de5f..47e8f1a 100644 --- a/src/org/apache/bcel/generic/ASTORE.java +++ b/src/org/apache/bcel/generic/ASTORE.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * ASTORE - Store reference into local variable - *
          Stack ..., objectref -> ... 
          - * + * + *
          + * Stack ..., objectref -> ...
          + * 
          + * * @version $Id: ASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ASTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ASTORE() { - super(org.apache.bcel.Constants.ASTORE, org.apache.bcel.Constants.ASTORE_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ASTORE() { + super(org.apache.bcel.Constants.ASTORE, + org.apache.bcel.Constants.ASTORE_0); + } - /** Store reference into local variable - * @param n index of local variable - */ - public ASTORE(int n) { - super(org.apache.bcel.Constants.ASTORE, org.apache.bcel.Constants.ASTORE_0, n); - } + /** + * Store reference into local variable + * + * @param n + * index of local variable + */ + public ASTORE(int n) { + super(org.apache.bcel.Constants.ASTORE, + org.apache.bcel.Constants.ASTORE_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/ATHROW.java b/src/org/apache/bcel/generic/ATHROW.java index 4694fbb..b5563b3 100644 --- a/src/org/apache/bcel/generic/ATHROW.java +++ b/src/org/apache/bcel/generic/ATHROW.java @@ -16,43 +16,52 @@ */ package org.apache.bcel.generic; -/** - * ATHROW - Throw exception - *
          Stack: ..., objectref -> objectref
          - * +/** + * ATHROW - Throw exception + * + *
          + * Stack: ..., objectref -> objectref
          + * 
          + * * @version $Id: ATHROW.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class ATHROW extends Instruction implements UnconditionalBranch, ExceptionThrower { +public class ATHROW extends Instruction implements UnconditionalBranch, + ExceptionThrower { - /** - * Throw exception - */ - public ATHROW() { - super(org.apache.bcel.Constants.ATHROW, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Throw exception + */ + public ATHROW() { + super(org.apache.bcel.Constants.ATHROW, (short) 1); + } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.THROWABLE - }; - } + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.THROWABLE }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitUnconditionalBranch(this); - v.visitExceptionThrower(this); - v.visitATHROW(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitUnconditionalBranch(this); + v.visitExceptionThrower(this); + v.visitATHROW(this); + } } diff --git a/src/org/apache/bcel/generic/AllocationInstruction.java b/src/org/apache/bcel/generic/AllocationInstruction.java index 652b887..a30ab52 100644 --- a/src/org/apache/bcel/generic/AllocationInstruction.java +++ b/src/org/apache/bcel/generic/AllocationInstruction.java @@ -18,9 +18,9 @@ package org.apache.bcel.generic; /** * Denote family of instructions that allocates space in the heap. - * + * * @version $Id: AllocationInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface AllocationInstruction { } diff --git a/src/org/apache/bcel/generic/ArithmeticInstruction.java b/src/org/apache/bcel/generic/ArithmeticInstruction.java index 6edb5f3..f60c295 100644 --- a/src/org/apache/bcel/generic/ArithmeticInstruction.java +++ b/src/org/apache/bcel/generic/ArithmeticInstruction.java @@ -20,75 +20,81 @@ import org.apache.bcel.Constants; /** * Super class for the family of arithmetic instructions. - * + * * @version $Id: ArithmeticInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction, - StackProducer, StackConsumer { +public abstract class ArithmeticInstruction extends Instruction implements + TypedInstruction, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ArithmeticInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ArithmeticInstruction() { + } - /** - * @param opcode of instruction - */ - protected ArithmeticInstruction(short opcode) { - super(opcode, (short) 1); - } + /** + * @param opcode + * of instruction + */ + protected ArithmeticInstruction(short opcode) { + super(opcode, (short) 1); + } - - /** @return type associated with the instruction - */ - public Type getType( ConstantPoolGen cp ) { - switch (opcode) { - case Constants.DADD: - case Constants.DDIV: - case Constants.DMUL: - case Constants.DNEG: - case Constants.DREM: - case Constants.DSUB: - return Type.DOUBLE; - case Constants.FADD: - case Constants.FDIV: - case Constants.FMUL: - case Constants.FNEG: - case Constants.FREM: - case Constants.FSUB: - return Type.FLOAT; - case Constants.IADD: - case Constants.IAND: - case Constants.IDIV: - case Constants.IMUL: - case Constants.INEG: - case Constants.IOR: - case Constants.IREM: - case Constants.ISHL: - case Constants.ISHR: - case Constants.ISUB: - case Constants.IUSHR: - case Constants.IXOR: - return Type.INT; - case Constants.LADD: - case Constants.LAND: - case Constants.LDIV: - case Constants.LMUL: - case Constants.LNEG: - case Constants.LOR: - case Constants.LREM: - case Constants.LSHL: - case Constants.LSHR: - case Constants.LSUB: - case Constants.LUSHR: - case Constants.LXOR: - return Type.LONG; - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); - } - } + /** + * @return type associated with the instruction + */ + @Override + public Type getType(ConstantPoolGen cp) { + switch (opcode) { + case Constants.DADD: + case Constants.DDIV: + case Constants.DMUL: + case Constants.DNEG: + case Constants.DREM: + case Constants.DSUB: + return Type.DOUBLE; + case Constants.FADD: + case Constants.FDIV: + case Constants.FMUL: + case Constants.FNEG: + case Constants.FREM: + case Constants.FSUB: + return Type.FLOAT; + case Constants.IADD: + case Constants.IAND: + case Constants.IDIV: + case Constants.IMUL: + case Constants.INEG: + case Constants.IOR: + case Constants.IREM: + case Constants.ISHL: + case Constants.ISHR: + case Constants.ISUB: + case Constants.IUSHR: + case Constants.IXOR: + return Type.INT; + case Constants.LADD: + case Constants.LAND: + case Constants.LDIV: + case Constants.LMUL: + case Constants.LNEG: + case Constants.LOR: + case Constants.LREM: + case Constants.LSHL: + case Constants.LSHR: + case Constants.LSUB: + case Constants.LUSHR: + case Constants.LXOR: + return Type.LONG; + default: // Never reached + throw new ClassGenException("Unknown type " + opcode); + } + } } diff --git a/src/org/apache/bcel/generic/ArrayInstruction.java b/src/org/apache/bcel/generic/ArrayInstruction.java index 29bfd08..883c7aa 100644 --- a/src/org/apache/bcel/generic/ArrayInstruction.java +++ b/src/org/apache/bcel/generic/ArrayInstruction.java @@ -18,64 +18,70 @@ package org.apache.bcel.generic; /** * Super class for instructions dealing with array access such as IALOAD. - * + * * @version $Id: ArrayInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class ArrayInstruction extends Instruction implements ExceptionThrower, - TypedInstruction { +public abstract class ArrayInstruction extends Instruction implements + ExceptionThrower, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ArrayInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ArrayInstruction() { + } - /** - * @param opcode of instruction - */ - protected ArrayInstruction(short opcode) { - super(opcode, (short) 1); - } + /** + * @param opcode + * of instruction + */ + protected ArrayInstruction(short opcode) { + super(opcode, (short) 1); + } + @Override + public Class[] getExceptions() { + return org.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; + } - public Class[] getExceptions() { - return org.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - } - - - /** @return type associated with the instruction - */ - public Type getType( ConstantPoolGen cp ) { - switch (opcode) { - case org.apache.bcel.Constants.IALOAD: - case org.apache.bcel.Constants.IASTORE: - return Type.INT; - case org.apache.bcel.Constants.CALOAD: - case org.apache.bcel.Constants.CASTORE: - return Type.CHAR; - case org.apache.bcel.Constants.BALOAD: - case org.apache.bcel.Constants.BASTORE: - return Type.BYTE; - case org.apache.bcel.Constants.SALOAD: - case org.apache.bcel.Constants.SASTORE: - return Type.SHORT; - case org.apache.bcel.Constants.LALOAD: - case org.apache.bcel.Constants.LASTORE: - return Type.LONG; - case org.apache.bcel.Constants.DALOAD: - case org.apache.bcel.Constants.DASTORE: - return Type.DOUBLE; - case org.apache.bcel.Constants.FALOAD: - case org.apache.bcel.Constants.FASTORE: - return Type.FLOAT; - case org.apache.bcel.Constants.AALOAD: - case org.apache.bcel.Constants.AASTORE: - return Type.OBJECT; - default: - throw new ClassGenException("Oops: unknown case in switch" + opcode); - } - } + /** + * @return type associated with the instruction + */ + @Override + public Type getType(ConstantPoolGen cp) { + switch (opcode) { + case org.apache.bcel.Constants.IALOAD: + case org.apache.bcel.Constants.IASTORE: + return Type.INT; + case org.apache.bcel.Constants.CALOAD: + case org.apache.bcel.Constants.CASTORE: + return Type.CHAR; + case org.apache.bcel.Constants.BALOAD: + case org.apache.bcel.Constants.BASTORE: + return Type.BYTE; + case org.apache.bcel.Constants.SALOAD: + case org.apache.bcel.Constants.SASTORE: + return Type.SHORT; + case org.apache.bcel.Constants.LALOAD: + case org.apache.bcel.Constants.LASTORE: + return Type.LONG; + case org.apache.bcel.Constants.DALOAD: + case org.apache.bcel.Constants.DASTORE: + return Type.DOUBLE; + case org.apache.bcel.Constants.FALOAD: + case org.apache.bcel.Constants.FASTORE: + return Type.FLOAT; + case org.apache.bcel.Constants.AALOAD: + case org.apache.bcel.Constants.AASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Oops: unknown case in switch" + opcode); + } + } } diff --git a/src/org/apache/bcel/generic/ArrayType.java b/src/org/apache/bcel/generic/ArrayType.java index 1750e25..fda1bc0 100644 --- a/src/org/apache/bcel/generic/ArrayType.java +++ b/src/org/apache/bcel/generic/ArrayType.java @@ -18,110 +18,117 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; -/** +/** * Denotes array type, such as int[][] - * + * * @version $Id: ArrayType.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class ArrayType extends ReferenceType { - private int dimensions; - private Type basic_type; + /** + * + */ + private static final long serialVersionUID = 1L; + private int dimensions; + private Type basic_type; + /** + * Convenience constructor for array type, e.g. int[] + * + * @param type + * array type, e.g. T_INT + */ + public ArrayType(byte type, int dimensions) { + this(BasicType.getType(type), dimensions); + } - /** - * Convenience constructor for array type, e.g. int[] - * - * @param type array type, e.g. T_INT - */ - public ArrayType(byte type, int dimensions) { - this(BasicType.getType(type), dimensions); - } + /** + * Convenience constructor for reference array type, e.g. Object[] + * + * @param class_name + * complete name of class (java.lang.String, e.g.) + */ + public ArrayType(String class_name, int dimensions) { + this(new ObjectType(class_name), dimensions); + } + /** + * Constructor for array of given type + * + * @param type + * type of array (may be an array itself) + */ + public ArrayType(Type type, int dimensions) { + super(Constants.T_ARRAY, ""); + if ((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) { + throw new ClassGenException("Invalid number of dimensions: " + + dimensions); + } + switch (type.getType()) { + case Constants.T_ARRAY: + ArrayType array = (ArrayType) type; + this.dimensions = dimensions + array.dimensions; + basic_type = array.basic_type; + break; + case Constants.T_VOID: + throw new ClassGenException("Invalid type: void[]"); + default: // Basic type or reference + this.dimensions = dimensions; + basic_type = type; + break; + } + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < this.dimensions; i++) { + buf.append('['); + } + buf.append(basic_type.getSignature()); + signature = buf.toString(); + } - /** - * Convenience constructor for reference array type, e.g. Object[] - * - * @param class_name complete name of class (java.lang.String, e.g.) - */ - public ArrayType(String class_name, int dimensions) { - this(new ObjectType(class_name), dimensions); - } + /** + * @return basic type of array, i.e., for int[][][] the basic type is int + */ + public Type getBasicType() { + return basic_type; + } + /** + * @return element type of array, i.e., for int[][][] the element type is + * int[][] + */ + public Type getElementType() { + if (dimensions == 1) { + return basic_type; + } + return new ArrayType(basic_type, dimensions - 1); + } - /** - * Constructor for array of given type - * - * @param type type of array (may be an array itself) - */ - public ArrayType(Type type, int dimensions) { - super(Constants.T_ARRAY, ""); - if ((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) { - throw new ClassGenException("Invalid number of dimensions: " + dimensions); - } - switch (type.getType()) { - case Constants.T_ARRAY: - ArrayType array = (ArrayType) type; - this.dimensions = dimensions + array.dimensions; - basic_type = array.basic_type; - break; - case Constants.T_VOID: - throw new ClassGenException("Invalid type: void[]"); - default: // Basic type or reference - this.dimensions = dimensions; - basic_type = type; - break; - } - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < this.dimensions; i++) { - buf.append('['); - } - buf.append(basic_type.getSignature()); - signature = buf.toString(); - } + /** + * @return number of dimensions of array + */ + public int getDimensions() { + return dimensions; + } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return basic_type.hashCode() ^ dimensions; + } - /** - * @return basic type of array, i.e., for int[][][] the basic type is int - */ - public Type getBasicType() { - return basic_type; - } - - - /** - * @return element type of array, i.e., for int[][][] the element type is int[][] - */ - public Type getElementType() { - if (dimensions == 1) { - return basic_type; - } - return new ArrayType(basic_type, dimensions - 1); - } - - - /** @return number of dimensions of array - */ - public int getDimensions() { - return dimensions; - } - - - /** @return a hash code value for the object. - */ - public int hashCode() { - return basic_type.hashCode() ^ dimensions; - } - - - /** @return true if both type objects refer to the same array type. - */ - public boolean equals( Object _type ) { - if (_type instanceof ArrayType) { - ArrayType array = (ArrayType) _type; - return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); - } - return false; - } + /** + * @return true if both type objects refer to the same array type. + */ + @Override + public boolean equals(Object _type) { + if (_type instanceof ArrayType) { + ArrayType array = (ArrayType) _type; + return (array.dimensions == dimensions) + && array.basic_type.equals(basic_type); + } + return false; + } } diff --git a/src/org/apache/bcel/generic/BALOAD.java b/src/org/apache/bcel/generic/BALOAD.java index e664378..9f6d6fe 100644 --- a/src/org/apache/bcel/generic/BALOAD.java +++ b/src/org/apache/bcel/generic/BALOAD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * BALOAD - Load byte or boolean from array - *
          Stack: ..., arrayref, index -> ..., value
          - * + * + *
          + * Stack: ..., arrayref, index -> ..., value
          + * 
          + * * @version $Id: BALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class BALOAD extends ArrayInstruction implements StackProducer { - /** Load byte or boolean from array - */ - public BALOAD() { - super(org.apache.bcel.Constants.BALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Load byte or boolean from array + */ + public BALOAD() { + super(org.apache.bcel.Constants.BALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitBALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitBALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/BASTORE.java b/src/org/apache/bcel/generic/BASTORE.java index 86e5889..cb0aefc 100644 --- a/src/org/apache/bcel/generic/BASTORE.java +++ b/src/org/apache/bcel/generic/BASTORE.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * BASTORE - Store into byte or boolean array - *
          Stack: ..., arrayref, index, value -> ...
          - * +/** + * BASTORE - Store into byte or boolean array + * + *
          + * Stack: ..., arrayref, index, value -> ...
          + * 
          + * * @version $Id: BASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class BASTORE extends ArrayInstruction implements StackConsumer { - /** Store byte or boolean into array - */ - public BASTORE() { - super(org.apache.bcel.Constants.BASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Store byte or boolean into array + */ + public BASTORE() { + super(org.apache.bcel.Constants.BASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitBASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitBASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/BIPUSH.java b/src/org/apache/bcel/generic/BIPUSH.java index 93c1a7b..b1412e9 100644 --- a/src/org/apache/bcel/generic/BIPUSH.java +++ b/src/org/apache/bcel/generic/BIPUSH.java @@ -20,86 +20,94 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * BIPUSH - Push byte on stack - * - *
          Stack: ... -> ..., value
          - * + * + *
          + * Stack: ... -> ..., value
          + * 
          + * * @version $Id: BIPUSH.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class BIPUSH extends Instruction implements ConstantPushInstruction { - private byte b; + /** + * + */ + private static final long serialVersionUID = 1L; + private byte b; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + BIPUSH() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - BIPUSH() { - } + /** + * Push byte on stack + */ + public BIPUSH(byte b) { + super(org.apache.bcel.Constants.BIPUSH, (short) 2); + this.b = b; + } + /** + * Dump instruction as byte code to stream out. + */ + @Override + public void dump(DataOutputStream out) throws IOException { + super.dump(out); + out.writeByte(b); + } - /** Push byte on stack - */ - public BIPUSH(byte b) { - super(org.apache.bcel.Constants.BIPUSH, (short) 2); - this.b = b; - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + b; + } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + length = 2; + b = bytes.readByte(); + } - /** - * Dump instruction as byte code to stream out. - */ - public void dump( DataOutputStream out ) throws IOException { - super.dump(out); - out.writeByte(b); - } + @Override + public Number getValue() { + return new Integer(b); + } + /** + * @return Type.BYTE + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.BYTE; + } - /** - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - return super.toString(verbose) + " " + b; - } - - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - length = 2; - b = bytes.readByte(); - } - - - public Number getValue() { - return new Integer(b); - } - - - /** @return Type.BYTE - */ - public Type getType( ConstantPoolGen cp ) { - return Type.BYTE; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitBIPUSH(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitBIPUSH(this); + } } diff --git a/src/org/apache/bcel/generic/BREAKPOINT.java b/src/org/apache/bcel/generic/BREAKPOINT.java index ceb39cb..74e7308 100644 --- a/src/org/apache/bcel/generic/BREAKPOINT.java +++ b/src/org/apache/bcel/generic/BREAKPOINT.java @@ -18,26 +18,32 @@ package org.apache.bcel.generic; /** * BREAKPOINT, JVM dependent, ignored by default - * + * * @version $Id: BREAKPOINT.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class BREAKPOINT extends Instruction { - public BREAKPOINT() { - super(org.apache.bcel.Constants.BREAKPOINT, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public BREAKPOINT() { + super(org.apache.bcel.Constants.BREAKPOINT, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitBREAKPOINT(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitBREAKPOINT(this); + } } diff --git a/src/org/apache/bcel/generic/BasicType.java b/src/org/apache/bcel/generic/BasicType.java index 664a65f..715039d 100644 --- a/src/org/apache/bcel/generic/BasicType.java +++ b/src/org/apache/bcel/generic/BasicType.java @@ -18,64 +18,72 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; -/** +/** * Denotes basic type such as int. - * + * * @version $Id: BasicType.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class BasicType extends Type { - /** - * Constructor for basic types such as int, long, `void' - * - * @param type one of T_INT, T_BOOLEAN, ..., T_VOID - * @see org.apache.bcel.Constants - */ - BasicType(byte type) { - super(type, Constants.SHORT_TYPE_NAMES[type]); - if ((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) { - throw new ClassGenException("Invalid type: " + type); - } - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Constructor for basic types such as int, long, `void' + * + * @param type + * one of T_INT, T_BOOLEAN, ..., T_VOID + * @see org.apache.bcel.Constants + */ + BasicType(byte type) { + super(type, Constants.SHORT_TYPE_NAMES[type]); + if ((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) { + throw new ClassGenException("Invalid type: " + type); + } + } - public static final BasicType getType( byte type ) { - switch (type) { - case Constants.T_VOID: - return VOID; - case Constants.T_BOOLEAN: - return BOOLEAN; - case Constants.T_BYTE: - return BYTE; - case Constants.T_SHORT: - return SHORT; - case Constants.T_CHAR: - return CHAR; - case Constants.T_INT: - return INT; - case Constants.T_LONG: - return LONG; - case Constants.T_DOUBLE: - return DOUBLE; - case Constants.T_FLOAT: - return FLOAT; - default: - throw new ClassGenException("Invalid type: " + type); - } - } + public static final BasicType getType(byte type) { + switch (type) { + case Constants.T_VOID: + return VOID; + case Constants.T_BOOLEAN: + return BOOLEAN; + case Constants.T_BYTE: + return BYTE; + case Constants.T_SHORT: + return SHORT; + case Constants.T_CHAR: + return CHAR; + case Constants.T_INT: + return INT; + case Constants.T_LONG: + return LONG; + case Constants.T_DOUBLE: + return DOUBLE; + case Constants.T_FLOAT: + return FLOAT; + default: + throw new ClassGenException("Invalid type: " + type); + } + } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return type; + } - /** @return a hash code value for the object. - */ - public int hashCode() { - return type; - } - - - /** @return true if both type objects refer to the same type - */ - public boolean equals( Object _type ) { - return (_type instanceof BasicType) ? ((BasicType) _type).type == this.type : false; - } + /** + * @return true if both type objects refer to the same type + */ + @Override + public boolean equals(Object _type) { + return (_type instanceof BasicType) ? ((BasicType) _type).type == this.type + : false; + } } diff --git a/src/org/apache/bcel/generic/BranchHandle.java b/src/org/apache/bcel/generic/BranchHandle.java index 094678c..bb946d6 100644 --- a/src/org/apache/bcel/generic/BranchHandle.java +++ b/src/org/apache/bcel/generic/BranchHandle.java @@ -19,103 +19,106 @@ package org.apache.bcel.generic; /** * BranchHandle is returned by specialized InstructionList.append() whenever a * BranchInstruction is appended. This is useful when the target of this - * instruction is not known at time of creation and must be set later - * via setTarget(). - * + * instruction is not known at time of creation and must be set later via + * setTarget(). + * * @see InstructionHandle * @see Instruction * @see InstructionList * @version $Id: BranchHandle.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class BranchHandle extends InstructionHandle { - private BranchInstruction bi; // An alias in fact, but saves lots of casts + /** + * + */ + private static final long serialVersionUID = 1L; + private BranchInstruction bi; // An alias in fact, but saves lots of casts + private BranchHandle(BranchInstruction i) { + super(i); + bi = i; + } - private BranchHandle(BranchInstruction i) { - super(i); - bi = i; - } + /** + * Factory methods. + */ + private static BranchHandle bh_list = null; // List of reusable handles - /** Factory methods. - */ - private static BranchHandle bh_list = null; // List of reusable handles + static final BranchHandle getBranchHandle(BranchInstruction i) { + if (bh_list == null) { + return new BranchHandle(i); + } + BranchHandle bh = bh_list; + bh_list = (BranchHandle) bh.next; + bh.setInstruction(i); + return bh; + } + /** + * Handle adds itself to the list of resuable handles. + */ + @Override + protected void addHandle() { + next = bh_list; + bh_list = this; + } - static final BranchHandle getBranchHandle( BranchInstruction i ) { - if (bh_list == null) { - return new BranchHandle(i); - } - BranchHandle bh = bh_list; - bh_list = (BranchHandle) bh.next; - bh.setInstruction(i); - return bh; - } + /* + * Override InstructionHandle methods: delegate to branch instruction. + * Through this overriding all access to the private i_position field should + * be prevented. + */ + @Override + public int getPosition() { + return bi.position; + } + @Override + void setPosition(int pos) { + i_position = bi.position = pos; + } - /** Handle adds itself to the list of resuable handles. - */ - protected void addHandle() { - next = bh_list; - bh_list = this; - } + @Override + protected int updatePosition(int offset, int max_offset) { + int x = bi.updatePosition(offset, max_offset); + i_position = bi.position; + return x; + } + /** + * Pass new target to instruction. + */ + public void setTarget(InstructionHandle ih) { + bi.setTarget(ih); + } - /* Override InstructionHandle methods: delegate to branch instruction. - * Through this overriding all access to the private i_position field should - * be prevented. - */ - public int getPosition() { - return bi.position; - } + /** + * Update target of instruction. + */ + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + bi.updateTarget(old_ih, new_ih); + } + /** + * @return target of instruction. + */ + public InstructionHandle getTarget() { + return bi.getTarget(); + } - void setPosition( int pos ) { - i_position = bi.position = pos; - } - - - protected int updatePosition( int offset, int max_offset ) { - int x = bi.updatePosition(offset, max_offset); - i_position = bi.position; - return x; - } - - - /** - * Pass new target to instruction. - */ - public void setTarget( InstructionHandle ih ) { - bi.setTarget(ih); - } - - - /** - * Update target of instruction. - */ - public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { - bi.updateTarget(old_ih, new_ih); - } - - - /** - * @return target of instruction. - */ - public InstructionHandle getTarget() { - return bi.getTarget(); - } - - - /** - * Set new contents. Old instruction is disposed and may not be used anymore. - */ - public void setInstruction( Instruction i ) { - super.setInstruction(i); - if (!(i instanceof BranchInstruction)) { - throw new ClassGenException("Assigning " + i - + " to branch handle which is not a branch instruction"); - } - bi = (BranchInstruction) i; - } + /** + * Set new contents. Old instruction is disposed and may not be used + * anymore. + */ + @Override + public void setInstruction(Instruction i) { + super.setInstruction(i); + if (!(i instanceof BranchInstruction)) { + throw new ClassGenException("Assigning " + i + + " to branch handle which is not a branch instruction"); + } + bi = (BranchInstruction) i; + } } diff --git a/src/org/apache/bcel/generic/BranchInstruction.java b/src/org/apache/bcel/generic/BranchInstruction.java index f62b831..2864a05 100644 --- a/src/org/apache/bcel/generic/BranchInstruction.java +++ b/src/org/apache/bcel/generic/BranchInstruction.java @@ -20,211 +20,230 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** - * Abstract super class for branching instructions like GOTO, IFEQ, etc.. - * Branch instructions may have a variable length, namely GOTO, JSR, - * LOOKUPSWITCH and TABLESWITCH. - * +/** + * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch + * instructions may have a variable length, namely GOTO, JSR, LOOKUPSWITCH and + * TABLESWITCH. + * * @see InstructionList * @version $Id: BranchInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class BranchInstruction extends Instruction implements InstructionTargeter { +public abstract class BranchInstruction extends Instruction implements + InstructionTargeter { - protected int index; // Branch target relative to this instruction - protected InstructionHandle target; // Target object in instruction list - protected int position; // Byte code offset + /** + * + */ + private static final long serialVersionUID = 1L; + protected int index; // Branch target relative to this instruction + protected InstructionHandle target; // Target object in instruction list + protected int position; // Byte code offset + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + BranchInstruction() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - BranchInstruction() { - } + /** + * Common super constructor + * + * @param opcode + * Instruction opcode + * @param target + * instruction to branch to + */ + protected BranchInstruction(short opcode, InstructionHandle target) { + super(opcode, (short) 3); + setTarget(target); + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + index = getTargetOffset(); + if (Math.abs(index) >= 32767) { + throw new ClassGenException( + "Branch target offset too large for short"); + } + out.writeShort(index); // May be negative, i.e., point backwards + } - /** Common super constructor - * @param opcode Instruction opcode - * @param target instruction to branch to - */ - protected BranchInstruction(short opcode, InstructionHandle target) { - super(opcode, (short) 3); - setTarget(target); - } + /** + * @param _target + * branch target + * @return the offset to `target' relative to this instruction + */ + protected int getTargetOffset(InstructionHandle _target) { + if (_target == null) { + throw new ClassGenException("Target of " + super.toString(true) + + " is invalid null handle"); + } + int t = _target.getPosition(); + if (t < 0) { + throw new ClassGenException( + "Invalid branch target position offset for " + + super.toString(true) + ":" + t + ":" + _target); + } + return t - position; + } + /** + * @return the offset to this instruction's target + */ + protected int getTargetOffset() { + return getTargetOffset(target); + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); - index = getTargetOffset(); - if (Math.abs(index) >= 32767) { - throw new ClassGenException("Branch target offset too large for short"); - } - out.writeShort(index); // May be negative, i.e., point backwards - } + /** + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset + * additional offset caused by preceding (variable length) + * instructions + * @param max_offset + * the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + protected int updatePosition(int offset, int max_offset) { + position += offset; + return 0; + } + /** + * Long output format: + * + * <position in byte code> <name of opcode> "["<opcode + * number>"]" "("<length of instruction>")" "<"<target + * instruction>">" "@"<branch target offset> + * + * @param verbose + * long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + String s = super.toString(verbose); + String t = "null"; + if (verbose) { + if (target != null) { + if (target.getInstruction() == this) { + t = ""; + } else if (target.getInstruction() == null) { + t = ""; + } else { + t = target.getInstruction().toString(false); // Avoid + // circles + } + } + } else { + if (target != null) { + index = getTargetOffset(); + t = "" + (index + position); + } + } + return s + " -> " + t; + } - /** - * @param _target branch target - * @return the offset to `target' relative to this instruction - */ - protected int getTargetOffset( InstructionHandle _target ) { - if (_target == null) { - throw new ClassGenException("Target of " + super.toString(true) - + " is invalid null handle"); - } - int t = _target.getPosition(); - if (t < 0) { - throw new ClassGenException("Invalid branch target position offset for " - + super.toString(true) + ":" + t + ":" + _target); - } - return t - position; - } + /** + * Read needed data (e.g. index) from file. Conversion to a + * InstructionHandle is done in InstructionList(byte[]). + * + * @param bytes + * input stream + * @param wide + * wide prefix? + * @see InstructionList + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + length = 3; + index = bytes.readShort(); + } + /** + * @return target offset in byte code + */ + public final int getIndex() { + return index; + } - /** - * @return the offset to this instruction's target - */ - protected int getTargetOffset() { - return getTargetOffset(target); - } + /** + * @return target of branch instruction + */ + public InstructionHandle getTarget() { + return target; + } + /** + * Set branch target + * + * @param target + * branch target + */ + public void setTarget(InstructionHandle target) { + notifyTarget(this.target, target, this); + this.target = target; + } - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition( int offset, int max_offset ) { - position += offset; - return 0; - } + /** + * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen + */ + static final void notifyTarget(InstructionHandle old_ih, + InstructionHandle new_ih, InstructionTargeter t) { + if (old_ih != null) { + old_ih.removeTargeter(t); + } + if (new_ih != null) { + new_ih.addTargeter(t); + } + } + /** + * @param old_ih + * old target + * @param new_ih + * new target + */ + @Override + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + if (target == old_ih) { + setTarget(new_ih); + } else { + throw new ClassGenException("Not targeting " + old_ih + ", but " + + target); + } + } - /** - * Long output format: - * - * <position in byte code> - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" - * "<"<target instruction>">" "@"<branch target offset> - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - String s = super.toString(verbose); - String t = "null"; - if (verbose) { - if (target != null) { - if (target.getInstruction() == this) { - t = ""; - } else if (target.getInstruction() == null) { - t = ""; - } else { - t = target.getInstruction().toString(false); // Avoid circles - } - } - } else { - if (target != null) { - index = getTargetOffset(); - t = "" + (index + position); - } - } - return s + " -> " + t; - } + /** + * @return true, if ih is target of this instruction + */ + @Override + public boolean containsTarget(InstructionHandle ih) { + return (target == ih); + } - - /** - * Read needed data (e.g. index) from file. Conversion to a InstructionHandle - * is done in InstructionList(byte[]). - * - * @param bytes input stream - * @param wide wide prefix? - * @see InstructionList - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - length = 3; - index = bytes.readShort(); - } - - - /** - * @return target offset in byte code - */ - public final int getIndex() { - return index; - } - - - /** - * @return target of branch instruction - */ - public InstructionHandle getTarget() { - return target; - } - - - /** - * Set branch target - * @param target branch target - */ - public void setTarget( InstructionHandle target ) { - notifyTarget(this.target, target, this); - this.target = target; - } - - - /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen - */ - static final void notifyTarget( InstructionHandle old_ih, InstructionHandle new_ih, - InstructionTargeter t ) { - if (old_ih != null) { - old_ih.removeTargeter(t); - } - if (new_ih != null) { - new_ih.addTargeter(t); - } - } - - - /** - * @param old_ih old target - * @param new_ih new target - */ - public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { - if (target == old_ih) { - setTarget(new_ih); - } else { - throw new ClassGenException("Not targeting " + old_ih + ", but " + target); - } - } - - - /** - * @return true, if ih is target of this instruction - */ - public boolean containsTarget( InstructionHandle ih ) { - return (target == ih); - } - - - /** - * Inform target that it's not targeted anymore. - */ - void dispose() { - setTarget(null); - index = -1; - position = -1; - } + /** + * Inform target that it's not targeted anymore. + */ + @Override + void dispose() { + setTarget(null); + index = -1; + position = -1; + } } diff --git a/src/org/apache/bcel/generic/CALOAD.java b/src/org/apache/bcel/generic/CALOAD.java index c3b1f31..50839af 100644 --- a/src/org/apache/bcel/generic/CALOAD.java +++ b/src/org/apache/bcel/generic/CALOAD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * CALOAD - Load char from array - *
          Stack: ..., arrayref, index -> ..., value
          - * + * + *
          + * Stack: ..., arrayref, index -> ..., value
          + * 
          + * * @version $Id: CALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class CALOAD extends ArrayInstruction implements StackProducer { - /** Load char from array - */ - public CALOAD() { - super(org.apache.bcel.Constants.CALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Load char from array + */ + public CALOAD() { + super(org.apache.bcel.Constants.CALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitCALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitCALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/CASTORE.java b/src/org/apache/bcel/generic/CASTORE.java index f293881..77d1c34 100644 --- a/src/org/apache/bcel/generic/CASTORE.java +++ b/src/org/apache/bcel/generic/CASTORE.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * CASTORE - Store into char array - *
          Stack: ..., arrayref, index, value -> ...
          - * +/** + * CASTORE - Store into char array + * + *
          + * Stack: ..., arrayref, index, value -> ...
          + * 
          + * * @version $Id: CASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class CASTORE extends ArrayInstruction implements StackConsumer { - /** Store char into array - */ - public CASTORE() { - super(org.apache.bcel.Constants.CASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Store char into array + */ + public CASTORE() { + super(org.apache.bcel.Constants.CASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitCASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitCASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/CHECKCAST.java b/src/org/apache/bcel/generic/CHECKCAST.java index 7f6cfe3..08882b1 100644 --- a/src/org/apache/bcel/generic/CHECKCAST.java +++ b/src/org/apache/bcel/generic/CHECKCAST.java @@ -18,67 +18,81 @@ package org.apache.bcel.generic; import org.apache.bcel.ExceptionConstants; -/** +/** * CHECKCAST - Check whether object is of given type - *
          Stack: ..., objectref -> ..., objectref
          - * + * + *
          + * Stack: ..., objectref -> ..., objectref
          + * 
          + * * @version $Id: CHECKCAST.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer, - StackConsumer { +public class CHECKCAST extends CPInstruction implements LoadClass, + ExceptionThrower, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - CHECKCAST() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + CHECKCAST() { + } - /** Check whether object is of given type - * @param index index to class in constant pool - */ - public CHECKCAST(int index) { - super(org.apache.bcel.Constants.CHECKCAST, index); - } + /** + * Check whether object is of given type + * + * @param index + * index to class in constant pool + */ + public CHECKCAST(int index) { + super(org.apache.bcel.Constants.CHECKCAST, index); + } + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; + System.arraycopy( + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, + 0, + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.CLASS_CAST_EXCEPTION; + return cs; + } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.CLASS_CAST_EXCEPTION; - return cs; - } + @Override + public ObjectType getLoadClassType(ConstantPoolGen cpg) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } - - public ObjectType getLoadClassType( ConstantPoolGen cpg ) { - Type t = getType(cpg); - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - return (t instanceof ObjectType) ? (ObjectType) t : null; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLoadClass(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitCHECKCAST(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLoadClass(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitCHECKCAST(this); + } } diff --git a/src/org/apache/bcel/generic/CPInstruction.java b/src/org/apache/bcel/generic/CPInstruction.java index 9f988f9..6efe659 100644 --- a/src/org/apache/bcel/generic/CPInstruction.java +++ b/src/org/apache/bcel/generic/CPInstruction.java @@ -23,116 +23,130 @@ import org.apache.bcel.classfile.ConstantClass; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.util.ByteSequence; -/** - * Abstract super class for instructions that use an index into the - * constant pool such as LDC, INVOKEVIRTUAL, etc. - * +/** + * Abstract super class for instructions that use an index into the constant + * pool such as LDC, INVOKEVIRTUAL, etc. + * * @see ConstantPoolGen * @see LDC * @see INVOKEVIRTUAL - * + * * @version $Id: CPInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class CPInstruction extends Instruction implements TypedInstruction, - IndexedInstruction { +public abstract class CPInstruction extends Instruction implements + TypedInstruction, IndexedInstruction { - protected int index; // index to constant pool + /** + * + */ + private static final long serialVersionUID = 1L; + protected int index; // index to constant pool + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + CPInstruction() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - CPInstruction() { - } + /** + * @param index + * to constant pool + */ + protected CPInstruction(short opcode, int index) { + super(opcode, (short) 3); + setIndex(index); + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeShort(index); + } - /** - * @param index to constant pool - */ - protected CPInstruction(short opcode, int index) { - super(opcode, (short) 3); - setIndex(index); - } + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" "<"< constant pool index>">" + * + * @param verbose + * long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + index; + } + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(ConstantPool cp) { + Constant c = cp.getConstant(index); + String str = cp.constantToString(c); + if (c instanceof ConstantClass) { + str = str.replace('.', '/'); + } + return org.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str; + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - } + /** + * Read needed data (i.e., index) from file. + * + * @param bytes + * input stream + * @param wide + * wide prefix? + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + setIndex(bytes.readUnsignedShort()); + length = 3; + } + /** + * @return index in constant pool referred by this instruction. + */ + @Override + public final int getIndex() { + return index; + } - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< constant pool index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - return super.toString(verbose) + " " + index; - } + /** + * Set the index to constant pool. + * + * @param index + * in constant pool. + */ + @Override + public void setIndex(int index) { + if (index < 0) { + throw new ClassGenException("Negative index value: " + index); + } + this.index = index; + } - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString( ConstantPool cp ) { - Constant c = cp.getConstant(index); - String str = cp.constantToString(c); - if (c instanceof ConstantClass) { - str = str.replace('.', '/'); - } - return org.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str; - } - - - /** - * Read needed data (i.e., index) from file. - * @param bytes input stream - * @param wide wide prefix? - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - setIndex(bytes.readUnsignedShort()); - length = 3; - } - - - /** - * @return index in constant pool referred by this instruction. - */ - public final int getIndex() { - return index; - } - - - /** - * Set the index to constant pool. - * @param index in constant pool. - */ - public void setIndex( int index ) { - if (index < 0) { - throw new ClassGenException("Negative index value: " + index); - } - this.index = index; - } - - - /** @return type related with this instruction. - */ - public Type getType( ConstantPoolGen cpg ) { - ConstantPool cp = cpg.getConstantPool(); - String name = cp.getConstantString(index, org.apache.bcel.Constants.CONSTANT_Class); - if (!name.startsWith("[")) { - name = "L" + name + ";"; - } - return Type.getType(name); - } + /** + * @return type related with this instruction. + */ + @Override + public Type getType(ConstantPoolGen cpg) { + ConstantPool cp = cpg.getConstantPool(); + String name = cp.getConstantString(index, + org.apache.bcel.Constants.CONSTANT_Class); + if (!name.startsWith("[")) { + name = "L" + name + ";"; + } + return Type.getType(name); + } } diff --git a/src/org/apache/bcel/generic/ClassGen.java b/src/org/apache/bcel/generic/ClassGen.java index 14c48d3..c9d3d14 100644 --- a/src/org/apache/bcel/generic/ClassGen.java +++ b/src/org/apache/bcel/generic/ClassGen.java @@ -19,6 +19,7 @@ package org.apache.bcel.generic; import java.util.ArrayList; import java.util.Iterator; import java.util.List; + import org.apache.bcel.Constants; import org.apache.bcel.classfile.AccessFlags; import org.apache.bcel.classfile.Attribute; @@ -29,513 +30,527 @@ import org.apache.bcel.classfile.Method; import org.apache.bcel.classfile.SourceFile; import org.apache.bcel.util.BCELComparator; -/** +/** * Template class for building up a java class. May be initialized with an * existing java class (file). - * + * * @see JavaClass * @version $Id: ClassGen.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ClassGen extends AccessFlags implements Cloneable { - /* Corresponds to the fields found in a JavaClass object. - */ - private String class_name, super_class_name, file_name; - private int class_name_index = -1, superclass_name_index = -1; - private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1; - private ConstantPoolGen cp; // Template for building up constant pool - // ArrayLists instead of arrays to gather fields, methods, etc. - private List field_vec = new ArrayList(); - private List method_vec = new ArrayList(); - private List attribute_vec = new ArrayList(); - private List interface_vec = new ArrayList(); - private static BCELComparator _cmp = new BCELComparator() { - - public boolean equals( Object o1, Object o2 ) { - ClassGen THIS = (ClassGen) o1; - ClassGen THAT = (ClassGen) o2; - return THIS.getClassName().equals(THAT.getClassName()); - } - - - public int hashCode( Object o ) { - ClassGen THIS = (ClassGen) o; - return THIS.getClassName().hashCode(); - } - }; - - - /** Convenience constructor to set up some important values initially. - * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers - * @param interfaces implemented interfaces - * @param cp constant pool to use - */ - public ClassGen(String class_name, String super_class_name, String file_name, int access_flags, - String[] interfaces, ConstantPoolGen cp) { - this.class_name = class_name; - this.super_class_name = super_class_name; - this.file_name = file_name; - this.access_flags = access_flags; - this.cp = cp; - // Put everything needed by default into the constant pool and the vectors - if (file_name != null) { - addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp - .getConstantPool())); - } - class_name_index = cp.addClass(class_name); - superclass_name_index = cp.addClass(super_class_name); - if (interfaces != null) { - for (int i = 0; i < interfaces.length; i++) { - addInterface(interfaces[i]); - } - } - } - - - /** Convenience constructor to set up some important values initially. - * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers - * @param interfaces implemented interfaces - */ - public ClassGen(String class_name, String super_class_name, String file_name, int access_flags, - String[] interfaces) { - this(class_name, super_class_name, file_name, access_flags, interfaces, - new ConstantPoolGen()); - } - - - /** - * Initialize with existing class. - * @param clazz JavaClass object (e.g. read from file) - */ - public ClassGen(JavaClass clazz) { - class_name_index = clazz.getClassNameIndex(); - superclass_name_index = clazz.getSuperclassNameIndex(); - class_name = clazz.getClassName(); - super_class_name = clazz.getSuperclassName(); - file_name = clazz.getSourceFileName(); - access_flags = clazz.getAccessFlags(); - cp = new ConstantPoolGen(clazz.getConstantPool()); - major = clazz.getMajor(); - minor = clazz.getMinor(); - Attribute[] attributes = clazz.getAttributes(); - Method[] methods = clazz.getMethods(); - Field[] fields = clazz.getFields(); - String[] interfaces = clazz.getInterfaceNames(); - for (int i = 0; i < interfaces.length; i++) { - addInterface(interfaces[i]); - } - for (int i = 0; i < attributes.length; i++) { - addAttribute(attributes[i]); - } - for (int i = 0; i < methods.length; i++) { - addMethod(methods[i]); - } - for (int i = 0; i < fields.length; i++) { - addField(fields[i]); - } - } - - - /** - * @return the (finally) built up Java class object. - */ - public JavaClass getJavaClass() { - int[] interfaces = getInterfaces(); - Field[] fields = getFields(); - Method[] methods = getMethods(); - Attribute[] attributes = getAttributes(); - // Must be last since the above calls may still add something to it - ConstantPool _cp = this.cp.getFinalConstantPool(); - return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, - access_flags, _cp, interfaces, fields, methods, attributes); - } - - - /** - * Add an interface to this class, i.e., this class has to implement it. - * @param name interface to implement (fully qualified class name) - */ - public void addInterface( String name ) { - interface_vec.add(name); - } - - - /** - * Remove an interface from this class. - * @param name interface to remove (fully qualified name) - */ - public void removeInterface( String name ) { - interface_vec.remove(name); - } - - - /** - * @return major version number of class file - */ - public int getMajor() { - return major; - } - - - /** Set major version number of class file, default value is 45 (JDK 1.1) - * @param major major version number - */ - public void setMajor( int major ) { - this.major = major; - } - - - /** Set minor version number of class file, default value is 3 (JDK 1.1) - * @param minor minor version number - */ - public void setMinor( int minor ) { - this.minor = minor; - } - - - /** - * @return minor version number of class file - */ - public int getMinor() { - return minor; - } - - - /** - * Add an attribute to this class. - * @param a attribute to add - */ - public void addAttribute( Attribute a ) { - attribute_vec.add(a); - } - - - /** - * Add a method to this class. - * @param m method to add - */ - public void addMethod( Method m ) { - method_vec.add(m); - } - - - /** - * Convenience method. - * - * Add an empty constructor to this class that does nothing but calling super(). - * @param access_flags rights for constructor - */ - public void addEmptyConstructor( int access_flags ) { - InstructionList il = new InstructionList(); - il.append(InstructionConstants.THIS); // Push `this' - il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "", "()V"))); - il.append(InstructionConstants.RETURN); - MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "", - class_name, il, cp); - mg.setMaxStack(1); - addMethod(mg.getMethod()); - } - - - /** - * Add a field to this class. - * @param f field to add - */ - public void addField( Field f ) { - field_vec.add(f); - } - - - public boolean containsField( Field f ) { - return field_vec.contains(f); - } - - - /** @return field object with given name, or null - */ - public Field containsField( String name ) { - for (Iterator e = field_vec.iterator(); e.hasNext();) { - Field f = (Field) e.next(); - if (f.getName().equals(name)) { - return f; - } - } - return null; - } - - - /** @return method object with given name and signature, or null - */ - public Method containsMethod( String name, String signature ) { - for (Iterator e = method_vec.iterator(); e.hasNext();) { - Method m = (Method) e.next(); - if (m.getName().equals(name) && m.getSignature().equals(signature)) { - return m; - } - } - return null; - } - - - /** - * Remove an attribute from this class. - * @param a attribute to remove - */ - public void removeAttribute( Attribute a ) { - attribute_vec.remove(a); - } - - - /** - * Remove a method from this class. - * @param m method to remove - */ - public void removeMethod( Method m ) { - method_vec.remove(m); - } - - - /** Replace given method with new one. If the old one does not exist - * add the new_ method to the class anyway. - */ - public void replaceMethod( Method old, Method new_ ) { - if (new_ == null) { - throw new ClassGenException("Replacement method must not be null"); - } - int i = method_vec.indexOf(old); - if (i < 0) { - method_vec.add(new_); - } else { - method_vec.set(i, new_); - } - } - - - /** Replace given field with new one. If the old one does not exist - * add the new_ field to the class anyway. - */ - public void replaceField( Field old, Field new_ ) { - if (new_ == null) { - throw new ClassGenException("Replacement method must not be null"); - } - int i = field_vec.indexOf(old); - if (i < 0) { - field_vec.add(new_); - } else { - field_vec.set(i, new_); - } - } - - - /** - * Remove a field to this class. - * @param f field to remove - */ - public void removeField( Field f ) { - field_vec.remove(f); - } - - - public String getClassName() { - return class_name; - } - - - public String getSuperclassName() { - return super_class_name; - } - - - public String getFileName() { - return file_name; - } - - - public void setClassName( String name ) { - class_name = name.replace('/', '.'); - class_name_index = cp.addClass(name); - } - - - public void setSuperclassName( String name ) { - super_class_name = name.replace('/', '.'); - superclass_name_index = cp.addClass(name); - } - - - public Method[] getMethods() { - return (Method[]) method_vec.toArray(new Method[method_vec.size()]); - } - - - public void setMethods( Method[] methods ) { - method_vec.clear(); - for (int m = 0; m < methods.length; m++) { - addMethod(methods[m]); - } - } - - - public void setMethodAt( Method method, int pos ) { - method_vec.set(pos, method); - } - - - public Method getMethodAt( int pos ) { - return (Method) method_vec.get(pos); - } - - - public String[] getInterfaceNames() { - int size = interface_vec.size(); - String[] interfaces = new String[size]; - interface_vec.toArray(interfaces); - return interfaces; - } - - - public int[] getInterfaces() { - int size = interface_vec.size(); - int[] interfaces = new int[size]; - for (int i = 0; i < size; i++) { - interfaces[i] = cp.addClass((String) interface_vec.get(i)); - } - return interfaces; - } - - - public Field[] getFields() { - return (Field[]) field_vec.toArray(new Field[field_vec.size()]); - } - - - public Attribute[] getAttributes() { - return (Attribute[]) attribute_vec.toArray(new Attribute[attribute_vec.size()]); - } - - - public ConstantPoolGen getConstantPool() { - return cp; - } - - - public void setConstantPool( ConstantPoolGen constant_pool ) { - cp = constant_pool; - } - - - public void setClassNameIndex( int class_name_index ) { - this.class_name_index = class_name_index; - class_name = cp.getConstantPool().getConstantString(class_name_index, - Constants.CONSTANT_Class).replace('/', '.'); - } - - - public void setSuperclassNameIndex( int superclass_name_index ) { - this.superclass_name_index = superclass_name_index; - super_class_name = cp.getConstantPool().getConstantString(superclass_name_index, - Constants.CONSTANT_Class).replace('/', '.'); - } - - - public int getSuperclassNameIndex() { - return superclass_name_index; - } - - - public int getClassNameIndex() { - return class_name_index; - } - - private ArrayList observers; - - - /** Add observer for this object. - */ - public void addObserver( ClassObserver o ) { - if (observers == null) { - observers = new ArrayList(); - } - observers.add(o); - } - - - /** Remove observer for this object. - */ - public void removeObserver( ClassObserver o ) { - if (observers != null) { - observers.remove(o); - } - } - - - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if (observers != null) { - for (Iterator e = observers.iterator(); e.hasNext();) { - ((ClassObserver) e.next()).notify(this); - } - } - } - - - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return _cmp; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( BCELComparator comparator ) { - _cmp = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two ClassGen objects are said to be equal when - * their class names are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals( Object obj ) { - return _cmp.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the class name. - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return _cmp.hashCode(this); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /* + * Corresponds to the fields found in a JavaClass object. + */ + private String class_name, super_class_name, file_name; + private int class_name_index = -1, superclass_name_index = -1; + private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1; + private ConstantPoolGen cp; // Template for building up constant pool + // ArrayLists instead of arrays to gather fields, methods, etc. + private List field_vec = new ArrayList(); + private List method_vec = new ArrayList(); + private List attribute_vec = new ArrayList(); + private List interface_vec = new ArrayList(); + private static BCELComparator _cmp = new BCELComparator() { + + @Override + public boolean equals(Object o1, Object o2) { + ClassGen THIS = (ClassGen) o1; + ClassGen THAT = (ClassGen) o2; + return THIS.getClassName().equals(THAT.getClassName()); + } + + @Override + public int hashCode(Object o) { + ClassGen THIS = (ClassGen) o; + return THIS.getClassName().hashCode(); + } + }; + + /** + * Convenience constructor to set up some important values initially. + * + * @param class_name + * fully qualified class name + * @param super_class_name + * fully qualified superclass name + * @param file_name + * source file name + * @param access_flags + * access qualifiers + * @param interfaces + * implemented interfaces + * @param cp + * constant pool to use + */ + public ClassGen(String class_name, String super_class_name, + String file_name, int access_flags, String[] interfaces, + ConstantPoolGen cp) { + this.class_name = class_name; + this.super_class_name = super_class_name; + this.file_name = file_name; + this.access_flags = access_flags; + this.cp = cp; + // Put everything needed by default into the constant pool and the + // vectors + if (file_name != null) { + addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, + cp.addUtf8(file_name), cp.getConstantPool())); + } + class_name_index = cp.addClass(class_name); + superclass_name_index = cp.addClass(super_class_name); + if (interfaces != null) { + for (int i = 0; i < interfaces.length; i++) { + addInterface(interfaces[i]); + } + } + } + + /** + * Convenience constructor to set up some important values initially. + * + * @param class_name + * fully qualified class name + * @param super_class_name + * fully qualified superclass name + * @param file_name + * source file name + * @param access_flags + * access qualifiers + * @param interfaces + * implemented interfaces + */ + public ClassGen(String class_name, String super_class_name, + String file_name, int access_flags, String[] interfaces) { + this(class_name, super_class_name, file_name, access_flags, interfaces, + new ConstantPoolGen()); + } + + /** + * Initialize with existing class. + * + * @param clazz + * JavaClass object (e.g. read from file) + */ + public ClassGen(JavaClass clazz) { + class_name_index = clazz.getClassNameIndex(); + superclass_name_index = clazz.getSuperclassNameIndex(); + class_name = clazz.getClassName(); + super_class_name = clazz.getSuperclassName(); + file_name = clazz.getSourceFileName(); + access_flags = clazz.getAccessFlags(); + cp = new ConstantPoolGen(clazz.getConstantPool()); + major = clazz.getMajor(); + minor = clazz.getMinor(); + Attribute[] attributes = clazz.getAttributes(); + Method[] methods = clazz.getMethods(); + Field[] fields = clazz.getFields(); + String[] interfaces = clazz.getInterfaceNames(); + for (int i = 0; i < interfaces.length; i++) { + addInterface(interfaces[i]); + } + for (int i = 0; i < attributes.length; i++) { + addAttribute(attributes[i]); + } + for (int i = 0; i < methods.length; i++) { + addMethod(methods[i]); + } + for (int i = 0; i < fields.length; i++) { + addField(fields[i]); + } + } + + /** + * @return the (finally) built up Java class object. + */ + public JavaClass getJavaClass() { + int[] interfaces = getInterfaces(); + Field[] fields = getFields(); + Method[] methods = getMethods(); + Attribute[] attributes = getAttributes(); + // Must be last since the above calls may still add something to it + ConstantPool _cp = this.cp.getFinalConstantPool(); + return new JavaClass(class_name_index, superclass_name_index, + file_name, major, minor, access_flags, _cp, interfaces, fields, + methods, attributes); + } + + /** + * Add an interface to this class, i.e., this class has to implement it. + * + * @param name + * interface to implement (fully qualified class name) + */ + public void addInterface(String name) { + interface_vec.add(name); + } + + /** + * Remove an interface from this class. + * + * @param name + * interface to remove (fully qualified name) + */ + public void removeInterface(String name) { + interface_vec.remove(name); + } + + /** + * @return major version number of class file + */ + public int getMajor() { + return major; + } + + /** + * Set major version number of class file, default value is 45 (JDK 1.1) + * + * @param major + * major version number + */ + public void setMajor(int major) { + this.major = major; + } + + /** + * Set minor version number of class file, default value is 3 (JDK 1.1) + * + * @param minor + * minor version number + */ + public void setMinor(int minor) { + this.minor = minor; + } + + /** + * @return minor version number of class file + */ + public int getMinor() { + return minor; + } + + /** + * Add an attribute to this class. + * + * @param a + * attribute to add + */ + public void addAttribute(Attribute a) { + attribute_vec.add(a); + } + + /** + * Add a method to this class. + * + * @param m + * method to add + */ + public void addMethod(Method m) { + method_vec.add(m); + } + + /** + * Convenience method. + * + * Add an empty constructor to this class that does nothing but calling + * super(). + * + * @param access_flags + * rights for constructor + */ + public void addEmptyConstructor(int access_flags) { + InstructionList il = new InstructionList(); + il.append(InstructionConstants.THIS); // Push `this' + il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "", + "()V"))); + il.append(InstructionConstants.RETURN); + MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, + null, "", class_name, il, cp); + mg.setMaxStack(1); + addMethod(mg.getMethod()); + } + + /** + * Add a field to this class. + * + * @param f + * field to add + */ + public void addField(Field f) { + field_vec.add(f); + } + + public boolean containsField(Field f) { + return field_vec.contains(f); + } + + /** + * @return field object with given name, or null + */ + public Field containsField(String name) { + for (Iterator e = field_vec.iterator(); e.hasNext();) { + Field f = e.next(); + if (f.getName().equals(name)) { + return f; + } + } + return null; + } + + /** + * @return method object with given name and signature, or null + */ + public Method containsMethod(String name, String signature) { + for (Iterator e = method_vec.iterator(); e.hasNext();) { + Method m = e.next(); + if (m.getName().equals(name) && m.getSignature().equals(signature)) { + return m; + } + } + return null; + } + + /** + * Remove an attribute from this class. + * + * @param a + * attribute to remove + */ + public void removeAttribute(Attribute a) { + attribute_vec.remove(a); + } + + /** + * Remove a method from this class. + * + * @param m + * method to remove + */ + public void removeMethod(Method m) { + method_vec.remove(m); + } + + /** + * Replace given method with new one. If the old one does not exist add the + * new_ method to the class anyway. + */ + public void replaceMethod(Method old, Method new_) { + if (new_ == null) { + throw new ClassGenException("Replacement method must not be null"); + } + int i = method_vec.indexOf(old); + if (i < 0) { + method_vec.add(new_); + } else { + method_vec.set(i, new_); + } + } + + /** + * Replace given field with new one. If the old one does not exist add the + * new_ field to the class anyway. + */ + public void replaceField(Field old, Field new_) { + if (new_ == null) { + throw new ClassGenException("Replacement method must not be null"); + } + int i = field_vec.indexOf(old); + if (i < 0) { + field_vec.add(new_); + } else { + field_vec.set(i, new_); + } + } + + /** + * Remove a field to this class. + * + * @param f + * field to remove + */ + public void removeField(Field f) { + field_vec.remove(f); + } + + public String getClassName() { + return class_name; + } + + public String getSuperclassName() { + return super_class_name; + } + + public String getFileName() { + return file_name; + } + + public void setClassName(String name) { + class_name = name.replace('/', '.'); + class_name_index = cp.addClass(name); + } + + public void setSuperclassName(String name) { + super_class_name = name.replace('/', '.'); + superclass_name_index = cp.addClass(name); + } + + public Method[] getMethods() { + return method_vec.toArray(new Method[method_vec.size()]); + } + + public void setMethods(Method[] methods) { + method_vec.clear(); + for (int m = 0; m < methods.length; m++) { + addMethod(methods[m]); + } + } + + public void setMethodAt(Method method, int pos) { + method_vec.set(pos, method); + } + + public Method getMethodAt(int pos) { + return method_vec.get(pos); + } + + public String[] getInterfaceNames() { + int size = interface_vec.size(); + String[] interfaces = new String[size]; + interface_vec.toArray(interfaces); + return interfaces; + } + + public int[] getInterfaces() { + int size = interface_vec.size(); + int[] interfaces = new int[size]; + for (int i = 0; i < size; i++) { + interfaces[i] = cp.addClass(interface_vec.get(i)); + } + return interfaces; + } + + public Field[] getFields() { + return field_vec.toArray(new Field[field_vec.size()]); + } + + public Attribute[] getAttributes() { + return attribute_vec.toArray(new Attribute[attribute_vec.size()]); + } + + public ConstantPoolGen getConstantPool() { + return cp; + } + + public void setConstantPool(ConstantPoolGen constant_pool) { + cp = constant_pool; + } + + public void setClassNameIndex(int class_name_index) { + this.class_name_index = class_name_index; + class_name = cp.getConstantPool() + .getConstantString(class_name_index, Constants.CONSTANT_Class) + .replace('/', '.'); + } + + public void setSuperclassNameIndex(int superclass_name_index) { + this.superclass_name_index = superclass_name_index; + super_class_name = cp + .getConstantPool() + .getConstantString(superclass_name_index, + Constants.CONSTANT_Class).replace('/', '.'); + } + + public int getSuperclassNameIndex() { + return superclass_name_index; + } + + public int getClassNameIndex() { + return class_name_index; + } + + private ArrayList observers; + + /** + * Add observer for this object. + */ + public void addObserver(ClassObserver o) { + if (observers == null) { + observers = new ArrayList(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(ClassObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (Iterator e = observers.iterator(); e.hasNext();) { + e.next().notify(this); + } + } + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + + /** + * @param comparator + * Comparison strategy object + */ + public static void setComparator(BCELComparator comparator) { + _cmp = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * ClassGen objects are said to be equal when their class names are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return _cmp.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the class name. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); + } } diff --git a/src/org/apache/bcel/generic/ClassGenException.java b/src/org/apache/bcel/generic/ClassGenException.java index c2d404d..8848b1b 100644 --- a/src/org/apache/bcel/generic/ClassGenException.java +++ b/src/org/apache/bcel/generic/ClassGenException.java @@ -16,21 +16,25 @@ */ package org.apache.bcel.generic; -/** - * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared - * in the throws clause every time. - * +/** + * Thrown on internal errors. Extends RuntimeException so it hasn't to be + * declared in the throws clause every time. + * * @version $Id: ClassGenException.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ClassGenException extends RuntimeException { - public ClassGenException() { - super(); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public ClassGenException() { + super(); + } - public ClassGenException(String s) { - super(s); - } + public ClassGenException(String s) { + super(s); + } } diff --git a/src/org/apache/bcel/generic/ClassObserver.java b/src/org/apache/bcel/generic/ClassObserver.java index e223d80..ce63df1 100644 --- a/src/org/apache/bcel/generic/ClassObserver.java +++ b/src/org/apache/bcel/generic/ClassObserver.java @@ -19,11 +19,11 @@ package org.apache.bcel.generic; /** * Implement this interface if you're interested in changes to a ClassGen object * and register yourself with addObserver(). - * + * * @version $Id: ClassObserver.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface ClassObserver { - public void notify( ClassGen clazz ); + public void notify(ClassGen clazz); } diff --git a/src/org/apache/bcel/generic/CodeExceptionGen.java b/src/org/apache/bcel/generic/CodeExceptionGen.java index 559993a..5ccfba0 100644 --- a/src/org/apache/bcel/generic/CodeExceptionGen.java +++ b/src/org/apache/bcel/generic/CodeExceptionGen.java @@ -18,167 +18,181 @@ package org.apache.bcel.generic; import org.apache.bcel.classfile.CodeException; -/** - * This class represents an exception handler, i.e., specifies the region where +/** + * This class represents an exception handler, i.e., specifies the region where * a handler is active and an instruction where the actual handling is done. * pool as parameters. Opposed to the JVM specification the end of the handled * region is set to be inclusive, i.e. all instructions between start and end * are protected including the start and end instructions (handles) themselves. * The end of the region is automatically mapped to be exclusive when calling * getCodeException(), i.e., there is no difference semantically. - * + * * @version $Id: CodeExceptionGen.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see MethodGen - * @see CodeException - * @see InstructionHandle + * @author M. Dahm + * @see MethodGen + * @see CodeException + * @see InstructionHandle */ -public final class CodeExceptionGen implements InstructionTargeter, Cloneable, java.io.Serializable { +public final class CodeExceptionGen implements InstructionTargeter, Cloneable, + java.io.Serializable { - private InstructionHandle start_pc; - private InstructionHandle end_pc; - private InstructionHandle handler_pc; - private ObjectType catch_type; + /** + * + */ + private static final long serialVersionUID = 1L; + private InstructionHandle start_pc; + private InstructionHandle end_pc; + private InstructionHandle handler_pc; + private ObjectType catch_type; + /** + * Add an exception handler, i.e., specify region where a handler is active + * and an instruction where the actual handling is done. + * + * @param start_pc + * Start of handled region (inclusive) + * @param end_pc + * End of handled region (inclusive) + * @param handler_pc + * Where handling is done + * @param catch_type + * which exception is handled, null for ANY + */ + public CodeExceptionGen(InstructionHandle start_pc, + InstructionHandle end_pc, InstructionHandle handler_pc, + ObjectType catch_type) { + setStartPC(start_pc); + setEndPC(end_pc); + setHandlerPC(handler_pc); + this.catch_type = catch_type; + } - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. - * - * @param start_pc Start of handled region (inclusive) - * @param end_pc End of handled region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type which exception is handled, null for ANY - */ - public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc, - InstructionHandle handler_pc, ObjectType catch_type) { - setStartPC(start_pc); - setEndPC(end_pc); - setHandlerPC(handler_pc); - this.catch_type = catch_type; - } + /** + * Get CodeException object.
          + * + * This relies on that the instruction list has already been dumped to byte + * code or or that the `setPositions' methods has been called for the + * instruction list. + * + * @param cp + * constant pool + */ + public CodeException getCodeException(ConstantPoolGen cp) { + return new CodeException(start_pc.getPosition(), end_pc.getPosition() + + end_pc.getInstruction().getLength(), + handler_pc.getPosition(), (catch_type == null) ? 0 + : cp.addClass(catch_type)); + } + /* + * Set start of handler + * + * @param start_pc Start of handled region (inclusive) + */ + public void setStartPC(InstructionHandle start_pc) { + BranchInstruction.notifyTarget(this.start_pc, start_pc, this); + this.start_pc = start_pc; + } - /** - * Get CodeException object.
          - * - * This relies on that the instruction list has already been dumped - * to byte code or or that the `setPositions' methods has been - * called for the instruction list. - * - * @param cp constant pool - */ - public CodeException getCodeException( ConstantPoolGen cp ) { - return new CodeException(start_pc.getPosition(), end_pc.getPosition() - + end_pc.getInstruction().getLength(), handler_pc.getPosition(), - (catch_type == null) ? 0 : cp.addClass(catch_type)); - } + /* + * Set end of handler + * + * @param end_pc End of handled region (inclusive) + */ + public void setEndPC(InstructionHandle end_pc) { + BranchInstruction.notifyTarget(this.end_pc, end_pc, this); + this.end_pc = end_pc; + } + /* + * Set handler code + * + * @param handler_pc Start of handler + */ + public void setHandlerPC(InstructionHandle handler_pc) { + BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this); + this.handler_pc = handler_pc; + } - /* Set start of handler - * @param start_pc Start of handled region (inclusive) - */ - public void setStartPC( InstructionHandle start_pc ) { - BranchInstruction.notifyTarget(this.start_pc, start_pc, this); - this.start_pc = start_pc; - } + /** + * @param old_ih + * old target, either start or end + * @param new_ih + * new target + */ + @Override + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + boolean targeted = false; + if (start_pc == old_ih) { + targeted = true; + setStartPC(new_ih); + } + if (end_pc == old_ih) { + targeted = true; + setEndPC(new_ih); + } + if (handler_pc == old_ih) { + targeted = true; + setHandlerPC(new_ih); + } + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih + ", but {" + + start_pc + ", " + end_pc + ", " + handler_pc + "}"); + } + } + /** + * @return true, if ih is target of this handler + */ + @Override + public boolean containsTarget(InstructionHandle ih) { + return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); + } - /* Set end of handler - * @param end_pc End of handled region (inclusive) - */ - public void setEndPC( InstructionHandle end_pc ) { - BranchInstruction.notifyTarget(this.end_pc, end_pc, this); - this.end_pc = end_pc; - } + /** Sets the type of the Exception to catch. Set 'null' for ANY. */ + public void setCatchType(ObjectType catch_type) { + this.catch_type = catch_type; + } + /** Gets the type of the Exception to catch, 'null' for ANY. */ + public ObjectType getCatchType() { + return catch_type; + } - /* Set handler code - * @param handler_pc Start of handler - */ - public void setHandlerPC( InstructionHandle handler_pc ) { - BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this); - this.handler_pc = handler_pc; - } + /** + * @return start of handled region (inclusive) + */ + public InstructionHandle getStartPC() { + return start_pc; + } + /** + * @return end of handled region (inclusive) + */ + public InstructionHandle getEndPC() { + return end_pc; + } - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { - boolean targeted = false; - if (start_pc == old_ih) { - targeted = true; - setStartPC(new_ih); - } - if (end_pc == old_ih) { - targeted = true; - setEndPC(new_ih); - } - if (handler_pc == old_ih) { - targeted = true; - setHandlerPC(new_ih); - } - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " - + end_pc + ", " + handler_pc + "}"); - } - } + /** + * @return start of handler + */ + public InstructionHandle getHandlerPC() { + return handler_pc; + } + @Override + public String toString() { + return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + + handler_pc + ")"; + } - /** - * @return true, if ih is target of this handler - */ - public boolean containsTarget( InstructionHandle ih ) { - return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); - } - - - /** Sets the type of the Exception to catch. Set 'null' for ANY. */ - public void setCatchType( ObjectType catch_type ) { - this.catch_type = catch_type; - } - - - /** Gets the type of the Exception to catch, 'null' for ANY. */ - public ObjectType getCatchType() { - return catch_type; - } - - - /** @return start of handled region (inclusive) - */ - public InstructionHandle getStartPC() { - return start_pc; - } - - - /** @return end of handled region (inclusive) - */ - public InstructionHandle getEndPC() { - return end_pc; - } - - - /** @return start of handler - */ - public InstructionHandle getHandlerPC() { - return handler_pc; - } - - - public String toString() { - return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; - } - - - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } } diff --git a/src/org/apache/bcel/generic/CompoundInstruction.java b/src/org/apache/bcel/generic/CompoundInstruction.java index 0d7eb23..2ad6f3a 100644 --- a/src/org/apache/bcel/generic/CompoundInstruction.java +++ b/src/org/apache/bcel/generic/CompoundInstruction.java @@ -17,22 +17,21 @@ package org.apache.bcel.generic; /** - * Wrapper class for `compound' operations, virtual instructions that - * don't exist as byte code, but give a useful meaning. For example, - * the (virtual) PUSH instruction takes an arbitray argument and produces the - * appropiate code at dump time (ICONST, LDC, BIPUSH, ...). Also you can use the - * SWITCH instruction as a useful template for either LOOKUPSWITCH or - * TABLESWITCH. - * - * The interface provides the possibilty for the user to write - * `templates' or `macros' for such reuseable code patterns. - * + * Wrapper class for `compound' operations, virtual instructions that don't + * exist as byte code, but give a useful meaning. For example, the (virtual) + * PUSH instruction takes an arbitray argument and produces the appropiate code + * at dump time (ICONST, LDC, BIPUSH, ...). Also you can use the SWITCH + * instruction as a useful template for either LOOKUPSWITCH or TABLESWITCH. + * + * The interface provides the possibilty for the user to write `templates' or + * `macros' for such reuseable code patterns. + * * @version $Id: CompoundInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see PUSH * @see SWITCH */ public interface CompoundInstruction { - public InstructionList getInstructionList(); + public InstructionList getInstructionList(); } diff --git a/src/org/apache/bcel/generic/ConstantPoolGen.java b/src/org/apache/bcel/generic/ConstantPoolGen.java index 581ca59..96fe39b 100644 --- a/src/org/apache/bcel/generic/ConstantPoolGen.java +++ b/src/org/apache/bcel/generic/ConstantPoolGen.java @@ -18,6 +18,7 @@ package org.apache.bcel.generic; import java.util.HashMap; import java.util.Map; + import org.apache.bcel.Constants; import org.apache.bcel.classfile.Constant; import org.apache.bcel.classfile.ConstantCP; @@ -34,731 +35,770 @@ import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.classfile.ConstantString; import org.apache.bcel.classfile.ConstantUtf8; -/** - * This class is used to build up a constant pool. The user adds - * constants via `addXXX' methods, `addString', `addClass', - * etc.. These methods return an index into the constant - * pool. Finally, `getFinalConstantPool()' returns the constant pool - * built up. Intermediate versions of the constant pool can be +/** + * This class is used to build up a constant pool. The user adds constants via + * `addXXX' methods, `addString', `addClass', etc.. These methods return an + * index into the constant pool. Finally, `getFinalConstantPool()' returns the + * constant pool built up. Intermediate versions of the constant pool can be * obtained with `getConstantPool()'. A constant pool has capacity for - * Constants.MAX_SHORT entries. Note that the first (0) is used by the - * JVM and that Double and Long constants need two slots. - * + * Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and + * that Double and Long constants need two slots. + * * @version $Id: ConstantPoolGen.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see Constant */ public class ConstantPoolGen implements java.io.Serializable { - protected int size = 1024; // Inital size, sufficient in most cases - protected Constant[] constants = new Constant[size]; - protected int index = 1; // First entry (0) used by JVM - private static final String METHODREF_DELIM = ":"; - private static final String IMETHODREF_DELIM = "#"; - private static final String FIELDREF_DELIM = "&"; - private static final String NAT_DELIM = "%"; - - private static class Index implements java.io.Serializable { - - int index; - - - Index(int i) { - index = i; - } - } - - - /** - * Initialize with given array of constants. - * - * @param cs array of given constants, new ones will be appended - */ - public ConstantPoolGen(Constant[] cs) { - if (cs.length > size) { - size = cs.length; - constants = new Constant[size]; - } - System.arraycopy(cs, 0, constants, 0, cs.length); - if (cs.length > 0) { - index = cs.length; - } - for (int i = 1; i < index; i++) { - Constant c = constants[i]; - if (c instanceof ConstantString) { - ConstantString s = (ConstantString) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; - String key = u8.getBytes(); - if (!string_table.containsKey(key)) { - string_table.put(key, new Index(i)); - } - } else if (c instanceof ConstantClass) { - ConstantClass s = (ConstantClass) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; - String key = u8.getBytes(); - if (!class_table.containsKey(key)) { - class_table.put(key, new Index(i)); - } - } else if (c instanceof ConstantNameAndType) { - ConstantNameAndType n = (ConstantNameAndType) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; - ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; - String key = u8.getBytes() + NAT_DELIM + u8_2.getBytes(); - if (!n_a_t_table.containsKey(key)) { - n_a_t_table.put(key, new Index(i)); - } - } else if (c instanceof ConstantUtf8) { - ConstantUtf8 u = (ConstantUtf8) c; - String key = u.getBytes(); - if (!utf8_table.containsKey(key)) { - utf8_table.put(key, new Index(i)); - } - } else if (c instanceof ConstantCP) { - ConstantCP m = (ConstantCP) c; - ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; - ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; - ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; - String class_name = u8.getBytes().replace('/', '.'); - u8 = (ConstantUtf8) constants[n.getNameIndex()]; - String method_name = u8.getBytes(); - u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; - String signature = u8.getBytes(); - String delim = METHODREF_DELIM; - if (c instanceof ConstantInterfaceMethodref) { - delim = IMETHODREF_DELIM; - } else if (c instanceof ConstantFieldref) { - delim = FIELDREF_DELIM; - } - String key = class_name + delim + method_name + delim + signature; - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(i)); - } - } - } - } - - - /** - * Initialize with given constant pool. - */ - public ConstantPoolGen(ConstantPool cp) { - this(cp.getConstantPool()); - } - - - /** - * Create empty constant pool. - */ - public ConstantPoolGen() { - } - - - /** Resize internal array of constants. - */ - protected void adjustSize() { - if (index + 3 >= size) { - Constant[] cs = constants; - size *= 2; - constants = new Constant[size]; - System.arraycopy(cs, 0, constants, 0, index); - } - } - - private Map string_table = new HashMap(); - - - /** - * Look for ConstantString in ConstantPool containing String `str'. - * - * @param str String to search for - * @return index on success, -1 otherwise - */ - public int lookupString( String str ) { - Index index = (Index) string_table.get(str); - return (index != null) ? index.index : -1; - } - - - /** - * Add a new String constant to the ConstantPool, if it is not already in there. - * - * @param str String to add - * @return index of entry - */ - public int addString( String str ) { - int ret; - if ((ret = lookupString(str)) != -1) { - return ret; // Already in CP - } - int utf8 = addUtf8(str); - adjustSize(); - ConstantString s = new ConstantString(utf8); - ret = index; - constants[index++] = s; - if (!string_table.containsKey(str)) { - string_table.put(str, new Index(ret)); - } - return ret; - } - - private Map class_table = new HashMap(); - - - /** - * Look for ConstantClass in ConstantPool named `str'. - * - * @param str String to search for - * @return index on success, -1 otherwise - */ - public int lookupClass( String str ) { - Index index = (Index) class_table.get(str.replace('.', '/')); - return (index != null) ? index.index : -1; - } - - - private int addClass_( String clazz ) { - int ret; - if ((ret = lookupClass(clazz)) != -1) { - return ret; // Already in CP - } - adjustSize(); - ConstantClass c = new ConstantClass(addUtf8(clazz)); - ret = index; - constants[index++] = c; - if (!class_table.containsKey(clazz)) { - class_table.put(clazz, new Index(ret)); - } - return ret; - } - - - /** - * Add a new Class reference to the ConstantPool, if it is not already in there. - * - * @param str Class to add - * @return index of entry - */ - public int addClass( String str ) { - return addClass_(str.replace('.', '/')); - } - - - /** - * Add a new Class reference to the ConstantPool for a given type. - * - * @param type Class to add - * @return index of entry - */ - public int addClass( ObjectType type ) { - return addClass(type.getClassName()); - } - - - /** - * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY - * instruction, e.g. to the ConstantPool. - * - * @param type type of array class - * @return index of entry - */ - public int addArrayClass( ArrayType type ) { - return addClass_(type.getSignature()); - } - - - /** - * Look for ConstantInteger in ConstantPool. - * - * @param n integer number to look for - * @return index on success, -1 otherwise - */ - public int lookupInteger( int n ) { - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantInteger) { - ConstantInteger c = (ConstantInteger) constants[i]; - if (c.getBytes() == n) { - return i; - } - } - } - return -1; - } - - - /** - * Add a new Integer constant to the ConstantPool, if it is not already in there. - * - * @param n integer number to add - * @return index of entry - */ - public int addInteger( int n ) { - int ret; - if ((ret = lookupInteger(n)) != -1) { - return ret; // Already in CP - } - adjustSize(); - ret = index; - constants[index++] = new ConstantInteger(n); - return ret; - } - - - /** - * Look for ConstantFloat in ConstantPool. - * - * @param n Float number to look for - * @return index on success, -1 otherwise - */ - public int lookupFloat( float n ) { - int bits = Float.floatToIntBits(n); - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantFloat) { - ConstantFloat c = (ConstantFloat) constants[i]; - if (Float.floatToIntBits(c.getBytes()) == bits) { - return i; - } - } - } - return -1; - } - - - /** - * Add a new Float constant to the ConstantPool, if it is not already in there. - * - * @param n Float number to add - * @return index of entry - */ - public int addFloat( float n ) { - int ret; - if ((ret = lookupFloat(n)) != -1) { - return ret; // Already in CP - } - adjustSize(); - ret = index; - constants[index++] = new ConstantFloat(n); - return ret; - } - - private Map utf8_table = new HashMap(); - - - /** - * Look for ConstantUtf8 in ConstantPool. - * - * @param n Utf8 string to look for - * @return index on success, -1 otherwise - */ - public int lookupUtf8( String n ) { - Index index = (Index) utf8_table.get(n); - return (index != null) ? index.index : -1; - } - - - /** - * Add a new Utf8 constant to the ConstantPool, if it is not already in there. - * - * @param n Utf8 string to add - * @return index of entry - */ - public int addUtf8( String n ) { - int ret; - if ((ret = lookupUtf8(n)) != -1) { - return ret; // Already in CP - } - adjustSize(); - ret = index; - constants[index++] = new ConstantUtf8(n); - if (!utf8_table.containsKey(n)) { - utf8_table.put(n, new Index(ret)); - } - return ret; - } - - - /** - * Look for ConstantLong in ConstantPool. - * - * @param n Long number to look for - * @return index on success, -1 otherwise - */ - public int lookupLong( long n ) { - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantLong) { - ConstantLong c = (ConstantLong) constants[i]; - if (c.getBytes() == n) { - return i; - } - } - } - return -1; - } - - - /** - * Add a new long constant to the ConstantPool, if it is not already in there. - * - * @param n Long number to add - * @return index of entry - */ - public int addLong( long n ) { - int ret; - if ((ret = lookupLong(n)) != -1) { - return ret; // Already in CP - } - adjustSize(); - ret = index; - constants[index] = new ConstantLong(n); - index += 2; // Wastes one entry according to spec - return ret; - } - - - /** - * Look for ConstantDouble in ConstantPool. - * - * @param n Double number to look for - * @return index on success, -1 otherwise - */ - public int lookupDouble( double n ) { - long bits = Double.doubleToLongBits(n); - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantDouble) { - ConstantDouble c = (ConstantDouble) constants[i]; - if (Double.doubleToLongBits(c.getBytes()) == bits) { - return i; - } - } - } - return -1; - } - - - /** - * Add a new double constant to the ConstantPool, if it is not already in there. - * - * @param n Double number to add - * @return index of entry - */ - public int addDouble( double n ) { - int ret; - if ((ret = lookupDouble(n)) != -1) { - return ret; // Already in CP - } - adjustSize(); - ret = index; - constants[index] = new ConstantDouble(n); - index += 2; // Wastes one entry according to spec - return ret; - } - - private Map n_a_t_table = new HashMap(); - - - /** - * Look for ConstantNameAndType in ConstantPool. - * - * @param name of variable/method - * @param signature of variable/method - * @return index on success, -1 otherwise - */ - public int lookupNameAndType( String name, String signature ) { - Index _index = (Index) n_a_t_table.get(name + NAT_DELIM + signature); - return (_index != null) ? _index.index : -1; - } - - - /** - * Add a new NameAndType constant to the ConstantPool if it is not already - * in there. - * - * @param name Name string to add - * @param signature signature string to add - * @return index of entry - */ - public int addNameAndType( String name, String signature ) { - int ret; - int name_index, signature_index; - if ((ret = lookupNameAndType(name, signature)) != -1) { - return ret; // Already in CP - } - adjustSize(); - name_index = addUtf8(name); - signature_index = addUtf8(signature); - ret = index; - constants[index++] = new ConstantNameAndType(name_index, signature_index); - String key = name + NAT_DELIM + signature; - if (!n_a_t_table.containsKey(key)) { - n_a_t_table.put(key, new Index(ret)); - } - return ret; - } - - private Map cp_table = new HashMap(); - - - /** - * Look for ConstantMethodref in ConstantPool. - * - * @param class_name Where to find method - * @param method_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupMethodref( String class_name, String method_name, String signature ) { - Index index = (Index) cp_table.get(class_name + METHODREF_DELIM + method_name - + METHODREF_DELIM + signature); - return (index != null) ? index.index : -1; - } - - - public int lookupMethodref( MethodGen method ) { - return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); - } - - - /** - * Add a new Methodref constant to the ConstantPool, if it is not already - * in there. - * - * @param class_name class name string to add - * @param method_name method name string to add - * @param signature method signature string to add - * @return index of entry - */ - public int addMethodref( String class_name, String method_name, String signature ) { - int ret, class_index, name_and_type_index; - if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { - return ret; // Already in CP - } - adjustSize(); - name_and_type_index = addNameAndType(method_name, signature); - class_index = addClass(class_name); - ret = index; - constants[index++] = new ConstantMethodref(class_index, name_and_type_index); - String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(ret)); - } - return ret; - } - - - public int addMethodref( MethodGen method ) { - return addMethodref(method.getClassName(), method.getName(), method.getSignature()); - } - - - /** - * Look for ConstantInterfaceMethodref in ConstantPool. - * - * @param class_name Where to find method - * @param method_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupInterfaceMethodref( String class_name, String method_name, String signature ) { - Index index = (Index) cp_table.get(class_name + IMETHODREF_DELIM + method_name - + IMETHODREF_DELIM + signature); - return (index != null) ? index.index : -1; - } - - - public int lookupInterfaceMethodref( MethodGen method ) { - return lookupInterfaceMethodref(method.getClassName(), method.getName(), method - .getSignature()); - } - - - /** - * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already - * in there. - * - * @param class_name class name string to add - * @param method_name method name string to add - * @param signature signature string to add - * @return index of entry - */ - public int addInterfaceMethodref( String class_name, String method_name, String signature ) { - int ret, class_index, name_and_type_index; - if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { - return ret; // Already in CP - } - adjustSize(); - class_index = addClass(class_name); - name_and_type_index = addNameAndType(method_name, signature); - ret = index; - constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); - String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(ret)); - } - return ret; - } - - - public int addInterfaceMethodref( MethodGen method ) { - return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); - } - - - /** - * Look for ConstantFieldref in ConstantPool. - * - * @param class_name Where to find method - * @param field_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupFieldref( String class_name, String field_name, String signature ) { - Index index = (Index) cp_table.get(class_name + FIELDREF_DELIM + field_name - + FIELDREF_DELIM + signature); - return (index != null) ? index.index : -1; - } - - - /** - * Add a new Fieldref constant to the ConstantPool, if it is not already - * in there. - * - * @param class_name class name string to add - * @param field_name field name string to add - * @param signature signature string to add - * @return index of entry - */ - public int addFieldref( String class_name, String field_name, String signature ) { - int ret; - int class_index, name_and_type_index; - if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { - return ret; // Already in CP - } - adjustSize(); - class_index = addClass(class_name); - name_and_type_index = addNameAndType(field_name, signature); - ret = index; - constants[index++] = new ConstantFieldref(class_index, name_and_type_index); - String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; - if (!cp_table.containsKey(key)) { - cp_table.put(key, new Index(ret)); - } - return ret; - } - - - /** - * @param i index in constant pool - * @return constant pool entry at index i - */ - public Constant getConstant( int i ) { - return constants[i]; - } - - - /** - * Use with care! - * - * @param i index in constant pool - * @param c new constant pool entry at index i - */ - public void setConstant( int i, Constant c ) { - constants[i] = c; - } - - - /** - * @return intermediate constant pool - */ - public ConstantPool getConstantPool() { - return new ConstantPool(constants); - } - - - /** - * @return current size of constant pool - */ - public int getSize() { - return index; - } - - - /** - * @return constant pool with proper length - */ - public ConstantPool getFinalConstantPool() { - Constant[] cs = new Constant[index]; - System.arraycopy(constants, 0, cs, 0, index); - return new ConstantPool(cs); - } - - - /** - * @return String representation. - */ - public String toString() { - StringBuffer buf = new StringBuffer(); - for (int i = 1; i < index; i++) { - buf.append(i).append(")").append(constants[i]).append("\n"); - } - return buf.toString(); - } - - - /** Import constant from another ConstantPool and return new index. - */ - public int addConstant( Constant c, ConstantPoolGen cp ) { - Constant[] constants = cp.getConstantPool().getConstantPool(); - switch (c.getTag()) { - case Constants.CONSTANT_String: { - ConstantString s = (ConstantString) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; - return addString(u8.getBytes()); - } - case Constants.CONSTANT_Class: { - ConstantClass s = (ConstantClass) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; - return addClass(u8.getBytes()); - } - case Constants.CONSTANT_NameAndType: { - ConstantNameAndType n = (ConstantNameAndType) c; - ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; - ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; - return addNameAndType(u8.getBytes(), u8_2.getBytes()); - } - case Constants.CONSTANT_Utf8: - return addUtf8(((ConstantUtf8) c).getBytes()); - case Constants.CONSTANT_Double: - return addDouble(((ConstantDouble) c).getBytes()); - case Constants.CONSTANT_Float: - return addFloat(((ConstantFloat) c).getBytes()); - case Constants.CONSTANT_Long: - return addLong(((ConstantLong) c).getBytes()); - case Constants.CONSTANT_Integer: - return addInteger(((ConstantInteger) c).getBytes()); - case Constants.CONSTANT_InterfaceMethodref: - case Constants.CONSTANT_Methodref: - case Constants.CONSTANT_Fieldref: { - ConstantCP m = (ConstantCP) c; - ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; - ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; - ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; - String class_name = u8.getBytes().replace('/', '.'); - u8 = (ConstantUtf8) constants[n.getNameIndex()]; - String name = u8.getBytes(); - u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; - String signature = u8.getBytes(); - switch (c.getTag()) { - case Constants.CONSTANT_InterfaceMethodref: - return addInterfaceMethodref(class_name, name, signature); - case Constants.CONSTANT_Methodref: - return addMethodref(class_name, name, signature); - case Constants.CONSTANT_Fieldref: - return addFieldref(class_name, name, signature); - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); - } - } - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); - } - } + /** + * + */ + private static final long serialVersionUID = 1L; + protected int size = 1024; // Inital size, sufficient in most cases + protected Constant[] constants = new Constant[size]; + protected int index = 1; // First entry (0) used by JVM + private static final String METHODREF_DELIM = ":"; + private static final String IMETHODREF_DELIM = "#"; + private static final String FIELDREF_DELIM = "&"; + private static final String NAT_DELIM = "%"; + + private static class Index implements java.io.Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + int index; + + Index(int i) { + index = i; + } + } + + /** + * Initialize with given array of constants. + * + * @param cs + * array of given constants, new ones will be appended + */ + public ConstantPoolGen(Constant[] cs) { + if (cs.length > size) { + size = cs.length; + constants = new Constant[size]; + } + System.arraycopy(cs, 0, constants, 0, cs.length); + if (cs.length > 0) { + index = cs.length; + } + for (int i = 1; i < index; i++) { + Constant c = constants[i]; + if (c instanceof ConstantString) { + ConstantString s = (ConstantString) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + String key = u8.getBytes(); + if (!string_table.containsKey(key)) { + string_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantClass) { + ConstantClass s = (ConstantClass) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + String key = u8.getBytes(); + if (!class_table.containsKey(key)) { + class_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantNameAndType) { + ConstantNameAndType n = (ConstantNameAndType) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + ConstantUtf8 u8_2 = (ConstantUtf8) constants[n + .getSignatureIndex()]; + String key = u8.getBytes() + NAT_DELIM + u8_2.getBytes(); + if (!n_a_t_table.containsKey(key)) { + n_a_t_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantUtf8) { + ConstantUtf8 u = (ConstantUtf8) c; + String key = u.getBytes(); + if (!utf8_table.containsKey(key)) { + utf8_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantCP) { + ConstantCP m = (ConstantCP) c; + ConstantClass clazz = (ConstantClass) constants[m + .getClassIndex()]; + ConstantNameAndType n = (ConstantNameAndType) constants[m + .getNameAndTypeIndex()]; + ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + String class_name = u8.getBytes().replace('/', '.'); + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + String method_name = u8.getBytes(); + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + String signature = u8.getBytes(); + String delim = METHODREF_DELIM; + if (c instanceof ConstantInterfaceMethodref) { + delim = IMETHODREF_DELIM; + } else if (c instanceof ConstantFieldref) { + delim = FIELDREF_DELIM; + } + String key = class_name + delim + method_name + delim + + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(i)); + } + } + } + } + + /** + * Initialize with given constant pool. + */ + public ConstantPoolGen(ConstantPool cp) { + this(cp.getConstantPool()); + } + + /** + * Create empty constant pool. + */ + public ConstantPoolGen() { + } + + /** + * Resize internal array of constants. + */ + protected void adjustSize() { + if (index + 3 >= size) { + Constant[] cs = constants; + size *= 2; + constants = new Constant[size]; + System.arraycopy(cs, 0, constants, 0, index); + } + } + + private Map string_table = new HashMap(); + + /** + * Look for ConstantString in ConstantPool containing String `str'. + * + * @param str + * String to search for + * @return index on success, -1 otherwise + */ + public int lookupString(String str) { + Index index = string_table.get(str); + return (index != null) ? index.index : -1; + } + + /** + * Add a new String constant to the ConstantPool, if it is not already in + * there. + * + * @param str + * String to add + * @return index of entry + */ + public int addString(String str) { + int ret; + if ((ret = lookupString(str)) != -1) { + return ret; // Already in CP + } + int utf8 = addUtf8(str); + adjustSize(); + ConstantString s = new ConstantString(utf8); + ret = index; + constants[index++] = s; + if (!string_table.containsKey(str)) { + string_table.put(str, new Index(ret)); + } + return ret; + } + + private Map class_table = new HashMap(); + + /** + * Look for ConstantClass in ConstantPool named `str'. + * + * @param str + * String to search for + * @return index on success, -1 otherwise + */ + public int lookupClass(String str) { + Index index = class_table.get(str.replace('.', '/')); + return (index != null) ? index.index : -1; + } + + private int addClass_(String clazz) { + int ret; + if ((ret = lookupClass(clazz)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ConstantClass c = new ConstantClass(addUtf8(clazz)); + ret = index; + constants[index++] = c; + if (!class_table.containsKey(clazz)) { + class_table.put(clazz, new Index(ret)); + } + return ret; + } + + /** + * Add a new Class reference to the ConstantPool, if it is not already in + * there. + * + * @param str + * Class to add + * @return index of entry + */ + public int addClass(String str) { + return addClass_(str.replace('.', '/')); + } + + /** + * Add a new Class reference to the ConstantPool for a given type. + * + * @param type + * Class to add + * @return index of entry + */ + public int addClass(ObjectType type) { + return addClass(type.getClassName()); + } + + /** + * Add a reference to an array class (e.g. String[][]) as needed by + * MULTIANEWARRAY instruction, e.g. to the ConstantPool. + * + * @param type + * type of array class + * @return index of entry + */ + public int addArrayClass(ArrayType type) { + return addClass_(type.getSignature()); + } + + /** + * Look for ConstantInteger in ConstantPool. + * + * @param n + * integer number to look for + * @return index on success, -1 otherwise + */ + public int lookupInteger(int n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantInteger) { + ConstantInteger c = (ConstantInteger) constants[i]; + if (c.getBytes() == n) { + return i; + } + } + } + return -1; + } + + /** + * Add a new Integer constant to the ConstantPool, if it is not already in + * there. + * + * @param n + * integer number to add + * @return index of entry + */ + public int addInteger(int n) { + int ret; + if ((ret = lookupInteger(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantInteger(n); + return ret; + } + + /** + * Look for ConstantFloat in ConstantPool. + * + * @param n + * Float number to look for + * @return index on success, -1 otherwise + */ + public int lookupFloat(float n) { + int bits = Float.floatToIntBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantFloat) { + ConstantFloat c = (ConstantFloat) constants[i]; + if (Float.floatToIntBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; + } + + /** + * Add a new Float constant to the ConstantPool, if it is not already in + * there. + * + * @param n + * Float number to add + * @return index of entry + */ + public int addFloat(float n) { + int ret; + if ((ret = lookupFloat(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantFloat(n); + return ret; + } + + private Map utf8_table = new HashMap(); + + /** + * Look for ConstantUtf8 in ConstantPool. + * + * @param n + * Utf8 string to look for + * @return index on success, -1 otherwise + */ + public int lookupUtf8(String n) { + Index index = utf8_table.get(n); + return (index != null) ? index.index : -1; + } + + /** + * Add a new Utf8 constant to the ConstantPool, if it is not already in + * there. + * + * @param n + * Utf8 string to add + * @return index of entry + */ + public int addUtf8(String n) { + int ret; + if ((ret = lookupUtf8(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantUtf8(n); + if (!utf8_table.containsKey(n)) { + utf8_table.put(n, new Index(ret)); + } + return ret; + } + + /** + * Look for ConstantLong in ConstantPool. + * + * @param n + * Long number to look for + * @return index on success, -1 otherwise + */ + public int lookupLong(long n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantLong) { + ConstantLong c = (ConstantLong) constants[i]; + if (c.getBytes() == n) { + return i; + } + } + } + return -1; + } + + /** + * Add a new long constant to the ConstantPool, if it is not already in + * there. + * + * @param n + * Long number to add + * @return index of entry + */ + public int addLong(long n) { + int ret; + if ((ret = lookupLong(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index] = new ConstantLong(n); + index += 2; // Wastes one entry according to spec + return ret; + } + + /** + * Look for ConstantDouble in ConstantPool. + * + * @param n + * Double number to look for + * @return index on success, -1 otherwise + */ + public int lookupDouble(double n) { + long bits = Double.doubleToLongBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantDouble) { + ConstantDouble c = (ConstantDouble) constants[i]; + if (Double.doubleToLongBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; + } + + /** + * Add a new double constant to the ConstantPool, if it is not already in + * there. + * + * @param n + * Double number to add + * @return index of entry + */ + public int addDouble(double n) { + int ret; + if ((ret = lookupDouble(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index] = new ConstantDouble(n); + index += 2; // Wastes one entry according to spec + return ret; + } + + private Map n_a_t_table = new HashMap(); + + /** + * Look for ConstantNameAndType in ConstantPool. + * + * @param name + * of variable/method + * @param signature + * of variable/method + * @return index on success, -1 otherwise + */ + public int lookupNameAndType(String name, String signature) { + Index _index = n_a_t_table.get(name + NAT_DELIM + signature); + return (_index != null) ? _index.index : -1; + } + + /** + * Add a new NameAndType constant to the ConstantPool if it is not already + * in there. + * + * @param name + * Name string to add + * @param signature + * signature string to add + * @return index of entry + */ + public int addNameAndType(String name, String signature) { + int ret; + int name_index, signature_index; + if ((ret = lookupNameAndType(name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + name_index = addUtf8(name); + signature_index = addUtf8(signature); + ret = index; + constants[index++] = new ConstantNameAndType(name_index, + signature_index); + String key = name + NAT_DELIM + signature; + if (!n_a_t_table.containsKey(key)) { + n_a_t_table.put(key, new Index(ret)); + } + return ret; + } + + private Map cp_table = new HashMap(); + + /** + * Look for ConstantMethodref in ConstantPool. + * + * @param class_name + * Where to find method + * @param method_name + * Guess what + * @param signature + * return and argument types + * @return index on success, -1 otherwise + */ + public int lookupMethodref(String class_name, String method_name, + String signature) { + Index index = cp_table.get(class_name + METHODREF_DELIM + method_name + + METHODREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + public int lookupMethodref(MethodGen method) { + return lookupMethodref(method.getClassName(), method.getName(), + method.getSignature()); + } + + /** + * Add a new Methodref constant to the ConstantPool, if it is not already in + * there. + * + * @param class_name + * class name string to add + * @param method_name + * method name string to add + * @param signature + * method signature string to add + * @return index of entry + */ + public int addMethodref(String class_name, String method_name, + String signature) { + int ret, class_index, name_and_type_index; + if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + name_and_type_index = addNameAndType(method_name, signature); + class_index = addClass(class_name); + ret = index; + constants[index++] = new ConstantMethodref(class_index, + name_and_type_index); + String key = class_name + METHODREF_DELIM + method_name + + METHODREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + public int addMethodref(MethodGen method) { + return addMethodref(method.getClassName(), method.getName(), + method.getSignature()); + } + + /** + * Look for ConstantInterfaceMethodref in ConstantPool. + * + * @param class_name + * Where to find method + * @param method_name + * Guess what + * @param signature + * return and argument types + * @return index on success, -1 otherwise + */ + public int lookupInterfaceMethodref(String class_name, String method_name, + String signature) { + Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name + + IMETHODREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + public int lookupInterfaceMethodref(MethodGen method) { + return lookupInterfaceMethodref(method.getClassName(), + method.getName(), method.getSignature()); + } + + /** + * Add a new InterfaceMethodref constant to the ConstantPool, if it is not + * already in there. + * + * @param class_name + * class name string to add + * @param method_name + * method name string to add + * @param signature + * signature string to add + * @return index of entry + */ + public int addInterfaceMethodref(String class_name, String method_name, + String signature) { + int ret, class_index, name_and_type_index; + if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + class_index = addClass(class_name); + name_and_type_index = addNameAndType(method_name, signature); + ret = index; + constants[index++] = new ConstantInterfaceMethodref(class_index, + name_and_type_index); + String key = class_name + IMETHODREF_DELIM + method_name + + IMETHODREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + public int addInterfaceMethodref(MethodGen method) { + return addInterfaceMethodref(method.getClassName(), method.getName(), + method.getSignature()); + } + + /** + * Look for ConstantFieldref in ConstantPool. + * + * @param class_name + * Where to find method + * @param field_name + * Guess what + * @param signature + * return and argument types + * @return index on success, -1 otherwise + */ + public int lookupFieldref(String class_name, String field_name, + String signature) { + Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name + + FIELDREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + /** + * Add a new Fieldref constant to the ConstantPool, if it is not already in + * there. + * + * @param class_name + * class name string to add + * @param field_name + * field name string to add + * @param signature + * signature string to add + * @return index of entry + */ + public int addFieldref(String class_name, String field_name, + String signature) { + int ret; + int class_index, name_and_type_index; + if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + class_index = addClass(class_name); + name_and_type_index = addNameAndType(field_name, signature); + ret = index; + constants[index++] = new ConstantFieldref(class_index, + name_and_type_index); + String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + /** + * @param i + * index in constant pool + * @return constant pool entry at index i + */ + public Constant getConstant(int i) { + return constants[i]; + } + + /** + * Use with care! + * + * @param i + * index in constant pool + * @param c + * new constant pool entry at index i + */ + public void setConstant(int i, Constant c) { + constants[i] = c; + } + + /** + * @return intermediate constant pool + */ + public ConstantPool getConstantPool() { + return new ConstantPool(constants); + } + + /** + * @return current size of constant pool + */ + public int getSize() { + return index; + } + + /** + * @return constant pool with proper length + */ + public ConstantPool getFinalConstantPool() { + Constant[] cs = new Constant[index]; + System.arraycopy(constants, 0, cs, 0, index); + return new ConstantPool(cs); + } + + /** + * @return String representation. + */ + @Override + public String toString() { + StringBuffer buf = new StringBuffer(); + for (int i = 1; i < index; i++) { + buf.append(i).append(")").append(constants[i]).append("\n"); + } + return buf.toString(); + } + + /** + * Import constant from another ConstantPool and return new index. + */ + public int addConstant(Constant c, ConstantPoolGen cp) { + Constant[] constants = cp.getConstantPool().getConstantPool(); + switch (c.getTag()) { + case Constants.CONSTANT_String: { + ConstantString s = (ConstantString) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + return addString(u8.getBytes()); + } + case Constants.CONSTANT_Class: { + ConstantClass s = (ConstantClass) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + return addClass(u8.getBytes()); + } + case Constants.CONSTANT_NameAndType: { + ConstantNameAndType n = (ConstantNameAndType) c; + ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; + return addNameAndType(u8.getBytes(), u8_2.getBytes()); + } + case Constants.CONSTANT_Utf8: + return addUtf8(((ConstantUtf8) c).getBytes()); + case Constants.CONSTANT_Double: + return addDouble(((ConstantDouble) c).getBytes()); + case Constants.CONSTANT_Float: + return addFloat(((ConstantFloat) c).getBytes()); + case Constants.CONSTANT_Long: + return addLong(((ConstantLong) c).getBytes()); + case Constants.CONSTANT_Integer: + return addInteger(((ConstantInteger) c).getBytes()); + case Constants.CONSTANT_InterfaceMethodref: + case Constants.CONSTANT_Methodref: + case Constants.CONSTANT_Fieldref: { + ConstantCP m = (ConstantCP) c; + ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + ConstantNameAndType n = (ConstantNameAndType) constants[m + .getNameAndTypeIndex()]; + ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + String class_name = u8.getBytes().replace('/', '.'); + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + String name = u8.getBytes(); + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + String signature = u8.getBytes(); + switch (c.getTag()) { + case Constants.CONSTANT_InterfaceMethodref: + return addInterfaceMethodref(class_name, name, signature); + case Constants.CONSTANT_Methodref: + return addMethodref(class_name, name, signature); + case Constants.CONSTANT_Fieldref: + return addFieldref(class_name, name, signature); + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } } diff --git a/src/org/apache/bcel/generic/ConstantPushInstruction.java b/src/org/apache/bcel/generic/ConstantPushInstruction.java index 2c69228..7fcfea8 100644 --- a/src/org/apache/bcel/generic/ConstantPushInstruction.java +++ b/src/org/apache/bcel/generic/ConstantPushInstruction.java @@ -17,16 +17,18 @@ package org.apache.bcel.generic; /** - * Denotes a push instruction that produces a literal on the stack - * such as SIPUSH, BIPUSH, ICONST, etc. - * - * @version $Id: ConstantPushInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - + * Denotes a push instruction that produces a literal on the stack such as + * SIPUSH, BIPUSH, ICONST, etc. + * + * @version $Id: ConstantPushInstruction.java 386056 2006-03-15 11:31:56Z tcurdt + * $ + * @author M. Dahm + * * @see ICONST * @see SIPUSH */ -public interface ConstantPushInstruction extends PushInstruction, TypedInstruction { +public interface ConstantPushInstruction extends PushInstruction, + TypedInstruction { - public Number getValue(); + public Number getValue(); } diff --git a/src/org/apache/bcel/generic/ConversionInstruction.java b/src/org/apache/bcel/generic/ConversionInstruction.java index accb79c..1cc400a 100644 --- a/src/org/apache/bcel/generic/ConversionInstruction.java +++ b/src/org/apache/bcel/generic/ConversionInstruction.java @@ -20,57 +20,63 @@ import org.apache.bcel.Constants; /** * Super class for the x2y family of instructions. - * + * * @version $Id: ConversionInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class ConversionInstruction extends Instruction implements TypedInstruction, - StackProducer, StackConsumer { +public abstract class ConversionInstruction extends Instruction implements + TypedInstruction, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ConversionInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ConversionInstruction() { + } - /** - * @param opcode opcode of instruction - */ - protected ConversionInstruction(short opcode) { - super(opcode, (short) 1); - } + /** + * @param opcode + * opcode of instruction + */ + protected ConversionInstruction(short opcode) { + super(opcode, (short) 1); + } - - /** @return type associated with the instruction - */ - public Type getType( ConstantPoolGen cp ) { - switch (opcode) { - case Constants.D2I: - case Constants.F2I: - case Constants.L2I: - return Type.INT; - case Constants.D2F: - case Constants.I2F: - case Constants.L2F: - return Type.FLOAT; - case Constants.D2L: - case Constants.F2L: - case Constants.I2L: - return Type.LONG; - case Constants.F2D: - case Constants.I2D: - case Constants.L2D: - return Type.DOUBLE; - case Constants.I2B: - return Type.BYTE; - case Constants.I2C: - return Type.CHAR; - case Constants.I2S: - return Type.SHORT; - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); - } - } + /** + * @return type associated with the instruction + */ + @Override + public Type getType(ConstantPoolGen cp) { + switch (opcode) { + case Constants.D2I: + case Constants.F2I: + case Constants.L2I: + return Type.INT; + case Constants.D2F: + case Constants.I2F: + case Constants.L2F: + return Type.FLOAT; + case Constants.D2L: + case Constants.F2L: + case Constants.I2L: + return Type.LONG; + case Constants.F2D: + case Constants.I2D: + case Constants.L2D: + return Type.DOUBLE; + case Constants.I2B: + return Type.BYTE; + case Constants.I2C: + return Type.CHAR; + case Constants.I2S: + return Type.SHORT; + default: // Never reached + throw new ClassGenException("Unknown type " + opcode); + } + } } diff --git a/src/org/apache/bcel/generic/D2F.java b/src/org/apache/bcel/generic/D2F.java index 1990492..8f733cb 100644 --- a/src/org/apache/bcel/generic/D2F.java +++ b/src/org/apache/bcel/generic/D2F.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * D2F - Convert double to float - *
          Stack: ..., value.word1, value.word2 -> ..., result
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result
          + * 
          + * * @version $Id: D2F.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class D2F extends ConversionInstruction { - /** Convert double to float - */ - public D2F() { - super(org.apache.bcel.Constants.D2F); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert double to float + */ + public D2F() { + super(org.apache.bcel.Constants.D2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2F(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2F(this); + } } diff --git a/src/org/apache/bcel/generic/D2I.java b/src/org/apache/bcel/generic/D2I.java index cca2f9f..d18b4c4 100644 --- a/src/org/apache/bcel/generic/D2I.java +++ b/src/org/apache/bcel/generic/D2I.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * D2I - Convert double to int - *
          Stack: ..., value.word1, value.word2 -> ..., result
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result
          + * 
          + * * @version $Id: D2I.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class D2I extends ConversionInstruction { - /** Convert double to int - */ - public D2I() { - super(org.apache.bcel.Constants.D2I); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert double to int + */ + public D2I() { + super(org.apache.bcel.Constants.D2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2I(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2I(this); + } } diff --git a/src/org/apache/bcel/generic/D2L.java b/src/org/apache/bcel/generic/D2L.java index 0f63663..39b653b 100644 --- a/src/org/apache/bcel/generic/D2L.java +++ b/src/org/apache/bcel/generic/D2L.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * D2L - Convert double to long - *
          Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: D2L.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class D2L extends ConversionInstruction { - /** Convert double to long - */ - public D2L() { - super(org.apache.bcel.Constants.D2L); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert double to long + */ + public D2L() { + super(org.apache.bcel.Constants.D2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2L(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2L(this); + } } diff --git a/src/org/apache/bcel/generic/DADD.java b/src/org/apache/bcel/generic/DADD.java index 7918b47..28b0625 100644 --- a/src/org/apache/bcel/generic/DADD.java +++ b/src/org/apache/bcel/generic/DADD.java @@ -16,36 +16,47 @@ */ package org.apache.bcel.generic; -/** +/** * DADD - Add doubles - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result1.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result1.word2 + * * @version $Id: DADD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DADD extends ArithmeticInstruction { - /** Add doubles - */ - public DADD() { - super(org.apache.bcel.Constants.DADD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Add doubles + */ + public DADD() { + super(org.apache.bcel.Constants.DADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDADD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDADD(this); + } } diff --git a/src/org/apache/bcel/generic/DALOAD.java b/src/org/apache/bcel/generic/DALOAD.java index de2def0..1f91fd7 100644 --- a/src/org/apache/bcel/generic/DALOAD.java +++ b/src/org/apache/bcel/generic/DALOAD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * DALOAD - Load double from array - *
          Stack: ..., arrayref, index -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., arrayref, index -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: DALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DALOAD extends ArrayInstruction implements StackProducer { - /** Load double from array - */ - public DALOAD() { - super(org.apache.bcel.Constants.DALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Load double from array + */ + public DALOAD() { + super(org.apache.bcel.Constants.DALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitDALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitDALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/DASTORE.java b/src/org/apache/bcel/generic/DASTORE.java index 5de71bc..18b4166 100644 --- a/src/org/apache/bcel/generic/DASTORE.java +++ b/src/org/apache/bcel/generic/DASTORE.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * DASTORE - Store into double array - *
          Stack: ..., arrayref, index, value.word1, value.word2 -> ...
          - * +/** + * DASTORE - Store into double array + * + *
          + * Stack: ..., arrayref, index, value.word1, value.word2 -> ...
          + * 
          + * * @version $Id: DASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DASTORE extends ArrayInstruction implements StackConsumer { - /** Store double into array - */ - public DASTORE() { - super(org.apache.bcel.Constants.DASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Store double into array + */ + public DASTORE() { + super(org.apache.bcel.Constants.DASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitDASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitDASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/DCMPG.java b/src/org/apache/bcel/generic/DCMPG.java index 7190b82..ab68ced 100644 --- a/src/org/apache/bcel/generic/DCMPG.java +++ b/src/org/apache/bcel/generic/DCMPG.java @@ -16,40 +16,52 @@ */ package org.apache.bcel.generic; -/** +/** * DCMPG - Compare doubles: value1 > value2 - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result + * * @version $Id: DCMPG.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class DCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { +public class DCMPG extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - public DCMPG() { - super(org.apache.bcel.Constants.DCMPG, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DCMPG() { + super(org.apache.bcel.Constants.DCMPG, (short) 1); + } - /** @return Type.DOUBLE - */ - public Type getType( ConstantPoolGen cp ) { - return Type.DOUBLE; - } + /** + * @return Type.DOUBLE + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.DOUBLE; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitDCMPG(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitDCMPG(this); + } } diff --git a/src/org/apache/bcel/generic/DCMPL.java b/src/org/apache/bcel/generic/DCMPL.java index 9dcfc4f..f3d98fd 100644 --- a/src/org/apache/bcel/generic/DCMPL.java +++ b/src/org/apache/bcel/generic/DCMPL.java @@ -16,40 +16,52 @@ */ package org.apache.bcel.generic; -/** +/** * DCMPL - Compare doubles: value1 < value2 - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result + * * @version $Id: DCMPL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class DCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { +public class DCMPL extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - public DCMPL() { - super(org.apache.bcel.Constants.DCMPL, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DCMPL() { + super(org.apache.bcel.Constants.DCMPL, (short) 1); + } - /** @return Type.DOUBLE - */ - public Type getType( ConstantPoolGen cp ) { - return Type.DOUBLE; - } + /** + * @return Type.DOUBLE + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.DOUBLE; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitDCMPL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitDCMPL(this); + } } diff --git a/src/org/apache/bcel/generic/DCONST.java b/src/org/apache/bcel/generic/DCONST.java index 5af8686..6fa8ad8 100644 --- a/src/org/apache/bcel/generic/DCONST.java +++ b/src/org/apache/bcel/generic/DCONST.java @@ -16,65 +16,73 @@ */ package org.apache.bcel.generic; -/** +/** * DCONST - Push 0.0 or 1.0, other values cause an exception - * - *
          Stack: ... -> ..., 
          - * + * + *
          + * Stack: ... -> ...,
          + * 
          + * * @version $Id: DCONST.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class DCONST extends Instruction implements ConstantPushInstruction, TypedInstruction { +public class DCONST extends Instruction implements ConstantPushInstruction, + TypedInstruction { - private double value; + /** + * + */ + private static final long serialVersionUID = 1L; + private double value; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DCONST() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DCONST() { - } + public DCONST(double f) { + super(org.apache.bcel.Constants.DCONST_0, (short) 1); + if (f == 0.0) { + opcode = org.apache.bcel.Constants.DCONST_0; + } else if (f == 1.0) { + opcode = org.apache.bcel.Constants.DCONST_1; + } else { + throw new ClassGenException( + "DCONST can be used only for 0.0 and 1.0: " + f); + } + value = f; + } + @Override + public Number getValue() { + return new Double(value); + } - public DCONST(double f) { - super(org.apache.bcel.Constants.DCONST_0, (short) 1); - if (f == 0.0) { - opcode = org.apache.bcel.Constants.DCONST_0; - } else if (f == 1.0) { - opcode = org.apache.bcel.Constants.DCONST_1; - } else { - throw new ClassGenException("DCONST can be used only for 0.0 and 1.0: " + f); - } - value = f; - } + /** + * @return Type.DOUBLE + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.DOUBLE; + } - - public Number getValue() { - return new Double(value); - } - - - /** @return Type.DOUBLE - */ - public Type getType( ConstantPoolGen cp ) { - return Type.DOUBLE; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitDCONST(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitDCONST(this); + } } diff --git a/src/org/apache/bcel/generic/DDIV.java b/src/org/apache/bcel/generic/DDIV.java index 44c2308..8df2367 100644 --- a/src/org/apache/bcel/generic/DDIV.java +++ b/src/org/apache/bcel/generic/DDIV.java @@ -16,36 +16,47 @@ */ package org.apache.bcel.generic; -/** - * DDIV - Divide doubles - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * +/** + * DDIV - Divide doubles + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: DDIV.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DDIV extends ArithmeticInstruction { - /** Divide doubles - */ - public DDIV() { - super(org.apache.bcel.Constants.DDIV); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Divide doubles + */ + public DDIV() { + super(org.apache.bcel.Constants.DDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDDIV(this); + } } diff --git a/src/org/apache/bcel/generic/DLOAD.java b/src/org/apache/bcel/generic/DLOAD.java index 360d23b..c7a6cbb 100644 --- a/src/org/apache/bcel/generic/DLOAD.java +++ b/src/org/apache/bcel/generic/DLOAD.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * DLOAD - Load double from local variable - *
          Stack ... -> ..., result.word1, result.word2
          - * + * + *
          + * Stack ... -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: DLOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DLOAD() { - super(org.apache.bcel.Constants.DLOAD, org.apache.bcel.Constants.DLOAD_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DLOAD() { + super(org.apache.bcel.Constants.DLOAD, + org.apache.bcel.Constants.DLOAD_0); + } - /** Load double from local variable - * @param n index of local variable - */ - public DLOAD(int n) { - super(org.apache.bcel.Constants.DLOAD, org.apache.bcel.Constants.DLOAD_0, n); - } + /** + * Load double from local variable + * + * @param n + * index of local variable + */ + public DLOAD(int n) { + super(org.apache.bcel.Constants.DLOAD, + org.apache.bcel.Constants.DLOAD_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitDLOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitDLOAD(this); + } } diff --git a/src/org/apache/bcel/generic/DMUL.java b/src/org/apache/bcel/generic/DMUL.java index 79e64ae..130f5df 100644 --- a/src/org/apache/bcel/generic/DMUL.java +++ b/src/org/apache/bcel/generic/DMUL.java @@ -16,36 +16,47 @@ */ package org.apache.bcel.generic; -/** +/** * DMUL - Multiply doubles - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: DMUL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DMUL extends ArithmeticInstruction { - /** Multiply doubles - */ - public DMUL() { - super(org.apache.bcel.Constants.DMUL); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Multiply doubles + */ + public DMUL() { + super(org.apache.bcel.Constants.DMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDMUL(this); + } } diff --git a/src/org/apache/bcel/generic/DNEG.java b/src/org/apache/bcel/generic/DNEG.java index c7e2d21..8046d70 100644 --- a/src/org/apache/bcel/generic/DNEG.java +++ b/src/org/apache/bcel/generic/DNEG.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * DNEG - Negate double - *
          Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: DNEG.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DNEG extends ArithmeticInstruction { - public DNEG() { - super(org.apache.bcel.Constants.DNEG); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DNEG() { + super(org.apache.bcel.Constants.DNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDNEG(this); + } } diff --git a/src/org/apache/bcel/generic/DREM.java b/src/org/apache/bcel/generic/DREM.java index 01dfc15..84599f0 100644 --- a/src/org/apache/bcel/generic/DREM.java +++ b/src/org/apache/bcel/generic/DREM.java @@ -16,36 +16,47 @@ */ package org.apache.bcel.generic; -/** +/** * DREM - Remainder of doubles - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: DREM.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DREM extends ArithmeticInstruction { - /** Remainder of doubles - */ - public DREM() { - super(org.apache.bcel.Constants.DREM); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Remainder of doubles + */ + public DREM() { + super(org.apache.bcel.Constants.DREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDREM(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDREM(this); + } } diff --git a/src/org/apache/bcel/generic/DRETURN.java b/src/org/apache/bcel/generic/DRETURN.java index a1ccc8b..1bf6d16 100644 --- a/src/org/apache/bcel/generic/DRETURN.java +++ b/src/org/apache/bcel/generic/DRETURN.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * DRETURN - Return double from method - *
          Stack: ..., value.word1, value.word2 -> <empty>
          - * +/** + * DRETURN - Return double from method + * + *
          + * Stack: ..., value.word1, value.word2 -> <empty>
          + * 
          + * * @version $Id: DRETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DRETURN extends ReturnInstruction { - /** Return double from method - */ - public DRETURN() { - super(org.apache.bcel.Constants.DRETURN); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Return double from method + */ + public DRETURN() { + super(org.apache.bcel.Constants.DRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitDRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitDRETURN(this); + } } diff --git a/src/org/apache/bcel/generic/DSTORE.java b/src/org/apache/bcel/generic/DSTORE.java index 9efeb3f..1040e06 100644 --- a/src/org/apache/bcel/generic/DSTORE.java +++ b/src/org/apache/bcel/generic/DSTORE.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * DSTORE - Store double into local variable - *
          Stack: ..., value.word1, value.word2 -> ... 
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ...
          + * 
          + * * @version $Id: DSTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DSTORE() { - super(org.apache.bcel.Constants.DSTORE, org.apache.bcel.Constants.DSTORE_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DSTORE() { + super(org.apache.bcel.Constants.DSTORE, + org.apache.bcel.Constants.DSTORE_0); + } - /** Store double into local variable - * @param n index of local variable - */ - public DSTORE(int n) { - super(org.apache.bcel.Constants.DSTORE, org.apache.bcel.Constants.DSTORE_0, n); - } + /** + * Store double into local variable + * + * @param n + * index of local variable + */ + public DSTORE(int n) { + super(org.apache.bcel.Constants.DSTORE, + org.apache.bcel.Constants.DSTORE_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitDSTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitDSTORE(this); + } } diff --git a/src/org/apache/bcel/generic/DSUB.java b/src/org/apache/bcel/generic/DSUB.java index 6169cfe..63a6f7b 100644 --- a/src/org/apache/bcel/generic/DSUB.java +++ b/src/org/apache/bcel/generic/DSUB.java @@ -16,36 +16,47 @@ */ package org.apache.bcel.generic; -/** +/** * DSUB - Substract doubles - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: DSUB.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DSUB extends ArithmeticInstruction { - /** Substract doubles - */ - public DSUB() { - super(org.apache.bcel.Constants.DSUB); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Substract doubles + */ + public DSUB() { + super(org.apache.bcel.Constants.DSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDSUB(this); + } } diff --git a/src/org/apache/bcel/generic/DUP.java b/src/org/apache/bcel/generic/DUP.java index 5900ddf..7726a0a 100644 --- a/src/org/apache/bcel/generic/DUP.java +++ b/src/org/apache/bcel/generic/DUP.java @@ -16,32 +16,41 @@ */ package org.apache.bcel.generic; -/** +/** * DUP - Duplicate top operand stack word - *
          Stack: ..., word -> ..., word, word
          - * + * + *
          + * Stack: ..., word -> ..., word, word
          + * 
          + * * @version $Id: DUP.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DUP extends StackInstruction implements PushInstruction { - public DUP() { - super(org.apache.bcel.Constants.DUP); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DUP() { + super(org.apache.bcel.Constants.DUP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitStackInstruction(this); - v.visitDUP(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitStackInstruction(this); + v.visitDUP(this); + } } diff --git a/src/org/apache/bcel/generic/DUP2.java b/src/org/apache/bcel/generic/DUP2.java index 688a33b..e33c39f 100644 --- a/src/org/apache/bcel/generic/DUP2.java +++ b/src/org/apache/bcel/generic/DUP2.java @@ -16,32 +16,41 @@ */ package org.apache.bcel.generic; -/** +/** * DUP2 - Duplicate two top operand stack words - *
          Stack: ..., word2, word1 -> ..., word2, word1, word2, word1
          - * + * + *
          + * Stack: ..., word2, word1 -> ..., word2, word1, word2, word1
          + * 
          + * * @version $Id: DUP2.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DUP2 extends StackInstruction implements PushInstruction { - public DUP2() { - super(org.apache.bcel.Constants.DUP2); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DUP2() { + super(org.apache.bcel.Constants.DUP2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitStackInstruction(this); - v.visitDUP2(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitStackInstruction(this); + v.visitDUP2(this); + } } diff --git a/src/org/apache/bcel/generic/DUP2_X1.java b/src/org/apache/bcel/generic/DUP2_X1.java index b522b1a..b35b991 100644 --- a/src/org/apache/bcel/generic/DUP2_X1.java +++ b/src/org/apache/bcel/generic/DUP2_X1.java @@ -16,30 +16,39 @@ */ package org.apache.bcel.generic; -/** +/** * DUP2_X1 - Duplicate two top operand stack words and put three down - *
          Stack: ..., word3, word2, word1 -> ..., word2, word1, word3, word2, word1
          - * + * + *
          + * Stack: ..., word3, word2, word1 -> ..., word2, word1, word3, word2, word1
          + * 
          + * * @version $Id: DUP2_X1.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DUP2_X1 extends StackInstruction { - public DUP2_X1() { - super(org.apache.bcel.Constants.DUP2_X1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DUP2_X1() { + super(org.apache.bcel.Constants.DUP2_X1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackInstruction(this); - v.visitDUP2_X1(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackInstruction(this); + v.visitDUP2_X1(this); + } } diff --git a/src/org/apache/bcel/generic/DUP2_X2.java b/src/org/apache/bcel/generic/DUP2_X2.java index 8cf009e..f4bd487 100644 --- a/src/org/apache/bcel/generic/DUP2_X2.java +++ b/src/org/apache/bcel/generic/DUP2_X2.java @@ -16,30 +16,39 @@ */ package org.apache.bcel.generic; -/** +/** * DUP2_X2 - Duplicate two top operand stack words and put four down - *
          Stack: ..., word4, word3, word2, word1 -> ..., word2, word1, word4, word3, word2, word1
          - * + * + *
          + * Stack: ..., word4, word3, word2, word1 -> ..., word2, word1, word4, word3, word2, word1
          + * 
          + * * @version $Id: DUP2_X2.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DUP2_X2 extends StackInstruction { - public DUP2_X2() { - super(org.apache.bcel.Constants.DUP2_X2); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DUP2_X2() { + super(org.apache.bcel.Constants.DUP2_X2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackInstruction(this); - v.visitDUP2_X2(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackInstruction(this); + v.visitDUP2_X2(this); + } } diff --git a/src/org/apache/bcel/generic/DUP_X1.java b/src/org/apache/bcel/generic/DUP_X1.java index a672e29..22a20da 100644 --- a/src/org/apache/bcel/generic/DUP_X1.java +++ b/src/org/apache/bcel/generic/DUP_X1.java @@ -16,30 +16,39 @@ */ package org.apache.bcel.generic; -/** +/** * DUP_X1 - Duplicate top operand stack word and put two down - *
          Stack: ..., word2, word1 -> ..., word1, word2, word1
          - * + * + *
          + * Stack: ..., word2, word1 -> ..., word1, word2, word1
          + * 
          + * * @version $Id: DUP_X1.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DUP_X1 extends StackInstruction { - public DUP_X1() { - super(org.apache.bcel.Constants.DUP_X1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DUP_X1() { + super(org.apache.bcel.Constants.DUP_X1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackInstruction(this); - v.visitDUP_X1(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackInstruction(this); + v.visitDUP_X1(this); + } } diff --git a/src/org/apache/bcel/generic/DUP_X2.java b/src/org/apache/bcel/generic/DUP_X2.java index 475c4c8..0b94197 100644 --- a/src/org/apache/bcel/generic/DUP_X2.java +++ b/src/org/apache/bcel/generic/DUP_X2.java @@ -16,30 +16,39 @@ */ package org.apache.bcel.generic; -/** +/** * DUP_X2 - Duplicate top operand stack word and put three down - *
          Stack: ..., word3, word2, word1 -> ..., word1, word3, word2, word1
          - * + * + *
          + * Stack: ..., word3, word2, word1 -> ..., word1, word3, word2, word1
          + * 
          + * * @version $Id: DUP_X2.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class DUP_X2 extends StackInstruction { - public DUP_X2() { - super(org.apache.bcel.Constants.DUP_X2); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public DUP_X2() { + super(org.apache.bcel.Constants.DUP_X2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackInstruction(this); - v.visitDUP_X2(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackInstruction(this); + v.visitDUP_X2(this); + } } diff --git a/src/org/apache/bcel/generic/EmptyVisitor.java b/src/org/apache/bcel/generic/EmptyVisitor.java index b28fecd..b56c77b 100644 --- a/src/org/apache/bcel/generic/EmptyVisitor.java +++ b/src/org/apache/bcel/generic/EmptyVisitor.java @@ -18,728 +18,729 @@ package org.apache.bcel.generic; /** * Supplies empty method bodies to be overridden by subclasses. - * + * * @version $Id: EmptyVisitor.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class EmptyVisitor implements Visitor { - public void visitStackInstruction( StackInstruction obj ) { - } + @Override + public void visitStackInstruction(StackInstruction obj) { + } + @Override + public void visitLocalVariableInstruction(LocalVariableInstruction obj) { + } - public void visitLocalVariableInstruction( LocalVariableInstruction obj ) { - } + @Override + public void visitBranchInstruction(BranchInstruction obj) { + } + @Override + public void visitLoadClass(LoadClass obj) { + } - public void visitBranchInstruction( BranchInstruction obj ) { - } + @Override + public void visitFieldInstruction(FieldInstruction obj) { + } + @Override + public void visitIfInstruction(IfInstruction obj) { + } - public void visitLoadClass( LoadClass obj ) { - } + @Override + public void visitConversionInstruction(ConversionInstruction obj) { + } + @Override + public void visitPopInstruction(PopInstruction obj) { + } - public void visitFieldInstruction( FieldInstruction obj ) { - } + @Override + public void visitJsrInstruction(JsrInstruction obj) { + } + @Override + public void visitGotoInstruction(GotoInstruction obj) { + } - public void visitIfInstruction( IfInstruction obj ) { - } + @Override + public void visitStoreInstruction(StoreInstruction obj) { + } + @Override + public void visitTypedInstruction(TypedInstruction obj) { + } - public void visitConversionInstruction( ConversionInstruction obj ) { - } + @Override + public void visitSelect(Select obj) { + } + @Override + public void visitUnconditionalBranch(UnconditionalBranch obj) { + } - public void visitPopInstruction( PopInstruction obj ) { - } + @Override + public void visitPushInstruction(PushInstruction obj) { + } + @Override + public void visitArithmeticInstruction(ArithmeticInstruction obj) { + } - public void visitJsrInstruction( JsrInstruction obj ) { - } + @Override + public void visitCPInstruction(CPInstruction obj) { + } + @Override + public void visitInvokeInstruction(InvokeInstruction obj) { + } - public void visitGotoInstruction( GotoInstruction obj ) { - } + @Override + public void visitArrayInstruction(ArrayInstruction obj) { + } + @Override + public void visitAllocationInstruction(AllocationInstruction obj) { + } - public void visitStoreInstruction( StoreInstruction obj ) { - } + @Override + public void visitReturnInstruction(ReturnInstruction obj) { + } + @Override + public void visitFieldOrMethod(FieldOrMethod obj) { + } - public void visitTypedInstruction( TypedInstruction obj ) { - } + @Override + public void visitConstantPushInstruction(ConstantPushInstruction obj) { + } + @Override + public void visitExceptionThrower(ExceptionThrower obj) { + } - public void visitSelect( Select obj ) { - } + @Override + public void visitLoadInstruction(LoadInstruction obj) { + } + @Override + public void visitVariableLengthInstruction(VariableLengthInstruction obj) { + } - public void visitUnconditionalBranch( UnconditionalBranch obj ) { - } + @Override + public void visitStackProducer(StackProducer obj) { + } + @Override + public void visitStackConsumer(StackConsumer obj) { + } - public void visitPushInstruction( PushInstruction obj ) { - } + @Override + public void visitACONST_NULL(ACONST_NULL obj) { + } + @Override + public void visitGETSTATIC(GETSTATIC obj) { + } - public void visitArithmeticInstruction( ArithmeticInstruction obj ) { - } + @Override + public void visitIF_ICMPLT(IF_ICMPLT obj) { + } + @Override + public void visitMONITOREXIT(MONITOREXIT obj) { + } - public void visitCPInstruction( CPInstruction obj ) { - } + @Override + public void visitIFLT(IFLT obj) { + } + @Override + public void visitLSTORE(LSTORE obj) { + } - public void visitInvokeInstruction( InvokeInstruction obj ) { - } + @Override + public void visitPOP2(POP2 obj) { + } + @Override + public void visitBASTORE(BASTORE obj) { + } - public void visitArrayInstruction( ArrayInstruction obj ) { - } + @Override + public void visitISTORE(ISTORE obj) { + } + @Override + public void visitCHECKCAST(CHECKCAST obj) { + } - public void visitAllocationInstruction( AllocationInstruction obj ) { - } + @Override + public void visitFCMPG(FCMPG obj) { + } + @Override + public void visitI2F(I2F obj) { + } - public void visitReturnInstruction( ReturnInstruction obj ) { - } + @Override + public void visitATHROW(ATHROW obj) { + } + @Override + public void visitDCMPL(DCMPL obj) { + } - public void visitFieldOrMethod( FieldOrMethod obj ) { - } + @Override + public void visitARRAYLENGTH(ARRAYLENGTH obj) { + } + @Override + public void visitDUP(DUP obj) { + } - public void visitConstantPushInstruction( ConstantPushInstruction obj ) { - } + @Override + public void visitINVOKESTATIC(INVOKESTATIC obj) { + } + @Override + public void visitLCONST(LCONST obj) { + } - public void visitExceptionThrower( ExceptionThrower obj ) { - } + @Override + public void visitDREM(DREM obj) { + } + @Override + public void visitIFGE(IFGE obj) { + } - public void visitLoadInstruction( LoadInstruction obj ) { - } + @Override + public void visitCALOAD(CALOAD obj) { + } + @Override + public void visitLASTORE(LASTORE obj) { + } - public void visitVariableLengthInstruction( VariableLengthInstruction obj ) { - } + @Override + public void visitI2D(I2D obj) { + } + @Override + public void visitDADD(DADD obj) { + } - public void visitStackProducer( StackProducer obj ) { - } + @Override + public void visitINVOKESPECIAL(INVOKESPECIAL obj) { + } + @Override + public void visitIAND(IAND obj) { + } - public void visitStackConsumer( StackConsumer obj ) { - } + @Override + public void visitPUTFIELD(PUTFIELD obj) { + } + @Override + public void visitILOAD(ILOAD obj) { + } - public void visitACONST_NULL( ACONST_NULL obj ) { - } + @Override + public void visitDLOAD(DLOAD obj) { + } + @Override + public void visitDCONST(DCONST obj) { + } - public void visitGETSTATIC( GETSTATIC obj ) { - } + @Override + public void visitNEW(NEW obj) { + } + @Override + public void visitIFNULL(IFNULL obj) { + } - public void visitIF_ICMPLT( IF_ICMPLT obj ) { - } + @Override + public void visitLSUB(LSUB obj) { + } + @Override + public void visitL2I(L2I obj) { + } - public void visitMONITOREXIT( MONITOREXIT obj ) { - } + @Override + public void visitISHR(ISHR obj) { + } + @Override + public void visitTABLESWITCH(TABLESWITCH obj) { + } - public void visitIFLT( IFLT obj ) { - } + @Override + public void visitIINC(IINC obj) { + } + @Override + public void visitDRETURN(DRETURN obj) { + } - public void visitLSTORE( LSTORE obj ) { - } + @Override + public void visitFSTORE(FSTORE obj) { + } + @Override + public void visitDASTORE(DASTORE obj) { + } - public void visitPOP2( POP2 obj ) { - } + @Override + public void visitIALOAD(IALOAD obj) { + } + @Override + public void visitDDIV(DDIV obj) { + } - public void visitBASTORE( BASTORE obj ) { - } + @Override + public void visitIF_ICMPGE(IF_ICMPGE obj) { + } + @Override + public void visitLAND(LAND obj) { + } - public void visitISTORE( ISTORE obj ) { - } + @Override + public void visitIDIV(IDIV obj) { + } + @Override + public void visitLOR(LOR obj) { + } - public void visitCHECKCAST( CHECKCAST obj ) { - } + @Override + public void visitCASTORE(CASTORE obj) { + } + @Override + public void visitFREM(FREM obj) { + } - public void visitFCMPG( FCMPG obj ) { - } + @Override + public void visitLDC(LDC obj) { + } + @Override + public void visitBIPUSH(BIPUSH obj) { + } - public void visitI2F( I2F obj ) { - } + @Override + public void visitDSTORE(DSTORE obj) { + } + @Override + public void visitF2L(F2L obj) { + } - public void visitATHROW( ATHROW obj ) { - } + @Override + public void visitFMUL(FMUL obj) { + } + @Override + public void visitLLOAD(LLOAD obj) { + } - public void visitDCMPL( DCMPL obj ) { - } + @Override + public void visitJSR(JSR obj) { + } + @Override + public void visitFSUB(FSUB obj) { + } - public void visitARRAYLENGTH( ARRAYLENGTH obj ) { - } + @Override + public void visitSASTORE(SASTORE obj) { + } + @Override + public void visitALOAD(ALOAD obj) { + } - public void visitDUP( DUP obj ) { - } + @Override + public void visitDUP2_X2(DUP2_X2 obj) { + } + @Override + public void visitRETURN(RETURN obj) { + } - public void visitINVOKESTATIC( INVOKESTATIC obj ) { - } + @Override + public void visitDALOAD(DALOAD obj) { + } + @Override + public void visitSIPUSH(SIPUSH obj) { + } - public void visitLCONST( LCONST obj ) { - } + @Override + public void visitDSUB(DSUB obj) { + } + @Override + public void visitL2F(L2F obj) { + } - public void visitDREM( DREM obj ) { - } + @Override + public void visitIF_ICMPGT(IF_ICMPGT obj) { + } + @Override + public void visitF2D(F2D obj) { + } - public void visitIFGE( IFGE obj ) { - } + @Override + public void visitI2L(I2L obj) { + } + @Override + public void visitIF_ACMPNE(IF_ACMPNE obj) { + } - public void visitCALOAD( CALOAD obj ) { - } + @Override + public void visitPOP(POP obj) { + } + @Override + public void visitI2S(I2S obj) { + } - public void visitLASTORE( LASTORE obj ) { - } + @Override + public void visitIFEQ(IFEQ obj) { + } + @Override + public void visitSWAP(SWAP obj) { + } - public void visitI2D( I2D obj ) { - } + @Override + public void visitIOR(IOR obj) { + } + @Override + public void visitIREM(IREM obj) { + } - public void visitDADD( DADD obj ) { - } + @Override + public void visitIASTORE(IASTORE obj) { + } + @Override + public void visitNEWARRAY(NEWARRAY obj) { + } - public void visitINVOKESPECIAL( INVOKESPECIAL obj ) { - } + @Override + public void visitINVOKEINTERFACE(INVOKEINTERFACE obj) { + } + @Override + public void visitINEG(INEG obj) { + } - public void visitIAND( IAND obj ) { - } + @Override + public void visitLCMP(LCMP obj) { + } + @Override + public void visitJSR_W(JSR_W obj) { + } - public void visitPUTFIELD( PUTFIELD obj ) { - } + @Override + public void visitMULTIANEWARRAY(MULTIANEWARRAY obj) { + } + @Override + public void visitDUP_X2(DUP_X2 obj) { + } - public void visitILOAD( ILOAD obj ) { - } + @Override + public void visitSALOAD(SALOAD obj) { + } + @Override + public void visitIFNONNULL(IFNONNULL obj) { + } - public void visitDLOAD( DLOAD obj ) { - } + @Override + public void visitDMUL(DMUL obj) { + } + @Override + public void visitIFNE(IFNE obj) { + } - public void visitDCONST( DCONST obj ) { - } + @Override + public void visitIF_ICMPLE(IF_ICMPLE obj) { + } + @Override + public void visitLDC2_W(LDC2_W obj) { + } - public void visitNEW( NEW obj ) { - } + @Override + public void visitGETFIELD(GETFIELD obj) { + } + @Override + public void visitLADD(LADD obj) { + } - public void visitIFNULL( IFNULL obj ) { - } + @Override + public void visitNOP(NOP obj) { + } + @Override + public void visitFALOAD(FALOAD obj) { + } - public void visitLSUB( LSUB obj ) { - } + @Override + public void visitINSTANCEOF(INSTANCEOF obj) { + } + @Override + public void visitIFLE(IFLE obj) { + } - public void visitL2I( L2I obj ) { - } + @Override + public void visitLXOR(LXOR obj) { + } + @Override + public void visitLRETURN(LRETURN obj) { + } - public void visitISHR( ISHR obj ) { - } + @Override + public void visitFCONST(FCONST obj) { + } + @Override + public void visitIUSHR(IUSHR obj) { + } - public void visitTABLESWITCH( TABLESWITCH obj ) { - } + @Override + public void visitBALOAD(BALOAD obj) { + } + @Override + public void visitDUP2(DUP2 obj) { + } - public void visitIINC( IINC obj ) { - } + @Override + public void visitIF_ACMPEQ(IF_ACMPEQ obj) { + } + @Override + public void visitIMPDEP1(IMPDEP1 obj) { + } - public void visitDRETURN( DRETURN obj ) { - } + @Override + public void visitMONITORENTER(MONITORENTER obj) { + } + @Override + public void visitLSHL(LSHL obj) { + } - public void visitFSTORE( FSTORE obj ) { - } + @Override + public void visitDCMPG(DCMPG obj) { + } + @Override + public void visitD2L(D2L obj) { + } - public void visitDASTORE( DASTORE obj ) { - } + @Override + public void visitIMPDEP2(IMPDEP2 obj) { + } + @Override + public void visitL2D(L2D obj) { + } - public void visitIALOAD( IALOAD obj ) { - } + @Override + public void visitRET(RET obj) { + } + @Override + public void visitIFGT(IFGT obj) { + } - public void visitDDIV( DDIV obj ) { - } + @Override + public void visitIXOR(IXOR obj) { + } + @Override + public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { + } - public void visitIF_ICMPGE( IF_ICMPGE obj ) { - } + @Override + public void visitFASTORE(FASTORE obj) { + } + @Override + public void visitIRETURN(IRETURN obj) { + } - public void visitLAND( LAND obj ) { - } + @Override + public void visitIF_ICMPNE(IF_ICMPNE obj) { + } + @Override + public void visitFLOAD(FLOAD obj) { + } - public void visitIDIV( IDIV obj ) { - } + @Override + public void visitLDIV(LDIV obj) { + } + @Override + public void visitPUTSTATIC(PUTSTATIC obj) { + } - public void visitLOR( LOR obj ) { - } + @Override + public void visitAALOAD(AALOAD obj) { + } + @Override + public void visitD2I(D2I obj) { + } - public void visitCASTORE( CASTORE obj ) { - } + @Override + public void visitIF_ICMPEQ(IF_ICMPEQ obj) { + } + @Override + public void visitAASTORE(AASTORE obj) { + } - public void visitFREM( FREM obj ) { - } + @Override + public void visitARETURN(ARETURN obj) { + } + @Override + public void visitDUP2_X1(DUP2_X1 obj) { + } - public void visitLDC( LDC obj ) { - } + @Override + public void visitFNEG(FNEG obj) { + } + @Override + public void visitGOTO_W(GOTO_W obj) { + } - public void visitBIPUSH( BIPUSH obj ) { - } + @Override + public void visitD2F(D2F obj) { + } + @Override + public void visitGOTO(GOTO obj) { + } - public void visitDSTORE( DSTORE obj ) { - } + @Override + public void visitISUB(ISUB obj) { + } + @Override + public void visitF2I(F2I obj) { + } - public void visitF2L( F2L obj ) { - } + @Override + public void visitDNEG(DNEG obj) { + } + @Override + public void visitICONST(ICONST obj) { + } - public void visitFMUL( FMUL obj ) { - } + @Override + public void visitFDIV(FDIV obj) { + } + @Override + public void visitI2B(I2B obj) { + } - public void visitLLOAD( LLOAD obj ) { - } + @Override + public void visitLNEG(LNEG obj) { + } + @Override + public void visitLREM(LREM obj) { + } - public void visitJSR( JSR obj ) { - } + @Override + public void visitIMUL(IMUL obj) { + } + @Override + public void visitIADD(IADD obj) { + } - public void visitFSUB( FSUB obj ) { - } + @Override + public void visitLSHR(LSHR obj) { + } + @Override + public void visitLOOKUPSWITCH(LOOKUPSWITCH obj) { + } - public void visitSASTORE( SASTORE obj ) { - } + @Override + public void visitDUP_X1(DUP_X1 obj) { + } + @Override + public void visitFCMPL(FCMPL obj) { + } - public void visitALOAD( ALOAD obj ) { - } + @Override + public void visitI2C(I2C obj) { + } + @Override + public void visitLMUL(LMUL obj) { + } - public void visitDUP2_X2( DUP2_X2 obj ) { - } + @Override + public void visitLUSHR(LUSHR obj) { + } + @Override + public void visitISHL(ISHL obj) { + } - public void visitRETURN( RETURN obj ) { - } + @Override + public void visitLALOAD(LALOAD obj) { + } + @Override + public void visitASTORE(ASTORE obj) { + } - public void visitDALOAD( DALOAD obj ) { - } + @Override + public void visitANEWARRAY(ANEWARRAY obj) { + } + @Override + public void visitFRETURN(FRETURN obj) { + } - public void visitSIPUSH( SIPUSH obj ) { - } + @Override + public void visitFADD(FADD obj) { + } - - public void visitDSUB( DSUB obj ) { - } - - - public void visitL2F( L2F obj ) { - } - - - public void visitIF_ICMPGT( IF_ICMPGT obj ) { - } - - - public void visitF2D( F2D obj ) { - } - - - public void visitI2L( I2L obj ) { - } - - - public void visitIF_ACMPNE( IF_ACMPNE obj ) { - } - - - public void visitPOP( POP obj ) { - } - - - public void visitI2S( I2S obj ) { - } - - - public void visitIFEQ( IFEQ obj ) { - } - - - public void visitSWAP( SWAP obj ) { - } - - - public void visitIOR( IOR obj ) { - } - - - public void visitIREM( IREM obj ) { - } - - - public void visitIASTORE( IASTORE obj ) { - } - - - public void visitNEWARRAY( NEWARRAY obj ) { - } - - - public void visitINVOKEINTERFACE( INVOKEINTERFACE obj ) { - } - - - public void visitINEG( INEG obj ) { - } - - - public void visitLCMP( LCMP obj ) { - } - - - public void visitJSR_W( JSR_W obj ) { - } - - - public void visitMULTIANEWARRAY( MULTIANEWARRAY obj ) { - } - - - public void visitDUP_X2( DUP_X2 obj ) { - } - - - public void visitSALOAD( SALOAD obj ) { - } - - - public void visitIFNONNULL( IFNONNULL obj ) { - } - - - public void visitDMUL( DMUL obj ) { - } - - - public void visitIFNE( IFNE obj ) { - } - - - public void visitIF_ICMPLE( IF_ICMPLE obj ) { - } - - - public void visitLDC2_W( LDC2_W obj ) { - } - - - public void visitGETFIELD( GETFIELD obj ) { - } - - - public void visitLADD( LADD obj ) { - } - - - public void visitNOP( NOP obj ) { - } - - - public void visitFALOAD( FALOAD obj ) { - } - - - public void visitINSTANCEOF( INSTANCEOF obj ) { - } - - - public void visitIFLE( IFLE obj ) { - } - - - public void visitLXOR( LXOR obj ) { - } - - - public void visitLRETURN( LRETURN obj ) { - } - - - public void visitFCONST( FCONST obj ) { - } - - - public void visitIUSHR( IUSHR obj ) { - } - - - public void visitBALOAD( BALOAD obj ) { - } - - - public void visitDUP2( DUP2 obj ) { - } - - - public void visitIF_ACMPEQ( IF_ACMPEQ obj ) { - } - - - public void visitIMPDEP1( IMPDEP1 obj ) { - } - - - public void visitMONITORENTER( MONITORENTER obj ) { - } - - - public void visitLSHL( LSHL obj ) { - } - - - public void visitDCMPG( DCMPG obj ) { - } - - - public void visitD2L( D2L obj ) { - } - - - public void visitIMPDEP2( IMPDEP2 obj ) { - } - - - public void visitL2D( L2D obj ) { - } - - - public void visitRET( RET obj ) { - } - - - public void visitIFGT( IFGT obj ) { - } - - - public void visitIXOR( IXOR obj ) { - } - - - public void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj ) { - } - - - public void visitFASTORE( FASTORE obj ) { - } - - - public void visitIRETURN( IRETURN obj ) { - } - - - public void visitIF_ICMPNE( IF_ICMPNE obj ) { - } - - - public void visitFLOAD( FLOAD obj ) { - } - - - public void visitLDIV( LDIV obj ) { - } - - - public void visitPUTSTATIC( PUTSTATIC obj ) { - } - - - public void visitAALOAD( AALOAD obj ) { - } - - - public void visitD2I( D2I obj ) { - } - - - public void visitIF_ICMPEQ( IF_ICMPEQ obj ) { - } - - - public void visitAASTORE( AASTORE obj ) { - } - - - public void visitARETURN( ARETURN obj ) { - } - - - public void visitDUP2_X1( DUP2_X1 obj ) { - } - - - public void visitFNEG( FNEG obj ) { - } - - - public void visitGOTO_W( GOTO_W obj ) { - } - - - public void visitD2F( D2F obj ) { - } - - - public void visitGOTO( GOTO obj ) { - } - - - public void visitISUB( ISUB obj ) { - } - - - public void visitF2I( F2I obj ) { - } - - - public void visitDNEG( DNEG obj ) { - } - - - public void visitICONST( ICONST obj ) { - } - - - public void visitFDIV( FDIV obj ) { - } - - - public void visitI2B( I2B obj ) { - } - - - public void visitLNEG( LNEG obj ) { - } - - - public void visitLREM( LREM obj ) { - } - - - public void visitIMUL( IMUL obj ) { - } - - - public void visitIADD( IADD obj ) { - } - - - public void visitLSHR( LSHR obj ) { - } - - - public void visitLOOKUPSWITCH( LOOKUPSWITCH obj ) { - } - - - public void visitDUP_X1( DUP_X1 obj ) { - } - - - public void visitFCMPL( FCMPL obj ) { - } - - - public void visitI2C( I2C obj ) { - } - - - public void visitLMUL( LMUL obj ) { - } - - - public void visitLUSHR( LUSHR obj ) { - } - - - public void visitISHL( ISHL obj ) { - } - - - public void visitLALOAD( LALOAD obj ) { - } - - - public void visitASTORE( ASTORE obj ) { - } - - - public void visitANEWARRAY( ANEWARRAY obj ) { - } - - - public void visitFRETURN( FRETURN obj ) { - } - - - public void visitFADD( FADD obj ) { - } - - - public void visitBREAKPOINT( BREAKPOINT obj ) { - } + @Override + public void visitBREAKPOINT(BREAKPOINT obj) { + } } diff --git a/src/org/apache/bcel/generic/ExceptionThrower.java b/src/org/apache/bcel/generic/ExceptionThrower.java index 570f47c..706e2c8 100644 --- a/src/org/apache/bcel/generic/ExceptionThrower.java +++ b/src/org/apache/bcel/generic/ExceptionThrower.java @@ -17,26 +17,24 @@ package org.apache.bcel.generic; /** - * Denote an instruction that may throw a run-time or a linking - * exception (or both) during execution. This is not quite the truth - * as such; because all instructions may throw an - * java.lang.VirtualMachineError. These exceptions are omitted. + * Denote an instruction that may throw a run-time or a linking exception (or + * both) during execution. This is not quite the truth as such; because all + * instructions may throw an java.lang.VirtualMachineError. These exceptions are + * omitted. * - * The Lava Language Specification specifies exactly which - * RUN-TIME and which LINKING exceptions each - * instruction may throw which is reflected by the implementers. Due - * to the structure of the JVM specification, it may be possible that - * an Instruction implementing this interface returns a Class[] of + * The Lava Language Specification specifies exactly which RUN-TIME and + * which LINKING exceptions each instruction may throw which is reflected + * by the implementers. Due to the structure of the JVM specification, it may be + * possible that an Instruction implementing this interface returns a Class[] of * size 0. - * - * Please note that we speak of an "exception" here when we mean any - * "Throwable" object; so this term is equally used for "Exception" - * and "Error" objects. - * + * + * Please note that we speak of an "exception" here when we mean any "Throwable" + * object; so this term is equally used for "Exception" and "Error" objects. + * * @version $Id: ExceptionThrower.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase + * @author Enver Haase */ public interface ExceptionThrower { - public java.lang.Class[] getExceptions(); + public java.lang.Class[] getExceptions(); } diff --git a/src/org/apache/bcel/generic/F2D.java b/src/org/apache/bcel/generic/F2D.java index b3f9ac1..a924f43 100644 --- a/src/org/apache/bcel/generic/F2D.java +++ b/src/org/apache/bcel/generic/F2D.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * F2D - Convert float to double - *
          Stack: ..., value -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: F2D.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class F2D extends ConversionInstruction { - /** Convert float to double - */ - public F2D() { - super(org.apache.bcel.Constants.F2D); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert float to double + */ + public F2D() { + super(org.apache.bcel.Constants.F2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2D(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2D(this); + } } diff --git a/src/org/apache/bcel/generic/F2I.java b/src/org/apache/bcel/generic/F2I.java index 155d019..31126f0 100644 --- a/src/org/apache/bcel/generic/F2I.java +++ b/src/org/apache/bcel/generic/F2I.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * F2I - Convert float to int - *
          Stack: ..., value -> ..., result
          - * + * + *
          + * Stack: ..., value -> ..., result
          + * 
          + * * @version $Id: F2I.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class F2I extends ConversionInstruction { - /** Convert float to int - */ - public F2I() { - super(org.apache.bcel.Constants.F2I); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert float to int + */ + public F2I() { + super(org.apache.bcel.Constants.F2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2I(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2I(this); + } } diff --git a/src/org/apache/bcel/generic/F2L.java b/src/org/apache/bcel/generic/F2L.java index 83ede65..a0bd284 100644 --- a/src/org/apache/bcel/generic/F2L.java +++ b/src/org/apache/bcel/generic/F2L.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * F2L - Convert float to long - *
          Stack: ..., value -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: F2L.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class F2L extends ConversionInstruction { - /** Convert float to long - */ - public F2L() { - super(org.apache.bcel.Constants.F2L); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert float to long + */ + public F2L() { + super(org.apache.bcel.Constants.F2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2L(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2L(this); + } } diff --git a/src/org/apache/bcel/generic/FADD.java b/src/org/apache/bcel/generic/FADD.java index 88dcb1e..e08e360 100644 --- a/src/org/apache/bcel/generic/FADD.java +++ b/src/org/apache/bcel/generic/FADD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * FADD - Add floats - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: FADD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FADD extends ArithmeticInstruction { - /** Add floats - */ - public FADD() { - super(org.apache.bcel.Constants.FADD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Add floats + */ + public FADD() { + super(org.apache.bcel.Constants.FADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFADD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFADD(this); + } } diff --git a/src/org/apache/bcel/generic/FALOAD.java b/src/org/apache/bcel/generic/FALOAD.java index 06fb7a3..c718f6a 100644 --- a/src/org/apache/bcel/generic/FALOAD.java +++ b/src/org/apache/bcel/generic/FALOAD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * FALOAD - Load float from array - *
          Stack: ..., arrayref, index -> ..., value
          - * + * + *
          + * Stack: ..., arrayref, index -> ..., value
          + * 
          + * * @version $Id: FALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FALOAD extends ArrayInstruction implements StackProducer { - /** Load float from array - */ - public FALOAD() { - super(org.apache.bcel.Constants.FALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Load float from array + */ + public FALOAD() { + super(org.apache.bcel.Constants.FALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitFALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitFALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/FASTORE.java b/src/org/apache/bcel/generic/FASTORE.java index 1545b49..4e8e13e 100644 --- a/src/org/apache/bcel/generic/FASTORE.java +++ b/src/org/apache/bcel/generic/FASTORE.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * FASTORE - Store into float array - *
          Stack: ..., arrayref, index, value -> ...
          - * +/** + * FASTORE - Store into float array + * + *
          + * Stack: ..., arrayref, index, value -> ...
          + * 
          + * * @version $Id: FASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FASTORE extends ArrayInstruction implements StackConsumer { - /** Store float into array - */ - public FASTORE() { - super(org.apache.bcel.Constants.FASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Store float into array + */ + public FASTORE() { + super(org.apache.bcel.Constants.FASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitFASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitFASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/FCMPG.java b/src/org/apache/bcel/generic/FCMPG.java index 9ff626e..da9504c 100644 --- a/src/org/apache/bcel/generic/FCMPG.java +++ b/src/org/apache/bcel/generic/FCMPG.java @@ -16,39 +16,50 @@ */ package org.apache.bcel.generic; -/** +/** * FCMPG - Compare floats: value1 > value2 - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: FCMPG.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class FCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { +public class FCMPG extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - public FCMPG() { - super(org.apache.bcel.Constants.FCMPG, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public FCMPG() { + super(org.apache.bcel.Constants.FCMPG, (short) 1); + } - /** @return Type.FLOAT - */ - public Type getType( ConstantPoolGen cp ) { - return Type.FLOAT; - } + /** + * @return Type.FLOAT + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.FLOAT; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitFCMPG(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitFCMPG(this); + } } diff --git a/src/org/apache/bcel/generic/FCMPL.java b/src/org/apache/bcel/generic/FCMPL.java index 7bc4bf2..5ca6078 100644 --- a/src/org/apache/bcel/generic/FCMPL.java +++ b/src/org/apache/bcel/generic/FCMPL.java @@ -16,39 +16,50 @@ */ package org.apache.bcel.generic; -/** +/** * FCMPL - Compare floats: value1 < value2 - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: FCMPL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class FCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { +public class FCMPL extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - public FCMPL() { - super(org.apache.bcel.Constants.FCMPL, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public FCMPL() { + super(org.apache.bcel.Constants.FCMPL, (short) 1); + } - /** @return Type.FLOAT - */ - public Type getType( ConstantPoolGen cp ) { - return Type.FLOAT; - } + /** + * @return Type.FLOAT + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.FLOAT; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitFCMPL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitFCMPL(this); + } } diff --git a/src/org/apache/bcel/generic/FCONST.java b/src/org/apache/bcel/generic/FCONST.java index 30bb0dc..3f0c2dd 100644 --- a/src/org/apache/bcel/generic/FCONST.java +++ b/src/org/apache/bcel/generic/FCONST.java @@ -16,67 +16,75 @@ */ package org.apache.bcel.generic; -/** +/** * FCONST - Push 0.0, 1.0 or 2.0, other values cause an exception - * - *
          Stack: ... -> ..., 
          - * + * + *
          + * Stack: ... -> ...,
          + * 
          + * * @version $Id: FCONST.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class FCONST extends Instruction implements ConstantPushInstruction, TypedInstruction { +public class FCONST extends Instruction implements ConstantPushInstruction, + TypedInstruction { - private float value; + /** + * + */ + private static final long serialVersionUID = 1L; + private float value; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FCONST() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FCONST() { - } + public FCONST(float f) { + super(org.apache.bcel.Constants.FCONST_0, (short) 1); + if (f == 0.0) { + opcode = org.apache.bcel.Constants.FCONST_0; + } else if (f == 1.0) { + opcode = org.apache.bcel.Constants.FCONST_1; + } else if (f == 2.0) { + opcode = org.apache.bcel.Constants.FCONST_2; + } else { + throw new ClassGenException( + "FCONST can be used only for 0.0, 1.0 and 2.0: " + f); + } + value = f; + } + @Override + public Number getValue() { + return new Float(value); + } - public FCONST(float f) { - super(org.apache.bcel.Constants.FCONST_0, (short) 1); - if (f == 0.0) { - opcode = org.apache.bcel.Constants.FCONST_0; - } else if (f == 1.0) { - opcode = org.apache.bcel.Constants.FCONST_1; - } else if (f == 2.0) { - opcode = org.apache.bcel.Constants.FCONST_2; - } else { - throw new ClassGenException("FCONST can be used only for 0.0, 1.0 and 2.0: " + f); - } - value = f; - } + /** + * @return Type.FLOAT + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.FLOAT; + } - - public Number getValue() { - return new Float(value); - } - - - /** @return Type.FLOAT - */ - public Type getType( ConstantPoolGen cp ) { - return Type.FLOAT; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitFCONST(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitFCONST(this); + } } diff --git a/src/org/apache/bcel/generic/FDIV.java b/src/org/apache/bcel/generic/FDIV.java index 72a2019..5d8a840 100644 --- a/src/org/apache/bcel/generic/FDIV.java +++ b/src/org/apache/bcel/generic/FDIV.java @@ -18,33 +18,43 @@ package org.apache.bcel.generic; /** * FDIV - Divide floats - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: FDIV.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FDIV extends ArithmeticInstruction { - /** Divide floats - */ - public FDIV() { - super(org.apache.bcel.Constants.FDIV); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Divide floats + */ + public FDIV() { + super(org.apache.bcel.Constants.FDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFDIV(this); + } } diff --git a/src/org/apache/bcel/generic/FLOAD.java b/src/org/apache/bcel/generic/FLOAD.java index beda2cb..5781361 100644 --- a/src/org/apache/bcel/generic/FLOAD.java +++ b/src/org/apache/bcel/generic/FLOAD.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * FLOAD - Load float from local variable - *
          Stack ... -> ..., result
          - * + * + *
          + * Stack ... -> ..., result
          + * 
          + * * @version $Id: FLOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FLOAD() { - super(org.apache.bcel.Constants.FLOAD, org.apache.bcel.Constants.FLOAD_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FLOAD() { + super(org.apache.bcel.Constants.FLOAD, + org.apache.bcel.Constants.FLOAD_0); + } - /** Load float from local variable - * @param n index of local variable - */ - public FLOAD(int n) { - super(org.apache.bcel.Constants.FLOAD, org.apache.bcel.Constants.FLOAD_0, n); - } + /** + * Load float from local variable + * + * @param n + * index of local variable + */ + public FLOAD(int n) { + super(org.apache.bcel.Constants.FLOAD, + org.apache.bcel.Constants.FLOAD_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitFLOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitFLOAD(this); + } } diff --git a/src/org/apache/bcel/generic/FMUL.java b/src/org/apache/bcel/generic/FMUL.java index 2375ffe..90c21b0 100644 --- a/src/org/apache/bcel/generic/FMUL.java +++ b/src/org/apache/bcel/generic/FMUL.java @@ -18,33 +18,43 @@ package org.apache.bcel.generic; /** * FMUL - Multiply floats - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: FMUL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FMUL extends ArithmeticInstruction { - /** Multiply floats - */ - public FMUL() { - super(org.apache.bcel.Constants.FMUL); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Multiply floats + */ + public FMUL() { + super(org.apache.bcel.Constants.FMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFMUL(this); + } } diff --git a/src/org/apache/bcel/generic/FNEG.java b/src/org/apache/bcel/generic/FNEG.java index a1c03ec..fe31946 100644 --- a/src/org/apache/bcel/generic/FNEG.java +++ b/src/org/apache/bcel/generic/FNEG.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * FNEG - Negate float - *
          Stack: ..., value -> ..., result
          - * + * + *
          + * Stack: ..., value -> ..., result
          + * 
          + * * @version $Id: FNEG.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FNEG extends ArithmeticInstruction { - public FNEG() { - super(org.apache.bcel.Constants.FNEG); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public FNEG() { + super(org.apache.bcel.Constants.FNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFNEG(this); + } } diff --git a/src/org/apache/bcel/generic/FREM.java b/src/org/apache/bcel/generic/FREM.java index 6227a63..4ded950 100644 --- a/src/org/apache/bcel/generic/FREM.java +++ b/src/org/apache/bcel/generic/FREM.java @@ -18,33 +18,43 @@ package org.apache.bcel.generic; /** * FREM - Remainder of floats - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: FREM.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FREM extends ArithmeticInstruction { - /** Remainder of floats - */ - public FREM() { - super(org.apache.bcel.Constants.FREM); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Remainder of floats + */ + public FREM() { + super(org.apache.bcel.Constants.FREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFREM(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFREM(this); + } } diff --git a/src/org/apache/bcel/generic/FRETURN.java b/src/org/apache/bcel/generic/FRETURN.java index 4676840..0946b65 100644 --- a/src/org/apache/bcel/generic/FRETURN.java +++ b/src/org/apache/bcel/generic/FRETURN.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * FRETURN - Return float from method - *
          Stack: ..., value -> <empty>
          - * +/** + * FRETURN - Return float from method + * + *
          + * Stack: ..., value -> <empty>
          + * 
          + * * @version $Id: FRETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FRETURN extends ReturnInstruction { - /** Return float from method - */ - public FRETURN() { - super(org.apache.bcel.Constants.FRETURN); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Return float from method + */ + public FRETURN() { + super(org.apache.bcel.Constants.FRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitFRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitFRETURN(this); + } } diff --git a/src/org/apache/bcel/generic/FSTORE.java b/src/org/apache/bcel/generic/FSTORE.java index ec4b950..fe0b2b7 100644 --- a/src/org/apache/bcel/generic/FSTORE.java +++ b/src/org/apache/bcel/generic/FSTORE.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * FSTORE - Store float into local variable - *
          Stack: ..., value -> ... 
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: FSTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FSTORE() { - super(org.apache.bcel.Constants.FSTORE, org.apache.bcel.Constants.FSTORE_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FSTORE() { + super(org.apache.bcel.Constants.FSTORE, + org.apache.bcel.Constants.FSTORE_0); + } - /** Store float into local variable - * @param n index of local variable - */ - public FSTORE(int n) { - super(org.apache.bcel.Constants.FSTORE, org.apache.bcel.Constants.FSTORE_0, n); - } + /** + * Store float into local variable + * + * @param n + * index of local variable + */ + public FSTORE(int n) { + super(org.apache.bcel.Constants.FSTORE, + org.apache.bcel.Constants.FSTORE_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitFSTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitFSTORE(this); + } } diff --git a/src/org/apache/bcel/generic/FSUB.java b/src/org/apache/bcel/generic/FSUB.java index 90a8dbb..7aab799 100644 --- a/src/org/apache/bcel/generic/FSUB.java +++ b/src/org/apache/bcel/generic/FSUB.java @@ -18,33 +18,43 @@ package org.apache.bcel.generic; /** * FSUB - Substract floats - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: FSUB.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class FSUB extends ArithmeticInstruction { - /** Substract floats - */ - public FSUB() { - super(org.apache.bcel.Constants.FSUB); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Substract floats + */ + public FSUB() { + super(org.apache.bcel.Constants.FSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFSUB(this); + } } diff --git a/src/org/apache/bcel/generic/FieldGen.java b/src/org/apache/bcel/generic/FieldGen.java index d9af25f..71658e2 100644 --- a/src/org/apache/bcel/generic/FieldGen.java +++ b/src/org/apache/bcel/generic/FieldGen.java @@ -29,329 +29,328 @@ import org.apache.bcel.classfile.Field; import org.apache.bcel.classfile.Utility; import org.apache.bcel.util.BCELComparator; -/** - * Template class for building up a field. The only extraordinary thing - * one can do is to add a constant value attribute to a field (which must of - * course be compatible with to the declared type). - * +/** + * Template class for building up a field. The only extraordinary thing one can + * do is to add a constant value attribute to a field (which must of course be + * compatible with to the declared type). + * * @version $Id: FieldGen.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see Field */ public class FieldGen extends FieldGenOrMethodGen { - private Object value = null; - private static BCELComparator _cmp = new BCELComparator() { + /** + * + */ + private static final long serialVersionUID = 1L; + private Object value = null; + private static BCELComparator _cmp = new BCELComparator() { - public boolean equals( Object o1, Object o2 ) { - FieldGen THIS = (FieldGen) o1; - FieldGen THAT = (FieldGen) o2; - return THIS.getName().equals(THAT.getName()) - && THIS.getSignature().equals(THAT.getSignature()); - } + @Override + public boolean equals(Object o1, Object o2) { + FieldGen THIS = (FieldGen) o1; + FieldGen THAT = (FieldGen) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } + @Override + public int hashCode(Object o) { + FieldGen THIS = (FieldGen) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; - public int hashCode( Object o ) { - FieldGen THIS = (FieldGen) o; - return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); - } - }; + /** + * Declare a field. If it is static (isStatic() == true) and has a basic + * type like int or String it may have an initial value associated with it + * as defined by setInitValue(). + * + * @param access_flags + * access qualifiers + * @param type + * field type + * @param name + * field name + * @param cp + * constant pool + */ + public FieldGen(int access_flags, Type type, String name, ConstantPoolGen cp) { + setAccessFlags(access_flags); + setType(type); + setName(name); + setConstantPool(cp); + } + /** + * Instantiate from existing field. + * + * @param field + * Field object + * @param cp + * constant pool (must contain the same entries as the field's + * constant pool) + */ + public FieldGen(Field field, ConstantPoolGen cp) { + this(field.getAccessFlags(), Type.getType(field.getSignature()), field + .getName(), cp); + Attribute[] attrs = field.getAttributes(); + for (int i = 0; i < attrs.length; i++) { + if (attrs[i] instanceof ConstantValue) { + setValue(((ConstantValue) attrs[i]).getConstantValueIndex()); + } else { + addAttribute(attrs[i]); + } + } + } - /** - * Declare a field. If it is static (isStatic() == true) and has a - * basic type like int or String it may have an initial value - * associated with it as defined by setInitValue(). - * - * @param access_flags access qualifiers - * @param type field type - * @param name field name - * @param cp constant pool - */ - public FieldGen(int access_flags, Type type, String name, ConstantPoolGen cp) { - setAccessFlags(access_flags); - setType(type); - setName(name); - setConstantPool(cp); - } + private void setValue(int index) { + ConstantPool cp = this.cp.getConstantPool(); + Constant c = cp.getConstant(index); + value = ((ConstantObject) c).getConstantValue(cp); + } + /** + * Set (optional) initial value of field, otherwise it will be set to + * null/0/false by the JVM automatically. + */ + public void setInitValue(String str) { + checkType(new ObjectType("java.lang.String")); + if (str != null) { + value = str; + } + } - /** - * Instantiate from existing field. - * - * @param field Field object - * @param cp constant pool (must contain the same entries as the field's constant pool) - */ - public FieldGen(Field field, ConstantPoolGen cp) { - this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp); - Attribute[] attrs = field.getAttributes(); - for (int i = 0; i < attrs.length; i++) { - if (attrs[i] instanceof ConstantValue) { - setValue(((ConstantValue) attrs[i]).getConstantValueIndex()); - } else { - addAttribute(attrs[i]); - } - } - } + public void setInitValue(long l) { + checkType(Type.LONG); + if (l != 0L) { + value = new Long(l); + } + } + public void setInitValue(int i) { + checkType(Type.INT); + if (i != 0) { + value = new Integer(i); + } + } - private void setValue( int index ) { - ConstantPool cp = this.cp.getConstantPool(); - Constant c = cp.getConstant(index); - value = ((ConstantObject) c).getConstantValue(cp); - } + public void setInitValue(short s) { + checkType(Type.SHORT); + if (s != 0) { + value = new Integer(s); + } + } + public void setInitValue(char c) { + checkType(Type.CHAR); + if (c != 0) { + value = new Integer(c); + } + } - /** - * Set (optional) initial value of field, otherwise it will be set to null/0/false - * by the JVM automatically. - */ - public void setInitValue( String str ) { - checkType(new ObjectType("java.lang.String")); - if (str != null) { - value = str; - } - } + public void setInitValue(byte b) { + checkType(Type.BYTE); + if (b != 0) { + value = new Integer(b); + } + } + public void setInitValue(boolean b) { + checkType(Type.BOOLEAN); + if (b) { + value = new Integer(1); + } + } - public void setInitValue( long l ) { - checkType(Type.LONG); - if (l != 0L) { - value = new Long(l); - } - } + public void setInitValue(float f) { + checkType(Type.FLOAT); + if (f != 0.0) { + value = new Float(f); + } + } + public void setInitValue(double d) { + checkType(Type.DOUBLE); + if (d != 0.0) { + value = new Double(d); + } + } - public void setInitValue( int i ) { - checkType(Type.INT); - if (i != 0) { - value = new Integer(i); - } - } + /** + * Remove any initial value. + */ + public void cancelInitValue() { + value = null; + } + private void checkType(Type atype) { + if (type == null) { + throw new ClassGenException( + "You haven't defined the type of the field yet"); + } + if (!isFinal()) { + throw new ClassGenException( + "Only final fields may have an initial value!"); + } + if (!type.equals(atype)) { + throw new ClassGenException("Types are not compatible: " + type + + " vs. " + atype); + } + } - public void setInitValue( short s ) { - checkType(Type.SHORT); - if (s != 0) { - value = new Integer(s); - } - } + /** + * Get field object after having set up all necessary values. + */ + public Field getField() { + String signature = getSignature(); + int name_index = cp.addUtf8(name); + int signature_index = cp.addUtf8(signature); + if (value != null) { + checkType(type); + int index = addConstant(); + addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, + index, cp.getConstantPool())); + } + return new Field(access_flags, name_index, signature_index, + getAttributes(), cp.getConstantPool()); + } + private int addConstant() { + switch (type.getType()) { + case Constants.T_INT: + case Constants.T_CHAR: + case Constants.T_BYTE: + case Constants.T_BOOLEAN: + case Constants.T_SHORT: + return cp.addInteger(((Integer) value).intValue()); + case Constants.T_FLOAT: + return cp.addFloat(((Float) value).floatValue()); + case Constants.T_DOUBLE: + return cp.addDouble(((Double) value).doubleValue()); + case Constants.T_LONG: + return cp.addLong(((Long) value).longValue()); + case Constants.T_REFERENCE: + return cp.addString(((String) value)); + default: + throw new RuntimeException("Oops: Unhandled : " + type.getType()); + } + } - public void setInitValue( char c ) { - checkType(Type.CHAR); - if (c != 0) { - value = new Integer(c); - } - } + @Override + public String getSignature() { + return type.getSignature(); + } + private List observers; - public void setInitValue( byte b ) { - checkType(Type.BYTE); - if (b != 0) { - value = new Integer(b); - } - } + /** + * Add observer for this object. + */ + public void addObserver(FieldObserver o) { + if (observers == null) { + observers = new ArrayList(); + } + observers.add(o); + } + /** + * Remove observer for this object. + */ + public void removeObserver(FieldObserver o) { + if (observers != null) { + observers.remove(o); + } + } - public void setInitValue( boolean b ) { - checkType(Type.BOOLEAN); - if (b) { - value = new Integer(1); - } - } + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (Iterator e = observers.iterator(); e.hasNext();) { + e.next().notify(this); + } + } + } + public String getInitValue() { + if (value != null) { + return value.toString(); + } else { + return null; + } + } - public void setInitValue( float f ) { - checkType(Type.FLOAT); - if (f != 0.0) { - value = new Float(f); - } - } + /** + * Return string representation close to declaration format, `public static + * final short MAX = 100', e.g.. + * + * @return String representation of field + */ + @Override + public final String toString() { + String name, signature, access; // Short cuts to constant pool + access = Utility.accessToString(access_flags); + access = access.equals("") ? "" : (access + " "); + signature = type.toString(); + name = getName(); + StringBuffer buf = new StringBuffer(32); + buf.append(access).append(signature).append(" ").append(name); + String value = getInitValue(); + if (value != null) { + buf.append(" = ").append(value); + } + return buf.toString(); + } + /** + * @return deep copy of this field + */ + public FieldGen copy(ConstantPoolGen cp) { + FieldGen fg = (FieldGen) clone(); + fg.setConstantPool(cp); + return fg; + } - public void setInitValue( double d ) { - checkType(Type.DOUBLE); - if (d != 0.0) { - value = new Double(d); - } - } + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + /** + * @param comparator + * Comparison strategy object + */ + public static void setComparator(BCELComparator comparator) { + _cmp = comparator; + } - /** Remove any initial value. - */ - public void cancelInitValue() { - value = null; - } + /** + * Return value as defined by given BCELComparator strategy. By default two + * FieldGen objects are said to be equal when their names and signatures are + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return _cmp.equals(this, obj); + } - - private void checkType( Type atype ) { - if (type == null) { - throw new ClassGenException("You haven't defined the type of the field yet"); - } - if (!isFinal()) { - throw new ClassGenException("Only final fields may have an initial value!"); - } - if (!type.equals(atype)) { - throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype); - } - } - - - /** - * Get field object after having set up all necessary values. - */ - public Field getField() { - String signature = getSignature(); - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(signature); - if (value != null) { - checkType(type); - int index = addConstant(); - addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, index, cp - .getConstantPool())); - } - return new Field(access_flags, name_index, signature_index, getAttributes(), cp - .getConstantPool()); - } - - - private int addConstant() { - switch (type.getType()) { - case Constants.T_INT: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_BOOLEAN: - case Constants.T_SHORT: - return cp.addInteger(((Integer) value).intValue()); - case Constants.T_FLOAT: - return cp.addFloat(((Float) value).floatValue()); - case Constants.T_DOUBLE: - return cp.addDouble(((Double) value).doubleValue()); - case Constants.T_LONG: - return cp.addLong(((Long) value).longValue()); - case Constants.T_REFERENCE: - return cp.addString(((String) value)); - default: - throw new RuntimeException("Oops: Unhandled : " + type.getType()); - } - } - - - public String getSignature() { - return type.getSignature(); - } - - private List observers; - - - /** Add observer for this object. - */ - public void addObserver( FieldObserver o ) { - if (observers == null) { - observers = new ArrayList(); - } - observers.add(o); - } - - - /** Remove observer for this object. - */ - public void removeObserver( FieldObserver o ) { - if (observers != null) { - observers.remove(o); - } - } - - - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if (observers != null) { - for (Iterator e = observers.iterator(); e.hasNext();) { - ((FieldObserver) e.next()).notify(this); - } - } - } - - - public String getInitValue() { - if (value != null) { - return value.toString(); - } else { - return null; - } - } - - - /** - * Return string representation close to declaration format, - * `public static final short MAX = 100', e.g.. - * - * @return String representation of field - */ - public final String toString() { - String name, signature, access; // Short cuts to constant pool - access = Utility.accessToString(access_flags); - access = access.equals("") ? "" : (access + " "); - signature = type.toString(); - name = getName(); - StringBuffer buf = new StringBuffer(32); - buf.append(access).append(signature).append(" ").append(name); - String value = getInitValue(); - if (value != null) { - buf.append(" = ").append(value); - } - return buf.toString(); - } - - - /** @return deep copy of this field - */ - public FieldGen copy( ConstantPoolGen cp ) { - FieldGen fg = (FieldGen) clone(); - fg.setConstantPool(cp); - return fg; - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return _cmp; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( BCELComparator comparator ) { - _cmp = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two FieldGen objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals( Object obj ) { - return _cmp.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the field's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return _cmp.hashCode(this); - } + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the field's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); + } } diff --git a/src/org/apache/bcel/generic/FieldGenOrMethodGen.java b/src/org/apache/bcel/generic/FieldGenOrMethodGen.java index c711cae..172d0a6 100644 --- a/src/org/apache/bcel/generic/FieldGenOrMethodGen.java +++ b/src/org/apache/bcel/generic/FieldGenOrMethodGen.java @@ -23,109 +23,108 @@ import org.apache.bcel.classfile.AccessFlags; import org.apache.bcel.classfile.Attribute; /** - * Super class for FieldGen and MethodGen objects, since they have - * some methods in common! - * + * Super class for FieldGen and MethodGen objects, since they have some methods + * in common! + * * @version $Id: FieldGenOrMethodGen.java 410087 2006-05-29 12:12:19Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable { +public abstract class FieldGenOrMethodGen extends AccessFlags implements + NamedAndTyped, Cloneable { - protected String name; - protected Type type; - protected ConstantPoolGen cp; - private List attribute_vec = new ArrayList(); + /** + * + */ + private static final long serialVersionUID = 1L; + protected String name; + protected Type type; + protected ConstantPoolGen cp; + private List attribute_vec = new ArrayList(); + protected FieldGenOrMethodGen() { + } - protected FieldGenOrMethodGen() { - } + @Override + public void setType(Type type) { + if (type.getType() == Constants.T_ADDRESS) { + throw new IllegalArgumentException("Type can not be " + type); + } + this.type = type; + } + @Override + public Type getType() { + return type; + } - public void setType( Type type ) { - if (type.getType() == Constants.T_ADDRESS) { - throw new IllegalArgumentException("Type can not be " + type); - } - this.type = type; - } + /** + * @return name of method/field. + */ + @Override + public String getName() { + return name; + } + @Override + public void setName(String name) { + this.name = name; + } - public Type getType() { - return type; - } + public ConstantPoolGen getConstantPool() { + return cp; + } + public void setConstantPool(ConstantPoolGen cp) { + this.cp = cp; + } - /** @return name of method/field. - */ - public String getName() { - return name; - } + /** + * Add an attribute to this method. Currently, the JVM knows about the + * `Code', `ConstantValue', `Synthetic' and `Exceptions' attributes. Other + * attributes will be ignored by the JVM but do no harm. + * + * @param a + * attribute to be added + */ + public void addAttribute(Attribute a) { + attribute_vec.add(a); + } + /** + * Remove an attribute. + */ + public void removeAttribute(Attribute a) { + attribute_vec.remove(a); + } - public void setName( String name ) { - this.name = name; - } + /** + * Remove all attributes. + */ + public void removeAttributes() { + attribute_vec.clear(); + } + /** + * @return all attributes of this method. + */ + public Attribute[] getAttributes() { + Attribute[] attributes = new Attribute[attribute_vec.size()]; + attribute_vec.toArray(attributes); + return attributes; + } - public ConstantPoolGen getConstantPool() { - return cp; - } + /** + * @return signature of method/field. + */ + public abstract String getSignature(); - - public void setConstantPool( ConstantPoolGen cp ) { - this.cp = cp; - } - - - /** - * Add an attribute to this method. Currently, the JVM knows about - * the `Code', `ConstantValue', `Synthetic' and `Exceptions' - * attributes. Other attributes will be ignored by the JVM but do no - * harm. - * - * @param a attribute to be added - */ - public void addAttribute( Attribute a ) { - attribute_vec.add(a); - } - - - /** - * Remove an attribute. - */ - public void removeAttribute( Attribute a ) { - attribute_vec.remove(a); - } - - - /** - * Remove all attributes. - */ - public void removeAttributes() { - attribute_vec.clear(); - } - - - /** - * @return all attributes of this method. - */ - public Attribute[] getAttributes() { - Attribute[] attributes = new Attribute[attribute_vec.size()]; - attribute_vec.toArray(attributes); - return attributes; - } - - - /** @return signature of method/field. - */ - public abstract String getSignature(); - - - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } } diff --git a/src/org/apache/bcel/generic/FieldInstruction.java b/src/org/apache/bcel/generic/FieldInstruction.java index 355b859..936be24 100644 --- a/src/org/apache/bcel/generic/FieldInstruction.java +++ b/src/org/apache/bcel/generic/FieldInstruction.java @@ -20,61 +20,70 @@ import org.apache.bcel.classfile.ConstantPool; /** * Super class for the GET/PUTxxx family of instructions. - * + * * @version $Id: FieldInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class FieldInstruction extends FieldOrMethod implements TypedInstruction { +public abstract class FieldInstruction extends FieldOrMethod implements + TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FieldInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FieldInstruction() { + } - /** - * @param index to constant pool - */ - protected FieldInstruction(short opcode, int index) { - super(opcode, index); - } + /** + * @param index + * to constant pool + */ + protected FieldInstruction(short opcode, int index) { + super(opcode, index); + } + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(ConstantPool cp) { + return org.apache.bcel.Constants.OPCODE_NAMES[opcode] + + " " + + cp.constantToString(index, + org.apache.bcel.Constants.CONSTANT_Fieldref); + } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString( ConstantPool cp ) { - return org.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " - + cp.constantToString(index, org.apache.bcel.Constants.CONSTANT_Fieldref); - } + /** + * @return size of field (1 or 2) + */ + protected int getFieldSize(ConstantPoolGen cpg) { + return getType(cpg).getSize(); + } + /** + * @return return type of referenced field + */ + @Override + public Type getType(ConstantPoolGen cpg) { + return getFieldType(cpg); + } - /** @return size of field (1 or 2) - */ - protected int getFieldSize( ConstantPoolGen cpg ) { - return getType(cpg).getSize(); - } + /** + * @return type of field + */ + public Type getFieldType(ConstantPoolGen cpg) { + return Type.getType(getSignature(cpg)); + } - - /** @return return type of referenced field - */ - public Type getType( ConstantPoolGen cpg ) { - return getFieldType(cpg); - } - - - /** @return type of field - */ - public Type getFieldType( ConstantPoolGen cpg ) { - return Type.getType(getSignature(cpg)); - } - - - /** @return name of referenced field. - */ - public String getFieldName( ConstantPoolGen cpg ) { - return getName(cpg); - } + /** + * @return name of referenced field. + */ + public String getFieldName(ConstantPoolGen cpg) { + return getName(cpg); + } } diff --git a/src/org/apache/bcel/generic/FieldObserver.java b/src/org/apache/bcel/generic/FieldObserver.java index 1731abc..9ec13b4 100644 --- a/src/org/apache/bcel/generic/FieldObserver.java +++ b/src/org/apache/bcel/generic/FieldObserver.java @@ -17,13 +17,13 @@ package org.apache.bcel.generic; /** - * Imnplement this interface if you're interested in changes to a FieldGen object - * and register yourself with addObserver(). - * + * Imnplement this interface if you're interested in changes to a FieldGen + * object and register yourself with addObserver(). + * * @version $Id: FieldObserver.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface FieldObserver { - public void notify( FieldGen field ); + public void notify(FieldGen field); } diff --git a/src/org/apache/bcel/generic/FieldOrMethod.java b/src/org/apache/bcel/generic/FieldOrMethod.java index 114f890..287fc54 100644 --- a/src/org/apache/bcel/generic/FieldOrMethod.java +++ b/src/org/apache/bcel/generic/FieldOrMethod.java @@ -22,107 +22,117 @@ import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.classfile.ConstantUtf8; /** - * Super class for InvokeInstruction and FieldInstruction, since they have - * some methods in common! - * + * Super class for InvokeInstruction and FieldInstruction, since they have some + * methods in common! + * * @version $Id: FieldOrMethod.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class FieldOrMethod extends CPInstruction implements LoadClass { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FieldOrMethod() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FieldOrMethod() { + } - /** - * @param index to constant pool - */ - protected FieldOrMethod(short opcode, int index) { - super(opcode, index); - } + /** + * @param index + * to constant pool + */ + protected FieldOrMethod(short opcode, int index) { + super(opcode, index); + } + /** + * @return signature of referenced method/field. + */ + public String getSignature(ConstantPoolGen cpg) { + ConstantPool cp = cpg.getConstantPool(); + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr + .getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())) + .getBytes(); + } - /** @return signature of referenced method/field. - */ - public String getSignature( ConstantPoolGen cpg ) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP) cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); - } + /** + * @return name of referenced method/field. + */ + public String getName(ConstantPoolGen cpg) { + ConstantPool cp = cpg.getConstantPool(); + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr + .getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } + /** + * @return name of the referenced class/interface + * @deprecated If the instruction references an array class, this method + * will return "java.lang.Object". For code generated by Java + * 1.5, this answer is sometimes wrong (e.g., if the "clone()" + * method is called on an array). A better idea is to use the + * getReferenceType() method, which correctly distinguishes + * between class types and array types. + */ + @Deprecated + public String getClassName(ConstantPoolGen cpg) { + ConstantPool cp = cpg.getConstantPool(); + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + String className = cp.getConstantString(cmr.getClassIndex(), + org.apache.bcel.Constants.CONSTANT_Class); + if (className.startsWith("[")) { + // Turn array classes into java.lang.Object. + return "java.lang.Object"; + } + return className.replace('/', '.'); + } - /** @return name of referenced method/field. - */ - public String getName( ConstantPoolGen cpg ) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP) cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); - } + /** + * @return type of the referenced class/interface + * @deprecated If the instruction references an array class, the ObjectType + * returned will be invalid. Use getReferenceType() instead. + */ + @Deprecated + public ObjectType getClassType(ConstantPoolGen cpg) { + return new ObjectType(getClassName(cpg)); + } + /** + * Return the reference type representing the class, interface, or array + * class referenced by the instruction. + * + * @param cpg + * the ConstantPoolGen used to create the instruction + * @return an ObjectType (if the referenced class type is a class or + * interface), or an ArrayType (if the referenced class type is an + * array class) + */ + public ReferenceType getReferenceType(ConstantPoolGen cpg) { + ConstantPool cp = cpg.getConstantPool(); + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + String className = cp.getConstantString(cmr.getClassIndex(), + org.apache.bcel.Constants.CONSTANT_Class); + if (className.startsWith("[")) { + return (ArrayType) Type.getType(className); + } else { + className = className.replace('/', '.'); + return new ObjectType(className); + } + } - /** @return name of the referenced class/interface - * @deprecated If the instruction references an array class, - * this method will return "java.lang.Object". - * For code generated by Java 1.5, this answer is - * sometimes wrong (e.g., if the "clone()" method is - * called on an array). A better idea is to use - * the getReferenceType() method, which correctly distinguishes - * between class types and array types. - */ - public String getClassName( ConstantPoolGen cpg ) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP) cp.getConstant(index); - String className = cp.getConstantString(cmr.getClassIndex(), - org.apache.bcel.Constants.CONSTANT_Class); - if (className.startsWith("[")) { - // Turn array classes into java.lang.Object. - return "java.lang.Object"; - } - return className.replace('/', '.'); - } - - - /** @return type of the referenced class/interface - * @deprecated If the instruction references an array class, - * the ObjectType returned will be invalid. Use - * getReferenceType() instead. - */ - public ObjectType getClassType( ConstantPoolGen cpg ) { - return new ObjectType(getClassName(cpg)); - } - - - /** - * Return the reference type representing the class, interface, - * or array class referenced by the instruction. - * @param cpg the ConstantPoolGen used to create the instruction - * @return an ObjectType (if the referenced class type is a class - * or interface), or an ArrayType (if the referenced class - * type is an array class) - */ - public ReferenceType getReferenceType( ConstantPoolGen cpg ) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP) cp.getConstant(index); - String className = cp.getConstantString(cmr.getClassIndex(), - org.apache.bcel.Constants.CONSTANT_Class); - if (className.startsWith("[")) { - return (ArrayType) Type.getType(className); - } else { - className = className.replace('/', '.'); - return new ObjectType(className); - } - } - - - /** @return type of the referenced class/interface - */ - public ObjectType getLoadClassType( ConstantPoolGen cpg ) { - return getClassType(cpg); - } + /** + * @return type of the referenced class/interface + */ + @Override + public ObjectType getLoadClassType(ConstantPoolGen cpg) { + return getClassType(cpg); + } } diff --git a/src/org/apache/bcel/generic/GETFIELD.java b/src/org/apache/bcel/generic/GETFIELD.java index 1ca8708..d72d012 100644 --- a/src/org/apache/bcel/generic/GETFIELD.java +++ b/src/org/apache/bcel/generic/GETFIELD.java @@ -19,63 +19,76 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.ExceptionConstants; -/** +/** * GETFIELD - Fetch field from object - *
          Stack: ..., objectref -> ..., value
          + * + *
          + * Stack: ..., objectref -> ..., value
          + * 
          + * * OR - *
          Stack: ..., objectref -> ..., value.word1, value.word2
          - * + * + *
          + * Stack: ..., objectref -> ..., value.word1, value.word2
          + * 
          + * * @version $Id: GETFIELD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class GETFIELD extends FieldInstruction implements ExceptionThrower, StackConsumer, - StackProducer { +public class GETFIELD extends FieldInstruction implements ExceptionThrower, + StackConsumer, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GETFIELD() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GETFIELD() { + } - public GETFIELD(int index) { - super(Constants.GETFIELD, index); - } + public GETFIELD(int index) { + super(Constants.GETFIELD, index); + } + @Override + public int produceStack(ConstantPoolGen cpg) { + return getFieldSize(cpg); + } - public int produceStack( ConstantPoolGen cpg ) { - return getFieldSize(cpg); - } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; + return cs; + } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitGETFIELD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitGETFIELD(this); + } } diff --git a/src/org/apache/bcel/generic/GETSTATIC.java b/src/org/apache/bcel/generic/GETSTATIC.java index 581bada..61c2975 100644 --- a/src/org/apache/bcel/generic/GETSTATIC.java +++ b/src/org/apache/bcel/generic/GETSTATIC.java @@ -19,61 +19,75 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.ExceptionConstants; -/** +/** * GETSTATIC - Fetch static field from class - *
          Stack: ..., -> ..., value
          + * + *
          + * Stack: ..., -> ..., value
          + * 
          + * * OR - *
          Stack: ..., -> ..., value.word1, value.word2
          - * + * + *
          + * Stack: ..., -> ..., value.word1, value.word2
          + * 
          + * * @version $Id: GETSTATIC.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class GETSTATIC extends FieldInstruction implements PushInstruction, ExceptionThrower { +public class GETSTATIC extends FieldInstruction implements PushInstruction, + ExceptionThrower { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GETSTATIC() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GETSTATIC() { + } - public GETSTATIC(int index) { - super(Constants.GETSTATIC, index); - } + public GETSTATIC(int index) { + super(Constants.GETSTATIC, index); + } + @Override + public int produceStack(ConstantPoolGen cpg) { + return getFieldSize(cpg); + } - public int produceStack( ConstantPoolGen cpg ) { - return getFieldSize(cpg); - } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + return cs; + } - - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitGETSTATIC(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitGETSTATIC(this); + } } diff --git a/src/org/apache/bcel/generic/GOTO.java b/src/org/apache/bcel/generic/GOTO.java index 50777f6..9dc4d7d 100644 --- a/src/org/apache/bcel/generic/GOTO.java +++ b/src/org/apache/bcel/generic/GOTO.java @@ -19,71 +19,80 @@ package org.apache.bcel.generic; import java.io.DataOutputStream; import java.io.IOException; -/** +/** * GOTO - Branch always (to relative offset, not absolute address) - * + * * @version $Id: GOTO.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class GOTO extends GotoInstruction implements VariableLengthInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GOTO() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GOTO() { + } - public GOTO(InstructionHandle target) { - super(org.apache.bcel.Constants.GOTO, target); - } + public GOTO(InstructionHandle target) { + super(org.apache.bcel.Constants.GOTO, target); + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + index = getTargetOffset(); + if (opcode == org.apache.bcel.Constants.GOTO) { + super.dump(out); + } else { // GOTO_W + index = getTargetOffset(); + out.writeByte(opcode); + out.writeInt(index); + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - index = getTargetOffset(); - if (opcode == org.apache.bcel.Constants.GOTO) { - super.dump(out); - } else { // GOTO_W - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - } + /** + * Called in pass 2 of InstructionList.setPositions() in order to update the + * branch target, that may shift due to variable length instructions. + */ + @Override + protected int updatePosition(int offset, int max_offset) { + int i = getTargetOffset(); // Depending on old position value + position += offset; // Position may be shifted by preceding expansions + if (Math.abs(i) >= (32767 - max_offset)) { // to large for short + // (estimate) + opcode = org.apache.bcel.Constants.GOTO_W; + length = 5; + return 2; // 5 - 3 + } + return 0; + } - - /** Called in pass 2 of InstructionList.setPositions() in order to update - * the branch target, that may shift due to variable length instructions. - */ - protected int updatePosition( int offset, int max_offset ) { - int i = getTargetOffset(); // Depending on old position value - position += offset; // Position may be shifted by preceding expansions - if (Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate) - opcode = org.apache.bcel.Constants.GOTO_W; - length = 5; - return 2; // 5 - 3 - } - return 0; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitVariableLengthInstruction(this); - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitVariableLengthInstruction(this); + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO(this); + } } diff --git a/src/org/apache/bcel/generic/GOTO_W.java b/src/org/apache/bcel/generic/GOTO_W.java index 3909cb0..228d95e 100644 --- a/src/org/apache/bcel/generic/GOTO_W.java +++ b/src/org/apache/bcel/generic/GOTO_W.java @@ -20,60 +20,68 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * GOTO_W - Branch always (to relative offset, not absolute address) - * + * * @version $Id: GOTO_W.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class GOTO_W extends GotoInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GOTO_W() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GOTO_W() { + } - public GOTO_W(InstructionHandle target) { - super(org.apache.bcel.Constants.GOTO_W, target); - length = 5; - } + public GOTO_W(InstructionHandle target) { + super(org.apache.bcel.Constants.GOTO_W, target); + length = 5; + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + index = getTargetOffset(); + out.writeByte(opcode); + out.writeInt(index); + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + index = bytes.readInt(); + length = 5; + } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - index = bytes.readInt(); - length = 5; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO_W(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO_W(this); + } } diff --git a/src/org/apache/bcel/generic/GotoInstruction.java b/src/org/apache/bcel/generic/GotoInstruction.java index f263dad..b0ceb55 100644 --- a/src/org/apache/bcel/generic/GotoInstruction.java +++ b/src/org/apache/bcel/generic/GotoInstruction.java @@ -16,23 +16,28 @@ */ package org.apache.bcel.generic; -/** +/** * Super class for GOTO - * + * * @version $Id: GotoInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class GotoInstruction extends BranchInstruction implements UnconditionalBranch { +public abstract class GotoInstruction extends BranchInstruction implements + UnconditionalBranch { - GotoInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } + /** + * + */ + private static final long serialVersionUID = 1L; + GotoInstruction(short opcode, InstructionHandle target) { + super(opcode, target); + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GotoInstruction() { - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GotoInstruction() { + } } diff --git a/src/org/apache/bcel/generic/I2B.java b/src/org/apache/bcel/generic/I2B.java index b35057c..1f609d4 100644 --- a/src/org/apache/bcel/generic/I2B.java +++ b/src/org/apache/bcel/generic/I2B.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * I2B - Convert int to byte - *
          Stack: ..., value -> ..., result
          - * + * + *
          + * Stack: ..., value -> ..., result
          + * 
          + * * @version $Id: I2B.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class I2B extends ConversionInstruction { - /** Convert int to byte - */ - public I2B() { - super(org.apache.bcel.Constants.I2B); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert int to byte + */ + public I2B() { + super(org.apache.bcel.Constants.I2B); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2B(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2B(this); + } } diff --git a/src/org/apache/bcel/generic/I2C.java b/src/org/apache/bcel/generic/I2C.java index b2a9849..87c7ee2 100644 --- a/src/org/apache/bcel/generic/I2C.java +++ b/src/org/apache/bcel/generic/I2C.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * I2C - Convert int to char - *
          Stack: ..., value -> ..., result
          - * + * + *
          + * Stack: ..., value -> ..., result
          + * 
          + * * @version $Id: I2C.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class I2C extends ConversionInstruction { - /** Convert int to char - */ - public I2C() { - super(org.apache.bcel.Constants.I2C); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert int to char + */ + public I2C() { + super(org.apache.bcel.Constants.I2C); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2C(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2C(this); + } } diff --git a/src/org/apache/bcel/generic/I2D.java b/src/org/apache/bcel/generic/I2D.java index cb002df..434685d 100644 --- a/src/org/apache/bcel/generic/I2D.java +++ b/src/org/apache/bcel/generic/I2D.java @@ -18,33 +18,43 @@ package org.apache.bcel.generic; /** * I2D - Convert int to double - *
          Stack: ..., value -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: I2D.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class I2D extends ConversionInstruction { - /** Convert int to double - */ - public I2D() { - super(org.apache.bcel.Constants.I2D); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert int to double + */ + public I2D() { + super(org.apache.bcel.Constants.I2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2D(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2D(this); + } } diff --git a/src/org/apache/bcel/generic/I2F.java b/src/org/apache/bcel/generic/I2F.java index 235cab9..e4ffa33 100644 --- a/src/org/apache/bcel/generic/I2F.java +++ b/src/org/apache/bcel/generic/I2F.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * I2F - Convert int to float - *
          Stack: ..., value -> ..., result
          - * + * + *
          + * Stack: ..., value -> ..., result
          + * 
          + * * @version $Id: I2F.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class I2F extends ConversionInstruction { - /** Convert int to float - */ - public I2F() { - super(org.apache.bcel.Constants.I2F); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert int to float + */ + public I2F() { + super(org.apache.bcel.Constants.I2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2F(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2F(this); + } } diff --git a/src/org/apache/bcel/generic/I2L.java b/src/org/apache/bcel/generic/I2L.java index 01bb564..f63e22d 100644 --- a/src/org/apache/bcel/generic/I2L.java +++ b/src/org/apache/bcel/generic/I2L.java @@ -18,33 +18,43 @@ package org.apache.bcel.generic; /** * I2L - Convert int to long - *
          Stack: ..., value -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: I2L.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class I2L extends ConversionInstruction { - /** Convert int to long - */ - public I2L() { - super(org.apache.bcel.Constants.I2L); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Convert int to long + */ + public I2L() { + super(org.apache.bcel.Constants.I2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2L(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2L(this); + } } diff --git a/src/org/apache/bcel/generic/I2S.java b/src/org/apache/bcel/generic/I2S.java index 3bbd2ae..492d3ef 100644 --- a/src/org/apache/bcel/generic/I2S.java +++ b/src/org/apache/bcel/generic/I2S.java @@ -18,31 +18,40 @@ package org.apache.bcel.generic; /** * I2S - Convert int to short - *
          Stack: ..., value -> ..., result
          - * + * + *
          + * Stack: ..., value -> ..., result
          + * 
          + * * @version $Id: I2S.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class I2S extends ConversionInstruction { - public I2S() { - super(org.apache.bcel.Constants.I2S); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public I2S() { + super(org.apache.bcel.Constants.I2S); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2S(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2S(this); + } } diff --git a/src/org/apache/bcel/generic/IADD.java b/src/org/apache/bcel/generic/IADD.java index 7fafc4f..ad8bbcf 100644 --- a/src/org/apache/bcel/generic/IADD.java +++ b/src/org/apache/bcel/generic/IADD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * IADD - Add ints - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: IADD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IADD extends ArithmeticInstruction { - /** Add ints - */ - public IADD() { - super(org.apache.bcel.Constants.IADD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Add ints + */ + public IADD() { + super(org.apache.bcel.Constants.IADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIADD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIADD(this); + } } diff --git a/src/org/apache/bcel/generic/IALOAD.java b/src/org/apache/bcel/generic/IALOAD.java index b90d887..1e43cf9 100644 --- a/src/org/apache/bcel/generic/IALOAD.java +++ b/src/org/apache/bcel/generic/IALOAD.java @@ -16,36 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * IALOAD - Load int from array - *
          Stack: ..., arrayref, index -> ..., value
          - * + * + *
          + * Stack: ..., arrayref, index -> ..., value
          + * 
          + * * @version $Id: IALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IALOAD extends ArrayInstruction implements StackProducer { - /** - * Load int from array - */ - public IALOAD() { - super(org.apache.bcel.Constants.IALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Load int from array + */ + public IALOAD() { + super(org.apache.bcel.Constants.IALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitIALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitIALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/IAND.java b/src/org/apache/bcel/generic/IAND.java index fd6917e..85ab840 100644 --- a/src/org/apache/bcel/generic/IAND.java +++ b/src/org/apache/bcel/generic/IAND.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * IAND - Bitwise AND int - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: IAND.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IAND extends ArithmeticInstruction { - public IAND() { - super(org.apache.bcel.Constants.IAND); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public IAND() { + super(org.apache.bcel.Constants.IAND); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIAND(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIAND(this); + } } diff --git a/src/org/apache/bcel/generic/IASTORE.java b/src/org/apache/bcel/generic/IASTORE.java index 0b87504..0a159db 100644 --- a/src/org/apache/bcel/generic/IASTORE.java +++ b/src/org/apache/bcel/generic/IASTORE.java @@ -16,36 +16,45 @@ */ package org.apache.bcel.generic; -/** - * IASTORE - Store into int array - *
          Stack: ..., arrayref, index, value -> ...
          - * +/** + * IASTORE - Store into int array + * + *
          + * Stack: ..., arrayref, index, value -> ...
          + * 
          + * * @version $Id: IASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IASTORE extends ArrayInstruction implements StackConsumer { - /** - * Store into int array - */ - public IASTORE() { - super(org.apache.bcel.Constants.IASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Store into int array + */ + public IASTORE() { + super(org.apache.bcel.Constants.IASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitIASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitIASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/ICONST.java b/src/org/apache/bcel/generic/ICONST.java index 98b9f00..6eab6d5 100644 --- a/src/org/apache/bcel/generic/ICONST.java +++ b/src/org/apache/bcel/generic/ICONST.java @@ -16,63 +16,74 @@ */ package org.apache.bcel.generic; -/** +/** * ICONST - Push value between -1, ..., 5, other values cause an exception - * - *
          Stack: ... -> ..., 
          - * + * + *
          + * Stack: ... -> ...,
          + * 
          + * * @version $Id: ICONST.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class ICONST extends Instruction implements ConstantPushInstruction, TypedInstruction { +public class ICONST extends Instruction implements ConstantPushInstruction, + TypedInstruction { - private int value; + /** + * + */ + private static final long serialVersionUID = 1L; + private int value; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ICONST() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ICONST() { - } + public ICONST(int i) { + super(org.apache.bcel.Constants.ICONST_0, (short) 1); + if ((i >= -1) && (i <= 5)) { + opcode = (short) (org.apache.bcel.Constants.ICONST_0 + i); // Even + // works + // for i + // == -1 + } else { + throw new ClassGenException( + "ICONST can be used only for value between -1 and 5: " + i); + } + value = i; + } + @Override + public Number getValue() { + return new Integer(value); + } - public ICONST(int i) { - super(org.apache.bcel.Constants.ICONST_0, (short) 1); - if ((i >= -1) && (i <= 5)) { - opcode = (short) (org.apache.bcel.Constants.ICONST_0 + i); // Even works for i == -1 - } else { - throw new ClassGenException("ICONST can be used only for value between -1 and 5: " + i); - } - value = i; - } + /** + * @return Type.INT + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.INT; + } - - public Number getValue() { - return new Integer(value); - } - - - /** @return Type.INT - */ - public Type getType( ConstantPoolGen cp ) { - return Type.INT; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitICONST(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitICONST(this); + } } diff --git a/src/org/apache/bcel/generic/IDIV.java b/src/org/apache/bcel/generic/IDIV.java index eb4d404..db8cfeb 100644 --- a/src/org/apache/bcel/generic/IDIV.java +++ b/src/org/apache/bcel/generic/IDIV.java @@ -18,43 +18,52 @@ package org.apache.bcel.generic; /** * IDIV - Divide ints - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: IDIV.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IDIV extends ArithmeticInstruction implements ExceptionThrower { - /** Divide ints - */ - public IDIV() { - super(org.apache.bcel.Constants.IDIV); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Divide ints + */ + public IDIV() { + super(org.apache.bcel.Constants.IDIV); + } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION - }; - } + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIDIV(this); + } } diff --git a/src/org/apache/bcel/generic/IFEQ.java b/src/org/apache/bcel/generic/IFEQ.java index 9747dcc..90f05a0 100644 --- a/src/org/apache/bcel/generic/IFEQ.java +++ b/src/org/apache/bcel/generic/IFEQ.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFEQ - Branch if int comparison with zero succeeds - * - *
          Stack: ..., value -> ...
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: IFEQ.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFEQ() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFEQ() { + } - public IFEQ(InstructionHandle target) { - super(org.apache.bcel.Constants.IFEQ, target); - } + public IFEQ(InstructionHandle target) { + super(org.apache.bcel.Constants.IFEQ, target); + } + /** + * @return negation of instruction, e.g. IFEQ.negate() == IFNE + */ + @Override + public IfInstruction negate() { + return new IFNE(target); + } - /** - * @return negation of instruction, e.g. IFEQ.negate() == IFNE - */ - public IfInstruction negate() { - return new IFNE(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFEQ(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFEQ(this); + } } diff --git a/src/org/apache/bcel/generic/IFGE.java b/src/org/apache/bcel/generic/IFGE.java index f4478ad..93a4314 100644 --- a/src/org/apache/bcel/generic/IFGE.java +++ b/src/org/apache/bcel/generic/IFGE.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFGE - Branch if int comparison with zero succeeds - * - *
          Stack: ..., value -> ...
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: IFGE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFGE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFGE() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFGE() { + } - public IFGE(InstructionHandle target) { - super(org.apache.bcel.Constants.IFGE, target); - } + public IFGE(InstructionHandle target) { + super(org.apache.bcel.Constants.IFGE, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLT(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFLT(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFGE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFGE(this); + } } diff --git a/src/org/apache/bcel/generic/IFGT.java b/src/org/apache/bcel/generic/IFGT.java index 990c163..1b74414 100644 --- a/src/org/apache/bcel/generic/IFGT.java +++ b/src/org/apache/bcel/generic/IFGT.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFGT - Branch if int comparison with zero succeeds - * - *
          Stack: ..., value -> ...
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: IFGT.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFGT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFGT() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFGT() { + } - public IFGT(InstructionHandle target) { - super(org.apache.bcel.Constants.IFGT, target); - } + public IFGT(InstructionHandle target) { + super(org.apache.bcel.Constants.IFGT, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLE(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFLE(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFGT(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFGT(this); + } } diff --git a/src/org/apache/bcel/generic/IFLE.java b/src/org/apache/bcel/generic/IFLE.java index d8f5f37..61326d6 100644 --- a/src/org/apache/bcel/generic/IFLE.java +++ b/src/org/apache/bcel/generic/IFLE.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFLE - Branch if int comparison with zero succeeds - * - *
          Stack: ..., value -> ...
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: IFLE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFLE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFLE() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFLE() { + } - public IFLE(InstructionHandle target) { - super(org.apache.bcel.Constants.IFLE, target); - } + public IFLE(InstructionHandle target) { + super(org.apache.bcel.Constants.IFLE, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGT(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFGT(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFLE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFLE(this); + } } diff --git a/src/org/apache/bcel/generic/IFLT.java b/src/org/apache/bcel/generic/IFLT.java index 5a048a6..62c323c 100644 --- a/src/org/apache/bcel/generic/IFLT.java +++ b/src/org/apache/bcel/generic/IFLT.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFLT - Branch if int comparison with zero succeeds - * - *
          Stack: ..., value -> ...
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: IFLT.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFLT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFLT() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFLT() { + } - public IFLT(InstructionHandle target) { - super(org.apache.bcel.Constants.IFLT, target); - } + public IFLT(InstructionHandle target) { + super(org.apache.bcel.Constants.IFLT, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGE(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFGE(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFLT(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFLT(this); + } } diff --git a/src/org/apache/bcel/generic/IFNE.java b/src/org/apache/bcel/generic/IFNE.java index 2658aa1..b76f955 100644 --- a/src/org/apache/bcel/generic/IFNE.java +++ b/src/org/apache/bcel/generic/IFNE.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFNE - Branch if int comparison with zero succeeds - * - *
          Stack: ..., value -> ...
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: IFNE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNE() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNE() { + } - public IFNE(InstructionHandle target) { - super(org.apache.bcel.Constants.IFNE, target); - } + public IFNE(InstructionHandle target) { + super(org.apache.bcel.Constants.IFNE, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFEQ(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFEQ(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNE(this); + } } diff --git a/src/org/apache/bcel/generic/IFNONNULL.java b/src/org/apache/bcel/generic/IFNONNULL.java index e986bdc..8513726 100644 --- a/src/org/apache/bcel/generic/IFNONNULL.java +++ b/src/org/apache/bcel/generic/IFNONNULL.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFNONNULL - Branch if reference is not null - * - *
          Stack: ..., reference -> ...
          - * + * + *
          + * Stack: ..., reference -> ...
          + * 
          + * * @version $Id: IFNONNULL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFNONNULL extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNONNULL() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNONNULL() { + } - public IFNONNULL(InstructionHandle target) { - super(org.apache.bcel.Constants.IFNONNULL, target); - } + public IFNONNULL(InstructionHandle target) { + super(org.apache.bcel.Constants.IFNONNULL, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNULL(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFNULL(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNONNULL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNONNULL(this); + } } diff --git a/src/org/apache/bcel/generic/IFNULL.java b/src/org/apache/bcel/generic/IFNULL.java index 0e91ca1..4936f2c 100644 --- a/src/org/apache/bcel/generic/IFNULL.java +++ b/src/org/apache/bcel/generic/IFNULL.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IFNULL - Branch if reference is not null - * - *
          Stack: ..., reference -> ...
          - * + * + *
          + * Stack: ..., reference -> ...
          + * 
          + * * @version $Id: IFNULL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IFNULL extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNULL() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNULL() { + } - public IFNULL(InstructionHandle target) { - super(org.apache.bcel.Constants.IFNULL, target); - } + public IFNULL(InstructionHandle target) { + super(org.apache.bcel.Constants.IFNULL, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNONNULL(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFNONNULL(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNULL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNULL(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ACMPEQ.java b/src/org/apache/bcel/generic/IF_ACMPEQ.java index 42eed3b..ac61b05 100644 --- a/src/org/apache/bcel/generic/IF_ACMPEQ.java +++ b/src/org/apache/bcel/generic/IF_ACMPEQ.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ACMPEQ - Branch if reference comparison succeeds - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ACMPEQ.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ACMPEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ACMPEQ() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ACMPEQ() { + } - public IF_ACMPEQ(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ACMPEQ, target); - } + public IF_ACMPEQ(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ACMPEQ, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPNE(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ACMPNE(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ACMPEQ(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ACMPEQ(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ACMPNE.java b/src/org/apache/bcel/generic/IF_ACMPNE.java index 14fc230..ddb4a4d 100644 --- a/src/org/apache/bcel/generic/IF_ACMPNE.java +++ b/src/org/apache/bcel/generic/IF_ACMPNE.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ACMPNE - Branch if reference comparison doesn't succeed - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ACMPNE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ACMPNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ACMPNE() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ACMPNE() { + } - public IF_ACMPNE(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ACMPNE, target); - } + public IF_ACMPNE(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ACMPNE, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPEQ(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ACMPEQ(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ACMPNE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ACMPNE(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ICMPEQ.java b/src/org/apache/bcel/generic/IF_ICMPEQ.java index 5308842..d7dfb4d 100644 --- a/src/org/apache/bcel/generic/IF_ICMPEQ.java +++ b/src/org/apache/bcel/generic/IF_ICMPEQ.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ICMPEQ - Branch if int comparison succeeds - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ICMPEQ.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ICMPEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPEQ() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPEQ() { + } - public IF_ICMPEQ(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ICMPEQ, target); - } + public IF_ICMPEQ(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ICMPEQ, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPNE(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPNE(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPEQ(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPEQ(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ICMPGE.java b/src/org/apache/bcel/generic/IF_ICMPGE.java index 9e23be2..7d30e01 100644 --- a/src/org/apache/bcel/generic/IF_ICMPGE.java +++ b/src/org/apache/bcel/generic/IF_ICMPGE.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ICMPGE - Branch if int comparison succeeds - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ICMPGE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ICMPGE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPGE() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPGE() { + } - public IF_ICMPGE(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ICMPGE, target); - } + public IF_ICMPGE(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ICMPGE, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLT(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPLT(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPGE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPGE(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ICMPGT.java b/src/org/apache/bcel/generic/IF_ICMPGT.java index 32f1ece..cc907ad 100644 --- a/src/org/apache/bcel/generic/IF_ICMPGT.java +++ b/src/org/apache/bcel/generic/IF_ICMPGT.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ICMPGT - Branch if int comparison succeeds - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ICMPGT.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ICMPGT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPGT() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPGT() { + } - public IF_ICMPGT(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ICMPGT, target); - } + public IF_ICMPGT(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ICMPGT, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLE(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPLE(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPGT(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPGT(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ICMPLE.java b/src/org/apache/bcel/generic/IF_ICMPLE.java index 381a78b..0e30a5f 100644 --- a/src/org/apache/bcel/generic/IF_ICMPLE.java +++ b/src/org/apache/bcel/generic/IF_ICMPLE.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ICMPLE - Branch if int comparison succeeds - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ICMPLE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ICMPLE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPLE() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPLE() { + } - public IF_ICMPLE(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ICMPLE, target); - } + public IF_ICMPLE(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ICMPLE, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGT(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPGT(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPLE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPLE(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ICMPLT.java b/src/org/apache/bcel/generic/IF_ICMPLT.java index c9e269e..9ebabcd 100644 --- a/src/org/apache/bcel/generic/IF_ICMPLT.java +++ b/src/org/apache/bcel/generic/IF_ICMPLT.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ICMPLT - Branch if int comparison succeeds - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ICMPLT.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ICMPLT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPLT() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPLT() { + } - public IF_ICMPLT(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ICMPLT, target); - } + public IF_ICMPLT(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ICMPLT, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGE(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPGE(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPLT(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPLT(this); + } } diff --git a/src/org/apache/bcel/generic/IF_ICMPNE.java b/src/org/apache/bcel/generic/IF_ICMPNE.java index 537b416..ca67f6c 100644 --- a/src/org/apache/bcel/generic/IF_ICMPNE.java +++ b/src/org/apache/bcel/generic/IF_ICMPNE.java @@ -16,49 +16,56 @@ */ package org.apache.bcel.generic; -/** +/** * IF_ICMPNE - Branch if int comparison doesn't succeed - * - *
          Stack: ..., value1, value2 -> ...
          - * + * + *
          + * Stack: ..., value1, value2 -> ...
          + * 
          + * * @version $Id: IF_ICMPNE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IF_ICMPNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPNE() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPNE() { + } - public IF_ICMPNE(InstructionHandle target) { - super(org.apache.bcel.Constants.IF_ICMPNE, target); - } + public IF_ICMPNE(InstructionHandle target) { + super(org.apache.bcel.Constants.IF_ICMPNE, target); + } + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPEQ(target); + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPEQ(target); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPNE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPNE(this); + } } diff --git a/src/org/apache/bcel/generic/IINC.java b/src/org/apache/bcel/generic/IINC.java index 72af3ab..ecd01d4 100644 --- a/src/org/apache/bcel/generic/IINC.java +++ b/src/org/apache/bcel/generic/IINC.java @@ -22,137 +22,144 @@ import org.apache.bcel.util.ByteSequence; /** * IINC - Increment local variable by constant - * + * * @version $Id: IINC.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IINC extends LocalVariableInstruction { - private boolean wide; - private int c; + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean wide; + private int c; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IINC() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IINC() { - } + /** + * @param n + * index of local variable + * @param c + * increment factor + */ + public IINC(int n, int c) { + super(); // Default behaviour of LocalVariableInstruction causes error + this.opcode = org.apache.bcel.Constants.IINC; + this.length = (short) 3; + setIndex(n); // May set wide as side effect + setIncrement(c); + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + if (wide) { + out.writeByte(org.apache.bcel.Constants.WIDE); + } + out.writeByte(opcode); + if (wide) { + out.writeShort(n); + out.writeShort(c); + } else { + out.writeByte(n); + out.writeByte(c); + } + } - /** - * @param n index of local variable - * @param c increment factor - */ - public IINC(int n, int c) { - super(); // Default behaviour of LocalVariableInstruction causes error - this.opcode = org.apache.bcel.Constants.IINC; - this.length = (short) 3; - setIndex(n); // May set wide as side effect - setIncrement(c); - } + private final void setWide() { + wide = (n > org.apache.bcel.Constants.MAX_BYTE) + || (Math.abs(c) > Byte.MAX_VALUE); + if (wide) { + length = 6; // wide byte included + } else { + length = 3; + } + } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + this.wide = wide; + if (wide) { + length = 6; + n = bytes.readUnsignedShort(); + c = bytes.readShort(); + } else { + length = 3; + n = bytes.readUnsignedByte(); + c = bytes.readByte(); + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - if (wide) { - out.writeByte(org.apache.bcel.Constants.WIDE); - } - out.writeByte(opcode); - if (wide) { - out.writeShort(n); - out.writeShort(c); - } else { - out.writeByte(n); - out.writeByte(c); - } - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + c; + } + /** + * Set index of local variable. + */ + @Override + public final void setIndex(int n) { + if (n < 0) { + throw new ClassGenException("Negative index value: " + n); + } + this.n = n; + setWide(); + } - private final void setWide() { - wide = (n > org.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE); - if (wide) { - length = 6; // wide byte included - } else { - length = 3; - } - } + /** + * @return increment factor + */ + public final int getIncrement() { + return c; + } + /** + * Set increment factor. + */ + public final void setIncrement(int c) { + this.c = c; + setWide(); + } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - this.wide = wide; - if (wide) { - length = 6; - n = bytes.readUnsignedShort(); - c = bytes.readShort(); - } else { - length = 3; - n = bytes.readUnsignedByte(); - c = bytes.readByte(); - } - } + /** + * @return int type + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.INT; + } - - /** - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - return super.toString(verbose) + " " + c; - } - - - /** - * Set index of local variable. - */ - public final void setIndex( int n ) { - if (n < 0) { - throw new ClassGenException("Negative index value: " + n); - } - this.n = n; - setWide(); - } - - - /** - * @return increment factor - */ - public final int getIncrement() { - return c; - } - - - /** - * Set increment factor. - */ - public final void setIncrement( int c ) { - this.c = c; - setWide(); - } - - - /** @return int type - */ - public Type getType( ConstantPoolGen cp ) { - return Type.INT; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLocalVariableInstruction(this); - v.visitIINC(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLocalVariableInstruction(this); + v.visitIINC(this); + } } diff --git a/src/org/apache/bcel/generic/ILOAD.java b/src/org/apache/bcel/generic/ILOAD.java index 64368d3..bdcacca 100644 --- a/src/org/apache/bcel/generic/ILOAD.java +++ b/src/org/apache/bcel/generic/ILOAD.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * ILOAD - Load int from local variable onto stack - *
          Stack: ... -> ..., result
          - * + * + *
          + * Stack: ... -> ..., result
          + * 
          + * * @version $Id: ILOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ILOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ILOAD() { - super(org.apache.bcel.Constants.ILOAD, org.apache.bcel.Constants.ILOAD_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ILOAD() { + super(org.apache.bcel.Constants.ILOAD, + org.apache.bcel.Constants.ILOAD_0); + } - /** Load int from local variable - * @param n index of local variable - */ - public ILOAD(int n) { - super(org.apache.bcel.Constants.ILOAD, org.apache.bcel.Constants.ILOAD_0, n); - } + /** + * Load int from local variable + * + * @param n + * index of local variable + */ + public ILOAD(int n) { + super(org.apache.bcel.Constants.ILOAD, + org.apache.bcel.Constants.ILOAD_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitILOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitILOAD(this); + } } diff --git a/src/org/apache/bcel/generic/IMPDEP1.java b/src/org/apache/bcel/generic/IMPDEP1.java index 2d16659..cfc560b 100644 --- a/src/org/apache/bcel/generic/IMPDEP1.java +++ b/src/org/apache/bcel/generic/IMPDEP1.java @@ -18,26 +18,32 @@ package org.apache.bcel.generic; /** * IMPDEP1 - Implementation dependent - * + * * @version $Id: IMPDEP1.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IMPDEP1 extends Instruction { - public IMPDEP1() { - super(org.apache.bcel.Constants.IMPDEP1, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public IMPDEP1() { + super(org.apache.bcel.Constants.IMPDEP1, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitIMPDEP1(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitIMPDEP1(this); + } } diff --git a/src/org/apache/bcel/generic/IMPDEP2.java b/src/org/apache/bcel/generic/IMPDEP2.java index 4efdb87..cd57b29 100644 --- a/src/org/apache/bcel/generic/IMPDEP2.java +++ b/src/org/apache/bcel/generic/IMPDEP2.java @@ -18,26 +18,32 @@ package org.apache.bcel.generic; /** * IMPDEP2 - Implementation dependent - * + * * @version $Id: IMPDEP2.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IMPDEP2 extends Instruction { - public IMPDEP2() { - super(org.apache.bcel.Constants.IMPDEP2, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public IMPDEP2() { + super(org.apache.bcel.Constants.IMPDEP2, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitIMPDEP2(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitIMPDEP2(this); + } } diff --git a/src/org/apache/bcel/generic/IMUL.java b/src/org/apache/bcel/generic/IMUL.java index bb212c2..b944b5b 100644 --- a/src/org/apache/bcel/generic/IMUL.java +++ b/src/org/apache/bcel/generic/IMUL.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * IMUL - Multiply ints - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: IMUL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IMUL extends ArithmeticInstruction { - /** Multiply ints - */ - public IMUL() { - super(org.apache.bcel.Constants.IMUL); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Multiply ints + */ + public IMUL() { + super(org.apache.bcel.Constants.IMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIMUL(this); + } } diff --git a/src/org/apache/bcel/generic/INEG.java b/src/org/apache/bcel/generic/INEG.java index c7ef3c8..db25323 100644 --- a/src/org/apache/bcel/generic/INEG.java +++ b/src/org/apache/bcel/generic/INEG.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * INEG - Negate int - *
          Stack: ..., value -> ..., result
          - * + * + *
          + * Stack: ..., value -> ..., result
          + * 
          + * * @version $Id: INEG.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class INEG extends ArithmeticInstruction { - public INEG() { - super(org.apache.bcel.Constants.INEG); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public INEG() { + super(org.apache.bcel.Constants.INEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitINEG(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitINEG(this); + } } diff --git a/src/org/apache/bcel/generic/INSTANCEOF.java b/src/org/apache/bcel/generic/INSTANCEOF.java index 139f708..db79830 100644 --- a/src/org/apache/bcel/generic/INSTANCEOF.java +++ b/src/org/apache/bcel/generic/INSTANCEOF.java @@ -16,58 +16,66 @@ */ package org.apache.bcel.generic; -/** +/** * INSTANCEOF - Determine if object is of given type - *
          Stack: ..., objectref -> ..., result
          - * + * + *
          + * Stack: ..., objectref -> ..., result
          + * 
          + * * @version $Id: INSTANCEOF.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class INSTANCEOF extends CPInstruction implements LoadClass, ExceptionThrower, - StackProducer, StackConsumer { +public class INSTANCEOF extends CPInstruction implements LoadClass, + ExceptionThrower, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INSTANCEOF() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INSTANCEOF() { + } - public INSTANCEOF(int index) { - super(org.apache.bcel.Constants.INSTANCEOF, index); - } + public INSTANCEOF(int index) { + super(org.apache.bcel.Constants.INSTANCEOF, index); + } + @Override + public Class[] getExceptions() { + return org.apache.bcel.ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION; + } - public Class[] getExceptions() { - return org.apache.bcel.ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION; - } + @Override + public ObjectType getLoadClassType(ConstantPoolGen cpg) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } - - public ObjectType getLoadClassType( ConstantPoolGen cpg ) { - Type t = getType(cpg); - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - return (t instanceof ObjectType) ? (ObjectType) t : null; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLoadClass(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitINSTANCEOF(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLoadClass(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitINSTANCEOF(this); + } } diff --git a/src/org/apache/bcel/generic/INVOKEINTERFACE.java b/src/org/apache/bcel/generic/INVOKEINTERFACE.java index 99da626..4af8f41 100644 --- a/src/org/apache/bcel/generic/INVOKEINTERFACE.java +++ b/src/org/apache/bcel/generic/INVOKEINTERFACE.java @@ -23,110 +23,122 @@ import org.apache.bcel.ExceptionConstants; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.util.ByteSequence; -/** +/** * INVOKEINTERFACE - Invoke interface method - *
          Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
          - * + * + *
          + * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
          + * 
          + * * @version $Id: INVOKEINTERFACE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class INVOKEINTERFACE extends InvokeInstruction { - private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 + /** + * + */ + private static final long serialVersionUID = 1L; + private int nargs; // Number of arguments on stack (number of stack slots), + // called "count" in vmspec2 + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEINTERFACE() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKEINTERFACE() { - } + public INVOKEINTERFACE(int index, int nargs) { + super(Constants.INVOKEINTERFACE, index); + length = 5; + if (nargs < 1) { + throw new ClassGenException("Number of arguments must be > 0 " + + nargs); + } + this.nargs = nargs; + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeShort(index); + out.writeByte(nargs); + out.writeByte(0); + } - public INVOKEINTERFACE(int index, int nargs) { - super(Constants.INVOKEINTERFACE, index); - length = 5; - if (nargs < 1) { - throw new ClassGenException("Number of arguments must be > 0 " + nargs); - } - this.nargs = nargs; - } + /** + * The count argument according to the Java Language Specification, + * Second Edition. + */ + public int getCount() { + return nargs; + } + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + super.initFromFile(bytes, wide); + length = 5; + nargs = bytes.readUnsignedByte(); + bytes.readByte(); // Skip 0 byte + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - out.writeByte(nargs); - out.writeByte(0); - } + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(ConstantPool cp) { + return super.toString(cp) + " " + nargs; + } + @Override + public int consumeStack(ConstantPoolGen cpg) { // nargs is given in + // byte-code + return nargs; // nargs includes this reference + } - /** - * The count argument according to the Java Language Specification, - * Second Edition. - */ - public int getCount() { - return nargs; - } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; + cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 1] = ExceptionConstants.ABSTRACT_METHOD_ERROR; + cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; + return cs; + } - - /** - * Read needed data (i.e., index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - super.initFromFile(bytes, wide); - length = 5; - nargs = bytes.readUnsignedByte(); - bytes.readByte(); // Skip 0 byte - } - - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString( ConstantPool cp ) { - return super.toString(cp) + " " + nargs; - } - - - public int consumeStack( ConstantPoolGen cpg ) { // nargs is given in byte-code - return nargs; // nargs includes this reference - } - - - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 1] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKEINTERFACE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEINTERFACE(this); + } } diff --git a/src/org/apache/bcel/generic/INVOKESPECIAL.java b/src/org/apache/bcel/generic/INVOKESPECIAL.java index d960c49..3b9bfc5 100644 --- a/src/org/apache/bcel/generic/INVOKESPECIAL.java +++ b/src/org/apache/bcel/generic/INVOKESPECIAL.java @@ -19,59 +19,67 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.ExceptionConstants; -/** - * INVOKESPECIAL - Invoke instance method; special handling for superclass, private - * and instance initialization method invocations - * - *
          Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
          - * +/** + * INVOKESPECIAL - Invoke instance method; special handling for superclass, + * private and instance initialization method invocations + * + *
          + * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
          + * 
          + * * @version $Id: INVOKESPECIAL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class INVOKESPECIAL extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKESPECIAL() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKESPECIAL() { + } - public INVOKESPECIAL(int index) { - super(Constants.INVOKESPECIAL, index); - } + public INVOKESPECIAL(int index) { + super(Constants.INVOKESPECIAL, index); + } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; + return cs; + } - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKESPECIAL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKESPECIAL(this); + } } diff --git a/src/org/apache/bcel/generic/INVOKESTATIC.java b/src/org/apache/bcel/generic/INVOKESTATIC.java index 6300182..72409d4 100644 --- a/src/org/apache/bcel/generic/INVOKESTATIC.java +++ b/src/org/apache/bcel/generic/INVOKESTATIC.java @@ -19,56 +19,64 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.ExceptionConstants; -/** +/** * INVOKESTATIC - Invoke a class (static) method - * - *
          Stack: ..., [arg1, [arg2 ...]] -> ...
          - * + * + *
          + * Stack: ..., [arg1, [arg2 ...]] -> ...
          + * 
          + * * @version $Id: INVOKESTATIC.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class INVOKESTATIC extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKESTATIC() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKESTATIC() { + } - public INVOKESTATIC(int index) { - super(Constants.INVOKESTATIC, index); - } + public INVOKESTATIC(int index) { + super(Constants.INVOKESTATIC, index); + } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + return cs; + } - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKESTATIC(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKESTATIC(this); + } } diff --git a/src/org/apache/bcel/generic/INVOKEVIRTUAL.java b/src/org/apache/bcel/generic/INVOKEVIRTUAL.java index d4faaac..fd4fbee 100644 --- a/src/org/apache/bcel/generic/INVOKEVIRTUAL.java +++ b/src/org/apache/bcel/generic/INVOKEVIRTUAL.java @@ -19,58 +19,66 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.ExceptionConstants; -/** +/** * INVOKEVIRTUAL - Invoke instance method; dispatch based on class - * - *
          Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
          - * + * + *
          + * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
          + * 
          + * * @version $Id: INVOKEVIRTUAL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class INVOKEVIRTUAL extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKEVIRTUAL() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEVIRTUAL() { + } - public INVOKEVIRTUAL(int index) { - super(Constants.INVOKEVIRTUAL, index); - } + public INVOKEVIRTUAL(int index) { + super(Constants.INVOKEVIRTUAL, index); + } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; + return cs; + } - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKEVIRTUAL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEVIRTUAL(this); + } } diff --git a/src/org/apache/bcel/generic/IOR.java b/src/org/apache/bcel/generic/IOR.java index c1c6598..21547eb 100644 --- a/src/org/apache/bcel/generic/IOR.java +++ b/src/org/apache/bcel/generic/IOR.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * IOR - Bitwise OR int - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: IOR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IOR extends ArithmeticInstruction { - public IOR() { - super(org.apache.bcel.Constants.IOR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public IOR() { + super(org.apache.bcel.Constants.IOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIOR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIOR(this); + } } diff --git a/src/org/apache/bcel/generic/IREM.java b/src/org/apache/bcel/generic/IREM.java index 9504b9d..4977625 100644 --- a/src/org/apache/bcel/generic/IREM.java +++ b/src/org/apache/bcel/generic/IREM.java @@ -18,43 +18,52 @@ package org.apache.bcel.generic; /** * IREM - Remainder of int - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: IREM.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IREM extends ArithmeticInstruction implements ExceptionThrower { - /** Remainder of ints - */ - public IREM() { - super(org.apache.bcel.Constants.IREM); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Remainder of ints + */ + public IREM() { + super(org.apache.bcel.Constants.IREM); + } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION - }; - } + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIREM(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIREM(this); + } } diff --git a/src/org/apache/bcel/generic/IRETURN.java b/src/org/apache/bcel/generic/IRETURN.java index 61d45bd..767b4be 100644 --- a/src/org/apache/bcel/generic/IRETURN.java +++ b/src/org/apache/bcel/generic/IRETURN.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * IRETURN - Return int from method - *
          Stack: ..., value -> <empty>
          - * +/** + * IRETURN - Return int from method + * + *
          + * Stack: ..., value -> <empty>
          + * 
          + * * @version $Id: IRETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IRETURN extends ReturnInstruction { - /** Return int from method - */ - public IRETURN() { - super(org.apache.bcel.Constants.IRETURN); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Return int from method + */ + public IRETURN() { + super(org.apache.bcel.Constants.IRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitIRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitIRETURN(this); + } } diff --git a/src/org/apache/bcel/generic/ISHL.java b/src/org/apache/bcel/generic/ISHL.java index 510773c..05244cf 100644 --- a/src/org/apache/bcel/generic/ISHL.java +++ b/src/org/apache/bcel/generic/ISHL.java @@ -18,31 +18,40 @@ package org.apache.bcel.generic; /** * ISHL - Arithmetic shift left int - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: ISHL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ISHL extends ArithmeticInstruction { - public ISHL() { - super(org.apache.bcel.Constants.ISHL); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public ISHL() { + super(org.apache.bcel.Constants.ISHL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISHL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISHL(this); + } } diff --git a/src/org/apache/bcel/generic/ISHR.java b/src/org/apache/bcel/generic/ISHR.java index 2bc71a3..03f3178 100644 --- a/src/org/apache/bcel/generic/ISHR.java +++ b/src/org/apache/bcel/generic/ISHR.java @@ -18,31 +18,40 @@ package org.apache.bcel.generic; /** * ISHR - Arithmetic shift right int - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: ISHR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ISHR extends ArithmeticInstruction { - public ISHR() { - super(org.apache.bcel.Constants.ISHR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public ISHR() { + super(org.apache.bcel.Constants.ISHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISHR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISHR(this); + } } diff --git a/src/org/apache/bcel/generic/ISTORE.java b/src/org/apache/bcel/generic/ISTORE.java index bca07c1..3f80b96 100644 --- a/src/org/apache/bcel/generic/ISTORE.java +++ b/src/org/apache/bcel/generic/ISTORE.java @@ -16,42 +16,55 @@ */ package org.apache.bcel.generic; -/** +/** * ISTORE - Store int from stack into local variable - *
          Stack: ..., value -> ... 
          - * + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * @version $Id: ISTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ISTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ISTORE() { - super(org.apache.bcel.Constants.ISTORE, org.apache.bcel.Constants.ISTORE_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ISTORE() { + super(org.apache.bcel.Constants.ISTORE, + org.apache.bcel.Constants.ISTORE_0); + } - /** Store int into local variable - * @param n index of local variable - */ - public ISTORE(int n) { - super(org.apache.bcel.Constants.ISTORE, org.apache.bcel.Constants.ISTORE_0, n); - } + /** + * Store int into local variable + * + * @param n + * index of local variable + */ + public ISTORE(int n) { + super(org.apache.bcel.Constants.ISTORE, + org.apache.bcel.Constants.ISTORE_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitISTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitISTORE(this); + } } diff --git a/src/org/apache/bcel/generic/ISUB.java b/src/org/apache/bcel/generic/ISUB.java index 9885687..a303f30 100644 --- a/src/org/apache/bcel/generic/ISUB.java +++ b/src/org/apache/bcel/generic/ISUB.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * ISUB - Substract ints - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: ISUB.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ISUB extends ArithmeticInstruction { - /** Substract ints - */ - public ISUB() { - super(org.apache.bcel.Constants.ISUB); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Substract ints + */ + public ISUB() { + super(org.apache.bcel.Constants.ISUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISUB(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISUB(this); + } } diff --git a/src/org/apache/bcel/generic/IUSHR.java b/src/org/apache/bcel/generic/IUSHR.java index 6e5cc1c..36bc1ec 100644 --- a/src/org/apache/bcel/generic/IUSHR.java +++ b/src/org/apache/bcel/generic/IUSHR.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * IUSHR - Logical shift right int - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: IUSHR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IUSHR extends ArithmeticInstruction { - public IUSHR() { - super(org.apache.bcel.Constants.IUSHR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public IUSHR() { + super(org.apache.bcel.Constants.IUSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIUSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIUSHR(this); + } } diff --git a/src/org/apache/bcel/generic/IXOR.java b/src/org/apache/bcel/generic/IXOR.java index 0e3472f..9338502 100644 --- a/src/org/apache/bcel/generic/IXOR.java +++ b/src/org/apache/bcel/generic/IXOR.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * IXOR - Bitwise XOR int - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: IXOR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class IXOR extends ArithmeticInstruction { - public IXOR() { - super(org.apache.bcel.Constants.IXOR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public IXOR() { + super(org.apache.bcel.Constants.IXOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIXOR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIXOR(this); + } } diff --git a/src/org/apache/bcel/generic/IfInstruction.java b/src/org/apache/bcel/generic/IfInstruction.java index 33af0c0..c443b9c 100644 --- a/src/org/apache/bcel/generic/IfInstruction.java +++ b/src/org/apache/bcel/generic/IfInstruction.java @@ -18,31 +18,37 @@ package org.apache.bcel.generic; /** * Super class for the IFxxx family of instructions. - * + * * @version $Id: IfInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class IfInstruction extends BranchInstruction implements StackConsumer { +public abstract class IfInstruction extends BranchInstruction implements + StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IfInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IfInstruction() { + } - /** - * @param opcode opcode of instruction - * @param target Target instruction to branch to - */ - protected IfInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } + /** + * @param opcode + * opcode of instruction + * @param target + * Target instruction to branch to + */ + protected IfInstruction(short opcode, InstructionHandle target) { + super(opcode, target); + } - - /** - * @return negation of instruction, e.g. IFEQ.negate() == IFNE - */ - public abstract IfInstruction negate(); + /** + * @return negation of instruction, e.g. IFEQ.negate() == IFNE + */ + public abstract IfInstruction negate(); } diff --git a/src/org/apache/bcel/generic/IndexedInstruction.java b/src/org/apache/bcel/generic/IndexedInstruction.java index 3735f2c..25bf990 100644 --- a/src/org/apache/bcel/generic/IndexedInstruction.java +++ b/src/org/apache/bcel/generic/IndexedInstruction.java @@ -17,16 +17,15 @@ package org.apache.bcel.generic; /** - * Denote entity that refers to an index, e.g. local variable instructions, - * RET, CPInstruction, etc. - * + * Denote entity that refers to an index, e.g. local variable instructions, RET, + * CPInstruction, etc. + * * @version $Id: IndexedInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface IndexedInstruction { - public int getIndex(); + public int getIndex(); - - public void setIndex( int index ); + public void setIndex(int index); } diff --git a/src/org/apache/bcel/generic/Instruction.java b/src/org/apache/bcel/generic/Instruction.java index 4de3c5c..0704729 100644 --- a/src/org/apache/bcel/generic/Instruction.java +++ b/src/org/apache/bcel/generic/Instruction.java @@ -24,269 +24,278 @@ import org.apache.bcel.Constants; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.util.ByteSequence; -/** +/** * Abstract super class for all Java byte codes. - * + * * @version $Id: Instruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class Instruction implements Cloneable, Serializable { - protected short length = 1; // Length of instruction in bytes - protected short opcode = -1; // Opcode number - private static InstructionComparator cmp = InstructionComparator.DEFAULT; + /** + * + */ + private static final long serialVersionUID = 1L; + protected short length = 1; // Length of instruction in bytes + protected short opcode = -1; // Opcode number + private static InstructionComparator cmp = InstructionComparator.DEFAULT; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + Instruction() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - Instruction() { - } + public Instruction(short opcode, short length) { + this.length = length; + this.opcode = opcode; + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); // Common for all instructions + } - public Instruction(short opcode, short length) { - this.length = length; - this.opcode = opcode; - } + /** + * @return name of instruction, i.e., opcode name + */ + public String getName() { + return Constants.OPCODE_NAMES[opcode]; + } + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" + * + * @param verbose + * long/short format switch + * @return mnemonic for instruction + */ + public String toString(boolean verbose) { + if (verbose) { + return getName() + "[" + opcode + "](" + length + ")"; + } else { + return getName(); + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); // Common for all instructions - } + /** + * @return mnemonic for instruction in verbose format + */ + @Override + public String toString() { + return toString(true); + } + /** + * @return mnemonic for instruction with sumbolic references resolved + */ + public String toString(ConstantPool cp) { + return toString(false); + } - /** @return name of instruction, i.e., opcode name - */ - public String getName() { - return Constants.OPCODE_NAMES[opcode]; - } + /** + * Use with caution, since `BranchInstruction's have a `target' reference + * which is not copied correctly (only basic types are). This also applies + * for `Select' instructions with their multiple branch targets. + * + * @see BranchInstruction + * @return (shallow) copy of an instruction + */ + public Instruction copy() { + Instruction i = null; + // "Constant" instruction, no need to duplicate + if (InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null) { + i = this; + } else { + try { + i = (Instruction) clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + } + } + return i; + } + /** + * Read needed data (e.g. index) from file. + * + * @param bytes + * byte sequence to read from + * @param wide + * "wide" instruction flag + */ + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + } - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - if (verbose) { - return getName() + "[" + opcode + "](" + length + ")"; - } else { - return getName(); - } - } + /** + * Read an instruction from (byte code) input stream and return the + * appropiate object. + * + * @param bytes + * input stream bytes + * @return instruction object being read + */ + public static final Instruction readInstruction(ByteSequence bytes) + throws IOException { + boolean wide = false; + short opcode = (short) bytes.readUnsignedByte(); + Instruction obj = null; + if (opcode == Constants.WIDE) { // Read next opcode after wide byte + wide = true; + opcode = (short) bytes.readUnsignedByte(); + } + if (InstructionConstants.INSTRUCTIONS[opcode] != null) { + return InstructionConstants.INSTRUCTIONS[opcode]; // Used predefined + // immutable + // object, if + // available + } + /* + * Find appropiate class, instantiate an (empty) instruction object and + * initialize it by hand. + */ + Class clazz; + try { + clazz = Class.forName(className(opcode)); + } catch (ClassNotFoundException cnfe) { + // If a class by that name does not exist, the opcode is illegal. + // Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a + // sense. + throw new ClassGenException("Illegal opcode detected."); + } + try { + obj = (Instruction) clazz.newInstance(); + if (wide + && !((obj instanceof LocalVariableInstruction) + || (obj instanceof IINC) || (obj instanceof RET))) { + throw new Exception("Illegal opcode after wide: " + opcode); + } + obj.setOpcode(opcode); + obj.initFromFile(bytes, wide); // Do further initializations, if any + // Byte code offset set in InstructionList + } catch (Exception e) { + throw new ClassGenException(e.toString()); + } + return obj; + } + private static final String className(short opcode) { + String name = Constants.OPCODE_NAMES[opcode] + .toUpperCase(Locale.ENGLISH); + /* + * ICONST_0, etc. will be shortened to ICONST, etc., since ICONST_0 and + * the like are not implemented (directly). + */ + try { + int len = name.length(); + char ch1 = name.charAt(len - 2), ch2 = name.charAt(len - 1); + if ((ch1 == '_') && (ch2 >= '0') && (ch2 <= '5')) { + name = name.substring(0, len - 2); + } + if (name.equals("ICONST_M1")) { + name = "ICONST"; + } + } catch (StringIndexOutOfBoundsException e) { + System.err.println(e); + } + return "org.apache.bcel.generic." + name; + } - /** - * @return mnemonic for instruction in verbose format - */ - public String toString() { - return toString(true); - } + /** + * This method also gives right results for instructions whose effect on the + * stack depends on the constant pool entry they reference. + * + * @return Number of words consumed from stack by this instruction, or + * Constants.UNPREDICTABLE, if this can not be computed statically + */ + public int consumeStack(ConstantPoolGen cpg) { + return Constants.CONSUME_STACK[opcode]; + } + /** + * This method also gives right results for instructions whose effect on the + * stack depends on the constant pool entry they reference. + * + * @return Number of words produced onto stack by this instruction, or + * Constants.UNPREDICTABLE, if this can not be computed statically + */ + public int produceStack(ConstantPoolGen cpg) { + return Constants.PRODUCE_STACK[opcode]; + } - /** - * @return mnemonic for instruction with sumbolic references resolved - */ - public String toString( ConstantPool cp ) { - return toString(false); - } + /** + * @return this instructions opcode + */ + public short getOpcode() { + return opcode; + } + /** + * @return length (in bytes) of instruction + */ + public int getLength() { + return length; + } - /** - * Use with caution, since `BranchInstruction's have a `target' reference which - * is not copied correctly (only basic types are). This also applies for - * `Select' instructions with their multiple branch targets. - * - * @see BranchInstruction - * @return (shallow) copy of an instruction - */ - public Instruction copy() { - Instruction i = null; - // "Constant" instruction, no need to duplicate - if (InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null) { - i = this; - } else { - try { - i = (Instruction) clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - } - } - return i; - } + /** + * Needed in readInstruction. + */ + private void setOpcode(short opcode) { + this.opcode = opcode; + } + /** + * Some instructions may be reused, so don't do anything by default. + */ + void dispose() { + } - /** - * Read needed data (e.g. index) from file. - * - * @param bytes byte sequence to read from - * @param wide "wide" instruction flag - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + public abstract void accept(Visitor v); + /** + * Get Comparator object used in the equals() method to determine equality + * of instructions. + * + * @return currently used comparator for equals() + */ + public static InstructionComparator getComparator() { + return cmp; + } - /** - * Read an instruction from (byte code) input stream and return the - * appropiate object. - * - * @param bytes input stream bytes - * @return instruction object being read - */ - public static final Instruction readInstruction( ByteSequence bytes ) throws IOException { - boolean wide = false; - short opcode = (short) bytes.readUnsignedByte(); - Instruction obj = null; - if (opcode == Constants.WIDE) { // Read next opcode after wide byte - wide = true; - opcode = (short) bytes.readUnsignedByte(); - } - if (InstructionConstants.INSTRUCTIONS[opcode] != null) { - return InstructionConstants.INSTRUCTIONS[opcode]; // Used predefined immutable object, if available - } - /* Find appropiate class, instantiate an (empty) instruction object - * and initialize it by hand. - */ - Class clazz; - try { - clazz = Class.forName(className(opcode)); - } catch (ClassNotFoundException cnfe) { - // If a class by that name does not exist, the opcode is illegal. - // Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a sense. - throw new ClassGenException("Illegal opcode detected."); - } - try { - obj = (Instruction) clazz.newInstance(); - if (wide - && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) { - throw new Exception("Illegal opcode after wide: " + opcode); - } - obj.setOpcode(opcode); - obj.initFromFile(bytes, wide); // Do further initializations, if any - // Byte code offset set in InstructionList - } catch (Exception e) { - throw new ClassGenException(e.toString()); - } - return obj; - } + /** + * Set comparator to be used for equals(). + */ + public static void setComparator(InstructionComparator c) { + cmp = c; + } - - private static final String className( short opcode ) { - String name = Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH); - /* ICONST_0, etc. will be shortened to ICONST, etc., since ICONST_0 and the like - * are not implemented (directly). - */ - try { - int len = name.length(); - char ch1 = name.charAt(len - 2), ch2 = name.charAt(len - 1); - if ((ch1 == '_') && (ch2 >= '0') && (ch2 <= '5')) { - name = name.substring(0, len - 2); - } - if (name.equals("ICONST_M1")) { - name = "ICONST"; - } - } catch (StringIndexOutOfBoundsException e) { - System.err.println(e); - } - return "org.apache.bcel.generic." + name; - } - - - /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words consumed from stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically - */ - public int consumeStack( ConstantPoolGen cpg ) { - return Constants.CONSUME_STACK[opcode]; - } - - - /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words produced onto stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically - */ - public int produceStack( ConstantPoolGen cpg ) { - return Constants.PRODUCE_STACK[opcode]; - } - - - /** - * @return this instructions opcode - */ - public short getOpcode() { - return opcode; - } - - - /** - * @return length (in bytes) of instruction - */ - public int getLength() { - return length; - } - - - /** - * Needed in readInstruction. - */ - private void setOpcode( short opcode ) { - this.opcode = opcode; - } - - - /** Some instructions may be reused, so don't do anything by default. - */ - void dispose() { - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public abstract void accept( Visitor v ); - - - /** Get Comparator object used in the equals() method to determine - * equality of instructions. - * - * @return currently used comparator for equals() - */ - public static InstructionComparator getComparator() { - return cmp; - } - - - /** Set comparator to be used for equals(). - */ - public static void setComparator( InstructionComparator c ) { - cmp = c; - } - - - /** Check for equality, delegated to comparator - * @return true if that is an Instruction and has the same opcode - */ - public boolean equals( Object that ) { - return (that instanceof Instruction) ? cmp.equals(this, (Instruction) that) : false; - } + /** + * Check for equality, delegated to comparator + * + * @return true if that is an Instruction and has the same opcode + */ + @Override + public boolean equals(Object that) { + return (that instanceof Instruction) ? cmp.equals(this, + (Instruction) that) : false; + } } diff --git a/src/org/apache/bcel/generic/InstructionComparator.java b/src/org/apache/bcel/generic/InstructionComparator.java index 0813011..7717631 100644 --- a/src/org/apache/bcel/generic/InstructionComparator.java +++ b/src/org/apache/bcel/generic/InstructionComparator.java @@ -17,53 +17,54 @@ package org.apache.bcel.generic; /** - * Equality of instructions isn't clearly to be defined. You might - * wish, for example, to compare whether instructions have the same - * meaning. E.g., whether two INVOKEVIRTUALs describe the same - * call.
          The DEFAULT comparator however, considers two instructions - * to be equal if they have same opcode and point to the same indexes - * (if any) in the constant pool or the same local variable index. Branch - * instructions must have the same target. - * + * Equality of instructions isn't clearly to be defined. You might wish, for + * example, to compare whether instructions have the same meaning. E.g., whether + * two INVOKEVIRTUALs describe the same call.
          + * The DEFAULT comparator however, considers two instructions to be equal if + * they have same opcode and point to the same indexes (if any) in the constant + * pool or the same local variable index. Branch instructions must have the same + * target. + * * @see Instruction * @version $Id: InstructionComparator.java 386056 2006-03-15 11:31:56Z tcurdt $ * @author M. Dahm */ public interface InstructionComparator { - public static final InstructionComparator DEFAULT = new InstructionComparator() { + public static final InstructionComparator DEFAULT = new InstructionComparator() { - public boolean equals( Instruction i1, Instruction i2 ) { - if (i1.opcode == i2.opcode) { - if (i1 instanceof Select) { - InstructionHandle[] t1 = ((Select) i1).getTargets(); - InstructionHandle[] t2 = ((Select) i2).getTargets(); - if (t1.length == t2.length) { - for (int i = 0; i < t1.length; i++) { - if (t1[i] != t2[i]) { - return false; - } - } - return true; - } - } else if (i1 instanceof BranchInstruction) { - return ((BranchInstruction) i1).target == ((BranchInstruction) i2).target; - } else if (i1 instanceof ConstantPushInstruction) { - return ((ConstantPushInstruction) i1).getValue().equals( - ((ConstantPushInstruction) i2).getValue()); - } else if (i1 instanceof IndexedInstruction) { - return ((IndexedInstruction) i1).getIndex() == ((IndexedInstruction) i2) - .getIndex(); - } else if (i1 instanceof NEWARRAY) { - return ((NEWARRAY) i1).getTypecode() == ((NEWARRAY) i2).getTypecode(); - } else { - return true; - } - } - return false; - } - }; + @Override + public boolean equals(Instruction i1, Instruction i2) { + if (i1.opcode == i2.opcode) { + if (i1 instanceof Select) { + InstructionHandle[] t1 = ((Select) i1).getTargets(); + InstructionHandle[] t2 = ((Select) i2).getTargets(); + if (t1.length == t2.length) { + for (int i = 0; i < t1.length; i++) { + if (t1[i] != t2[i]) { + return false; + } + } + return true; + } + } else if (i1 instanceof BranchInstruction) { + return ((BranchInstruction) i1).target == ((BranchInstruction) i2).target; + } else if (i1 instanceof ConstantPushInstruction) { + return ((ConstantPushInstruction) i1).getValue().equals( + ((ConstantPushInstruction) i2).getValue()); + } else if (i1 instanceof IndexedInstruction) { + return ((IndexedInstruction) i1).getIndex() == ((IndexedInstruction) i2) + .getIndex(); + } else if (i1 instanceof NEWARRAY) { + return ((NEWARRAY) i1).getTypecode() == ((NEWARRAY) i2) + .getTypecode(); + } else { + return true; + } + } + return false; + } + }; - - public boolean equals( Instruction i1, Instruction i2 ); + public boolean equals(Instruction i1, Instruction i2); } diff --git a/src/org/apache/bcel/generic/InstructionConstants.java b/src/org/apache/bcel/generic/InstructionConstants.java index 38846bf..4d78841 100644 --- a/src/org/apache/bcel/generic/InstructionConstants.java +++ b/src/org/apache/bcel/generic/InstructionConstants.java @@ -18,269 +18,273 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; -/** +/** * This interface contains shareable instruction objects. - * - * In order to save memory you can use some instructions multiply, - * since they have an immutable state and are directly derived from - * Instruction. I.e. they have no instance fields that could be - * changed. Since some of these instructions like ICONST_0 occur - * very frequently this can save a lot of time and space. This - * feature is an adaptation of the FlyWeight design pattern, we + * + * In order to save memory you can use some instructions multiply, since they + * have an immutable state and are directly derived from Instruction. I.e. they + * have no instance fields that could be changed. Since some of these + * instructions like ICONST_0 occur very frequently this can save a lot of time + * and space. This feature is an adaptation of the FlyWeight design pattern, we * just use an array instead of a factory. - * - * The Instructions can also accessed directly under their names, so - * it's possible to write il.append(Instruction.ICONST_0); - * + * + * The Instructions can also accessed directly under their names, so it's + * possible to write il.append(Instruction.ICONST_0); + * * @version $Id: InstructionConstants.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface InstructionConstants { - /** Predefined instruction objects - */ - public static final Instruction NOP = new NOP(); - public static final Instruction ACONST_NULL = new ACONST_NULL(); - public static final Instruction ICONST_M1 = new ICONST(-1); - public static final Instruction ICONST_0 = new ICONST(0); - public static final Instruction ICONST_1 = new ICONST(1); - public static final Instruction ICONST_2 = new ICONST(2); - public static final Instruction ICONST_3 = new ICONST(3); - public static final Instruction ICONST_4 = new ICONST(4); - public static final Instruction ICONST_5 = new ICONST(5); - public static final Instruction LCONST_0 = new LCONST(0); - public static final Instruction LCONST_1 = new LCONST(1); - public static final Instruction FCONST_0 = new FCONST(0); - public static final Instruction FCONST_1 = new FCONST(1); - public static final Instruction FCONST_2 = new FCONST(2); - public static final Instruction DCONST_0 = new DCONST(0); - public static final Instruction DCONST_1 = new DCONST(1); - public static final ArrayInstruction IALOAD = new IALOAD(); - public static final ArrayInstruction LALOAD = new LALOAD(); - public static final ArrayInstruction FALOAD = new FALOAD(); - public static final ArrayInstruction DALOAD = new DALOAD(); - public static final ArrayInstruction AALOAD = new AALOAD(); - public static final ArrayInstruction BALOAD = new BALOAD(); - public static final ArrayInstruction CALOAD = new CALOAD(); - public static final ArrayInstruction SALOAD = new SALOAD(); - public static final ArrayInstruction IASTORE = new IASTORE(); - public static final ArrayInstruction LASTORE = new LASTORE(); - public static final ArrayInstruction FASTORE = new FASTORE(); - public static final ArrayInstruction DASTORE = new DASTORE(); - public static final ArrayInstruction AASTORE = new AASTORE(); - public static final ArrayInstruction BASTORE = new BASTORE(); - public static final ArrayInstruction CASTORE = new CASTORE(); - public static final ArrayInstruction SASTORE = new SASTORE(); - public static final StackInstruction POP = new POP(); - public static final StackInstruction POP2 = new POP2(); - public static final StackInstruction DUP = new DUP(); - public static final StackInstruction DUP_X1 = new DUP_X1(); - public static final StackInstruction DUP_X2 = new DUP_X2(); - public static final StackInstruction DUP2 = new DUP2(); - public static final StackInstruction DUP2_X1 = new DUP2_X1(); - public static final StackInstruction DUP2_X2 = new DUP2_X2(); - public static final StackInstruction SWAP = new SWAP(); - public static final ArithmeticInstruction IADD = new IADD(); - public static final ArithmeticInstruction LADD = new LADD(); - public static final ArithmeticInstruction FADD = new FADD(); - public static final ArithmeticInstruction DADD = new DADD(); - public static final ArithmeticInstruction ISUB = new ISUB(); - public static final ArithmeticInstruction LSUB = new LSUB(); - public static final ArithmeticInstruction FSUB = new FSUB(); - public static final ArithmeticInstruction DSUB = new DSUB(); - public static final ArithmeticInstruction IMUL = new IMUL(); - public static final ArithmeticInstruction LMUL = new LMUL(); - public static final ArithmeticInstruction FMUL = new FMUL(); - public static final ArithmeticInstruction DMUL = new DMUL(); - public static final ArithmeticInstruction IDIV = new IDIV(); - public static final ArithmeticInstruction LDIV = new LDIV(); - public static final ArithmeticInstruction FDIV = new FDIV(); - public static final ArithmeticInstruction DDIV = new DDIV(); - public static final ArithmeticInstruction IREM = new IREM(); - public static final ArithmeticInstruction LREM = new LREM(); - public static final ArithmeticInstruction FREM = new FREM(); - public static final ArithmeticInstruction DREM = new DREM(); - public static final ArithmeticInstruction INEG = new INEG(); - public static final ArithmeticInstruction LNEG = new LNEG(); - public static final ArithmeticInstruction FNEG = new FNEG(); - public static final ArithmeticInstruction DNEG = new DNEG(); - public static final ArithmeticInstruction ISHL = new ISHL(); - public static final ArithmeticInstruction LSHL = new LSHL(); - public static final ArithmeticInstruction ISHR = new ISHR(); - public static final ArithmeticInstruction LSHR = new LSHR(); - public static final ArithmeticInstruction IUSHR = new IUSHR(); - public static final ArithmeticInstruction LUSHR = new LUSHR(); - public static final ArithmeticInstruction IAND = new IAND(); - public static final ArithmeticInstruction LAND = new LAND(); - public static final ArithmeticInstruction IOR = new IOR(); - public static final ArithmeticInstruction LOR = new LOR(); - public static final ArithmeticInstruction IXOR = new IXOR(); - public static final ArithmeticInstruction LXOR = new LXOR(); - public static final ConversionInstruction I2L = new I2L(); - public static final ConversionInstruction I2F = new I2F(); - public static final ConversionInstruction I2D = new I2D(); - public static final ConversionInstruction L2I = new L2I(); - public static final ConversionInstruction L2F = new L2F(); - public static final ConversionInstruction L2D = new L2D(); - public static final ConversionInstruction F2I = new F2I(); - public static final ConversionInstruction F2L = new F2L(); - public static final ConversionInstruction F2D = new F2D(); - public static final ConversionInstruction D2I = new D2I(); - public static final ConversionInstruction D2L = new D2L(); - public static final ConversionInstruction D2F = new D2F(); - public static final ConversionInstruction I2B = new I2B(); - public static final ConversionInstruction I2C = new I2C(); - public static final ConversionInstruction I2S = new I2S(); - public static final Instruction LCMP = new LCMP(); - public static final Instruction FCMPL = new FCMPL(); - public static final Instruction FCMPG = new FCMPG(); - public static final Instruction DCMPL = new DCMPL(); - public static final Instruction DCMPG = new DCMPG(); - public static final ReturnInstruction IRETURN = new IRETURN(); - public static final ReturnInstruction LRETURN = new LRETURN(); - public static final ReturnInstruction FRETURN = new FRETURN(); - public static final ReturnInstruction DRETURN = new DRETURN(); - public static final ReturnInstruction ARETURN = new ARETURN(); - public static final ReturnInstruction RETURN = new RETURN(); - public static final Instruction ARRAYLENGTH = new ARRAYLENGTH(); - public static final Instruction ATHROW = new ATHROW(); - public static final Instruction MONITORENTER = new MONITORENTER(); - public static final Instruction MONITOREXIT = new MONITOREXIT(); - /** You can use these constants in multiple places safely, if you can guarantee - * that you will never alter their internal values, e.g. call setIndex(). - */ - public static final LocalVariableInstruction THIS = new ALOAD(0); - public static final LocalVariableInstruction ALOAD_0 = THIS; - public static final LocalVariableInstruction ALOAD_1 = new ALOAD(1); - public static final LocalVariableInstruction ALOAD_2 = new ALOAD(2); - public static final LocalVariableInstruction ILOAD_0 = new ILOAD(0); - public static final LocalVariableInstruction ILOAD_1 = new ILOAD(1); - public static final LocalVariableInstruction ILOAD_2 = new ILOAD(2); - public static final LocalVariableInstruction ASTORE_0 = new ASTORE(0); - public static final LocalVariableInstruction ASTORE_1 = new ASTORE(1); - public static final LocalVariableInstruction ASTORE_2 = new ASTORE(2); - public static final LocalVariableInstruction ISTORE_0 = new ISTORE(0); - public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1); - public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2); - /** Get object via its opcode, for immutable instructions like - * branch instructions entries are set to null. - */ - public static final Instruction[] INSTRUCTIONS = new Instruction[256]; - /** Interfaces may have no static initializers, so we simulate this - * with an inner class. - */ - static final Clinit bla = new Clinit(); + /** + * Predefined instruction objects + */ + public static final Instruction NOP = new NOP(); + public static final Instruction ACONST_NULL = new ACONST_NULL(); + public static final Instruction ICONST_M1 = new ICONST(-1); + public static final Instruction ICONST_0 = new ICONST(0); + public static final Instruction ICONST_1 = new ICONST(1); + public static final Instruction ICONST_2 = new ICONST(2); + public static final Instruction ICONST_3 = new ICONST(3); + public static final Instruction ICONST_4 = new ICONST(4); + public static final Instruction ICONST_5 = new ICONST(5); + public static final Instruction LCONST_0 = new LCONST(0); + public static final Instruction LCONST_1 = new LCONST(1); + public static final Instruction FCONST_0 = new FCONST(0); + public static final Instruction FCONST_1 = new FCONST(1); + public static final Instruction FCONST_2 = new FCONST(2); + public static final Instruction DCONST_0 = new DCONST(0); + public static final Instruction DCONST_1 = new DCONST(1); + public static final ArrayInstruction IALOAD = new IALOAD(); + public static final ArrayInstruction LALOAD = new LALOAD(); + public static final ArrayInstruction FALOAD = new FALOAD(); + public static final ArrayInstruction DALOAD = new DALOAD(); + public static final ArrayInstruction AALOAD = new AALOAD(); + public static final ArrayInstruction BALOAD = new BALOAD(); + public static final ArrayInstruction CALOAD = new CALOAD(); + public static final ArrayInstruction SALOAD = new SALOAD(); + public static final ArrayInstruction IASTORE = new IASTORE(); + public static final ArrayInstruction LASTORE = new LASTORE(); + public static final ArrayInstruction FASTORE = new FASTORE(); + public static final ArrayInstruction DASTORE = new DASTORE(); + public static final ArrayInstruction AASTORE = new AASTORE(); + public static final ArrayInstruction BASTORE = new BASTORE(); + public static final ArrayInstruction CASTORE = new CASTORE(); + public static final ArrayInstruction SASTORE = new SASTORE(); + public static final StackInstruction POP = new POP(); + public static final StackInstruction POP2 = new POP2(); + public static final StackInstruction DUP = new DUP(); + public static final StackInstruction DUP_X1 = new DUP_X1(); + public static final StackInstruction DUP_X2 = new DUP_X2(); + public static final StackInstruction DUP2 = new DUP2(); + public static final StackInstruction DUP2_X1 = new DUP2_X1(); + public static final StackInstruction DUP2_X2 = new DUP2_X2(); + public static final StackInstruction SWAP = new SWAP(); + public static final ArithmeticInstruction IADD = new IADD(); + public static final ArithmeticInstruction LADD = new LADD(); + public static final ArithmeticInstruction FADD = new FADD(); + public static final ArithmeticInstruction DADD = new DADD(); + public static final ArithmeticInstruction ISUB = new ISUB(); + public static final ArithmeticInstruction LSUB = new LSUB(); + public static final ArithmeticInstruction FSUB = new FSUB(); + public static final ArithmeticInstruction DSUB = new DSUB(); + public static final ArithmeticInstruction IMUL = new IMUL(); + public static final ArithmeticInstruction LMUL = new LMUL(); + public static final ArithmeticInstruction FMUL = new FMUL(); + public static final ArithmeticInstruction DMUL = new DMUL(); + public static final ArithmeticInstruction IDIV = new IDIV(); + public static final ArithmeticInstruction LDIV = new LDIV(); + public static final ArithmeticInstruction FDIV = new FDIV(); + public static final ArithmeticInstruction DDIV = new DDIV(); + public static final ArithmeticInstruction IREM = new IREM(); + public static final ArithmeticInstruction LREM = new LREM(); + public static final ArithmeticInstruction FREM = new FREM(); + public static final ArithmeticInstruction DREM = new DREM(); + public static final ArithmeticInstruction INEG = new INEG(); + public static final ArithmeticInstruction LNEG = new LNEG(); + public static final ArithmeticInstruction FNEG = new FNEG(); + public static final ArithmeticInstruction DNEG = new DNEG(); + public static final ArithmeticInstruction ISHL = new ISHL(); + public static final ArithmeticInstruction LSHL = new LSHL(); + public static final ArithmeticInstruction ISHR = new ISHR(); + public static final ArithmeticInstruction LSHR = new LSHR(); + public static final ArithmeticInstruction IUSHR = new IUSHR(); + public static final ArithmeticInstruction LUSHR = new LUSHR(); + public static final ArithmeticInstruction IAND = new IAND(); + public static final ArithmeticInstruction LAND = new LAND(); + public static final ArithmeticInstruction IOR = new IOR(); + public static final ArithmeticInstruction LOR = new LOR(); + public static final ArithmeticInstruction IXOR = new IXOR(); + public static final ArithmeticInstruction LXOR = new LXOR(); + public static final ConversionInstruction I2L = new I2L(); + public static final ConversionInstruction I2F = new I2F(); + public static final ConversionInstruction I2D = new I2D(); + public static final ConversionInstruction L2I = new L2I(); + public static final ConversionInstruction L2F = new L2F(); + public static final ConversionInstruction L2D = new L2D(); + public static final ConversionInstruction F2I = new F2I(); + public static final ConversionInstruction F2L = new F2L(); + public static final ConversionInstruction F2D = new F2D(); + public static final ConversionInstruction D2I = new D2I(); + public static final ConversionInstruction D2L = new D2L(); + public static final ConversionInstruction D2F = new D2F(); + public static final ConversionInstruction I2B = new I2B(); + public static final ConversionInstruction I2C = new I2C(); + public static final ConversionInstruction I2S = new I2S(); + public static final Instruction LCMP = new LCMP(); + public static final Instruction FCMPL = new FCMPL(); + public static final Instruction FCMPG = new FCMPG(); + public static final Instruction DCMPL = new DCMPL(); + public static final Instruction DCMPG = new DCMPG(); + public static final ReturnInstruction IRETURN = new IRETURN(); + public static final ReturnInstruction LRETURN = new LRETURN(); + public static final ReturnInstruction FRETURN = new FRETURN(); + public static final ReturnInstruction DRETURN = new DRETURN(); + public static final ReturnInstruction ARETURN = new ARETURN(); + public static final ReturnInstruction RETURN = new RETURN(); + public static final Instruction ARRAYLENGTH = new ARRAYLENGTH(); + public static final Instruction ATHROW = new ATHROW(); + public static final Instruction MONITORENTER = new MONITORENTER(); + public static final Instruction MONITOREXIT = new MONITOREXIT(); + /** + * You can use these constants in multiple places safely, if you can + * guarantee that you will never alter their internal values, e.g. call + * setIndex(). + */ + public static final LocalVariableInstruction THIS = new ALOAD(0); + public static final LocalVariableInstruction ALOAD_0 = THIS; + public static final LocalVariableInstruction ALOAD_1 = new ALOAD(1); + public static final LocalVariableInstruction ALOAD_2 = new ALOAD(2); + public static final LocalVariableInstruction ILOAD_0 = new ILOAD(0); + public static final LocalVariableInstruction ILOAD_1 = new ILOAD(1); + public static final LocalVariableInstruction ILOAD_2 = new ILOAD(2); + public static final LocalVariableInstruction ASTORE_0 = new ASTORE(0); + public static final LocalVariableInstruction ASTORE_1 = new ASTORE(1); + public static final LocalVariableInstruction ASTORE_2 = new ASTORE(2); + public static final LocalVariableInstruction ISTORE_0 = new ISTORE(0); + public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1); + public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2); + /** + * Get object via its opcode, for immutable instructions like branch + * instructions entries are set to null. + */ + public static final Instruction[] INSTRUCTIONS = new Instruction[256]; + /** + * Interfaces may have no static initializers, so we simulate this with an + * inner class. + */ + static final Clinit bla = new Clinit(); - static class Clinit { + static class Clinit { - Clinit() { - INSTRUCTIONS[Constants.NOP] = NOP; - INSTRUCTIONS[Constants.ACONST_NULL] = ACONST_NULL; - INSTRUCTIONS[Constants.ICONST_M1] = ICONST_M1; - INSTRUCTIONS[Constants.ICONST_0] = ICONST_0; - INSTRUCTIONS[Constants.ICONST_1] = ICONST_1; - INSTRUCTIONS[Constants.ICONST_2] = ICONST_2; - INSTRUCTIONS[Constants.ICONST_3] = ICONST_3; - INSTRUCTIONS[Constants.ICONST_4] = ICONST_4; - INSTRUCTIONS[Constants.ICONST_5] = ICONST_5; - INSTRUCTIONS[Constants.LCONST_0] = LCONST_0; - INSTRUCTIONS[Constants.LCONST_1] = LCONST_1; - INSTRUCTIONS[Constants.FCONST_0] = FCONST_0; - INSTRUCTIONS[Constants.FCONST_1] = FCONST_1; - INSTRUCTIONS[Constants.FCONST_2] = FCONST_2; - INSTRUCTIONS[Constants.DCONST_0] = DCONST_0; - INSTRUCTIONS[Constants.DCONST_1] = DCONST_1; - INSTRUCTIONS[Constants.IALOAD] = IALOAD; - INSTRUCTIONS[Constants.LALOAD] = LALOAD; - INSTRUCTIONS[Constants.FALOAD] = FALOAD; - INSTRUCTIONS[Constants.DALOAD] = DALOAD; - INSTRUCTIONS[Constants.AALOAD] = AALOAD; - INSTRUCTIONS[Constants.BALOAD] = BALOAD; - INSTRUCTIONS[Constants.CALOAD] = CALOAD; - INSTRUCTIONS[Constants.SALOAD] = SALOAD; - INSTRUCTIONS[Constants.IASTORE] = IASTORE; - INSTRUCTIONS[Constants.LASTORE] = LASTORE; - INSTRUCTIONS[Constants.FASTORE] = FASTORE; - INSTRUCTIONS[Constants.DASTORE] = DASTORE; - INSTRUCTIONS[Constants.AASTORE] = AASTORE; - INSTRUCTIONS[Constants.BASTORE] = BASTORE; - INSTRUCTIONS[Constants.CASTORE] = CASTORE; - INSTRUCTIONS[Constants.SASTORE] = SASTORE; - INSTRUCTIONS[Constants.POP] = POP; - INSTRUCTIONS[Constants.POP2] = POP2; - INSTRUCTIONS[Constants.DUP] = DUP; - INSTRUCTIONS[Constants.DUP_X1] = DUP_X1; - INSTRUCTIONS[Constants.DUP_X2] = DUP_X2; - INSTRUCTIONS[Constants.DUP2] = DUP2; - INSTRUCTIONS[Constants.DUP2_X1] = DUP2_X1; - INSTRUCTIONS[Constants.DUP2_X2] = DUP2_X2; - INSTRUCTIONS[Constants.SWAP] = SWAP; - INSTRUCTIONS[Constants.IADD] = IADD; - INSTRUCTIONS[Constants.LADD] = LADD; - INSTRUCTIONS[Constants.FADD] = FADD; - INSTRUCTIONS[Constants.DADD] = DADD; - INSTRUCTIONS[Constants.ISUB] = ISUB; - INSTRUCTIONS[Constants.LSUB] = LSUB; - INSTRUCTIONS[Constants.FSUB] = FSUB; - INSTRUCTIONS[Constants.DSUB] = DSUB; - INSTRUCTIONS[Constants.IMUL] = IMUL; - INSTRUCTIONS[Constants.LMUL] = LMUL; - INSTRUCTIONS[Constants.FMUL] = FMUL; - INSTRUCTIONS[Constants.DMUL] = DMUL; - INSTRUCTIONS[Constants.IDIV] = IDIV; - INSTRUCTIONS[Constants.LDIV] = LDIV; - INSTRUCTIONS[Constants.FDIV] = FDIV; - INSTRUCTIONS[Constants.DDIV] = DDIV; - INSTRUCTIONS[Constants.IREM] = IREM; - INSTRUCTIONS[Constants.LREM] = LREM; - INSTRUCTIONS[Constants.FREM] = FREM; - INSTRUCTIONS[Constants.DREM] = DREM; - INSTRUCTIONS[Constants.INEG] = INEG; - INSTRUCTIONS[Constants.LNEG] = LNEG; - INSTRUCTIONS[Constants.FNEG] = FNEG; - INSTRUCTIONS[Constants.DNEG] = DNEG; - INSTRUCTIONS[Constants.ISHL] = ISHL; - INSTRUCTIONS[Constants.LSHL] = LSHL; - INSTRUCTIONS[Constants.ISHR] = ISHR; - INSTRUCTIONS[Constants.LSHR] = LSHR; - INSTRUCTIONS[Constants.IUSHR] = IUSHR; - INSTRUCTIONS[Constants.LUSHR] = LUSHR; - INSTRUCTIONS[Constants.IAND] = IAND; - INSTRUCTIONS[Constants.LAND] = LAND; - INSTRUCTIONS[Constants.IOR] = IOR; - INSTRUCTIONS[Constants.LOR] = LOR; - INSTRUCTIONS[Constants.IXOR] = IXOR; - INSTRUCTIONS[Constants.LXOR] = LXOR; - INSTRUCTIONS[Constants.I2L] = I2L; - INSTRUCTIONS[Constants.I2F] = I2F; - INSTRUCTIONS[Constants.I2D] = I2D; - INSTRUCTIONS[Constants.L2I] = L2I; - INSTRUCTIONS[Constants.L2F] = L2F; - INSTRUCTIONS[Constants.L2D] = L2D; - INSTRUCTIONS[Constants.F2I] = F2I; - INSTRUCTIONS[Constants.F2L] = F2L; - INSTRUCTIONS[Constants.F2D] = F2D; - INSTRUCTIONS[Constants.D2I] = D2I; - INSTRUCTIONS[Constants.D2L] = D2L; - INSTRUCTIONS[Constants.D2F] = D2F; - INSTRUCTIONS[Constants.I2B] = I2B; - INSTRUCTIONS[Constants.I2C] = I2C; - INSTRUCTIONS[Constants.I2S] = I2S; - INSTRUCTIONS[Constants.LCMP] = LCMP; - INSTRUCTIONS[Constants.FCMPL] = FCMPL; - INSTRUCTIONS[Constants.FCMPG] = FCMPG; - INSTRUCTIONS[Constants.DCMPL] = DCMPL; - INSTRUCTIONS[Constants.DCMPG] = DCMPG; - INSTRUCTIONS[Constants.IRETURN] = IRETURN; - INSTRUCTIONS[Constants.LRETURN] = LRETURN; - INSTRUCTIONS[Constants.FRETURN] = FRETURN; - INSTRUCTIONS[Constants.DRETURN] = DRETURN; - INSTRUCTIONS[Constants.ARETURN] = ARETURN; - INSTRUCTIONS[Constants.RETURN] = RETURN; - INSTRUCTIONS[Constants.ARRAYLENGTH] = ARRAYLENGTH; - INSTRUCTIONS[Constants.ATHROW] = ATHROW; - INSTRUCTIONS[Constants.MONITORENTER] = MONITORENTER; - INSTRUCTIONS[Constants.MONITOREXIT] = MONITOREXIT; - } - } + Clinit() { + INSTRUCTIONS[Constants.NOP] = NOP; + INSTRUCTIONS[Constants.ACONST_NULL] = ACONST_NULL; + INSTRUCTIONS[Constants.ICONST_M1] = ICONST_M1; + INSTRUCTIONS[Constants.ICONST_0] = ICONST_0; + INSTRUCTIONS[Constants.ICONST_1] = ICONST_1; + INSTRUCTIONS[Constants.ICONST_2] = ICONST_2; + INSTRUCTIONS[Constants.ICONST_3] = ICONST_3; + INSTRUCTIONS[Constants.ICONST_4] = ICONST_4; + INSTRUCTIONS[Constants.ICONST_5] = ICONST_5; + INSTRUCTIONS[Constants.LCONST_0] = LCONST_0; + INSTRUCTIONS[Constants.LCONST_1] = LCONST_1; + INSTRUCTIONS[Constants.FCONST_0] = FCONST_0; + INSTRUCTIONS[Constants.FCONST_1] = FCONST_1; + INSTRUCTIONS[Constants.FCONST_2] = FCONST_2; + INSTRUCTIONS[Constants.DCONST_0] = DCONST_0; + INSTRUCTIONS[Constants.DCONST_1] = DCONST_1; + INSTRUCTIONS[Constants.IALOAD] = IALOAD; + INSTRUCTIONS[Constants.LALOAD] = LALOAD; + INSTRUCTIONS[Constants.FALOAD] = FALOAD; + INSTRUCTIONS[Constants.DALOAD] = DALOAD; + INSTRUCTIONS[Constants.AALOAD] = AALOAD; + INSTRUCTIONS[Constants.BALOAD] = BALOAD; + INSTRUCTIONS[Constants.CALOAD] = CALOAD; + INSTRUCTIONS[Constants.SALOAD] = SALOAD; + INSTRUCTIONS[Constants.IASTORE] = IASTORE; + INSTRUCTIONS[Constants.LASTORE] = LASTORE; + INSTRUCTIONS[Constants.FASTORE] = FASTORE; + INSTRUCTIONS[Constants.DASTORE] = DASTORE; + INSTRUCTIONS[Constants.AASTORE] = AASTORE; + INSTRUCTIONS[Constants.BASTORE] = BASTORE; + INSTRUCTIONS[Constants.CASTORE] = CASTORE; + INSTRUCTIONS[Constants.SASTORE] = SASTORE; + INSTRUCTIONS[Constants.POP] = POP; + INSTRUCTIONS[Constants.POP2] = POP2; + INSTRUCTIONS[Constants.DUP] = DUP; + INSTRUCTIONS[Constants.DUP_X1] = DUP_X1; + INSTRUCTIONS[Constants.DUP_X2] = DUP_X2; + INSTRUCTIONS[Constants.DUP2] = DUP2; + INSTRUCTIONS[Constants.DUP2_X1] = DUP2_X1; + INSTRUCTIONS[Constants.DUP2_X2] = DUP2_X2; + INSTRUCTIONS[Constants.SWAP] = SWAP; + INSTRUCTIONS[Constants.IADD] = IADD; + INSTRUCTIONS[Constants.LADD] = LADD; + INSTRUCTIONS[Constants.FADD] = FADD; + INSTRUCTIONS[Constants.DADD] = DADD; + INSTRUCTIONS[Constants.ISUB] = ISUB; + INSTRUCTIONS[Constants.LSUB] = LSUB; + INSTRUCTIONS[Constants.FSUB] = FSUB; + INSTRUCTIONS[Constants.DSUB] = DSUB; + INSTRUCTIONS[Constants.IMUL] = IMUL; + INSTRUCTIONS[Constants.LMUL] = LMUL; + INSTRUCTIONS[Constants.FMUL] = FMUL; + INSTRUCTIONS[Constants.DMUL] = DMUL; + INSTRUCTIONS[Constants.IDIV] = IDIV; + INSTRUCTIONS[Constants.LDIV] = LDIV; + INSTRUCTIONS[Constants.FDIV] = FDIV; + INSTRUCTIONS[Constants.DDIV] = DDIV; + INSTRUCTIONS[Constants.IREM] = IREM; + INSTRUCTIONS[Constants.LREM] = LREM; + INSTRUCTIONS[Constants.FREM] = FREM; + INSTRUCTIONS[Constants.DREM] = DREM; + INSTRUCTIONS[Constants.INEG] = INEG; + INSTRUCTIONS[Constants.LNEG] = LNEG; + INSTRUCTIONS[Constants.FNEG] = FNEG; + INSTRUCTIONS[Constants.DNEG] = DNEG; + INSTRUCTIONS[Constants.ISHL] = ISHL; + INSTRUCTIONS[Constants.LSHL] = LSHL; + INSTRUCTIONS[Constants.ISHR] = ISHR; + INSTRUCTIONS[Constants.LSHR] = LSHR; + INSTRUCTIONS[Constants.IUSHR] = IUSHR; + INSTRUCTIONS[Constants.LUSHR] = LUSHR; + INSTRUCTIONS[Constants.IAND] = IAND; + INSTRUCTIONS[Constants.LAND] = LAND; + INSTRUCTIONS[Constants.IOR] = IOR; + INSTRUCTIONS[Constants.LOR] = LOR; + INSTRUCTIONS[Constants.IXOR] = IXOR; + INSTRUCTIONS[Constants.LXOR] = LXOR; + INSTRUCTIONS[Constants.I2L] = I2L; + INSTRUCTIONS[Constants.I2F] = I2F; + INSTRUCTIONS[Constants.I2D] = I2D; + INSTRUCTIONS[Constants.L2I] = L2I; + INSTRUCTIONS[Constants.L2F] = L2F; + INSTRUCTIONS[Constants.L2D] = L2D; + INSTRUCTIONS[Constants.F2I] = F2I; + INSTRUCTIONS[Constants.F2L] = F2L; + INSTRUCTIONS[Constants.F2D] = F2D; + INSTRUCTIONS[Constants.D2I] = D2I; + INSTRUCTIONS[Constants.D2L] = D2L; + INSTRUCTIONS[Constants.D2F] = D2F; + INSTRUCTIONS[Constants.I2B] = I2B; + INSTRUCTIONS[Constants.I2C] = I2C; + INSTRUCTIONS[Constants.I2S] = I2S; + INSTRUCTIONS[Constants.LCMP] = LCMP; + INSTRUCTIONS[Constants.FCMPL] = FCMPL; + INSTRUCTIONS[Constants.FCMPG] = FCMPG; + INSTRUCTIONS[Constants.DCMPL] = DCMPL; + INSTRUCTIONS[Constants.DCMPG] = DCMPG; + INSTRUCTIONS[Constants.IRETURN] = IRETURN; + INSTRUCTIONS[Constants.LRETURN] = LRETURN; + INSTRUCTIONS[Constants.FRETURN] = FRETURN; + INSTRUCTIONS[Constants.DRETURN] = DRETURN; + INSTRUCTIONS[Constants.ARETURN] = ARETURN; + INSTRUCTIONS[Constants.RETURN] = RETURN; + INSTRUCTIONS[Constants.ARRAYLENGTH] = ARRAYLENGTH; + INSTRUCTIONS[Constants.ATHROW] = ATHROW; + INSTRUCTIONS[Constants.MONITORENTER] = MONITORENTER; + INSTRUCTIONS[Constants.MONITOREXIT] = MONITOREXIT; + } + } } diff --git a/src/org/apache/bcel/generic/InstructionFactory.java b/src/org/apache/bcel/generic/InstructionFactory.java index 54d4304..35c1c5f 100644 --- a/src/org/apache/bcel/generic/InstructionFactory.java +++ b/src/org/apache/bcel/generic/InstructionFactory.java @@ -18,726 +18,729 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; -/** - * Instances of this class may be used, e.g., to generate typed - * versions of instructions. Its main purpose is to be used as the - * byte code generating backend of a compiler. You can subclass it to - * add your own create methods. - * +/** + * Instances of this class may be used, e.g., to generate typed versions of + * instructions. Its main purpose is to be used as the byte code generating + * backend of a compiler. You can subclass it to add your own create methods. + * * @version $Id: InstructionFactory.java 386056 2006-03-15 11:31:56Z tcurdt $ * @author M. Dahm * @see Constants */ -public class InstructionFactory implements InstructionConstants, java.io.Serializable { +public class InstructionFactory implements InstructionConstants, + java.io.Serializable { - protected ClassGen cg; - protected ConstantPoolGen cp; + /** + * + */ + private static final long serialVersionUID = 1L; + protected ClassGen cg; + protected ConstantPoolGen cp; + public InstructionFactory(ClassGen cg, ConstantPoolGen cp) { + this.cg = cg; + this.cp = cp; + } - public InstructionFactory(ClassGen cg, ConstantPoolGen cp) { - this.cg = cg; - this.cp = cp; - } + /** + * Initialize with ClassGen object + */ + public InstructionFactory(ClassGen cg) { + this(cg, cg.getConstantPool()); + } + /** + * Initialize just with ConstantPoolGen object + */ + public InstructionFactory(ConstantPoolGen cp) { + this(null, cp); + } - /** Initialize with ClassGen object - */ - public InstructionFactory(ClassGen cg) { - this(cg, cg.getConstantPool()); - } + /** + * Create an invoke instruction. + * + * @param class_name + * name of the called class + * @param name + * name of the called method + * @param ret_type + * return type of method + * @param arg_types + * argument types of method + * @param kind + * how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, + * INVOKEVIRTUAL, or INVOKESPECIAL + * @see Constants + */ + public InvokeInstruction createInvoke(String class_name, String name, + Type ret_type, Type[] arg_types, short kind) { + int index; + int nargs = 0; + String signature = Type.getMethodSignature(ret_type, arg_types); + for (int i = 0; i < arg_types.length; i++) { + nargs += arg_types[i].getSize(); + } + if (kind == Constants.INVOKEINTERFACE) { + index = cp.addInterfaceMethodref(class_name, name, signature); + } else { + index = cp.addMethodref(class_name, name, signature); + } + switch (kind) { + case Constants.INVOKESPECIAL: + return new INVOKESPECIAL(index); + case Constants.INVOKEVIRTUAL: + return new INVOKEVIRTUAL(index); + case Constants.INVOKESTATIC: + return new INVOKESTATIC(index); + case Constants.INVOKEINTERFACE: + return new INVOKEINTERFACE(index, nargs + 1); + default: + throw new RuntimeException("Oops: Unknown invoke kind:" + kind); + } + } + /** + * Create a call to the most popular System.out.println() method. + * + * @param s + * the string to print + */ + public InstructionList createPrintln(String s) { + InstructionList il = new InstructionList(); + int out = cp.addFieldref("java.lang.System", "out", + "Ljava/io/PrintStream;"); + int println = cp.addMethodref("java.io.PrintStream", "println", + "(Ljava/lang/String;)V"); + il.append(new GETSTATIC(out)); + il.append(new PUSH(cp, s)); + il.append(new INVOKEVIRTUAL(println)); + return il; + } - /** Initialize just with ConstantPoolGen object - */ - public InstructionFactory(ConstantPoolGen cp) { - this(null, cp); - } + /** + * Uses PUSH to push a constant value onto the stack. + * + * @param value + * must be of type Number, Boolean, Character or String + */ + public Instruction createConstant(Object value) { + PUSH push; + if (value instanceof Number) { + push = new PUSH(cp, (Number) value); + } else if (value instanceof String) { + push = new PUSH(cp, (String) value); + } else if (value instanceof Boolean) { + push = new PUSH(cp, (Boolean) value); + } else if (value instanceof Character) { + push = new PUSH(cp, (Character) value); + } else { + throw new ClassGenException("Illegal type: " + value.getClass()); + } + return push.getInstruction(); + } + private static class MethodObject { - /** Create an invoke instruction. - * - * @param class_name name of the called class - * @param name name of the called method - * @param ret_type return type of method - * @param arg_types argument types of method - * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, - * or INVOKESPECIAL - * @see Constants - */ - public InvokeInstruction createInvoke( String class_name, String name, Type ret_type, - Type[] arg_types, short kind ) { - int index; - int nargs = 0; - String signature = Type.getMethodSignature(ret_type, arg_types); - for (int i = 0; i < arg_types.length; i++) { - nargs += arg_types[i].getSize(); - } - if (kind == Constants.INVOKEINTERFACE) { - index = cp.addInterfaceMethodref(class_name, name, signature); - } else { - index = cp.addMethodref(class_name, name, signature); - } - switch (kind) { - case Constants.INVOKESPECIAL: - return new INVOKESPECIAL(index); - case Constants.INVOKEVIRTUAL: - return new INVOKEVIRTUAL(index); - case Constants.INVOKESTATIC: - return new INVOKESTATIC(index); - case Constants.INVOKEINTERFACE: - return new INVOKEINTERFACE(index, nargs + 1); - default: - throw new RuntimeException("Oops: Unknown invoke kind:" + kind); - } - } + Type[] arg_types; + Type result_type; + String class_name; + String name; + MethodObject(String c, String n, Type r, Type[] a, int acc) { + class_name = c; + name = n; + result_type = r; + arg_types = a; + } + } - /** Create a call to the most popular System.out.println() method. - * - * @param s the string to print - */ - public InstructionList createPrintln( String s ) { - InstructionList il = new InstructionList(); - int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;"); - int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V"); - il.append(new GETSTATIC(out)); - il.append(new PUSH(cp, s)); - il.append(new INVOKEVIRTUAL(println)); - return il; - } + private InvokeInstruction createInvoke(MethodObject m, short kind) { + return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, + kind); + } + private static MethodObject[] append_mos = { + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.STRING }, + Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.OBJECT }, + Constants.ACC_PUBLIC), + null, + null, // indices 2, 3 + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.BOOLEAN }, + Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.CHAR }, + Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.FLOAT }, + Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.DOUBLE }, + Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.INT }, + Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, // No append(byte) + new Type[] { Type.INT }, Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, // No append(short) + new Type[] { Type.INT }, Constants.ACC_PUBLIC), + new MethodObject("java.lang.StringBuffer", "append", + Type.STRINGBUFFER, new Type[] { Type.LONG }, + Constants.ACC_PUBLIC) }; - /** Uses PUSH to push a constant value onto the stack. - * @param value must be of type Number, Boolean, Character or String - */ - public Instruction createConstant( Object value ) { - PUSH push; - if (value instanceof Number) { - push = new PUSH(cp, (Number) value); - } else if (value instanceof String) { - push = new PUSH(cp, (String) value); - } else if (value instanceof Boolean) { - push = new PUSH(cp, (Boolean) value); - } else if (value instanceof Character) { - push = new PUSH(cp, (Character) value); - } else { - throw new ClassGenException("Illegal type: " + value.getClass()); - } - return push.getInstruction(); - } + private static final boolean isString(Type type) { + return ((type instanceof ObjectType) && ((ObjectType) type) + .getClassName().equals("java.lang.String")); + } - private static class MethodObject { + public Instruction createAppend(Type type) { + byte t = type.getType(); + if (isString(type)) { + return createInvoke(append_mos[0], Constants.INVOKEVIRTUAL); + } + switch (t) { + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_FLOAT: + case Constants.T_DOUBLE: + case Constants.T_BYTE: + case Constants.T_SHORT: + case Constants.T_INT: + case Constants.T_LONG: + return createInvoke(append_mos[t], Constants.INVOKEVIRTUAL); + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return createInvoke(append_mos[1], Constants.INVOKEVIRTUAL); + default: + throw new RuntimeException("Oops: No append for this type? " + type); + } + } - Type[] arg_types; - Type result_type; - String class_name; - String name; - int access; + /** + * Create a field instruction. + * + * @param class_name + * name of the accessed class + * @param name + * name of the referenced field + * @param type + * type of field + * @param kind + * how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC + * @see Constants + */ + public FieldInstruction createFieldAccess(String class_name, String name, + Type type, short kind) { + int index; + String signature = type.getSignature(); + index = cp.addFieldref(class_name, name, signature); + switch (kind) { + case Constants.GETFIELD: + return new GETFIELD(index); + case Constants.PUTFIELD: + return new PUTFIELD(index); + case Constants.GETSTATIC: + return new GETSTATIC(index); + case Constants.PUTSTATIC: + return new PUTSTATIC(index); + default: + throw new RuntimeException("Oops: Unknown getfield kind:" + kind); + } + } + /** + * Create reference to `this' + */ + public static Instruction createThis() { + return new ALOAD(0); + } - MethodObject(String c, String n, Type r, Type[] a, int acc) { - class_name = c; - name = n; - result_type = r; - arg_types = a; - access = acc; - } - } + /** + * Create typed return + */ + public static ReturnInstruction createReturn(Type type) { + switch (type.getType()) { + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return ARETURN; + case Constants.T_INT: + case Constants.T_SHORT: + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + return IRETURN; + case Constants.T_FLOAT: + return FRETURN; + case Constants.T_DOUBLE: + return DRETURN; + case Constants.T_LONG: + return LRETURN; + case Constants.T_VOID: + return RETURN; + default: + throw new RuntimeException("Invalid type: " + type); + } + } + private static final ArithmeticInstruction createBinaryIntOp(char first, + String op) { + switch (first) { + case '-': + return ISUB; + case '+': + return IADD; + case '%': + return IREM; + case '*': + return IMUL; + case '/': + return IDIV; + case '&': + return IAND; + case '|': + return IOR; + case '^': + return IXOR; + case '<': + return ISHL; + case '>': + return op.equals(">>>") ? (ArithmeticInstruction) IUSHR + : (ArithmeticInstruction) ISHR; + default: + throw new RuntimeException("Invalid operand " + op); + } + } - private InvokeInstruction createInvoke( MethodObject m, short kind ) { - return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind); - } + private static final ArithmeticInstruction createBinaryLongOp(char first, + String op) { + switch (first) { + case '-': + return LSUB; + case '+': + return LADD; + case '%': + return LREM; + case '*': + return LMUL; + case '/': + return LDIV; + case '&': + return LAND; + case '|': + return LOR; + case '^': + return LXOR; + case '<': + return LSHL; + case '>': + return op.equals(">>>") ? (ArithmeticInstruction) LUSHR + : (ArithmeticInstruction) LSHR; + default: + throw new RuntimeException("Invalid operand " + op); + } + } - private static MethodObject[] append_mos = { - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.STRING - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.OBJECT - }, Constants.ACC_PUBLIC), - null, - null, // indices 2, 3 - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.BOOLEAN - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.CHAR - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.FLOAT - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.DOUBLE - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.INT - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte) - new Type[] { - Type.INT - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short) - new Type[] { - Type.INT - }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.LONG - }, Constants.ACC_PUBLIC) - }; + private static final ArithmeticInstruction createBinaryFloatOp(char op) { + switch (op) { + case '-': + return FSUB; + case '+': + return FADD; + case '*': + return FMUL; + case '/': + return FDIV; + default: + throw new RuntimeException("Invalid operand " + op); + } + } + private static final ArithmeticInstruction createBinaryDoubleOp(char op) { + switch (op) { + case '-': + return DSUB; + case '+': + return DADD; + case '*': + return DMUL; + case '/': + return DDIV; + default: + throw new RuntimeException("Invalid operand " + op); + } + } - private static final boolean isString( Type type ) { - return ((type instanceof ObjectType) && ((ObjectType) type).getClassName().equals( - "java.lang.String")); - } - - - public Instruction createAppend( Type type ) { - byte t = type.getType(); - if (isString(type)) { - return createInvoke(append_mos[0], Constants.INVOKEVIRTUAL); - } - switch (t) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_FLOAT: - case Constants.T_DOUBLE: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - case Constants.T_LONG: - return createInvoke(append_mos[t], Constants.INVOKEVIRTUAL); - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return createInvoke(append_mos[1], Constants.INVOKEVIRTUAL); - default: - throw new RuntimeException("Oops: No append for this type? " + type); - } - } - - - /** Create a field instruction. - * - * @param class_name name of the accessed class - * @param name name of the referenced field - * @param type type of field - * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC - * @see Constants - */ - public FieldInstruction createFieldAccess( String class_name, String name, Type type, short kind ) { - int index; - String signature = type.getSignature(); - index = cp.addFieldref(class_name, name, signature); - switch (kind) { - case Constants.GETFIELD: - return new GETFIELD(index); - case Constants.PUTFIELD: - return new PUTFIELD(index); - case Constants.GETSTATIC: - return new GETSTATIC(index); - case Constants.PUTSTATIC: - return new PUTSTATIC(index); - default: - throw new RuntimeException("Oops: Unknown getfield kind:" + kind); - } - } - - - /** Create reference to `this' - */ - public static Instruction createThis() { - return new ALOAD(0); - } - - - /** Create typed return - */ - public static ReturnInstruction createReturn( Type type ) { - switch (type.getType()) { - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return ARETURN; - case Constants.T_INT: - case Constants.T_SHORT: - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - return IRETURN; - case Constants.T_FLOAT: - return FRETURN; - case Constants.T_DOUBLE: - return DRETURN; - case Constants.T_LONG: - return LRETURN; - case Constants.T_VOID: - return RETURN; - default: - throw new RuntimeException("Invalid type: " + type); - } - } - - - private static final ArithmeticInstruction createBinaryIntOp( char first, String op ) { - switch (first) { - case '-': - return ISUB; - case '+': - return IADD; - case '%': - return IREM; - case '*': - return IMUL; - case '/': - return IDIV; - case '&': - return IAND; - case '|': - return IOR; - case '^': - return IXOR; - case '<': - return ISHL; - case '>': - return op.equals(">>>") - ? (ArithmeticInstruction) IUSHR - : (ArithmeticInstruction) ISHR; - default: - throw new RuntimeException("Invalid operand " + op); - } - } - - - private static final ArithmeticInstruction createBinaryLongOp( char first, String op ) { - switch (first) { - case '-': - return LSUB; - case '+': - return LADD; - case '%': - return LREM; - case '*': - return LMUL; - case '/': - return LDIV; - case '&': - return LAND; - case '|': - return LOR; - case '^': - return LXOR; - case '<': - return LSHL; - case '>': - return op.equals(">>>") - ? (ArithmeticInstruction) LUSHR - : (ArithmeticInstruction) LSHR; - default: - throw new RuntimeException("Invalid operand " + op); - } - } - - - private static final ArithmeticInstruction createBinaryFloatOp( char op ) { - switch (op) { - case '-': - return FSUB; - case '+': - return FADD; - case '*': - return FMUL; - case '/': - return FDIV; - default: - throw new RuntimeException("Invalid operand " + op); - } - } - - - private static final ArithmeticInstruction createBinaryDoubleOp( char op ) { - switch (op) { - case '-': - return DSUB; - case '+': - return DADD; - case '*': - return DMUL; - case '/': - return DDIV; - default: - throw new RuntimeException("Invalid operand " + op); - } - } - - - /** +/** * Create binary operation for simple basic types, such as int and float. * * @param op operation, such as "+", "*", "<<", etc. */ - public static ArithmeticInstruction createBinaryOperation( String op, Type type ) { - char first = op.toCharArray()[0]; - switch (type.getType()) { - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - case Constants.T_CHAR: - return createBinaryIntOp(first, op); - case Constants.T_LONG: - return createBinaryLongOp(first, op); - case Constants.T_FLOAT: - return createBinaryFloatOp(first); - case Constants.T_DOUBLE: - return createBinaryDoubleOp(first); - default: - throw new RuntimeException("Invalid type " + type); - } - } + public static ArithmeticInstruction createBinaryOperation(String op, + Type type) { + char first = op.toCharArray()[0]; + switch (type.getType()) { + case Constants.T_BYTE: + case Constants.T_SHORT: + case Constants.T_INT: + case Constants.T_CHAR: + return createBinaryIntOp(first, op); + case Constants.T_LONG: + return createBinaryLongOp(first, op); + case Constants.T_FLOAT: + return createBinaryFloatOp(first); + case Constants.T_DOUBLE: + return createBinaryDoubleOp(first); + default: + throw new RuntimeException("Invalid type " + type); + } + } + /** + * @param size + * size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createPop(int size) { + return (size == 2) ? (StackInstruction) POP2 : (StackInstruction) POP; + } - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createPop( int size ) { - return (size == 2) ? (StackInstruction) POP2 : (StackInstruction) POP; - } + /** + * @param size + * size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup(int size) { + return (size == 2) ? (StackInstruction) DUP2 : (StackInstruction) DUP; + } + /** + * @param size + * size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup_2(int size) { + return (size == 2) ? (StackInstruction) DUP2_X2 + : (StackInstruction) DUP_X2; + } - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup( int size ) { - return (size == 2) ? (StackInstruction) DUP2 : (StackInstruction) DUP; - } + /** + * @param size + * size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup_1(int size) { + return (size == 2) ? (StackInstruction) DUP2_X1 + : (StackInstruction) DUP_X1; + } + /** + * @param index + * index of local variable + */ + public static LocalVariableInstruction createStore(Type type, int index) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + case Constants.T_SHORT: + case Constants.T_INT: + return new ISTORE(index); + case Constants.T_FLOAT: + return new FSTORE(index); + case Constants.T_DOUBLE: + return new DSTORE(index); + case Constants.T_LONG: + return new LSTORE(index); + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return new ASTORE(index); + default: + throw new RuntimeException("Invalid type " + type); + } + } - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup_2( int size ) { - return (size == 2) ? (StackInstruction) DUP2_X2 : (StackInstruction) DUP_X2; - } + /** + * @param index + * index of local variable + */ + public static LocalVariableInstruction createLoad(Type type, int index) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + case Constants.T_SHORT: + case Constants.T_INT: + return new ILOAD(index); + case Constants.T_FLOAT: + return new FLOAD(index); + case Constants.T_DOUBLE: + return new DLOAD(index); + case Constants.T_LONG: + return new LLOAD(index); + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return new ALOAD(index); + default: + throw new RuntimeException("Invalid type " + type); + } + } + /** + * @param type + * type of elements of array, i.e., array.getElementType() + */ + public static ArrayInstruction createArrayLoad(Type type) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_BYTE: + return BALOAD; + case Constants.T_CHAR: + return CALOAD; + case Constants.T_SHORT: + return SALOAD; + case Constants.T_INT: + return IALOAD; + case Constants.T_FLOAT: + return FALOAD; + case Constants.T_DOUBLE: + return DALOAD; + case Constants.T_LONG: + return LALOAD; + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return AALOAD; + default: + throw new RuntimeException("Invalid type " + type); + } + } - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup_1( int size ) { - return (size == 2) ? (StackInstruction) DUP2_X1 : (StackInstruction) DUP_X1; - } + /** + * @param type + * type of elements of array, i.e., array.getElementType() + */ + public static ArrayInstruction createArrayStore(Type type) { + switch (type.getType()) { + case Constants.T_BOOLEAN: + case Constants.T_BYTE: + return BASTORE; + case Constants.T_CHAR: + return CASTORE; + case Constants.T_SHORT: + return SASTORE; + case Constants.T_INT: + return IASTORE; + case Constants.T_FLOAT: + return FASTORE; + case Constants.T_DOUBLE: + return DASTORE; + case Constants.T_LONG: + return LASTORE; + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return AASTORE; + default: + throw new RuntimeException("Invalid type " + type); + } + } + /** + * Create conversion operation for two stack operands, this may be an I2C, + * instruction, e.g., if the operands are basic types and CHECKCAST if they + * are reference types. + */ + public Instruction createCast(Type src_type, Type dest_type) { + if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { + byte dest = dest_type.getType(); + byte src = src_type.getType(); + if (dest == Constants.T_LONG + && (src == Constants.T_CHAR || src == Constants.T_BYTE || src == Constants.T_SHORT)) { + src = Constants.T_INT; + } + String[] short_names = { "C", "F", "D", "B", "S", "I", "L" }; + String name = "org.apache.bcel.generic." + + short_names[src - Constants.T_CHAR] + "2" + + short_names[dest - Constants.T_CHAR]; + Instruction i = null; + try { + i = (Instruction) java.lang.Class.forName(name).newInstance(); + } catch (Exception e) { + throw new RuntimeException("Could not find instruction: " + + name); + } + return i; + } else if ((src_type instanceof ReferenceType) + && (dest_type instanceof ReferenceType)) { + if (dest_type instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) dest_type)); + } else { + return new CHECKCAST(cp.addClass(((ObjectType) dest_type) + .getClassName())); + } + } else { + throw new RuntimeException("Can not cast " + src_type + " to " + + dest_type); + } + } - /** - * @param index index of local variable - */ - public static LocalVariableInstruction createStore( Type type, int index ) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - return new ISTORE(index); - case Constants.T_FLOAT: - return new FSTORE(index); - case Constants.T_DOUBLE: - return new DSTORE(index); - case Constants.T_LONG: - return new LSTORE(index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return new ASTORE(index); - default: - throw new RuntimeException("Invalid type " + type); - } - } + public GETFIELD createGetField(String class_name, String name, Type t) { + return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); + } + public GETSTATIC createGetStatic(String class_name, String name, Type t) { + return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + } - /** - * @param index index of local variable - */ - public static LocalVariableInstruction createLoad( Type type, int index ) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - return new ILOAD(index); - case Constants.T_FLOAT: - return new FLOAD(index); - case Constants.T_DOUBLE: - return new DLOAD(index); - case Constants.T_LONG: - return new LLOAD(index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return new ALOAD(index); - default: - throw new RuntimeException("Invalid type " + type); - } - } + public PUTFIELD createPutField(String class_name, String name, Type t) { + return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); + } + public PUTSTATIC createPutStatic(String class_name, String name, Type t) { + return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + } - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static ArrayInstruction createArrayLoad( Type type ) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: - return BALOAD; - case Constants.T_CHAR: - return CALOAD; - case Constants.T_SHORT: - return SALOAD; - case Constants.T_INT: - return IALOAD; - case Constants.T_FLOAT: - return FALOAD; - case Constants.T_DOUBLE: - return DALOAD; - case Constants.T_LONG: - return LALOAD; - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return AALOAD; - default: - throw new RuntimeException("Invalid type " + type); - } - } + public CHECKCAST createCheckCast(ReferenceType t) { + if (t instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) t)); + } else { + return new CHECKCAST(cp.addClass((ObjectType) t)); + } + } + public INSTANCEOF createInstanceOf(ReferenceType t) { + if (t instanceof ArrayType) { + return new INSTANCEOF(cp.addArrayClass((ArrayType) t)); + } else { + return new INSTANCEOF(cp.addClass((ObjectType) t)); + } + } - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static ArrayInstruction createArrayStore( Type type ) { - switch (type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: - return BASTORE; - case Constants.T_CHAR: - return CASTORE; - case Constants.T_SHORT: - return SASTORE; - case Constants.T_INT: - return IASTORE; - case Constants.T_FLOAT: - return FASTORE; - case Constants.T_DOUBLE: - return DASTORE; - case Constants.T_LONG: - return LASTORE; - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return AASTORE; - default: - throw new RuntimeException("Invalid type " + type); - } - } + public NEW createNew(ObjectType t) { + return new NEW(cp.addClass(t)); + } + public NEW createNew(String s) { + return createNew(new ObjectType(s)); + } - /** Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., - * if the operands are basic types and CHECKCAST if they are reference types. - */ - public Instruction createCast( Type src_type, Type dest_type ) { - if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { - byte dest = dest_type.getType(); - byte src = src_type.getType(); - if (dest == Constants.T_LONG - && (src == Constants.T_CHAR || src == Constants.T_BYTE || src == Constants.T_SHORT)) { - src = Constants.T_INT; - } - String[] short_names = { - "C", "F", "D", "B", "S", "I", "L" - }; - String name = "org.apache.bcel.generic." + short_names[src - Constants.T_CHAR] + "2" - + short_names[dest - Constants.T_CHAR]; - Instruction i = null; - try { - i = (Instruction) java.lang.Class.forName(name).newInstance(); - } catch (Exception e) { - throw new RuntimeException("Could not find instruction: " + name); - } - return i; - } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { - if (dest_type instanceof ArrayType) { - return new CHECKCAST(cp.addArrayClass((ArrayType) dest_type)); - } else { - return new CHECKCAST(cp.addClass(((ObjectType) dest_type).getClassName())); - } - } else { - throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); - } - } + /** + * Create new array of given size and type. + * + * @return an instruction that creates the corresponding array at runtime, + * i.e. is an AllocationInstruction + */ + public Instruction createNewArray(Type t, short dim) { + if (dim == 1) { + if (t instanceof ObjectType) { + return new ANEWARRAY(cp.addClass((ObjectType) t)); + } else if (t instanceof ArrayType) { + return new ANEWARRAY(cp.addArrayClass((ArrayType) t)); + } else { + return new NEWARRAY(((BasicType) t).getType()); + } + } else { + ArrayType at; + if (t instanceof ArrayType) { + at = (ArrayType) t; + } else { + at = new ArrayType(t, dim); + } + return new MULTIANEWARRAY(cp.addArrayClass(at), dim); + } + } + /** + * Create "null" value for reference types, 0 for basic types like int + */ + public static Instruction createNull(Type type) { + switch (type.getType()) { + case Constants.T_ARRAY: + case Constants.T_OBJECT: + return ACONST_NULL; + case Constants.T_INT: + case Constants.T_SHORT: + case Constants.T_BOOLEAN: + case Constants.T_CHAR: + case Constants.T_BYTE: + return ICONST_0; + case Constants.T_FLOAT: + return FCONST_0; + case Constants.T_DOUBLE: + return DCONST_0; + case Constants.T_LONG: + return LCONST_0; + case Constants.T_VOID: + return NOP; + default: + throw new RuntimeException("Invalid type: " + type); + } + } - public GETFIELD createGetField( String class_name, String name, Type t ) { - return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); - } + /** + * Create branch instruction by given opcode, except LOOKUPSWITCH and + * TABLESWITCH. For those you should use the SWITCH compound instruction. + */ + public static BranchInstruction createBranchInstruction(short opcode, + InstructionHandle target) { + switch (opcode) { + case Constants.IFEQ: + return new IFEQ(target); + case Constants.IFNE: + return new IFNE(target); + case Constants.IFLT: + return new IFLT(target); + case Constants.IFGE: + return new IFGE(target); + case Constants.IFGT: + return new IFGT(target); + case Constants.IFLE: + return new IFLE(target); + case Constants.IF_ICMPEQ: + return new IF_ICMPEQ(target); + case Constants.IF_ICMPNE: + return new IF_ICMPNE(target); + case Constants.IF_ICMPLT: + return new IF_ICMPLT(target); + case Constants.IF_ICMPGE: + return new IF_ICMPGE(target); + case Constants.IF_ICMPGT: + return new IF_ICMPGT(target); + case Constants.IF_ICMPLE: + return new IF_ICMPLE(target); + case Constants.IF_ACMPEQ: + return new IF_ACMPEQ(target); + case Constants.IF_ACMPNE: + return new IF_ACMPNE(target); + case Constants.GOTO: + return new GOTO(target); + case Constants.JSR: + return new JSR(target); + case Constants.IFNULL: + return new IFNULL(target); + case Constants.IFNONNULL: + return new IFNONNULL(target); + case Constants.GOTO_W: + return new GOTO_W(target); + case Constants.JSR_W: + return new JSR_W(target); + default: + throw new RuntimeException("Invalid opcode: " + opcode); + } + } + public void setClassGen(ClassGen c) { + cg = c; + } - public GETSTATIC createGetStatic( String class_name, String name, Type t ) { - return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); - } + public ClassGen getClassGen() { + return cg; + } + public void setConstantPool(ConstantPoolGen c) { + cp = c; + } - public PUTFIELD createPutField( String class_name, String name, Type t ) { - return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); - } - - - public PUTSTATIC createPutStatic( String class_name, String name, Type t ) { - return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); - } - - - public CHECKCAST createCheckCast( ReferenceType t ) { - if (t instanceof ArrayType) { - return new CHECKCAST(cp.addArrayClass((ArrayType) t)); - } else { - return new CHECKCAST(cp.addClass((ObjectType) t)); - } - } - - - public INSTANCEOF createInstanceOf( ReferenceType t ) { - if (t instanceof ArrayType) { - return new INSTANCEOF(cp.addArrayClass((ArrayType) t)); - } else { - return new INSTANCEOF(cp.addClass((ObjectType) t)); - } - } - - - public NEW createNew( ObjectType t ) { - return new NEW(cp.addClass(t)); - } - - - public NEW createNew( String s ) { - return createNew(new ObjectType(s)); - } - - - /** Create new array of given size and type. - * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction - */ - public Instruction createNewArray( Type t, short dim ) { - if (dim == 1) { - if (t instanceof ObjectType) { - return new ANEWARRAY(cp.addClass((ObjectType) t)); - } else if (t instanceof ArrayType) { - return new ANEWARRAY(cp.addArrayClass((ArrayType) t)); - } else { - return new NEWARRAY(((BasicType) t).getType()); - } - } else { - ArrayType at; - if (t instanceof ArrayType) { - at = (ArrayType) t; - } else { - at = new ArrayType(t, dim); - } - return new MULTIANEWARRAY(cp.addArrayClass(at), dim); - } - } - - - /** Create "null" value for reference types, 0 for basic types like int - */ - public static Instruction createNull( Type type ) { - switch (type.getType()) { - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return ACONST_NULL; - case Constants.T_INT: - case Constants.T_SHORT: - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - return ICONST_0; - case Constants.T_FLOAT: - return FCONST_0; - case Constants.T_DOUBLE: - return DCONST_0; - case Constants.T_LONG: - return LCONST_0; - case Constants.T_VOID: - return NOP; - default: - throw new RuntimeException("Invalid type: " + type); - } - } - - - /** Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. - * For those you should use the SWITCH compound instruction. - */ - public static BranchInstruction createBranchInstruction( short opcode, InstructionHandle target ) { - switch (opcode) { - case Constants.IFEQ: - return new IFEQ(target); - case Constants.IFNE: - return new IFNE(target); - case Constants.IFLT: - return new IFLT(target); - case Constants.IFGE: - return new IFGE(target); - case Constants.IFGT: - return new IFGT(target); - case Constants.IFLE: - return new IFLE(target); - case Constants.IF_ICMPEQ: - return new IF_ICMPEQ(target); - case Constants.IF_ICMPNE: - return new IF_ICMPNE(target); - case Constants.IF_ICMPLT: - return new IF_ICMPLT(target); - case Constants.IF_ICMPGE: - return new IF_ICMPGE(target); - case Constants.IF_ICMPGT: - return new IF_ICMPGT(target); - case Constants.IF_ICMPLE: - return new IF_ICMPLE(target); - case Constants.IF_ACMPEQ: - return new IF_ACMPEQ(target); - case Constants.IF_ACMPNE: - return new IF_ACMPNE(target); - case Constants.GOTO: - return new GOTO(target); - case Constants.JSR: - return new JSR(target); - case Constants.IFNULL: - return new IFNULL(target); - case Constants.IFNONNULL: - return new IFNONNULL(target); - case Constants.GOTO_W: - return new GOTO_W(target); - case Constants.JSR_W: - return new JSR_W(target); - default: - throw new RuntimeException("Invalid opcode: " + opcode); - } - } - - - public void setClassGen( ClassGen c ) { - cg = c; - } - - - public ClassGen getClassGen() { - return cg; - } - - - public void setConstantPool( ConstantPoolGen c ) { - cp = c; - } - - - public ConstantPoolGen getConstantPool() { - return cp; - } + public ConstantPoolGen getConstantPool() { + return cp; + } } diff --git a/src/org/apache/bcel/generic/InstructionHandle.java b/src/org/apache/bcel/generic/InstructionHandle.java index 176b76f..5129d00 100644 --- a/src/org/apache/bcel/generic/InstructionHandle.java +++ b/src/org/apache/bcel/generic/InstructionHandle.java @@ -21,270 +21,276 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; + import org.apache.bcel.classfile.Utility; /** * Instances of this class give users a handle to the instructions contained in * an InstructionList. Instruction objects may be used more than once within a * list, this is useful because it saves memory and may be much faster. - * - * Within an InstructionList an InstructionHandle object is wrapped - * around all instructions, i.e., it implements a cell in a - * doubly-linked list. From the outside only the next and the - * previous instruction (handle) are accessible. One - * can traverse the list via an Enumeration returned by + * + * Within an InstructionList an InstructionHandle object is wrapped around all + * instructions, i.e., it implements a cell in a doubly-linked list. From the + * outside only the next and the previous instruction (handle) are accessible. + * One can traverse the list via an Enumeration returned by * InstructionList.elements(). - * + * * @version $Id: InstructionHandle.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see Instruction * @see BranchHandle - * @see InstructionList + * @see InstructionList */ public class InstructionHandle implements java.io.Serializable { - InstructionHandle next, prev; // Will be set from the outside - Instruction instruction; - protected int i_position = -1; // byte code offset of instruction - private Set targeters; - private Map attributes; + /** + * + */ + private static final long serialVersionUID = 1L; + InstructionHandle next, prev; // Will be set from the outside + Instruction instruction; + protected int i_position = -1; // byte code offset of instruction + private Set targeters; + private Map attributes; + public final InstructionHandle getNext() { + return next; + } - public final InstructionHandle getNext() { - return next; - } + public final InstructionHandle getPrev() { + return prev; + } + public final Instruction getInstruction() { + return instruction; + } - public final InstructionHandle getPrev() { - return prev; - } + /** + * Replace current instruction contained in this handle. Old instruction is + * disposed using Instruction.dispose(). + */ + public void setInstruction(Instruction i) { // Overridden in BranchHandle + if (i == null) { + throw new ClassGenException("Assigning null to handle"); + } + if ((this.getClass() != BranchHandle.class) + && (i instanceof BranchInstruction)) { + throw new ClassGenException("Assigning branch instruction " + i + + " to plain handle"); + } + if (instruction != null) { + instruction.dispose(); + } + instruction = i; + } + /** + * Temporarily swap the current instruction, without disturbing anything. + * Meant to be used by a debugger, implementing breakpoints. Current + * instruction is returned. + */ + public Instruction swapInstruction(Instruction i) { + Instruction oldInstruction = instruction; + instruction = i; + return oldInstruction; + } - public final Instruction getInstruction() { - return instruction; - } + /* private */protected InstructionHandle(Instruction i) { + setInstruction(i); + } + private static InstructionHandle ih_list = null; // List of reusable handles - /** - * Replace current instruction contained in this handle. - * Old instruction is disposed using Instruction.dispose(). - */ - public void setInstruction( Instruction i ) { // Overridden in BranchHandle - if (i == null) { - throw new ClassGenException("Assigning null to handle"); - } - if ((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) { - throw new ClassGenException("Assigning branch instruction " + i + " to plain handle"); - } - if (instruction != null) { - instruction.dispose(); - } - instruction = i; - } + /** + * Factory method. + */ + static final InstructionHandle getInstructionHandle(Instruction i) { + if (ih_list == null) { + return new InstructionHandle(i); + } else { + InstructionHandle ih = ih_list; + ih_list = ih.next; + ih.setInstruction(i); + return ih; + } + } + /** + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions()' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset + * additional offset caused by preceding (variable length) + * instructions + * @param max_offset + * the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + protected int updatePosition(int offset, int max_offset) { + i_position += offset; + return 0; + } - /** - * Temporarily swap the current instruction, without disturbing - * anything. Meant to be used by a debugger, implementing - * breakpoints. Current instruction is returned. - */ - public Instruction swapInstruction( Instruction i ) { - Instruction oldInstruction = instruction; - instruction = i; - return oldInstruction; - } + /** + * @return the position, i.e., the byte code offset of the contained + * instruction. This is accurate only after + * InstructionList.setPositions() has been called. + */ + public int getPosition() { + return i_position; + } + /** + * Set the position, i.e., the byte code offset of the contained + * instruction. + */ + void setPosition(int pos) { + i_position = pos; + } - /*private*/protected InstructionHandle(Instruction i) { - setInstruction(i); - } + /** + * Overridden in BranchHandle + */ + protected void addHandle() { + next = ih_list; + ih_list = this; + } - private static InstructionHandle ih_list = null; // List of reusable handles + /** + * Delete contents, i.e., remove user access and make handle reusable. + */ + void dispose() { + next = prev = null; + instruction.dispose(); + instruction = null; + i_position = -1; + attributes = null; + removeAllTargeters(); + addHandle(); + } + /** + * Remove all targeters, if any. + */ + public void removeAllTargeters() { + if (targeters != null) { + targeters.clear(); + } + } - /** Factory method. - */ - static final InstructionHandle getInstructionHandle( Instruction i ) { - if (ih_list == null) { - return new InstructionHandle(i); - } else { - InstructionHandle ih = ih_list; - ih_list = ih.next; - ih.setInstruction(i); - return ih; - } - } + /** + * Denote this handle isn't referenced anymore by t. + */ + public void removeTargeter(InstructionTargeter t) { + if (targeters != null) { + targeters.remove(t); + } + } + /** + * Denote this handle is being referenced by t. + */ + public void addTargeter(InstructionTargeter t) { + if (targeters == null) { + targeters = new HashSet(); + } + // if(!targeters.contains(t)) + targeters.add(t); + } - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions()' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition( int offset, int max_offset ) { - i_position += offset; - return 0; - } + public boolean hasTargeters() { + return (targeters != null) && (targeters.size() > 0); + } + /** + * @return null, if there are no targeters + */ + public InstructionTargeter[] getTargeters() { + if (!hasTargeters()) { + return null; + } + InstructionTargeter[] t = new InstructionTargeter[targeters.size()]; + targeters.toArray(t); + return t; + } - /** @return the position, i.e., the byte code offset of the contained - * instruction. This is accurate only after - * InstructionList.setPositions() has been called. - */ - public int getPosition() { - return i_position; - } + /** + * @return a (verbose) string representation of the contained instruction. + */ + public String toString(boolean verbose) { + return Utility.format(i_position, 4, false, ' ') + ": " + + instruction.toString(verbose); + } + /** + * @return a string representation of the contained instruction. + */ + @Override + public String toString() { + return toString(true); + } - /** Set the position, i.e., the byte code offset of the contained - * instruction. - */ - void setPosition( int pos ) { - i_position = pos; - } + /** + * Add an attribute to an instruction handle. + * + * @param key + * the key object to store/retrieve the attribute + * @param attr + * the attribute to associate with this handle + */ + public void addAttribute(Object key, Object attr) { + if (attributes == null) { + attributes = new HashMap(3); + } + attributes.put(key, attr); + } + /** + * Delete an attribute of an instruction handle. + * + * @param key + * the key object to retrieve the attribute + */ + public void removeAttribute(Object key) { + if (attributes != null) { + attributes.remove(key); + } + } - /** Overridden in BranchHandle - */ - protected void addHandle() { - next = ih_list; - ih_list = this; - } + /** + * Get attribute of an instruction handle. + * + * @param key + * the key object to store/retrieve the attribute + */ + public Object getAttribute(Object key) { + if (attributes != null) { + return attributes.get(key); + } + return null; + } + /** + * @return all attributes associated with this handle + */ + public Collection getAttributes() { + if (attributes == null) { + attributes = new HashMap(3); + } + return attributes.values(); + } - /** - * Delete contents, i.e., remove user access and make handle reusable. - */ - void dispose() { - next = prev = null; - instruction.dispose(); - instruction = null; - i_position = -1; - attributes = null; - removeAllTargeters(); - addHandle(); - } - - - /** Remove all targeters, if any. - */ - public void removeAllTargeters() { - if (targeters != null) { - targeters.clear(); - } - } - - - /** - * Denote this handle isn't referenced anymore by t. - */ - public void removeTargeter( InstructionTargeter t ) { - if (targeters != null) { - targeters.remove(t); - } - } - - - /** - * Denote this handle is being referenced by t. - */ - public void addTargeter( InstructionTargeter t ) { - if (targeters == null) { - targeters = new HashSet(); - } - //if(!targeters.contains(t)) - targeters.add(t); - } - - - public boolean hasTargeters() { - return (targeters != null) && (targeters.size() > 0); - } - - - /** - * @return null, if there are no targeters - */ - public InstructionTargeter[] getTargeters() { - if (!hasTargeters()) { - return null; - } - InstructionTargeter[] t = new InstructionTargeter[targeters.size()]; - targeters.toArray(t); - return t; - } - - - /** @return a (verbose) string representation of the contained instruction. - */ - public String toString( boolean verbose ) { - return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose); - } - - - /** @return a string representation of the contained instruction. - */ - public String toString() { - return toString(true); - } - - - /** Add an attribute to an instruction handle. - * - * @param key the key object to store/retrieve the attribute - * @param attr the attribute to associate with this handle - */ - public void addAttribute( Object key, Object attr ) { - if (attributes == null) { - attributes = new HashMap(3); - } - attributes.put(key, attr); - } - - - /** Delete an attribute of an instruction handle. - * - * @param key the key object to retrieve the attribute - */ - public void removeAttribute( Object key ) { - if (attributes != null) { - attributes.remove(key); - } - } - - - /** Get attribute of an instruction handle. - * - * @param key the key object to store/retrieve the attribute - */ - public Object getAttribute( Object key ) { - if (attributes != null) { - return attributes.get(key); - } - return null; - } - - - /** @return all attributes associated with this handle - */ - public Collection getAttributes() { - if (attributes == null) { - attributes = new HashMap(3); - } - return attributes.values(); - } - - - /** Convenience method, simply calls accept() on the contained instruction. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - instruction.accept(v); - } + /** + * Convenience method, simply calls accept() on the contained instruction. + * + * @param v + * Visitor object + */ + public void accept(Visitor v) { + instruction.accept(v); + } } diff --git a/src/org/apache/bcel/generic/InstructionList.java b/src/org/apache/bcel/generic/InstructionList.java index 9a10664..5003628 100644 --- a/src/org/apache/bcel/generic/InstructionList.java +++ b/src/org/apache/bcel/generic/InstructionList.java @@ -25,1241 +25,1310 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; + import org.apache.bcel.Constants; import org.apache.bcel.classfile.Constant; import org.apache.bcel.util.ByteSequence; -/** +/** * This class is a container for a list of Instruction objects. Instructions can - * be appended, inserted, moved, deleted, etc.. Instructions are being - * wrapped into InstructionHandles objects that - * are returned upon append/insert operations. They give the user - * (read only) access to the list structure, such that it can be traversed and - * manipulated in a controlled way. - * + * href="Instruction.html">Instruction objects. Instructions can be + * appended, inserted, moved, deleted, etc.. Instructions are being wrapped into + * InstructionHandles objects that are + * returned upon append/insert operations. They give the user (read only) access + * to the list structure, such that it can be traversed and manipulated in a + * controlled way. + * * A list is finally dumped to a byte code array with getByteCode. - * + * * @version $Id: InstructionList.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Instruction - * @see InstructionHandle + * @author M. Dahm + * @see Instruction + * @see InstructionHandle * @see BranchHandle */ public class InstructionList implements Serializable { - private InstructionHandle start = null, end = null; - private int length = 0; // number of elements in list - private int[] byte_positions; // byte code offsets corresponding to instructions - - - /** - * Create (empty) instruction list. - */ - public InstructionList() { - } - - - /** - * Create instruction list containing one instruction. - * @param i initial instruction - */ - public InstructionList(Instruction i) { - append(i); - } - - - /** - * Create instruction list containing one instruction. - * @param i initial instruction - */ - public InstructionList(BranchInstruction i) { - append(i); - } - - - /** - * Initialize list with (nonnull) compound instruction. Consumes argument - * list, i.e., it becomes empty. - * - * @param c compound instruction (list) - */ - public InstructionList(CompoundInstruction c) { - append(c.getInstructionList()); - } - - - /** - * Test for empty list. - */ - public boolean isEmpty() { - return start == null; - } // && end == null - - - /** - * Find the target instruction (handle) that corresponds to the given target - * position (byte code offset). - * - * @param ihs array of instruction handles, i.e. il.getInstructionHandles() - * @param pos array of positions corresponding to ihs, i.e. il.getInstructionPositions() - * @param count length of arrays - * @param target target position to search for - * @return target position's instruction handle if available - */ - public static InstructionHandle findHandle( InstructionHandle[] ihs, int[] pos, int count, - int target ) { - int l = 0, r = count - 1; - /* Do a binary search since the pos array is orderd. - */ - do { - int i = (l + r) / 2; - int j = pos[i]; - if (j == target) { - return ihs[i]; - } else if (target < j) { - r = i - 1; - } else { - l = i + 1; - } - } while (l <= r); - return null; - } - - - /** - * Get instruction handle for instruction at byte code position pos. - * This only works properly, if the list is freshly initialized from a byte array or - * setPositions() has been called before this method. - * - * @param pos byte code position to search for - * @return target position's instruction handle if available - */ - public InstructionHandle findHandle( int pos ) { - InstructionHandle[] ihs = getInstructionHandles(); - return findHandle(ihs, byte_positions, length, pos); - } - - - /** - * Initialize instruction list from byte array. - * - * @param code byte array containing the instructions - */ - public InstructionList(byte[] code) { - ByteSequence bytes = new ByteSequence(code); - InstructionHandle[] ihs = new InstructionHandle[code.length]; - int[] pos = new int[code.length]; // Can't be more than that - int count = 0; // Contains actual length - /* Pass 1: Create an object for each byte code and append them - * to the list. - */ - try { - while (bytes.available() > 0) { - // Remember byte offset and associate it with the instruction - int off = bytes.getIndex(); - pos[count] = off; - /* Read one instruction from the byte stream, the byte position is set - * accordingly. - */ - Instruction i = Instruction.readInstruction(bytes); - InstructionHandle ih; - if (i instanceof BranchInstruction) { - ih = append((BranchInstruction) i); - } else { - ih = append(i); - } - ih.setPosition(off); - ihs[count] = ih; - count++; - } - } catch (IOException e) { - throw new ClassGenException(e.toString()); - } - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); - /* Pass 2: Look for BranchInstruction and update their targets, i.e., - * convert offsets to instruction handles. - */ - for (int i = 0; i < count; i++) { - if (ihs[i] instanceof BranchHandle) { - BranchInstruction bi = (BranchInstruction) ihs[i].instruction; - int target = bi.position + bi.getIndex(); /* Byte code position: - * relative -> absolute. */ - // Search for target position - InstructionHandle ih = findHandle(ihs, pos, count, target); - if (ih == null) { - throw new ClassGenException("Couldn't find target for branch: " + bi); - } - bi.setTarget(ih); // Update target - // If it is a Select instruction, update all branch targets - if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - Select s = (Select) bi; - int[] indices = s.getIndices(); - for (int j = 0; j < indices.length; j++) { - target = bi.position + indices[j]; - ih = findHandle(ihs, pos, count, target); - if (ih == null) { - throw new ClassGenException("Couldn't find target for switch: " + bi); - } - s.setTarget(j, ih); // Update target - } - } - } - } - } - - - /** - * Append another list after instruction (handle) ih contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param ih where to append the instruction list - * @param il Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append( InstructionHandle ih, InstructionList il ) { - if (il == null) { - throw new ClassGenException("Appending null InstructionList"); - } - if (il.isEmpty()) { - return ih; - } - InstructionHandle next = ih.next, ret = il.start; - ih.next = il.start; - il.start.prev = ih; - il.end.next = next; - if (next != null) { - next.prev = il.end; - } else { - end = il.end; // Update end ... - } - length += il.length; // Update length - il.clear(); - return ret; - } - - - /** - * Append another list after instruction i contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append( Instruction i, InstructionList il ) { - InstructionHandle ih; - if ((ih = findInstruction2(i)) == null) { - throw new ClassGenException("Instruction " + i + " is not contained in this list."); - } - return append(ih, il); - } - - - /** - * Append another list to this one. - * Consumes argument list, i.e., it becomes empty. - * - * @param il list to append to end of this list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append( InstructionList il ) { - if (il == null) { - throw new ClassGenException("Appending null InstructionList"); - } - if (il.isEmpty()) { - return null; - } - if (isEmpty()) { - start = il.start; - end = il.end; - length = il.length; - il.clear(); - return start; - } else { - return append(end, il); // was end.instruction - } - } - - - /** - * Append an instruction to the end of this list. - * - * @param ih instruction to append - */ - private void append( InstructionHandle ih ) { - if (isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } else { - end.next = ih; - ih.prev = end; - ih.next = null; - end = ih; - } - length++; // Update length - } - - - /** - * Append an instruction to the end of this list. - * - * @param i instruction to append - * @return instruction handle of the appended instruction - */ - public InstructionHandle append( Instruction i ) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - append(ih); - return ih; - } - - - /** - * Append a branch instruction to the end of this list. - * - * @param i branch instruction to append - * @return branch instruction handle of the appended instruction - */ - public BranchHandle append( BranchInstruction i ) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - append(ih); - return ih; - } - - - /** - * Append a single instruction j after another instruction i, which - * must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to append after i in list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append( Instruction i, Instruction j ) { - return append(i, new InstructionList(j)); - } - - - /** - * Append a compound instruction, after instruction i. - * - * @param i Instruction in list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append( Instruction i, CompoundInstruction c ) { - return append(i, c.getInstructionList()); - } - - - /** - * Append a compound instruction. - * - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append( CompoundInstruction c ) { - return append(c.getInstructionList()); - } - - - /** - * Append a compound instruction. - * - * @param ih where to append the instruction list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append( InstructionHandle ih, CompoundInstruction c ) { - return append(ih, c.getInstructionList()); - } - - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append( InstructionHandle ih, Instruction i ) { - return append(ih, new InstructionList(i)); - } - - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public BranchHandle append( InstructionHandle ih, BranchInstruction i ) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - append(ih, il); - return bh; - } - - - /** - * Insert another list before Instruction handle ih contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param ih where to append the instruction list - * @param il Instruction list to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert( InstructionHandle ih, InstructionList il ) { - if (il == null) { - throw new ClassGenException("Inserting null InstructionList"); - } - if (il.isEmpty()) { - return ih; - } - InstructionHandle prev = ih.prev, ret = il.start; - ih.prev = il.end; - il.end.next = ih; - il.start.prev = prev; - if (prev != null) { - prev.next = il.start; - } else { - start = il.start; // Update start ... - } - length += il.length; // Update length - il.clear(); - return ret; - } - - - /** - * Insert another list. - * - * @param il list to insert before start of this list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert( InstructionList il ) { - if (isEmpty()) { - append(il); // Code is identical for this case - return start; - } else { - return insert(start, il); - } - } - - - /** - * Insert an instruction at start of this list. - * - * @param ih instruction to insert - */ - private void insert( InstructionHandle ih ) { - if (isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } else { - start.prev = ih; - ih.next = start; - ih.prev = null; - start = ih; - } - length++; - } - - - /** - * Insert another list before Instruction i contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to insert - * @return instruction handle pointing to the first inserted instruction, - * i.e., il.getStart() - */ - public InstructionHandle insert( Instruction i, InstructionList il ) { - InstructionHandle ih; - if ((ih = findInstruction1(i)) == null) { - throw new ClassGenException("Instruction " + i + " is not contained in this list."); - } - return insert(ih, il); - } - - - /** - * Insert an instruction at start of this list. - * - * @param i instruction to insert - * @return instruction handle of the inserted instruction - */ - public InstructionHandle insert( Instruction i ) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - insert(ih); - return ih; - } - - - /** - * Insert a branch instruction at start of this list. - * - * @param i branch instruction to insert - * @return branch instruction handle of the appended instruction - */ - public BranchHandle insert( BranchInstruction i ) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - insert(ih); - return ih; - } - - - /** - * Insert a single instruction j before another instruction i, which - * must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to insert before i in list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert( Instruction i, Instruction j ) { - return insert(i, new InstructionList(j)); - } - - - /** - * Insert a compound instruction before instruction i. - * - * @param i Instruction in list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert( Instruction i, CompoundInstruction c ) { - return insert(i, c.getInstructionList()); - } - - - /** - * Insert a compound instruction. - * - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert( CompoundInstruction c ) { - return insert(c.getInstructionList()); - } - - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert( InstructionHandle ih, Instruction i ) { - return insert(ih, new InstructionList(i)); - } - - - /** - * Insert a compound instruction. - * - * @param ih where to insert the instruction list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert( InstructionHandle ih, CompoundInstruction c ) { - return insert(ih, c.getInstructionList()); - } - - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public BranchHandle insert( InstructionHandle ih, BranchInstruction i ) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - insert(ih, il); - return bh; - } - - - /** - * Take all instructions (handles) from "start" to "end" and append them after the - * new location "target". Of course, "end" must be after "start" and target must - * not be located withing this range. If you want to move something to the start of - * the list use null as value for target.
          - * Any instruction targeters pointing to handles within the block, keep their targets. - * - * @param start of moved block - * @param end of moved block - * @param target of moved block - */ - public void move( InstructionHandle start, InstructionHandle end, InstructionHandle target ) { - // Step 1: Check constraints - if ((start == null) || (end == null)) { - throw new ClassGenException("Invalid null handle: From " + start + " to " + end); - } - if ((target == start) || (target == end)) { - throw new ClassGenException("Invalid range: From " + start + " to " + end - + " contains target " + target); - } - for (InstructionHandle ih = start; ih != end.next; ih = ih.next) { - if (ih == null) { - throw new ClassGenException("Invalid range: From " + start + " to " + end); - } else if (ih == target) { - throw new ClassGenException("Invalid range: From " + start + " to " + end - + " contains target " + target); - } - } - // Step 2: Temporarily remove the given instructions from the list - InstructionHandle prev = start.prev, next = end.next; - if (prev != null) { - prev.next = next; - } else { - this.start = next; - } - if (next != null) { - next.prev = prev; - } else { - this.end = prev; - } - start.prev = end.next = null; - // Step 3: append after target - if (target == null) { // append to start of list - if (this.start != null) { - this.start.prev = end; - } - end.next = this.start; - this.start = start; - } else { - next = target.next; - target.next = start; - start.prev = target; - end.next = next; - if (next != null) { - next.prev = end; - } else { - this.end = end; - } - } - } - - - /** - * Move a single instruction (handle) to a new location. - * - * @param ih moved instruction - * @param target new location of moved instruction - */ - public void move( InstructionHandle ih, InstructionHandle target ) { - move(ih, ih, target); - } - - - /** - * Remove from instruction `prev' to instruction `next' both contained - * in this list. Throws TargetLostException when one of the removed instruction handles - * is still being targeted. - * - * @param prev where to start deleting (predecessor, exclusive) - * @param next where to end deleting (successor, exclusive) - */ - private void remove( InstructionHandle prev, InstructionHandle next ) - throws TargetLostException { - InstructionHandle first, last; // First and last deleted instruction - if ((prev == null) && (next == null)) { // singleton list - first = last = start; - start = end = null; - } else { - if (prev == null) { // At start of list - first = start; - start = next; - } else { - first = prev.next; - prev.next = next; - } - if (next == null) { // At end of list - last = end; - end = prev; - } else { - last = next.prev; - next.prev = prev; - } - } - first.prev = null; // Completely separated from rest of list - last.next = null; - List target_vec = new ArrayList(); - for (InstructionHandle ih = first; ih != null; ih = ih.next) { - ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets - } - StringBuffer buf = new StringBuffer("{ "); - for (InstructionHandle ih = first; ih != null; ih = next) { - next = ih.next; - length--; - if (ih.hasTargeters()) { // Still got targeters? - target_vec.add(ih); - buf.append(ih.toString(true) + " "); - ih.next = ih.prev = null; - } else { - ih.dispose(); - } - } - buf.append("}"); - if (!target_vec.isEmpty()) { - InstructionHandle[] targeted = new InstructionHandle[target_vec.size()]; - target_vec.toArray(targeted); - throw new TargetLostException(targeted, buf.toString()); - } - } - - - /** - * Remove instruction from this list. The corresponding Instruction - * handles must not be reused! - * - * @param ih instruction (handle) to remove - */ - public void delete( InstructionHandle ih ) throws TargetLostException { - remove(ih.prev, ih.next); - } - - - /** - * Remove instruction from this list. The corresponding Instruction - * handles must not be reused! - * - * @param i instruction to remove - */ - public void delete( Instruction i ) throws TargetLostException { - InstructionHandle ih; - if ((ih = findInstruction1(i)) == null) { - throw new ClassGenException("Instruction " + i + " is not contained in this list."); - } - delete(ih); - } - - - /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete( InstructionHandle from, InstructionHandle to ) throws TargetLostException { - remove(from.prev, to.next); - } - - - /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete( Instruction from, Instruction to ) throws TargetLostException { - InstructionHandle from_ih, to_ih; - if ((from_ih = findInstruction1(from)) == null) { - throw new ClassGenException("Instruction " + from + " is not contained in this list."); - } - if ((to_ih = findInstruction2(to)) == null) { - throw new ClassGenException("Instruction " + to + " is not contained in this list."); - } - delete(from_ih, to_ih); - } - - - /** - * Search for given Instruction reference, start at beginning of list. - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction1( Instruction i ) { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - if (ih.instruction == i) { - return ih; - } - } - return null; - } - - - /** - * Search for given Instruction reference, start at end of list - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction2( Instruction i ) { - for (InstructionHandle ih = end; ih != null; ih = ih.prev) { - if (ih.instruction == i) { - return ih; - } - } - return null; - } - - - public boolean contains( InstructionHandle i ) { - if (i == null) { - return false; - } - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - if (ih == i) { - return true; - } - } - return false; - } - - - public boolean contains( Instruction i ) { - return findInstruction1(i) != null; - } - - - public void setPositions() { - setPositions(false); - } - - - /** - * Give all instructions their position number (offset in byte stream), i.e., - * make the list ready to be dumped. - * - * @param check Perform sanity checks, e.g. if all targeted instructions really belong - * to this list - */ - public void setPositions( boolean check ) { - int max_additional_bytes = 0, additional_bytes = 0; - int index = 0, count = 0; - int[] pos = new int[length]; - /* Pass 0: Sanity checks - */ - if (check) { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - if (i instanceof BranchInstruction) { // target instruction within list? - Instruction inst = ((BranchInstruction) i).getTarget().instruction; - if (!contains(inst)) { - throw new ClassGenException("Branch target of " - + Constants.OPCODE_NAMES[i.opcode] + ":" + inst - + " not in instruction list"); - } - if (i instanceof Select) { - InstructionHandle[] targets = ((Select) i).getTargets(); - for (int j = 0; j < targets.length; j++) { - inst = targets[j].instruction; - if (!contains(inst)) { - throw new ClassGenException("Branch target of " - + Constants.OPCODE_NAMES[i.opcode] + ":" + inst - + " not in instruction list"); - } - } - } - if (!(ih instanceof BranchHandle)) { - throw new ClassGenException("Branch instruction " - + Constants.OPCODE_NAMES[i.opcode] + ":" + inst - + " not contained in BranchHandle."); - } - } - } - } - /* Pass 1: Set position numbers and sum up the maximum number of bytes an - * instruction may be shifted. - */ - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - ih.setPosition(index); - pos[count++] = index; - /* Get an estimate about how many additional bytes may be added, because - * BranchInstructions may have variable length depending on the target - * offset (short vs. int) or alignment issues (TABLESWITCH and - * LOOKUPSWITCH). - */ - switch (i.getOpcode()) { - case Constants.JSR: - case Constants.GOTO: - max_additional_bytes += 2; - break; - case Constants.TABLESWITCH: - case Constants.LOOKUPSWITCH: - max_additional_bytes += 3; - break; - } - index += i.getLength(); - } - /* Pass 2: Expand the variable-length (Branch)Instructions depending on - * the target offset (short or int) and ensure that branch targets are - * within this list. - */ - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes); - } - /* Pass 3: Update position numbers (which may have changed due to the - * preceding expansions), like pass 1. - */ - index = count = 0; - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - ih.setPosition(index); - pos[count++] = index; - index += i.getLength(); - } - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); - } - - - /** - * When everything is finished, use this method to convert the instruction - * list into an array of bytes. - * - * @return the byte code ready to be dumped - */ - public byte[] getByteCode() { - // Update position indices of instructions - setPositions(); - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(b); - try { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - i.dump(out); // Traverse list - } - } catch (IOException e) { - System.err.println(e); - return null; - } - return b.toByteArray(); - } - - - /** - * @return an array of instructions without target information for branch instructions. - */ - public Instruction[] getInstructions() { - ByteSequence bytes = new ByteSequence(getByteCode()); - List instructions = new ArrayList(); - try { - while (bytes.available() > 0) { - instructions.add(Instruction.readInstruction(bytes)); - } - } catch (IOException e) { - throw new ClassGenException(e.toString()); - } - return (Instruction[]) instructions.toArray(new Instruction[instructions.size()]); - } - - - public String toString() { - return toString(true); - } - - - /** - * @param verbose toggle output format - * @return String containing all instructions in this list. - */ - public String toString( boolean verbose ) { - StringBuffer buf = new StringBuffer(); - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - buf.append(ih.toString(verbose)).append("\n"); - } - return buf.toString(); - } - - - /** - * @return Enumeration that lists all instructions (handles) - */ - public Iterator iterator() { - return new Iterator() { - - private InstructionHandle ih = start; - - - public Object next() { - InstructionHandle i = ih; - ih = ih.next; - return i; - } - - - public void remove() { - throw new UnsupportedOperationException(); - } - - - public boolean hasNext() { - return ih != null; - } - }; - } - - - /** - * @return array containing all instructions (handles) - */ - public InstructionHandle[] getInstructionHandles() { - InstructionHandle[] ihs = new InstructionHandle[length]; - InstructionHandle ih = start; - for (int i = 0; i < length; i++) { - ihs[i] = ih; - ih = ih.next; - } - return ihs; - } - - - /** - * Get positions (offsets) of all instructions in the list. This relies on that - * the list has been freshly created from an byte code array, or that setPositions() - * has been called. Otherwise this may be inaccurate. - * - * @return array containing all instruction's offset in byte code - */ - public int[] getInstructionPositions() { - return byte_positions; - } - - - /** - * @return complete, i.e., deep copy of this list - */ - public InstructionList copy() { - Map map = new HashMap(); - InstructionList il = new InstructionList(); - /* Pass 1: Make copies of all instructions, append them to the new list - * and associate old instruction references with the new ones, i.e., - * a 1:1 mapping. - */ - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - Instruction c = i.copy(); // Use clone for shallow copy - if (c instanceof BranchInstruction) { - map.put(ih, il.append((BranchInstruction) c)); - } else { - map.put(ih, il.append(c)); - } - } - /* Pass 2: Update branch targets. - */ - InstructionHandle ih = start; - InstructionHandle ch = il.start; - while (ih != null) { - Instruction i = ih.instruction; - Instruction c = ch.instruction; - if (i instanceof BranchInstruction) { - BranchInstruction bi = (BranchInstruction) i; - BranchInstruction bc = (BranchInstruction) c; - InstructionHandle itarget = bi.getTarget(); // old target - // New target is in hash map - bc.setTarget((InstructionHandle) map.get(itarget)); - if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] itargets = ((Select) bi).getTargets(); - InstructionHandle[] ctargets = ((Select) bc).getTargets(); - for (int j = 0; j < itargets.length; j++) { // Update all targets - ctargets[j] = (InstructionHandle) map.get(itargets[j]); - } - } - } - ih = ih.next; - ch = ch.next; - } - return il; - } - - - /** Replace all references to the old constant pool with references to the new - * constant pool - */ - public void replaceConstantPool( ConstantPoolGen old_cp, ConstantPoolGen new_cp ) { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - if (i instanceof CPInstruction) { - CPInstruction ci = (CPInstruction) i; - Constant c = old_cp.getConstant(ci.getIndex()); - ci.setIndex(new_cp.addConstant(c, old_cp)); - } - } - } - - - private void clear() { - start = end = null; - length = 0; - } - - - /** - * Delete contents of list. Provides besser memory utilization, - * because the system then may reuse the instruction handles. This - * method is typically called right after - * MethodGen.getMethod(). - */ - public void dispose() { - // Traverse in reverse order, because ih.next is overwritten - for (InstructionHandle ih = end; ih != null; ih = ih.prev) { - /* Causes BranchInstructions to release target and targeters, because it - * calls dispose() on the contained instruction. - */ - ih.dispose(); - } - clear(); - } - - - /** - * @return start of list - */ - public InstructionHandle getStart() { - return start; - } - - - /** - * @return end of list - */ - public InstructionHandle getEnd() { - return end; - } - - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int getLength() { - return length; - } - - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int size() { - return length; - } - - - /** - * Redirect all references from old_target to new_target, i.e., update targets - * of branch instructions. - * - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - */ - public void redirectBranches( InstructionHandle old_target, InstructionHandle new_target ) { - for (InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.getInstruction(); - if (i instanceof BranchInstruction) { - BranchInstruction b = (BranchInstruction) i; - InstructionHandle target = b.getTarget(); - if (target == old_target) { - b.setTarget(new_target); - } - if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] targets = ((Select) b).getTargets(); - for (int j = 0; j < targets.length; j++) { - if (targets[j] == old_target) { - ((Select) b).setTarget(j, new_target); - } - } - } - } - } - } - - - /** - * Redirect all references of local variables from old_target to new_target. - * - * @param lg array of local variables - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - * @see MethodGen - */ - public void redirectLocalVariables( LocalVariableGen[] lg, InstructionHandle old_target, - InstructionHandle new_target ) { - for (int i = 0; i < lg.length; i++) { - InstructionHandle start = lg[i].getStart(); - InstructionHandle end = lg[i].getEnd(); - if (start == old_target) { - lg[i].setStart(new_target); - } - if (end == old_target) { - lg[i].setEnd(new_target); - } - } - } - - - /** - * Redirect all references of exception handlers from old_target to new_target. - * - * @param exceptions array of exception handlers - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - * @see MethodGen - */ - public void redirectExceptionHandlers( CodeExceptionGen[] exceptions, - InstructionHandle old_target, InstructionHandle new_target ) { - for (int i = 0; i < exceptions.length; i++) { - if (exceptions[i].getStartPC() == old_target) { - exceptions[i].setStartPC(new_target); - } - if (exceptions[i].getEndPC() == old_target) { - exceptions[i].setEndPC(new_target); - } - if (exceptions[i].getHandlerPC() == old_target) { - exceptions[i].setHandlerPC(new_target); - } - } - } - - private List observers; - - - /** Add observer for this object. - */ - public void addObserver( InstructionListObserver o ) { - if (observers == null) { - observers = new ArrayList(); - } - observers.add(o); - } - - - /** Remove observer for this object. - */ - public void removeObserver( InstructionListObserver o ) { - if (observers != null) { - observers.remove(o); - } - } - - - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if (observers != null) { - for (Iterator e = observers.iterator(); e.hasNext();) { - ((InstructionListObserver) e.next()).notify(this); - } - } - } + /** + * + */ + private static final long serialVersionUID = 1L; + private InstructionHandle start = null, end = null; + private int length = 0; // number of elements in list + private int[] byte_positions; // byte code offsets corresponding to + // instructions + + /** + * Create (empty) instruction list. + */ + public InstructionList() { + } + + /** + * Create instruction list containing one instruction. + * + * @param i + * initial instruction + */ + public InstructionList(Instruction i) { + append(i); + } + + /** + * Create instruction list containing one instruction. + * + * @param i + * initial instruction + */ + public InstructionList(BranchInstruction i) { + append(i); + } + + /** + * Initialize list with (nonnull) compound instruction. Consumes argument + * list, i.e., it becomes empty. + * + * @param c + * compound instruction (list) + */ + public InstructionList(CompoundInstruction c) { + append(c.getInstructionList()); + } + + /** + * Test for empty list. + */ + public boolean isEmpty() { + return start == null; + } // && end == null + + /** + * Find the target instruction (handle) that corresponds to the given target + * position (byte code offset). + * + * @param ihs + * array of instruction handles, i.e. il.getInstructionHandles() + * @param pos + * array of positions corresponding to ihs, i.e. + * il.getInstructionPositions() + * @param count + * length of arrays + * @param target + * target position to search for + * @return target position's instruction handle if available + */ + public static InstructionHandle findHandle(InstructionHandle[] ihs, + int[] pos, int count, int target) { + int l = 0, r = count - 1; + /* + * Do a binary search since the pos array is orderd. + */ + do { + int i = (l + r) / 2; + int j = pos[i]; + if (j == target) { + return ihs[i]; + } else if (target < j) { + r = i - 1; + } else { + l = i + 1; + } + } while (l <= r); + return null; + } + + /** + * Get instruction handle for instruction at byte code position pos. This + * only works properly, if the list is freshly initialized from a byte array + * or setPositions() has been called before this method. + * + * @param pos + * byte code position to search for + * @return target position's instruction handle if available + */ + public InstructionHandle findHandle(int pos) { + InstructionHandle[] ihs = getInstructionHandles(); + return findHandle(ihs, byte_positions, length, pos); + } + + /** + * Initialize instruction list from byte array. + * + * @param code + * byte array containing the instructions + */ + public InstructionList(byte[] code) { + ByteSequence bytes = new ByteSequence(code); + InstructionHandle[] ihs = new InstructionHandle[code.length]; + int[] pos = new int[code.length]; // Can't be more than that + int count = 0; // Contains actual length + /* + * Pass 1: Create an object for each byte code and append them to the + * list. + */ + try { + while (bytes.available() > 0) { + // Remember byte offset and associate it with the instruction + int off = bytes.getIndex(); + pos[count] = off; + /* + * Read one instruction from the byte stream, the byte position + * is set accordingly. + */ + Instruction i = Instruction.readInstruction(bytes); + InstructionHandle ih; + if (i instanceof BranchInstruction) { + ih = append((BranchInstruction) i); + } else { + ih = append(i); + } + ih.setPosition(off); + ihs[count] = ih; + count++; + } + } catch (IOException e) { + throw new ClassGenException(e.toString()); + } + byte_positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, byte_positions, 0, count); + /* + * Pass 2: Look for BranchInstruction and update their targets, i.e., + * convert offsets to instruction handles. + */ + for (int i = 0; i < count; i++) { + if (ihs[i] instanceof BranchHandle) { + BranchInstruction bi = (BranchInstruction) ihs[i].instruction; + int target = bi.position + bi.getIndex(); /* + * Byte code position: + * relative -> absolute. + */ + // Search for target position + InstructionHandle ih = findHandle(ihs, pos, count, target); + if (ih == null) { + throw new ClassGenException( + "Couldn't find target for branch: " + bi); + } + bi.setTarget(ih); // Update target + // If it is a Select instruction, update all branch targets + if (bi instanceof Select) { // Either LOOKUPSWITCH or + // TABLESWITCH + Select s = (Select) bi; + int[] indices = s.getIndices(); + for (int j = 0; j < indices.length; j++) { + target = bi.position + indices[j]; + ih = findHandle(ihs, pos, count, target); + if (ih == null) { + throw new ClassGenException( + "Couldn't find target for switch: " + bi); + } + s.setTarget(j, ih); // Update target + } + } + } + } + } + + /** + * Append another list after instruction (handle) ih contained in this list. + * Consumes argument list, i.e., it becomes empty. + * + * @param ih + * where to append the instruction list + * @param il + * Instruction list to append to this one + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(InstructionHandle ih, InstructionList il) { + if (il == null) { + throw new ClassGenException("Appending null InstructionList"); + } + if (il.isEmpty()) { + return ih; + } + InstructionHandle next = ih.next, ret = il.start; + ih.next = il.start; + il.start.prev = ih; + il.end.next = next; + if (next != null) { + next.prev = il.end; + } else { + end = il.end; // Update end ... + } + length += il.length; // Update length + il.clear(); + return ret; + } + + /** + * Append another list after instruction i contained in this list. Consumes + * argument list, i.e., it becomes empty. + * + * @param i + * where to append the instruction list + * @param il + * Instruction list to append to this one + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(Instruction i, InstructionList il) { + InstructionHandle ih; + if ((ih = findInstruction2(i)) == null) { + throw new ClassGenException("Instruction " + i + + " is not contained in this list."); + } + return append(ih, il); + } + + /** + * Append another list to this one. Consumes argument list, i.e., it becomes + * empty. + * + * @param il + * list to append to end of this list + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(InstructionList il) { + if (il == null) { + throw new ClassGenException("Appending null InstructionList"); + } + if (il.isEmpty()) { + return null; + } + if (isEmpty()) { + start = il.start; + end = il.end; + length = il.length; + il.clear(); + return start; + } else { + return append(end, il); // was end.instruction + } + } + + /** + * Append an instruction to the end of this list. + * + * @param ih + * instruction to append + */ + private void append(InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.next = ih.prev = null; + } else { + end.next = ih; + ih.prev = end; + ih.next = null; + end = ih; + } + length++; // Update length + } + + /** + * Append an instruction to the end of this list. + * + * @param i + * instruction to append + * @return instruction handle of the appended instruction + */ + public InstructionHandle append(Instruction i) { + InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + append(ih); + return ih; + } + + /** + * Append a branch instruction to the end of this list. + * + * @param i + * branch instruction to append + * @return branch instruction handle of the appended instruction + */ + public BranchHandle append(BranchInstruction i) { + BranchHandle ih = BranchHandle.getBranchHandle(i); + append(ih); + return ih; + } + + /** + * Append a single instruction j after another instruction i, which must be + * in this list of course! + * + * @param i + * Instruction in list + * @param j + * Instruction to append after i in list + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(Instruction i, Instruction j) { + return append(i, new InstructionList(j)); + } + + /** + * Append a compound instruction, after instruction i. + * + * @param i + * Instruction in list + * @param c + * The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(Instruction i, CompoundInstruction c) { + return append(i, c.getInstructionList()); + } + + /** + * Append a compound instruction. + * + * @param c + * The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(CompoundInstruction c) { + return append(c.getInstructionList()); + } + + /** + * Append a compound instruction. + * + * @param ih + * where to append the instruction list + * @param c + * The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(InstructionHandle ih, CompoundInstruction c) { + return append(ih, c.getInstructionList()); + } + + /** + * Append an instruction after instruction (handle) ih contained in this + * list. + * + * @param ih + * where to append the instruction list + * @param i + * Instruction to append + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(InstructionHandle ih, Instruction i) { + return append(ih, new InstructionList(i)); + } + + /** + * Append an instruction after instruction (handle) ih contained in this + * list. + * + * @param ih + * where to append the instruction list + * @param i + * Instruction to append + * @return instruction handle pointing to the first appended + * instruction + */ + public BranchHandle append(InstructionHandle ih, BranchInstruction i) { + BranchHandle bh = BranchHandle.getBranchHandle(i); + InstructionList il = new InstructionList(); + il.append(bh); + append(ih, il); + return bh; + } + + /** + * Insert another list before Instruction handle ih contained in this list. + * Consumes argument list, i.e., it becomes empty. + * + * @param ih + * where to append the instruction list + * @param il + * Instruction list to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(InstructionHandle ih, InstructionList il) { + if (il == null) { + throw new ClassGenException("Inserting null InstructionList"); + } + if (il.isEmpty()) { + return ih; + } + InstructionHandle prev = ih.prev, ret = il.start; + ih.prev = il.end; + il.end.next = ih; + il.start.prev = prev; + if (prev != null) { + prev.next = il.start; + } else { + start = il.start; // Update start ... + } + length += il.length; // Update length + il.clear(); + return ret; + } + + /** + * Insert another list. + * + * @param il + * list to insert before start of this list + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(InstructionList il) { + if (isEmpty()) { + append(il); // Code is identical for this case + return start; + } else { + return insert(start, il); + } + } + + /** + * Insert an instruction at start of this list. + * + * @param ih + * instruction to insert + */ + private void insert(InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.next = ih.prev = null; + } else { + start.prev = ih; + ih.next = start; + ih.prev = null; + start = ih; + } + length++; + } + + /** + * Insert another list before Instruction i contained in this list. Consumes + * argument list, i.e., it becomes empty. + * + * @param i + * where to append the instruction list + * @param il + * Instruction list to insert + * @return instruction handle pointing to the first inserted instruction, + * i.e., il.getStart() + */ + public InstructionHandle insert(Instruction i, InstructionList il) { + InstructionHandle ih; + if ((ih = findInstruction1(i)) == null) { + throw new ClassGenException("Instruction " + i + + " is not contained in this list."); + } + return insert(ih, il); + } + + /** + * Insert an instruction at start of this list. + * + * @param i + * instruction to insert + * @return instruction handle of the inserted instruction + */ + public InstructionHandle insert(Instruction i) { + InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + insert(ih); + return ih; + } + + /** + * Insert a branch instruction at start of this list. + * + * @param i + * branch instruction to insert + * @return branch instruction handle of the appended instruction + */ + public BranchHandle insert(BranchInstruction i) { + BranchHandle ih = BranchHandle.getBranchHandle(i); + insert(ih); + return ih; + } + + /** + * Insert a single instruction j before another instruction i, which must be + * in this list of course! + * + * @param i + * Instruction in list + * @param j + * Instruction to insert before i in list + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(Instruction i, Instruction j) { + return insert(i, new InstructionList(j)); + } + + /** + * Insert a compound instruction before instruction i. + * + * @param i + * Instruction in list + * @param c + * The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(Instruction i, CompoundInstruction c) { + return insert(i, c.getInstructionList()); + } + + /** + * Insert a compound instruction. + * + * @param c + * The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(CompoundInstruction c) { + return insert(c.getInstructionList()); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this + * list. + * + * @param ih + * where to insert to the instruction list + * @param i + * Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(InstructionHandle ih, Instruction i) { + return insert(ih, new InstructionList(i)); + } + + /** + * Insert a compound instruction. + * + * @param ih + * where to insert the instruction list + * @param c + * The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(InstructionHandle ih, CompoundInstruction c) { + return insert(ih, c.getInstructionList()); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this + * list. + * + * @param ih + * where to insert to the instruction list + * @param i + * Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public BranchHandle insert(InstructionHandle ih, BranchInstruction i) { + BranchHandle bh = BranchHandle.getBranchHandle(i); + InstructionList il = new InstructionList(); + il.append(bh); + insert(ih, il); + return bh; + } + + /** + * Take all instructions (handles) from "start" to "end" and append them + * after the new location "target". Of course, "end" must be after "start" + * and target must not be located withing this range. If you want to move + * something to the start of the list use null as value for target.
          + * Any instruction targeters pointing to handles within the block, keep + * their targets. + * + * @param start + * of moved block + * @param end + * of moved block + * @param target + * of moved block + */ + public void move(InstructionHandle start, InstructionHandle end, + InstructionHandle target) { + // Step 1: Check constraints + if ((start == null) || (end == null)) { + throw new ClassGenException("Invalid null handle: From " + start + + " to " + end); + } + if ((target == start) || (target == end)) { + throw new ClassGenException("Invalid range: From " + start + " to " + + end + " contains target " + target); + } + for (InstructionHandle ih = start; ih != end.next; ih = ih.next) { + if (ih == null) { + throw new ClassGenException("Invalid range: From " + start + + " to " + end); + } else if (ih == target) { + throw new ClassGenException("Invalid range: From " + start + + " to " + end + " contains target " + target); + } + } + // Step 2: Temporarily remove the given instructions from the list + InstructionHandle prev = start.prev, next = end.next; + if (prev != null) { + prev.next = next; + } else { + this.start = next; + } + if (next != null) { + next.prev = prev; + } else { + this.end = prev; + } + start.prev = end.next = null; + // Step 3: append after target + if (target == null) { // append to start of list + if (this.start != null) { + this.start.prev = end; + } + end.next = this.start; + this.start = start; + } else { + next = target.next; + target.next = start; + start.prev = target; + end.next = next; + if (next != null) { + next.prev = end; + } else { + this.end = end; + } + } + } + + /** + * Move a single instruction (handle) to a new location. + * + * @param ih + * moved instruction + * @param target + * new location of moved instruction + */ + public void move(InstructionHandle ih, InstructionHandle target) { + move(ih, ih, target); + } + + /** + * Remove from instruction `prev' to instruction `next' both contained in + * this list. Throws TargetLostException when one of the removed instruction + * handles is still being targeted. + * + * @param prev + * where to start deleting (predecessor, exclusive) + * @param next + * where to end deleting (successor, exclusive) + */ + private void remove(InstructionHandle prev, InstructionHandle next) + throws TargetLostException { + InstructionHandle first, last; // First and last deleted instruction + if ((prev == null) && (next == null)) { // singleton list + first = last = start; + start = end = null; + } else { + if (prev == null) { // At start of list + first = start; + start = next; + } else { + first = prev.next; + prev.next = next; + } + if (next == null) { // At end of list + last = end; + end = prev; + } else { + last = next.prev; + next.prev = prev; + } + } + first.prev = null; // Completely separated from rest of list + last.next = null; + List target_vec = new ArrayList(); + for (InstructionHandle ih = first; ih != null; ih = ih.next) { + ih.getInstruction().dispose(); // e.g. BranchInstructions release + // their targets + } + StringBuffer buf = new StringBuffer("{ "); + for (InstructionHandle ih = first; ih != null; ih = next) { + next = ih.next; + length--; + if (ih.hasTargeters()) { // Still got targeters? + target_vec.add(ih); + buf.append(ih.toString(true) + " "); + ih.next = ih.prev = null; + } else { + ih.dispose(); + } + } + buf.append("}"); + if (!target_vec.isEmpty()) { + InstructionHandle[] targeted = new InstructionHandle[target_vec + .size()]; + target_vec.toArray(targeted); + throw new TargetLostException(targeted, buf.toString()); + } + } + + /** + * Remove instruction from this list. The corresponding Instruction handles + * must not be reused! + * + * @param ih + * instruction (handle) to remove + */ + public void delete(InstructionHandle ih) throws TargetLostException { + remove(ih.prev, ih.next); + } + + /** + * Remove instruction from this list. The corresponding Instruction handles + * must not be reused! + * + * @param i + * instruction to remove + */ + public void delete(Instruction i) throws TargetLostException { + InstructionHandle ih; + if ((ih = findInstruction1(i)) == null) { + throw new ClassGenException("Instruction " + i + + " is not contained in this list."); + } + delete(ih); + } + + /** + * Remove instructions from instruction `from' to instruction `to' contained + * in this list. The user must ensure that `from' is an instruction before + * `to', or risk havoc. The corresponding Instruction handles must not be + * reused! + * + * @param from + * where to start deleting (inclusive) + * @param to + * where to end deleting (inclusive) + */ + public void delete(InstructionHandle from, InstructionHandle to) + throws TargetLostException { + remove(from.prev, to.next); + } + + /** + * Remove instructions from instruction `from' to instruction `to' contained + * in this list. The user must ensure that `from' is an instruction before + * `to', or risk havoc. The corresponding Instruction handles must not be + * reused! + * + * @param from + * where to start deleting (inclusive) + * @param to + * where to end deleting (inclusive) + */ + public void delete(Instruction from, Instruction to) + throws TargetLostException { + InstructionHandle from_ih, to_ih; + if ((from_ih = findInstruction1(from)) == null) { + throw new ClassGenException("Instruction " + from + + " is not contained in this list."); + } + if ((to_ih = findInstruction2(to)) == null) { + throw new ClassGenException("Instruction " + to + + " is not contained in this list."); + } + delete(from_ih, to_ih); + } + + /** + * Search for given Instruction reference, start at beginning of list. + * + * @param i + * instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction1(Instruction i) { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + if (ih.instruction == i) { + return ih; + } + } + return null; + } + + /** + * Search for given Instruction reference, start at end of list + * + * @param i + * instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction2(Instruction i) { + for (InstructionHandle ih = end; ih != null; ih = ih.prev) { + if (ih.instruction == i) { + return ih; + } + } + return null; + } + + public boolean contains(InstructionHandle i) { + if (i == null) { + return false; + } + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + if (ih == i) { + return true; + } + } + return false; + } + + public boolean contains(Instruction i) { + return findInstruction1(i) != null; + } + + public void setPositions() { + setPositions(false); + } + + /** + * Give all instructions their position number (offset in byte stream), + * i.e., make the list ready to be dumped. + * + * @param check + * Perform sanity checks, e.g. if all targeted instructions + * really belong to this list + */ + public void setPositions(boolean check) { + int max_additional_bytes = 0, additional_bytes = 0; + int index = 0, count = 0; + int[] pos = new int[length]; + /* + * Pass 0: Sanity checks + */ + if (check) { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + if (i instanceof BranchInstruction) { // target instruction + // within list? + Instruction inst = ((BranchInstruction) i).getTarget().instruction; + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + + Constants.OPCODE_NAMES[i.opcode] + ":" + inst + + " not in instruction list"); + } + if (i instanceof Select) { + InstructionHandle[] targets = ((Select) i).getTargets(); + for (int j = 0; j < targets.length; j++) { + inst = targets[j].instruction; + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + + Constants.OPCODE_NAMES[i.opcode] + + ":" + inst + + " not in instruction list"); + } + } + } + if (!(ih instanceof BranchHandle)) { + throw new ClassGenException("Branch instruction " + + Constants.OPCODE_NAMES[i.opcode] + ":" + inst + + " not contained in BranchHandle."); + } + } + } + } + /* + * Pass 1: Set position numbers and sum up the maximum number of bytes + * an instruction may be shifted. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + ih.setPosition(index); + pos[count++] = index; + /* + * Get an estimate about how many additional bytes may be added, + * because BranchInstructions may have variable length depending on + * the target offset (short vs. int) or alignment issues + * (TABLESWITCH and LOOKUPSWITCH). + */ + switch (i.getOpcode()) { + case Constants.JSR: + case Constants.GOTO: + max_additional_bytes += 2; + break; + case Constants.TABLESWITCH: + case Constants.LOOKUPSWITCH: + max_additional_bytes += 3; + break; + } + index += i.getLength(); + } + /* + * Pass 2: Expand the variable-length (Branch)Instructions depending on + * the target offset (short or int) and ensure that branch targets are + * within this list. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + additional_bytes += ih.updatePosition(additional_bytes, + max_additional_bytes); + } + /* + * Pass 3: Update position numbers (which may have changed due to the + * preceding expansions), like pass 1. + */ + index = count = 0; + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + ih.setPosition(index); + pos[count++] = index; + index += i.getLength(); + } + byte_positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, byte_positions, 0, count); + } + + /** + * When everything is finished, use this method to convert the instruction + * list into an array of bytes. + * + * @return the byte code ready to be dumped + */ + public byte[] getByteCode() { + // Update position indices of instructions + setPositions(); + ByteArrayOutputStream b = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(b); + try { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + i.dump(out); // Traverse list + } + } catch (IOException e) { + System.err.println(e); + return null; + } + return b.toByteArray(); + } + + /** + * @return an array of instructions without target information for branch + * instructions. + */ + public Instruction[] getInstructions() { + ByteSequence bytes = new ByteSequence(getByteCode()); + List instructions = new ArrayList(); + try { + while (bytes.available() > 0) { + instructions.add(Instruction.readInstruction(bytes)); + } + } catch (IOException e) { + throw new ClassGenException(e.toString()); + } + return instructions.toArray(new Instruction[instructions.size()]); + } + + @Override + public String toString() { + return toString(true); + } + + /** + * @param verbose + * toggle output format + * @return String containing all instructions in this list. + */ + public String toString(boolean verbose) { + StringBuffer buf = new StringBuffer(); + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + buf.append(ih.toString(verbose)).append("\n"); + } + return buf.toString(); + } + + /** + * @return Enumeration that lists all instructions (handles) + */ + public Iterator iterator() { + return new Iterator() { + + private InstructionHandle ih = start; + + @Override + public Object next() { + InstructionHandle i = ih; + ih = ih.next; + return i; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + return ih != null; + } + }; + } + + /** + * @return array containing all instructions (handles) + */ + public InstructionHandle[] getInstructionHandles() { + InstructionHandle[] ihs = new InstructionHandle[length]; + InstructionHandle ih = start; + for (int i = 0; i < length; i++) { + ihs[i] = ih; + ih = ih.next; + } + return ihs; + } + + /** + * Get positions (offsets) of all instructions in the list. This relies on + * that the list has been freshly created from an byte code array, or that + * setPositions() has been called. Otherwise this may be inaccurate. + * + * @return array containing all instruction's offset in byte code + */ + public int[] getInstructionPositions() { + return byte_positions; + } + + /** + * @return complete, i.e., deep copy of this list + */ + public InstructionList copy() { + Map map = new HashMap(); + InstructionList il = new InstructionList(); + /* + * Pass 1: Make copies of all instructions, append them to the new list + * and associate old instruction references with the new ones, i.e., a + * 1:1 mapping. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + Instruction c = i.copy(); // Use clone for shallow copy + if (c instanceof BranchInstruction) { + map.put(ih, il.append((BranchInstruction) c)); + } else { + map.put(ih, il.append(c)); + } + } + /* + * Pass 2: Update branch targets. + */ + InstructionHandle ih = start; + InstructionHandle ch = il.start; + while (ih != null) { + Instruction i = ih.instruction; + Instruction c = ch.instruction; + if (i instanceof BranchInstruction) { + BranchInstruction bi = (BranchInstruction) i; + BranchInstruction bc = (BranchInstruction) c; + InstructionHandle itarget = bi.getTarget(); // old target + // New target is in hash map + bc.setTarget(map.get(itarget)); + if (bi instanceof Select) { // Either LOOKUPSWITCH or + // TABLESWITCH + InstructionHandle[] itargets = ((Select) bi).getTargets(); + InstructionHandle[] ctargets = ((Select) bc).getTargets(); + for (int j = 0; j < itargets.length; j++) { // Update all + // targets + ctargets[j] = map.get(itargets[j]); + } + } + } + ih = ih.next; + ch = ch.next; + } + return il; + } + + /** + * Replace all references to the old constant pool with references to the + * new constant pool + */ + public void replaceConstantPool(ConstantPoolGen old_cp, + ConstantPoolGen new_cp) { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.instruction; + if (i instanceof CPInstruction) { + CPInstruction ci = (CPInstruction) i; + Constant c = old_cp.getConstant(ci.getIndex()); + ci.setIndex(new_cp.addConstant(c, old_cp)); + } + } + } + + private void clear() { + start = end = null; + length = 0; + } + + /** + * Delete contents of list. Provides besser memory utilization, because the + * system then may reuse the instruction handles. This method is typically + * called right after + * MethodGen.getMethod(). + */ + public void dispose() { + // Traverse in reverse order, because ih.next is overwritten + for (InstructionHandle ih = end; ih != null; ih = ih.prev) { + /* + * Causes BranchInstructions to release target and targeters, + * because it calls dispose() on the contained instruction. + */ + ih.dispose(); + } + clear(); + } + + /** + * @return start of list + */ + public InstructionHandle getStart() { + return start; + } + + /** + * @return end of list + */ + public InstructionHandle getEnd() { + return end; + } + + /** + * @return length of list (Number of instructions, not bytes) + */ + public int getLength() { + return length; + } + + /** + * @return length of list (Number of instructions, not bytes) + */ + public int size() { + return length; + } + + /** + * Redirect all references from old_target to new_target, i.e., update + * targets of branch instructions. + * + * @param old_target + * the old target instruction handle + * @param new_target + * the new target instruction handle + */ + public void redirectBranches(InstructionHandle old_target, + InstructionHandle new_target) { + for (InstructionHandle ih = start; ih != null; ih = ih.next) { + Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { + BranchInstruction b = (BranchInstruction) i; + InstructionHandle target = b.getTarget(); + if (target == old_target) { + b.setTarget(new_target); + } + if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + InstructionHandle[] targets = ((Select) b).getTargets(); + for (int j = 0; j < targets.length; j++) { + if (targets[j] == old_target) { + ((Select) b).setTarget(j, new_target); + } + } + } + } + } + } + + /** + * Redirect all references of local variables from old_target to new_target. + * + * @param lg + * array of local variables + * @param old_target + * the old target instruction handle + * @param new_target + * the new target instruction handle + * @see MethodGen + */ + public void redirectLocalVariables(LocalVariableGen[] lg, + InstructionHandle old_target, InstructionHandle new_target) { + for (int i = 0; i < lg.length; i++) { + InstructionHandle start = lg[i].getStart(); + InstructionHandle end = lg[i].getEnd(); + if (start == old_target) { + lg[i].setStart(new_target); + } + if (end == old_target) { + lg[i].setEnd(new_target); + } + } + } + + /** + * Redirect all references of exception handlers from old_target to + * new_target. + * + * @param exceptions + * array of exception handlers + * @param old_target + * the old target instruction handle + * @param new_target + * the new target instruction handle + * @see MethodGen + */ + public void redirectExceptionHandlers(CodeExceptionGen[] exceptions, + InstructionHandle old_target, InstructionHandle new_target) { + for (int i = 0; i < exceptions.length; i++) { + if (exceptions[i].getStartPC() == old_target) { + exceptions[i].setStartPC(new_target); + } + if (exceptions[i].getEndPC() == old_target) { + exceptions[i].setEndPC(new_target); + } + if (exceptions[i].getHandlerPC() == old_target) { + exceptions[i].setHandlerPC(new_target); + } + } + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(InstructionListObserver o) { + if (observers == null) { + observers = new ArrayList(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(InstructionListObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (Iterator e = observers.iterator(); e + .hasNext();) { + e.next().notify(this); + } + } + } } diff --git a/src/org/apache/bcel/generic/InstructionListObserver.java b/src/org/apache/bcel/generic/InstructionListObserver.java index 243b4fc..b89f6da 100644 --- a/src/org/apache/bcel/generic/InstructionListObserver.java +++ b/src/org/apache/bcel/generic/InstructionListObserver.java @@ -17,13 +17,14 @@ package org.apache.bcel.generic; /** - * Implement this interface if you're interested in changes to an InstructionList object - * and register yourself with addObserver(). - * - * @version $Id: InstructionListObserver.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * Implement this interface if you're interested in changes to an + * InstructionList object and register yourself with addObserver(). + * + * @version $Id: InstructionListObserver.java 386056 2006-03-15 11:31:56Z tcurdt + * $ + * @author M. Dahm */ public interface InstructionListObserver { - public void notify( InstructionList list ); + public void notify(InstructionList list); } diff --git a/src/org/apache/bcel/generic/InstructionTargeter.java b/src/org/apache/bcel/generic/InstructionTargeter.java index e096b3f..2e78bff 100644 --- a/src/org/apache/bcel/generic/InstructionTargeter.java +++ b/src/org/apache/bcel/generic/InstructionTargeter.java @@ -17,19 +17,18 @@ package org.apache.bcel.generic; /** - * Denote that a class targets InstructionHandles within an InstructionList. Namely - * the following implementers: - * + * Denote that a class targets InstructionHandles within an InstructionList. + * Namely the following implementers: + * * @see BranchHandle * @see LocalVariableGen * @see CodeExceptionGen * @version $Id: InstructionTargeter.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface InstructionTargeter { - public boolean containsTarget( InstructionHandle ih ); + public boolean containsTarget(InstructionHandle ih); - - public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ); + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih); } diff --git a/src/org/apache/bcel/generic/InvokeInstruction.java b/src/org/apache/bcel/generic/InvokeInstruction.java index 2b12e5e..e6f7f5a 100644 --- a/src/org/apache/bcel/generic/InvokeInstruction.java +++ b/src/org/apache/bcel/generic/InvokeInstruction.java @@ -23,96 +23,104 @@ import org.apache.bcel.classfile.ConstantPool; /** * Super class for the INVOKExxx family of instructions. - * + * * @version $Id: InvokeInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower, - TypedInstruction, StackConsumer, StackProducer { +public abstract class InvokeInstruction extends FieldOrMethod implements + ExceptionThrower, TypedInstruction, StackConsumer, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - InvokeInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + InvokeInstruction() { + } - /** - * @param index to constant pool - */ - protected InvokeInstruction(short opcode, int index) { - super(opcode, index); - } + /** + * @param index + * to constant pool + */ + protected InvokeInstruction(short opcode, int index) { + super(opcode, index); + } + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(ConstantPool cp) { + Constant c = cp.getConstant(index); + StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); + return Constants.OPCODE_NAMES[opcode] + " " + + tok.nextToken().replace('.', '/') + tok.nextToken(); + } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString( ConstantPool cp ) { - Constant c = cp.getConstant(index); - StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); - return Constants.OPCODE_NAMES[opcode] + " " + tok.nextToken().replace('.', '/') - + tok.nextToken(); - } + /** + * Also works for instructions whose stack effect depends on the constant + * pool entry they reference. + * + * @return Number of words consumed from stack by this instruction + */ + @Override + public int consumeStack(ConstantPoolGen cpg) { + String signature = getSignature(cpg); + Type[] args = Type.getArgumentTypes(signature); + int sum; + if (opcode == Constants.INVOKESTATIC) { + sum = 0; + } else { + sum = 1; // this reference + } + int n = args.length; + for (int i = 0; i < n; i++) { + sum += args[i].getSize(); + } + return sum; + } + /** + * Also works for instructions whose stack effect depends on the constant + * pool entry they reference. + * + * @return Number of words produced onto stack by this instruction + */ + @Override + public int produceStack(ConstantPoolGen cpg) { + return getReturnType(cpg).getSize(); + } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words consumed from stack by this instruction - */ - public int consumeStack( ConstantPoolGen cpg ) { - String signature = getSignature(cpg); - Type[] args = Type.getArgumentTypes(signature); - int sum; - if (opcode == Constants.INVOKESTATIC) { - sum = 0; - } else { - sum = 1; // this reference - } - int n = args.length; - for (int i = 0; i < n; i++) { - sum += args[i].getSize(); - } - return sum; - } + /** + * @return return type of referenced method. + */ + @Override + public Type getType(ConstantPoolGen cpg) { + return getReturnType(cpg); + } + /** + * @return name of referenced method. + */ + public String getMethodName(ConstantPoolGen cpg) { + return getName(cpg); + } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words produced onto stack by this instruction - */ - public int produceStack( ConstantPoolGen cpg ) { - return getReturnType(cpg).getSize(); - } + /** + * @return return type of referenced method. + */ + public Type getReturnType(ConstantPoolGen cpg) { + return Type.getReturnType(getSignature(cpg)); + } - - /** @return return type of referenced method. - */ - public Type getType( ConstantPoolGen cpg ) { - return getReturnType(cpg); - } - - - /** @return name of referenced method. - */ - public String getMethodName( ConstantPoolGen cpg ) { - return getName(cpg); - } - - - /** @return return type of referenced method. - */ - public Type getReturnType( ConstantPoolGen cpg ) { - return Type.getReturnType(getSignature(cpg)); - } - - - /** @return argument types of referenced method. - */ - public Type[] getArgumentTypes( ConstantPoolGen cpg ) { - return Type.getArgumentTypes(getSignature(cpg)); - } + /** + * @return argument types of referenced method. + */ + public Type[] getArgumentTypes(ConstantPoolGen cpg) { + return Type.getArgumentTypes(getSignature(cpg)); + } } diff --git a/src/org/apache/bcel/generic/JSR.java b/src/org/apache/bcel/generic/JSR.java index 8e20e58..8ef3a0d 100644 --- a/src/org/apache/bcel/generic/JSR.java +++ b/src/org/apache/bcel/generic/JSR.java @@ -19,68 +19,76 @@ package org.apache.bcel.generic; import java.io.DataOutputStream; import java.io.IOException; -/** +/** * JSR - Jump to subroutine - * + * * @version $Id: JSR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class JSR extends JsrInstruction implements VariableLengthInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JSR() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JSR() { + } - public JSR(InstructionHandle target) { - super(org.apache.bcel.Constants.JSR, target); - } + public JSR(InstructionHandle target) { + super(org.apache.bcel.Constants.JSR, target); + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + index = getTargetOffset(); + if (opcode == org.apache.bcel.Constants.JSR) { + super.dump(out); + } else { // JSR_W + index = getTargetOffset(); + out.writeByte(opcode); + out.writeInt(index); + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - index = getTargetOffset(); - if (opcode == org.apache.bcel.Constants.JSR) { - super.dump(out); - } else { // JSR_W - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - } + @Override + protected int updatePosition(int offset, int max_offset) { + int i = getTargetOffset(); // Depending on old position value + position += offset; // Position may be shifted by preceding expansions + if (Math.abs(i) >= (32767 - max_offset)) { // to large for short + // (estimate) + opcode = org.apache.bcel.Constants.JSR_W; + length = 5; + return 2; // 5 - 3 + } + return 0; + } - - protected int updatePosition( int offset, int max_offset ) { - int i = getTargetOffset(); // Depending on old position value - position += offset; // Position may be shifted by preceding expansions - if (Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate) - opcode = org.apache.bcel.Constants.JSR_W; - length = 5; - return 2; // 5 - 3 - } - return 0; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitVariableLengthInstruction(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitVariableLengthInstruction(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR(this); + } } diff --git a/src/org/apache/bcel/generic/JSR_W.java b/src/org/apache/bcel/generic/JSR_W.java index fbed4b6..b6d7c2b 100644 --- a/src/org/apache/bcel/generic/JSR_W.java +++ b/src/org/apache/bcel/generic/JSR_W.java @@ -20,60 +20,68 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * JSR_W - Jump to subroutine - * + * * @version $Id: JSR_W.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class JSR_W extends JsrInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JSR_W() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JSR_W() { + } - public JSR_W(InstructionHandle target) { - super(org.apache.bcel.Constants.JSR_W, target); - length = 5; - } + public JSR_W(InstructionHandle target) { + super(org.apache.bcel.Constants.JSR_W, target); + length = 5; + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + index = getTargetOffset(); + out.writeByte(opcode); + out.writeInt(index); + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + index = bytes.readInt(); + length = 5; + } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - index = bytes.readInt(); - length = 5; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR_W(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR_W(this); + } } diff --git a/src/org/apache/bcel/generic/JsrInstruction.java b/src/org/apache/bcel/generic/JsrInstruction.java index 80a5c9a..c8aa663 100644 --- a/src/org/apache/bcel/generic/JsrInstruction.java +++ b/src/org/apache/bcel/generic/JsrInstruction.java @@ -16,64 +16,68 @@ */ package org.apache.bcel.generic; -/** +/** * Super class for JSR - Jump to subroutine - * + * * @version $Id: JsrInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch, - TypedInstruction, StackProducer { +public abstract class JsrInstruction extends BranchInstruction implements + UnconditionalBranch, TypedInstruction, StackProducer { - JsrInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } + /** + * + */ + private static final long serialVersionUID = 1L; + JsrInstruction(short opcode, InstructionHandle target) { + super(opcode, target); + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JsrInstruction() { - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JsrInstruction() { + } + /** + * @return return address type + */ + @Override + public Type getType(ConstantPoolGen cp) { + return new ReturnaddressType(physicalSuccessor()); + } - /** @return return address type - */ - public Type getType( ConstantPoolGen cp ) { - return new ReturnaddressType(physicalSuccessor()); - } - - - /** - * Returns an InstructionHandle to the physical successor - * of this JsrInstruction. For this method to work, - * this JsrInstruction object must not be shared between - * multiple InstructionHandle objects! - * Formally, there must not be InstructionHandle objects - * i, j where i != j and i.getInstruction() == this == - * j.getInstruction(). - * @return an InstructionHandle to the "next" instruction that - * will be executed when RETurned from a subroutine. - */ - public InstructionHandle physicalSuccessor() { - InstructionHandle ih = this.target; - // Rewind! - while (ih.getPrev() != null) { - ih = ih.getPrev(); - } - // Find the handle for "this" JsrInstruction object. - while (ih.getInstruction() != this) { - ih = ih.getNext(); - } - InstructionHandle toThis = ih; - while (ih != null) { - ih = ih.getNext(); - if ((ih != null) && (ih.getInstruction() == this)) { - throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); - } - } - // Return the physical successor - return toThis.getNext(); - } + /** + * Returns an InstructionHandle to the physical successor of this + * JsrInstruction. For this method to work, this JsrInstruction object + * must not be shared between multiple InstructionHandle objects! + * Formally, there must not be InstructionHandle objects i, j where i != j + * and i.getInstruction() == this == j.getInstruction(). + * + * @return an InstructionHandle to the "next" instruction that will be + * executed when RETurned from a subroutine. + */ + public InstructionHandle physicalSuccessor() { + InstructionHandle ih = this.target; + // Rewind! + while (ih.getPrev() != null) { + ih = ih.getPrev(); + } + // Find the handle for "this" JsrInstruction object. + while (ih.getInstruction() != this) { + ih = ih.getNext(); + } + InstructionHandle toThis = ih; + while (ih != null) { + ih = ih.getNext(); + if ((ih != null) && (ih.getInstruction() == this)) { + throw new RuntimeException( + "physicalSuccessor() called on a shared JsrInstruction."); + } + } + // Return the physical successor + return toThis.getNext(); + } } diff --git a/src/org/apache/bcel/generic/L2D.java b/src/org/apache/bcel/generic/L2D.java index 345aac8..046f452 100644 --- a/src/org/apache/bcel/generic/L2D.java +++ b/src/org/apache/bcel/generic/L2D.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * L2D - Convert long to double - *
          Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: L2D.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class L2D extends ConversionInstruction { - public L2D() { - super(org.apache.bcel.Constants.L2D); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public L2D() { + super(org.apache.bcel.Constants.L2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2D(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2D(this); + } } diff --git a/src/org/apache/bcel/generic/L2F.java b/src/org/apache/bcel/generic/L2F.java index 17e63ff..04bae18 100644 --- a/src/org/apache/bcel/generic/L2F.java +++ b/src/org/apache/bcel/generic/L2F.java @@ -18,31 +18,40 @@ package org.apache.bcel.generic; /** * L2F - Convert long to float - *
          Stack: ..., value.word1, value.word2 -> ..., result
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result
          + * 
          + * * @version $Id: L2F.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class L2F extends ConversionInstruction { - public L2F() { - super(org.apache.bcel.Constants.L2F); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public L2F() { + super(org.apache.bcel.Constants.L2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2F(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2F(this); + } } diff --git a/src/org/apache/bcel/generic/L2I.java b/src/org/apache/bcel/generic/L2I.java index be495b4..24e328b 100644 --- a/src/org/apache/bcel/generic/L2I.java +++ b/src/org/apache/bcel/generic/L2I.java @@ -18,31 +18,40 @@ package org.apache.bcel.generic; /** * L2I - Convert long to int - *
          Stack: ..., value.word1, value.word2 -> ..., result
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result
          + * 
          + * * @version $Id: L2I.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class L2I extends ConversionInstruction { - public L2I() { - super(org.apache.bcel.Constants.L2I); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public L2I() { + super(org.apache.bcel.Constants.L2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2I(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2I(this); + } } diff --git a/src/org/apache/bcel/generic/LADD.java b/src/org/apache/bcel/generic/LADD.java index d2e38e0..3f60586 100644 --- a/src/org/apache/bcel/generic/LADD.java +++ b/src/org/apache/bcel/generic/LADD.java @@ -16,34 +16,44 @@ */ package org.apache.bcel.generic; -/** +/** * LADD - Add longs - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: LADD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LADD extends ArithmeticInstruction { - public LADD() { - super(org.apache.bcel.Constants.LADD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LADD() { + super(org.apache.bcel.Constants.LADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLADD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLADD(this); + } } diff --git a/src/org/apache/bcel/generic/LALOAD.java b/src/org/apache/bcel/generic/LALOAD.java index d0704ed..b627d12 100644 --- a/src/org/apache/bcel/generic/LALOAD.java +++ b/src/org/apache/bcel/generic/LALOAD.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** +/** * LALOAD - Load long from array - *
          Stack: ..., arrayref, index -> ..., value1, value2
          - * + * + *
          + * Stack: ..., arrayref, index -> ..., value1, value2
          + * 
          + * * @version $Id: LALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LALOAD extends ArrayInstruction implements StackProducer { - /** Load long from array - */ - public LALOAD() { - super(org.apache.bcel.Constants.LALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Load long from array + */ + public LALOAD() { + super(org.apache.bcel.Constants.LALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitLALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitLALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/LAND.java b/src/org/apache/bcel/generic/LAND.java index 1659e4d..09ae32c 100644 --- a/src/org/apache/bcel/generic/LAND.java +++ b/src/org/apache/bcel/generic/LAND.java @@ -16,34 +16,44 @@ */ package org.apache.bcel.generic; -/** +/** * LAND - Bitwise AND longs - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: LAND.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LAND extends ArithmeticInstruction { - public LAND() { - super(org.apache.bcel.Constants.LAND); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LAND() { + super(org.apache.bcel.Constants.LAND); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLAND(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLAND(this); + } } diff --git a/src/org/apache/bcel/generic/LASTORE.java b/src/org/apache/bcel/generic/LASTORE.java index e620e9f..b3e953b 100644 --- a/src/org/apache/bcel/generic/LASTORE.java +++ b/src/org/apache/bcel/generic/LASTORE.java @@ -16,35 +16,45 @@ */ package org.apache.bcel.generic; -/** - * LASTORE - Store into long array - *
          Stack: ..., arrayref, index, value.word1, value.word2 -> ...
          - * +/** + * LASTORE - Store into long array + * + *
          + * Stack: ..., arrayref, index, value.word1, value.word2 -> ...
          + * 
          + * * @version $Id: LASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LASTORE extends ArrayInstruction implements StackConsumer { - /** Store long into array - */ - public LASTORE() { - super(org.apache.bcel.Constants.LASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Store long into array + */ + public LASTORE() { + super(org.apache.bcel.Constants.LASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitLASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitLASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/LCMP.java b/src/org/apache/bcel/generic/LCMP.java index 2371924..70ce072 100644 --- a/src/org/apache/bcel/generic/LCMP.java +++ b/src/org/apache/bcel/generic/LCMP.java @@ -18,38 +18,50 @@ package org.apache.bcel.generic; /** * LCMP - Compare longs: - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result <= -1, 0, 1> - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result <= -1, 0, 1> + * * @version $Id: LCMP.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class LCMP extends Instruction implements TypedInstruction, StackProducer, StackConsumer { +public class LCMP extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - public LCMP() { - super(org.apache.bcel.Constants.LCMP, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LCMP() { + super(org.apache.bcel.Constants.LCMP, (short) 1); + } - /** @return Type.LONG - */ - public Type getType( ConstantPoolGen cp ) { - return Type.LONG; - } + /** + * @return Type.LONG + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.LONG; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitLCMP(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitLCMP(this); + } } diff --git a/src/org/apache/bcel/generic/LCONST.java b/src/org/apache/bcel/generic/LCONST.java index 92fd60f..c8ce03c 100644 --- a/src/org/apache/bcel/generic/LCONST.java +++ b/src/org/apache/bcel/generic/LCONST.java @@ -16,65 +16,73 @@ */ package org.apache.bcel.generic; -/** +/** * LCONST - Push 0 or 1, other values cause an exception - * - *
          Stack: ... -> ..., 
          - * + * + *
          + * Stack: ... -> ...,
          + * 
          + * * @version $Id: LCONST.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class LCONST extends Instruction implements ConstantPushInstruction, TypedInstruction { +public class LCONST extends Instruction implements ConstantPushInstruction, + TypedInstruction { - private long value; + /** + * + */ + private static final long serialVersionUID = 1L; + private long value; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LCONST() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LCONST() { - } + public LCONST(long l) { + super(org.apache.bcel.Constants.LCONST_0, (short) 1); + if (l == 0) { + opcode = org.apache.bcel.Constants.LCONST_0; + } else if (l == 1) { + opcode = org.apache.bcel.Constants.LCONST_1; + } else { + throw new ClassGenException("LCONST can be used only for 0 and 1: " + + l); + } + value = l; + } + @Override + public Number getValue() { + return new Long(value); + } - public LCONST(long l) { - super(org.apache.bcel.Constants.LCONST_0, (short) 1); - if (l == 0) { - opcode = org.apache.bcel.Constants.LCONST_0; - } else if (l == 1) { - opcode = org.apache.bcel.Constants.LCONST_1; - } else { - throw new ClassGenException("LCONST can be used only for 0 and 1: " + l); - } - value = l; - } + /** + * @return Type.LONG + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.LONG; + } - - public Number getValue() { - return new Long(value); - } - - - /** @return Type.LONG - */ - public Type getType( ConstantPoolGen cp ) { - return Type.LONG; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitLCONST(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitLCONST(this); + } } diff --git a/src/org/apache/bcel/generic/LDC.java b/src/org/apache/bcel/generic/LDC.java index 3f93694..e0e318d 100644 --- a/src/org/apache/bcel/generic/LDC.java +++ b/src/org/apache/bcel/generic/LDC.java @@ -20,129 +20,143 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * LDC - Push item from constant pool. - * - *
          Stack: ... -> ..., item
          - * + * + *
          + * Stack: ... -> ..., item
          + * 
          + * * @version $Id: LDC.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower, - TypedInstruction { +public class LDC extends CPInstruction implements PushInstruction, + ExceptionThrower, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC() { + } - public LDC(int index) { - super(org.apache.bcel.Constants.LDC_W, index); - setSize(); - } + public LDC(int index) { + super(org.apache.bcel.Constants.LDC_W, index); + setSize(); + } + // Adjust to proper size + protected final void setSize() { + if (index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte? + opcode = org.apache.bcel.Constants.LDC; + length = 2; + } else { + opcode = org.apache.bcel.Constants.LDC_W; + length = 3; + } + } - // Adjust to proper size - protected final void setSize() { - if (index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte? - opcode = org.apache.bcel.Constants.LDC; - length = 2; - } else { - opcode = org.apache.bcel.Constants.LDC_W; - length = 3; - } - } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + if (length == 2) { + out.writeByte(index); + } else { + out.writeShort(index); + } + } + /** + * Set the index to constant pool and adjust size. + */ + @Override + public final void setIndex(int index) { + super.setIndex(index); + setSize(); + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); - if (length == 2) { - out.writeByte(index); - } else { - out.writeShort(index); - } - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + length = 2; + index = bytes.readUnsignedByte(); + } + public Object getValue(ConstantPoolGen cpg) { + org.apache.bcel.classfile.Constant c = cpg.getConstantPool() + .getConstant(index); + switch (c.getTag()) { + case org.apache.bcel.Constants.CONSTANT_String: + int i = ((org.apache.bcel.classfile.ConstantString) c) + .getStringIndex(); + c = cpg.getConstantPool().getConstant(i); + return ((org.apache.bcel.classfile.ConstantUtf8) c).getBytes(); + case org.apache.bcel.Constants.CONSTANT_Float: + return new Float( + ((org.apache.bcel.classfile.ConstantFloat) c).getBytes()); + case org.apache.bcel.Constants.CONSTANT_Integer: + return new Integer( + ((org.apache.bcel.classfile.ConstantInteger) c).getBytes()); + case org.apache.bcel.Constants.CONSTANT_Class: + return c; + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + + index); + } + } - /** - * Set the index to constant pool and adjust size. - */ - public final void setIndex( int index ) { - super.setIndex(index); - setSize(); - } + @Override + public Type getType(ConstantPoolGen cpg) { + switch (cpg.getConstantPool().getConstant(index).getTag()) { + case org.apache.bcel.Constants.CONSTANT_String: + return Type.STRING; + case org.apache.bcel.Constants.CONSTANT_Float: + return Type.FLOAT; + case org.apache.bcel.Constants.CONSTANT_Integer: + return Type.INT; + case org.apache.bcel.Constants.CONSTANT_Class: + return Type.CLASS; + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + + index); + } + } + @Override + public Class[] getExceptions() { + return org.apache.bcel.ExceptionConstants.EXCS_STRING_RESOLUTION; + } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - length = 2; - index = bytes.readUnsignedByte(); - } - - - public Object getValue( ConstantPoolGen cpg ) { - org.apache.bcel.classfile.Constant c = cpg.getConstantPool().getConstant(index); - switch (c.getTag()) { - case org.apache.bcel.Constants.CONSTANT_String: - int i = ((org.apache.bcel.classfile.ConstantString) c).getStringIndex(); - c = cpg.getConstantPool().getConstant(i); - return ((org.apache.bcel.classfile.ConstantUtf8) c).getBytes(); - case org.apache.bcel.Constants.CONSTANT_Float: - return new Float(((org.apache.bcel.classfile.ConstantFloat) c).getBytes()); - case org.apache.bcel.Constants.CONSTANT_Integer: - return new Integer(((org.apache.bcel.classfile.ConstantInteger) c).getBytes()); - case org.apache.bcel.Constants.CONSTANT_Class: - return c; - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } - - - public Type getType( ConstantPoolGen cpg ) { - switch (cpg.getConstantPool().getConstant(index).getTag()) { - case org.apache.bcel.Constants.CONSTANT_String: - return Type.STRING; - case org.apache.bcel.Constants.CONSTANT_Float: - return Type.FLOAT; - case org.apache.bcel.Constants.CONSTANT_Integer: - return Type.INT; - case org.apache.bcel.Constants.CONSTANT_Class: - return Type.CLASS; - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } - - - public Class[] getExceptions() { - return org.apache.bcel.ExceptionConstants.EXCS_STRING_RESOLUTION; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitLDC(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitLDC(this); + } } diff --git a/src/org/apache/bcel/generic/LDC2_W.java b/src/org/apache/bcel/generic/LDC2_W.java index dacfc19..4d193fe 100644 --- a/src/org/apache/bcel/generic/LDC2_W.java +++ b/src/org/apache/bcel/generic/LDC2_W.java @@ -16,67 +16,78 @@ */ package org.apache.bcel.generic; -/** +/** * LDC2_W - Push long or double from constant pool - * - *
          Stack: ... -> ..., item.word1, item.word2
          - * + * + *
          + * Stack: ... -> ..., item.word1, item.word2
          + * 
          + * * @version $Id: LDC2_W.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class LDC2_W extends CPInstruction implements PushInstruction, TypedInstruction { +public class LDC2_W extends CPInstruction implements PushInstruction, + TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC2_W() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC2_W() { + } - public LDC2_W(int index) { - super(org.apache.bcel.Constants.LDC2_W, index); - } + public LDC2_W(int index) { + super(org.apache.bcel.Constants.LDC2_W, index); + } + @Override + public Type getType(ConstantPoolGen cpg) { + switch (cpg.getConstantPool().getConstant(index).getTag()) { + case org.apache.bcel.Constants.CONSTANT_Long: + return Type.LONG; + case org.apache.bcel.Constants.CONSTANT_Double: + return Type.DOUBLE; + default: // Never reached + throw new RuntimeException("Unknown constant type " + opcode); + } + } - public Type getType( ConstantPoolGen cpg ) { - switch (cpg.getConstantPool().getConstant(index).getTag()) { - case org.apache.bcel.Constants.CONSTANT_Long: - return Type.LONG; - case org.apache.bcel.Constants.CONSTANT_Double: - return Type.DOUBLE; - default: // Never reached - throw new RuntimeException("Unknown constant type " + opcode); - } - } + public Number getValue(ConstantPoolGen cpg) { + org.apache.bcel.classfile.Constant c = cpg.getConstantPool() + .getConstant(index); + switch (c.getTag()) { + case org.apache.bcel.Constants.CONSTANT_Long: + return new Long( + ((org.apache.bcel.classfile.ConstantLong) c).getBytes()); + case org.apache.bcel.Constants.CONSTANT_Double: + return new Double( + ((org.apache.bcel.classfile.ConstantDouble) c).getBytes()); + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + + index); + } + } - - public Number getValue( ConstantPoolGen cpg ) { - org.apache.bcel.classfile.Constant c = cpg.getConstantPool().getConstant(index); - switch (c.getTag()) { - case org.apache.bcel.Constants.CONSTANT_Long: - return new Long(((org.apache.bcel.classfile.ConstantLong) c).getBytes()); - case org.apache.bcel.Constants.CONSTANT_Double: - return new Double(((org.apache.bcel.classfile.ConstantDouble) c).getBytes()); - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitLDC2_W(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitLDC2_W(this); + } } diff --git a/src/org/apache/bcel/generic/LDC_W.java b/src/org/apache/bcel/generic/LDC_W.java index 4621ccd..e5c77f2 100644 --- a/src/org/apache/bcel/generic/LDC_W.java +++ b/src/org/apache/bcel/generic/LDC_W.java @@ -19,36 +19,43 @@ package org.apache.bcel.generic; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * LDC_W - Push item from constant pool (wide index) - * - *
          Stack: ... -> ..., item.word1, item.word2
          - * + * + *
          + * Stack: ... -> ..., item.word1, item.word2
          + * 
          + * * @version $Id: LDC_W.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LDC_W extends LDC { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC_W() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC_W() { + } - public LDC_W(int index) { - super(index); - } + public LDC_W(int index) { + super(index); + } - - /** - * Read needed data (i.e., index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - setIndex(bytes.readUnsignedShort()); - // Override just in case it has been changed - opcode = org.apache.bcel.Constants.LDC_W; - length = 3; - } + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + setIndex(bytes.readUnsignedShort()); + // Override just in case it has been changed + opcode = org.apache.bcel.Constants.LDC_W; + length = 3; + } } diff --git a/src/org/apache/bcel/generic/LDIV.java b/src/org/apache/bcel/generic/LDIV.java index f734ada..f35b670 100644 --- a/src/org/apache/bcel/generic/LDIV.java +++ b/src/org/apache/bcel/generic/LDIV.java @@ -18,40 +18,48 @@ package org.apache.bcel.generic; /** * LDIV - Divide longs - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: LDIV.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LDIV extends ArithmeticInstruction implements ExceptionThrower { - public LDIV() { - super(org.apache.bcel.Constants.LDIV); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LDIV() { + super(org.apache.bcel.Constants.LDIV); + } - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION - }; - } + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLDIV(this); + } } diff --git a/src/org/apache/bcel/generic/LLOAD.java b/src/org/apache/bcel/generic/LLOAD.java index bdf5fe4..ebe3e0d 100644 --- a/src/org/apache/bcel/generic/LLOAD.java +++ b/src/org/apache/bcel/generic/LLOAD.java @@ -16,39 +16,49 @@ */ package org.apache.bcel.generic; -/** +/** * LLOAD - Load long from local variable - *
          Stack ... -> ..., result.word1, result.word2
          - * + * + *
          + * Stack ... -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: LLOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LLOAD() { - super(org.apache.bcel.Constants.LLOAD, org.apache.bcel.Constants.LLOAD_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LLOAD() { + super(org.apache.bcel.Constants.LLOAD, + org.apache.bcel.Constants.LLOAD_0); + } - public LLOAD(int n) { - super(org.apache.bcel.Constants.LLOAD, org.apache.bcel.Constants.LLOAD_0, n); - } + public LLOAD(int n) { + super(org.apache.bcel.Constants.LLOAD, + org.apache.bcel.Constants.LLOAD_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitLLOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitLLOAD(this); + } } diff --git a/src/org/apache/bcel/generic/LMUL.java b/src/org/apache/bcel/generic/LMUL.java index ff41bdb..6c62284 100644 --- a/src/org/apache/bcel/generic/LMUL.java +++ b/src/org/apache/bcel/generic/LMUL.java @@ -16,34 +16,44 @@ */ package org.apache.bcel.generic; -/** +/** * LMUL - Multiply longs - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: LMUL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LMUL extends ArithmeticInstruction { - public LMUL() { - super(org.apache.bcel.Constants.LMUL); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LMUL() { + super(org.apache.bcel.Constants.LMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLMUL(this); + } } diff --git a/src/org/apache/bcel/generic/LNEG.java b/src/org/apache/bcel/generic/LNEG.java index d30d2cc..4c750e6 100644 --- a/src/org/apache/bcel/generic/LNEG.java +++ b/src/org/apache/bcel/generic/LNEG.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * LNEG - Negate long - *
          Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: LNEG.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LNEG extends ArithmeticInstruction { - public LNEG() { - super(org.apache.bcel.Constants.LNEG); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LNEG() { + super(org.apache.bcel.Constants.LNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLNEG(this); + } } diff --git a/src/org/apache/bcel/generic/LOOKUPSWITCH.java b/src/org/apache/bcel/generic/LOOKUPSWITCH.java index e85fff1..8b63e39 100644 --- a/src/org/apache/bcel/generic/LOOKUPSWITCH.java +++ b/src/org/apache/bcel/generic/LOOKUPSWITCH.java @@ -20,76 +20,88 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * LOOKUPSWITCH - Switch with unordered set of values - * + * * @version $Id: LOOKUPSWITCH.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see SWITCH */ public class LOOKUPSWITCH extends Select { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LOOKUPSWITCH() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LOOKUPSWITCH() { + } - public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, InstructionHandle defaultTarget) { - super(org.apache.bcel.Constants.LOOKUPSWITCH, match, targets, defaultTarget); - length = (short) (9 + match_length * 8); /* alignment remainder assumed - * 0 here, until dump time. */ - fixed_length = length; - } + public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, + InstructionHandle defaultTarget) { + super(org.apache.bcel.Constants.LOOKUPSWITCH, match, targets, + defaultTarget); + length = (short) (9 + match_length * 8); /* + * alignment remainder assumed 0 + * here, until dump time. + */ + fixed_length = length; + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + super.dump(out); + out.writeInt(match_length); // npairs + for (int i = 0; i < match_length; i++) { + out.writeInt(match[i]); // match-offset pairs + out.writeInt(indices[i] = getTargetOffset(targets[i])); + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - super.dump(out); - out.writeInt(match_length); // npairs - for (int i = 0; i < match_length; i++) { - out.writeInt(match[i]); // match-offset pairs - out.writeInt(indices[i] = getTargetOffset(targets[i])); - } - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + super.initFromFile(bytes, wide); // reads padding + match_length = bytes.readInt(); + fixed_length = (short) (9 + match_length * 8); + length = (short) (fixed_length + padding); + match = new int[match_length]; + indices = new int[match_length]; + targets = new InstructionHandle[match_length]; + for (int i = 0; i < match_length; i++) { + match[i] = bytes.readInt(); + indices[i] = bytes.readInt(); + } + } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - super.initFromFile(bytes, wide); // reads padding - match_length = bytes.readInt(); - fixed_length = (short) (9 + match_length * 8); - length = (short) (fixed_length + padding); - match = new int[match_length]; - indices = new int[match_length]; - targets = new InstructionHandle[match_length]; - for (int i = 0; i < match_length; i++) { - match[i] = bytes.readInt(); - indices[i] = bytes.readInt(); - } - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitVariableLengthInstruction(this); - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitLOOKUPSWITCH(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitVariableLengthInstruction(this); + v.visitStackProducer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitLOOKUPSWITCH(this); + } } diff --git a/src/org/apache/bcel/generic/LOR.java b/src/org/apache/bcel/generic/LOR.java index 2d716e9..3796ef0 100644 --- a/src/org/apache/bcel/generic/LOR.java +++ b/src/org/apache/bcel/generic/LOR.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * LOR - Bitwise OR long - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: LOR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LOR extends ArithmeticInstruction { - public LOR() { - super(org.apache.bcel.Constants.LOR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LOR() { + super(org.apache.bcel.Constants.LOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLOR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLOR(this); + } } diff --git a/src/org/apache/bcel/generic/LREM.java b/src/org/apache/bcel/generic/LREM.java index 12bdd40..1d595f8 100644 --- a/src/org/apache/bcel/generic/LREM.java +++ b/src/org/apache/bcel/generic/LREM.java @@ -18,39 +18,46 @@ package org.apache.bcel.generic; /** * LREM - Remainder of long - *
          Stack: ..., value1, value2 -> result
          - * + * + *
          + * Stack: ..., value1, value2 -> result
          + * 
          + * * @version $Id: LREM.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LREM extends ArithmeticInstruction implements ExceptionThrower { - public LREM() { - super(org.apache.bcel.Constants.LREM); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LREM() { + super(org.apache.bcel.Constants.LREM); + } - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION - }; - } + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLREM(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLREM(this); + } } diff --git a/src/org/apache/bcel/generic/LRETURN.java b/src/org/apache/bcel/generic/LRETURN.java index 161b39e..1450d7b 100644 --- a/src/org/apache/bcel/generic/LRETURN.java +++ b/src/org/apache/bcel/generic/LRETURN.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** - * LRETURN - Return long from method - *
          Stack: ..., value.word1, value.word2 -> <empty>
          - * +/** + * LRETURN - Return long from method + * + *
          + * Stack: ..., value.word1, value.word2 -> <empty>
          + * 
          + * * @version $Id: LRETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LRETURN extends ReturnInstruction { - public LRETURN() { - super(org.apache.bcel.Constants.LRETURN); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LRETURN() { + super(org.apache.bcel.Constants.LRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitLRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitLRETURN(this); + } } diff --git a/src/org/apache/bcel/generic/LSHL.java b/src/org/apache/bcel/generic/LSHL.java index 980504b..3f931c8 100644 --- a/src/org/apache/bcel/generic/LSHL.java +++ b/src/org/apache/bcel/generic/LSHL.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * LSHL - Arithmetic shift left long - *
          Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: LSHL.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LSHL extends ArithmeticInstruction { - public LSHL() { - super(org.apache.bcel.Constants.LSHL); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LSHL() { + super(org.apache.bcel.Constants.LSHL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSHL(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSHL(this); + } } diff --git a/src/org/apache/bcel/generic/LSHR.java b/src/org/apache/bcel/generic/LSHR.java index 68c2cf5..8ab7427 100644 --- a/src/org/apache/bcel/generic/LSHR.java +++ b/src/org/apache/bcel/generic/LSHR.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * LSHR - Arithmetic shift right long - *
          Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
          - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
          + * 
          + * * @version $Id: LSHR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LSHR extends ArithmeticInstruction { - public LSHR() { - super(org.apache.bcel.Constants.LSHR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LSHR() { + super(org.apache.bcel.Constants.LSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSHR(this); + } } diff --git a/src/org/apache/bcel/generic/LSTORE.java b/src/org/apache/bcel/generic/LSTORE.java index 988ab6f..3e2dc4a 100644 --- a/src/org/apache/bcel/generic/LSTORE.java +++ b/src/org/apache/bcel/generic/LSTORE.java @@ -16,39 +16,49 @@ */ package org.apache.bcel.generic; -/** +/** * LSTORE - Store long into local variable - *
          Stack: ..., value.word1, value.word2 -> ... 
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ...
          + * 
          + * * @version $Id: LSTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LSTORE() { - super(org.apache.bcel.Constants.LSTORE, org.apache.bcel.Constants.LSTORE_0); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LSTORE() { + super(org.apache.bcel.Constants.LSTORE, + org.apache.bcel.Constants.LSTORE_0); + } - public LSTORE(int n) { - super(org.apache.bcel.Constants.LSTORE, org.apache.bcel.Constants.LSTORE_0, n); - } + public LSTORE(int n) { + super(org.apache.bcel.Constants.LSTORE, + org.apache.bcel.Constants.LSTORE_0, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - super.accept(v); - v.visitLSTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + super.accept(v); + v.visitLSTORE(this); + } } diff --git a/src/org/apache/bcel/generic/LSUB.java b/src/org/apache/bcel/generic/LSUB.java index 9155902..21cc308 100644 --- a/src/org/apache/bcel/generic/LSUB.java +++ b/src/org/apache/bcel/generic/LSUB.java @@ -16,34 +16,44 @@ */ package org.apache.bcel.generic; -/** +/** * LSUB - Substract longs - *
          Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          - * ..., result.word1, result.word2 - * + * + *
          + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
          + * 
          + * + * ..., result.word1, result.word2 + * * @version $Id: LSUB.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LSUB extends ArithmeticInstruction { - public LSUB() { - super(org.apache.bcel.Constants.LSUB); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LSUB() { + super(org.apache.bcel.Constants.LSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSUB(this); + } } diff --git a/src/org/apache/bcel/generic/LUSHR.java b/src/org/apache/bcel/generic/LUSHR.java index ee65857..382e0fa 100644 --- a/src/org/apache/bcel/generic/LUSHR.java +++ b/src/org/apache/bcel/generic/LUSHR.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * LUSHR - Logical shift right long - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: LUSHR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LUSHR extends ArithmeticInstruction { - public LUSHR() { - super(org.apache.bcel.Constants.LUSHR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LUSHR() { + super(org.apache.bcel.Constants.LUSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLUSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLUSHR(this); + } } diff --git a/src/org/apache/bcel/generic/LXOR.java b/src/org/apache/bcel/generic/LXOR.java index 33090a8..a0101d2 100644 --- a/src/org/apache/bcel/generic/LXOR.java +++ b/src/org/apache/bcel/generic/LXOR.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * LXOR - Bitwise XOR long - *
          Stack: ..., value1, value2 -> ..., result
          - * + * + *
          + * Stack: ..., value1, value2 -> ..., result
          + * 
          + * * @version $Id: LXOR.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class LXOR extends ArithmeticInstruction { - public LXOR() { - super(org.apache.bcel.Constants.LXOR); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public LXOR() { + super(org.apache.bcel.Constants.LXOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLXOR(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLXOR(this); + } } diff --git a/src/org/apache/bcel/generic/LineNumberGen.java b/src/org/apache/bcel/generic/LineNumberGen.java index d34045f..5cb0b67 100644 --- a/src/org/apache/bcel/generic/LineNumberGen.java +++ b/src/org/apache/bcel/generic/LineNumberGen.java @@ -18,91 +18,95 @@ package org.apache.bcel.generic; import org.apache.bcel.classfile.LineNumber; -/** - * This class represents a line number within a method, i.e., give an instruction - * a line number corresponding to the source code line. - * +/** + * This class represents a line number within a method, i.e., give an + * instruction a line number corresponding to the source code line. + * * @version $Id: LineNumberGen.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see LineNumber - * @see MethodGen + * @author M. Dahm + * @see LineNumber + * @see MethodGen */ -public class LineNumberGen implements InstructionTargeter, Cloneable, java.io.Serializable { +public class LineNumberGen implements InstructionTargeter, Cloneable, + java.io.Serializable { - private InstructionHandle ih; - private int src_line; + /** + * + */ + private static final long serialVersionUID = 1L; + private InstructionHandle ih; + private int src_line; + /** + * Create a line number. + * + * @param ih + * instruction handle to reference + */ + public LineNumberGen(InstructionHandle ih, int src_line) { + setInstruction(ih); + setSourceLine(src_line); + } - /** - * Create a line number. - * - * @param ih instruction handle to reference - */ - public LineNumberGen(InstructionHandle ih, int src_line) { - setInstruction(ih); - setSourceLine(src_line); - } + /** + * @return true, if ih is target of this line number + */ + @Override + public boolean containsTarget(InstructionHandle ih) { + return this.ih == ih; + } + /** + * @param old_ih + * old target + * @param new_ih + * new target + */ + @Override + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + if (old_ih != ih) { + throw new ClassGenException("Not targeting " + old_ih + ", but " + + ih + "}"); + } else { + setInstruction(new_ih); + } + } - /** - * @return true, if ih is target of this line number - */ - public boolean containsTarget( InstructionHandle ih ) { - return this.ih == ih; - } + /** + * Get LineNumber attribute . + * + * This relies on that the instruction list has already been dumped to byte + * code or or that the `setPositions' methods has been called for the + * instruction list. + */ + public LineNumber getLineNumber() { + return new LineNumber(ih.getPosition(), src_line); + } + public void setInstruction(InstructionHandle ih) { + BranchInstruction.notifyTarget(this.ih, ih, this); + this.ih = ih; + } - /** - * @param old_ih old target - * @param new_ih new target - */ - public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { - if (old_ih != ih) { - throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); - } else { - setInstruction(new_ih); - } - } + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } + public InstructionHandle getInstruction() { + return ih; + } - /** - * Get LineNumber attribute . - * - * This relies on that the instruction list has already been dumped to byte code or - * or that the `setPositions' methods has been called for the instruction list. - */ - public LineNumber getLineNumber() { - return new LineNumber(ih.getPosition(), src_line); - } + public void setSourceLine(int src_line) { + this.src_line = src_line; + } - - public void setInstruction( InstructionHandle ih ) { - BranchInstruction.notifyTarget(this.ih, ih, this); - this.ih = ih; - } - - - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } - - - public InstructionHandle getInstruction() { - return ih; - } - - - public void setSourceLine( int src_line ) { - this.src_line = src_line; - } - - - public int getSourceLine() { - return src_line; - } + public int getSourceLine() { + return src_line; + } } diff --git a/src/org/apache/bcel/generic/LoadClass.java b/src/org/apache/bcel/generic/LoadClass.java index 4633acf..fcea1c0 100644 --- a/src/org/apache/bcel/generic/LoadClass.java +++ b/src/org/apache/bcel/generic/LoadClass.java @@ -17,34 +17,33 @@ package org.apache.bcel.generic; /** - * Denotes that an instruction may start the process of loading and resolving + * Denotes that an instruction may start the process of loading and resolving * the referenced class in the Virtual Machine. - * + * * @version $Id: LoadClass.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface LoadClass { - /** - * Returns the ObjectType of the referenced class or interface - * that may be loaded and resolved. - * @return object type that may be loaded or null if a primitive is - * referenced - */ - public ObjectType getLoadClassType( ConstantPoolGen cpg ); + /** + * Returns the ObjectType of the referenced class or interface that may be + * loaded and resolved. + * + * @return object type that may be loaded or null if a primitive is + * referenced + */ + public ObjectType getLoadClassType(ConstantPoolGen cpg); - - /** - * Returns the type associated with this instruction. - * LoadClass instances are always typed, but this type - * does not always refer to the type of the class or interface - * that it possibly forces to load. For example, GETFIELD would - * return the type of the field and not the type of the class - * where the field is defined. - * If no class is forced to be loaded, null is returned. - * An example for this is an ANEWARRAY instruction that creates - * an int[][]. - * @see #getLoadClassType(ConstantPoolGen) - */ - public Type getType( ConstantPoolGen cpg ); + /** + * Returns the type associated with this instruction. LoadClass instances + * are always typed, but this type does not always refer to the type of the + * class or interface that it possibly forces to load. For example, GETFIELD + * would return the type of the field and not the type of the class where + * the field is defined. If no class is forced to be loaded, null is + * returned. An example for this is an ANEWARRAY instruction that creates an + * int[][]. + * + * @see #getLoadClassType(ConstantPoolGen) + */ + public Type getType(ConstantPoolGen cpg); } diff --git a/src/org/apache/bcel/generic/LoadInstruction.java b/src/org/apache/bcel/generic/LoadInstruction.java index 9f46d10..b04252f 100644 --- a/src/org/apache/bcel/generic/LoadInstruction.java +++ b/src/org/apache/bcel/generic/LoadInstruction.java @@ -17,47 +17,56 @@ package org.apache.bcel.generic; /** - * Denotes an unparameterized instruction to load a value from a local - * variable, e.g. ILOAD. - * + * Denotes an unparameterized instruction to load a value from a local variable, + * e.g. ILOAD. + * * @version $Id: LoadInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @author M. Dahm */ -public abstract class LoadInstruction extends LocalVariableInstruction implements PushInstruction { +public abstract class LoadInstruction extends LocalVariableInstruction + implements PushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - LoadInstruction(short canon_tag, short c_tag) { - super(canon_tag, c_tag); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. tag and length + * are defined in readInstruction and initFromFile, respectively. + */ + LoadInstruction(short canon_tag, short c_tag) { + super(canon_tag, c_tag); + } - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. - * @param n local variable index (unsigned short) - */ - protected LoadInstruction(short opcode, short c_tag, int n) { - super(opcode, c_tag, n); - } + /** + * @param opcode + * Instruction opcode + * @param c_tag + * Instruction number for compact version, ALOAD_0, e.g. + * @param n + * local variable index (unsigned short) + */ + protected LoadInstruction(short opcode, short c_tag, int n) { + super(opcode, c_tag, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitLocalVariableInstruction(this); - v.visitLoadInstruction(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitLocalVariableInstruction(this); + v.visitLoadInstruction(this); + } } diff --git a/src/org/apache/bcel/generic/LocalVariableGen.java b/src/org/apache/bcel/generic/LocalVariableGen.java index b5eb8fc..df446e3 100644 --- a/src/org/apache/bcel/generic/LocalVariableGen.java +++ b/src/org/apache/bcel/generic/LocalVariableGen.java @@ -19,190 +19,199 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.classfile.LocalVariable; -/** +/** * This class represents a local variable within a method. It contains its - * scope, name and type. The generated LocalVariable object can be obtained - * with getLocalVariable which needs the instruction list and the constant - * pool as parameters. - * + * scope, name and type. The generated LocalVariable object can be obtained with + * getLocalVariable which needs the instruction list and the constant pool as + * parameters. + * * @version $Id: LocalVariableGen.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see LocalVariable - * @see MethodGen + * @author M. Dahm + * @see LocalVariable + * @see MethodGen */ -public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable, - java.io.Serializable { +public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, + Cloneable, java.io.Serializable { - private int index; - private String name; - private Type type; - private InstructionHandle start, end; + /** + * + */ + private static final long serialVersionUID = 1L; + private int index; + private String name; + private Type type; + private InstructionHandle start, end; + /** + * Generate a local variable that with index `index'. Note that double and + * long variables need two indexs. Index indices have to be provided by the + * user. + * + * @param index + * index of local variable + * @param name + * its name + * @param type + * its type + * @param start + * from where the instruction is valid (null means from the + * start) + * @param end + * until where the instruction is valid (null means to the end) + */ + public LocalVariableGen(int index, String name, Type type, + InstructionHandle start, InstructionHandle end) { + if ((index < 0) || (index > Constants.MAX_SHORT)) { + throw new ClassGenException("Invalid index index: " + index); + } + this.name = name; + this.type = type; + this.index = index; + setStart(start); + setEnd(end); + } - /** - * Generate a local variable that with index `index'. Note that double and long - * variables need two indexs. Index indices have to be provided by the user. - * - * @param index index of local variable - * @param name its name - * @param type its type - * @param start from where the instruction is valid (null means from the start) - * @param end until where the instruction is valid (null means to the end) - */ - public LocalVariableGen(int index, String name, Type type, InstructionHandle start, - InstructionHandle end) { - if ((index < 0) || (index > Constants.MAX_SHORT)) { - throw new ClassGenException("Invalid index index: " + index); - } - this.name = name; - this.type = type; - this.index = index; - setStart(start); - setEnd(end); - } + /** + * Get LocalVariable object. + * + * This relies on that the instruction list has already been dumped to byte + * code or or that the `setPositions' methods has been called for the + * instruction list. + * + * Note that for local variables whose scope end at the last instruction of + * the method's code, the JVM specification is ambiguous: both a + * start_pc+length ending at the last instruction and start_pc+length ending + * at first index beyond the end of the code are valid. + * + * @param cp + * constant pool + */ + public LocalVariable getLocalVariable(ConstantPoolGen cp) { + int start_pc = start.getPosition(); + int length = end.getPosition() - start_pc; + if (length > 0) { + length += end.getInstruction().getLength(); + } + int name_index = cp.addUtf8(name); + int signature_index = cp.addUtf8(type.getSignature()); + return new LocalVariable(start_pc, length, name_index, signature_index, + index, cp.getConstantPool()); + } + public void setIndex(int index) { + this.index = index; + } - /** - * Get LocalVariable object. - * - * This relies on that the instruction list has already been dumped to byte code or - * or that the `setPositions' methods has been called for the instruction list. - * - * Note that for local variables whose scope end at the last - * instruction of the method's code, the JVM specification is ambiguous: - * both a start_pc+length ending at the last instruction and - * start_pc+length ending at first index beyond the end of the code are - * valid. - * - * @param cp constant pool - */ - public LocalVariable getLocalVariable( ConstantPoolGen cp ) { - int start_pc = start.getPosition(); - int length = end.getPosition() - start_pc; - if (length > 0) { - length += end.getInstruction().getLength(); - } - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(type.getSignature()); - return new LocalVariable(start_pc, length, name_index, signature_index, index, cp - .getConstantPool()); - } + public int getIndex() { + return index; + } + @Override + public void setName(String name) { + this.name = name; + } - public void setIndex( int index ) { - this.index = index; - } + @Override + public String getName() { + return name; + } + @Override + public void setType(Type type) { + this.type = type; + } - public int getIndex() { - return index; - } + @Override + public Type getType() { + return type; + } + public InstructionHandle getStart() { + return start; + } - public void setName( String name ) { - this.name = name; - } + public InstructionHandle getEnd() { + return end; + } + public void setStart(InstructionHandle start) { + BranchInstruction.notifyTarget(this.start, start, this); + this.start = start; + } - public String getName() { - return name; - } + public void setEnd(InstructionHandle end) { + BranchInstruction.notifyTarget(this.end, end, this); + this.end = end; + } + /** + * @param old_ih + * old target, either start or end + * @param new_ih + * new target + */ + @Override + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + boolean targeted = false; + if (start == old_ih) { + targeted = true; + setStart(new_ih); + } + if (end == old_ih) { + targeted = true; + setEnd(new_ih); + } + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih + ", but {" + + start + ", " + end + "}"); + } + } - public void setType( Type type ) { - this.type = type; - } + /** + * @return true, if ih is target of this variable + */ + @Override + public boolean containsTarget(InstructionHandle ih) { + return (start == ih) || (end == ih); + } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + // If the user changes the name or type, problems with the targeter + // hashmap will occur + int hc = index ^ name.hashCode() ^ type.hashCode(); + return hc; + } - public Type getType() { - return type; - } + /** + * We consider to local variables to be equal, if the use the same index and + * are valid in the same range. + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof LocalVariableGen)) { + return false; + } + LocalVariableGen l = (LocalVariableGen) o; + return (l.index == index) && (l.start == start) && (l.end == end); + } + @Override + public String toString() { + return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + + end + ")"; + } - public InstructionHandle getStart() { - return start; - } - - - public InstructionHandle getEnd() { - return end; - } - - - public void setStart( InstructionHandle start ) { - BranchInstruction.notifyTarget(this.start, start, this); - this.start = start; - } - - - public void setEnd( InstructionHandle end ) { - BranchInstruction.notifyTarget(this.end, end, this); - this.end = end; - } - - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { - boolean targeted = false; - if (start == old_ih) { - targeted = true; - setStart(new_ih); - } - if (end == old_ih) { - targeted = true; - setEnd(new_ih); - } - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + end - + "}"); - } - } - - - /** - * @return true, if ih is target of this variable - */ - public boolean containsTarget( InstructionHandle ih ) { - return (start == ih) || (end == ih); - } - - - /** @return a hash code value for the object. - */ - public int hashCode() { - //If the user changes the name or type, problems with the targeter hashmap will occur - int hc = index ^ name.hashCode() ^ type.hashCode(); - return hc; - } - - - /** - * We consider to local variables to be equal, if the use the same index and - * are valid in the same range. - */ - public boolean equals( Object o ) { - if (!(o instanceof LocalVariableGen)) { - return false; - } - LocalVariableGen l = (LocalVariableGen) o; - return (l.index == index) && (l.start == start) && (l.end == end); - } - - - public String toString() { - return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; - } - - - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - System.err.println(e); - return null; - } - } + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + System.err.println(e); + return null; + } + } } diff --git a/src/org/apache/bcel/generic/LocalVariableInstruction.java b/src/org/apache/bcel/generic/LocalVariableInstruction.java index 3f8d953..ee7836c 100644 --- a/src/org/apache/bcel/generic/LocalVariableInstruction.java +++ b/src/org/apache/bcel/generic/LocalVariableInstruction.java @@ -23,180 +23,190 @@ import org.apache.bcel.util.ByteSequence; /** * Abstract super class for instructions dealing with local variables. - * - * @version $Id: LocalVariableInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * + * @version $Id: LocalVariableInstruction.java 386056 2006-03-15 11:31:56Z + * tcurdt $ + * @author M. Dahm */ -public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction, - IndexedInstruction { +public abstract class LocalVariableInstruction extends Instruction implements + TypedInstruction, IndexedInstruction { - protected int n = -1; // index of referenced variable - private short c_tag = -1; // compact version, such as ILOAD_0 - private short canon_tag = -1; // canonical tag such as ILOAD + /** + * + */ + private static final long serialVersionUID = 1L; + protected int n = -1; // index of referenced variable + private short c_tag = -1; // compact version, such as ILOAD_0 + private short canon_tag = -1; // canonical tag such as ILOAD + private final boolean wide() { + return n > Constants.MAX_BYTE; + } - private final boolean wide() { - return n > Constants.MAX_BYTE; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. tag and length + * are defined in readInstruction and initFromFile, respectively. + */ + LocalVariableInstruction(short canon_tag, short c_tag) { + super(); + this.canon_tag = canon_tag; + this.c_tag = c_tag; + } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Also used by IINC()! + */ + LocalVariableInstruction() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - LocalVariableInstruction(short canon_tag, short c_tag) { - super(); - this.canon_tag = canon_tag; - this.c_tag = c_tag; - } + /** + * @param opcode + * Instruction opcode + * @param c_tag + * Instruction number for compact version, ALOAD_0, e.g. + * @param n + * local variable index (unsigned short) + */ + protected LocalVariableInstruction(short opcode, short c_tag, int n) { + super(opcode, (short) 2); + this.c_tag = c_tag; + canon_tag = opcode; + setIndex(n); + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + if (wide()) { + out.writeByte(Constants.WIDE); + } + out.writeByte(opcode); + if (length > 1) { // Otherwise ILOAD_n, instruction, e.g. + if (wide()) { + out.writeShort(n); + } else { + out.writeByte(n); + } + } + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Also used by IINC()! - */ - LocalVariableInstruction() { - } + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" "<"< local variable index>">" + * + * @param verbose + * long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + if (((opcode >= Constants.ILOAD_0) && (opcode <= Constants.ALOAD_3)) + || ((opcode >= Constants.ISTORE_0) && (opcode <= Constants.ASTORE_3))) { + return super.toString(verbose); + } else { + return super.toString(verbose) + " " + n; + } + } + /** + * Read needed data (e.g. index) from file. PRE: (ILOAD <= tag <= ALOAD_3) + * || (ISTORE <= tag <= ASTORE_3) + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + if (wide) { + n = bytes.readUnsignedShort(); + length = 4; + } else if (((opcode >= Constants.ILOAD) && (opcode <= Constants.ALOAD)) + || ((opcode >= Constants.ISTORE) && (opcode <= Constants.ASTORE))) { + n = bytes.readUnsignedByte(); + length = 2; + } else if (opcode <= Constants.ALOAD_3) { // compact load instruction + // such as ILOAD_2 + n = (opcode - Constants.ILOAD_0) % 4; + length = 1; + } else { // Assert ISTORE_0 <= tag <= ASTORE_3 + n = (opcode - Constants.ISTORE_0) % 4; + length = 1; + } + } - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. - * @param n local variable index (unsigned short) - */ - protected LocalVariableInstruction(short opcode, short c_tag, int n) { - super(opcode, (short) 2); - this.c_tag = c_tag; - canon_tag = opcode; - setIndex(n); - } + /** + * @return local variable index referred by this instruction. + */ + @Override + public final int getIndex() { + return n; + } + /** + * Set the local variable index + */ + @Override + public void setIndex(int n) { + if ((n < 0) || (n > Constants.MAX_SHORT)) { + throw new ClassGenException("Illegal value: " + n); + } + this.n = n; + if (n >= 0 && n <= 3) { // Use more compact instruction xLOAD_n + opcode = (short) (c_tag + n); + length = 1; + } else { + opcode = canon_tag; + if (wide()) { + length = 4; + } else { + length = 2; + } + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - if (wide()) { - out.writeByte(Constants.WIDE); - } - out.writeByte(opcode); - if (length > 1) { // Otherwise ILOAD_n, instruction, e.g. - if (wide()) { - out.writeShort(n); - } else { - out.writeByte(n); - } - } - } + /** + * @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 + */ + public short getCanonicalTag() { + return canon_tag; + } - - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< local variable index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - if (((opcode >= Constants.ILOAD_0) && (opcode <= Constants.ALOAD_3)) - || ((opcode >= Constants.ISTORE_0) && (opcode <= Constants.ASTORE_3))) { - return super.toString(verbose); - } else { - return super.toString(verbose) + " " + n; - } - } - - - /** - * Read needed data (e.g. index) from file. - * PRE: (ILOAD <= tag <= ALOAD_3) || (ISTORE <= tag <= ASTORE_3) - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - if (wide) { - n = bytes.readUnsignedShort(); - length = 4; - } else if (((opcode >= Constants.ILOAD) && (opcode <= Constants.ALOAD)) - || ((opcode >= Constants.ISTORE) && (opcode <= Constants.ASTORE))) { - n = bytes.readUnsignedByte(); - length = 2; - } else if (opcode <= Constants.ALOAD_3) { // compact load instruction such as ILOAD_2 - n = (opcode - Constants.ILOAD_0) % 4; - length = 1; - } else { // Assert ISTORE_0 <= tag <= ASTORE_3 - n = (opcode - Constants.ISTORE_0) % 4; - length = 1; - } - } - - - /** - * @return local variable index referred by this instruction. - */ - public final int getIndex() { - return n; - } - - - /** - * Set the local variable index - */ - public void setIndex( int n ) { - if ((n < 0) || (n > Constants.MAX_SHORT)) { - throw new ClassGenException("Illegal value: " + n); - } - this.n = n; - if (n >= 0 && n <= 3) { // Use more compact instruction xLOAD_n - opcode = (short) (c_tag + n); - length = 1; - } else { - opcode = canon_tag; - if (wide()) { - length = 4; - } else { - length = 2; - } - } - } - - - /** @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 - */ - public short getCanonicalTag() { - return canon_tag; - } - - - /** - * Returns the type associated with the instruction - - * in case of ALOAD or ASTORE Type.OBJECT is returned. - * This is just a bit incorrect, because ALOAD and ASTORE - * may work on every ReferenceType (including Type.NULL) and - * ASTORE may even work on a ReturnaddressType . - * @return type associated with the instruction - */ - public Type getType( ConstantPoolGen cp ) { - switch (canon_tag) { - case Constants.ILOAD: - case Constants.ISTORE: - return Type.INT; - case Constants.LLOAD: - case Constants.LSTORE: - return Type.LONG; - case Constants.DLOAD: - case Constants.DSTORE: - return Type.DOUBLE; - case Constants.FLOAD: - case Constants.FSTORE: - return Type.FLOAT; - case Constants.ALOAD: - case Constants.ASTORE: - return Type.OBJECT; - default: - throw new ClassGenException("Oops: unknown case in switch" + canon_tag); - } - } + /** + * Returns the type associated with the instruction - in case of ALOAD or + * ASTORE Type.OBJECT is returned. This is just a bit incorrect, because + * ALOAD and ASTORE may work on every ReferenceType (including Type.NULL) + * and ASTORE may even work on a ReturnaddressType . + * + * @return type associated with the instruction + */ + @Override + public Type getType(ConstantPoolGen cp) { + switch (canon_tag) { + case Constants.ILOAD: + case Constants.ISTORE: + return Type.INT; + case Constants.LLOAD: + case Constants.LSTORE: + return Type.LONG; + case Constants.DLOAD: + case Constants.DSTORE: + return Type.DOUBLE; + case Constants.FLOAD: + case Constants.FSTORE: + return Type.FLOAT; + case Constants.ALOAD: + case Constants.ASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Oops: unknown case in switch" + + canon_tag); + } + } } diff --git a/src/org/apache/bcel/generic/MONITORENTER.java b/src/org/apache/bcel/generic/MONITORENTER.java index 1f115f7..b0e706e 100644 --- a/src/org/apache/bcel/generic/MONITORENTER.java +++ b/src/org/apache/bcel/generic/MONITORENTER.java @@ -16,38 +16,46 @@ */ package org.apache.bcel.generic; -/** +/** * MONITORENTER - Enter monitor for object - *
          Stack: ..., objectref -> ...
          - * + * + *
          + * Stack: ..., objectref -> ...
          + * 
          + * * @version $Id: MONITORENTER.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class MONITORENTER extends Instruction implements ExceptionThrower, StackConsumer { +public class MONITORENTER extends Instruction implements ExceptionThrower, + StackConsumer { - public MONITORENTER() { - super(org.apache.bcel.Constants.MONITORENTER, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public MONITORENTER() { + super(org.apache.bcel.Constants.MONITORENTER, (short) 1); + } - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION - }; - } + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitMONITORENTER(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitMONITORENTER(this); + } } diff --git a/src/org/apache/bcel/generic/MONITOREXIT.java b/src/org/apache/bcel/generic/MONITOREXIT.java index 29ecbd5..5db445d 100644 --- a/src/org/apache/bcel/generic/MONITOREXIT.java +++ b/src/org/apache/bcel/generic/MONITOREXIT.java @@ -16,38 +16,46 @@ */ package org.apache.bcel.generic; -/** +/** * MONITOREXIT - Exit monitor for object - *
          Stack: ..., objectref -> ...
          - * + * + *
          + * Stack: ..., objectref -> ...
          + * 
          + * * @version $Id: MONITOREXIT.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class MONITOREXIT extends Instruction implements ExceptionThrower, StackConsumer { +public class MONITOREXIT extends Instruction implements ExceptionThrower, + StackConsumer { - public MONITOREXIT() { - super(org.apache.bcel.Constants.MONITOREXIT, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public MONITOREXIT() { + super(org.apache.bcel.Constants.MONITOREXIT, (short) 1); + } - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION - }; - } + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION }; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitMONITOREXIT(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitMONITOREXIT(this); + } } diff --git a/src/org/apache/bcel/generic/MULTIANEWARRAY.java b/src/org/apache/bcel/generic/MULTIANEWARRAY.java index 0709f15..9c5bf1e 100644 --- a/src/org/apache/bcel/generic/MULTIANEWARRAY.java +++ b/src/org/apache/bcel/generic/MULTIANEWARRAY.java @@ -22,125 +22,137 @@ import org.apache.bcel.ExceptionConstants; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.util.ByteSequence; -/** +/** * MULTIANEWARRAY - Create new mutidimensional array of references - *
          Stack: ..., count1, [count2, ...] -> ..., arrayref
          - * + * + *
          + * Stack: ..., count1, [count2, ...] -> ..., arrayref
          + * 
          + * * @version $Id: MULTIANEWARRAY.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, - ExceptionThrower { +public class MULTIANEWARRAY extends CPInstruction implements LoadClass, + AllocationInstruction, ExceptionThrower { - private short dimensions; + /** + * + */ + private static final long serialVersionUID = 1L; + private short dimensions; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + MULTIANEWARRAY() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - MULTIANEWARRAY() { - } + public MULTIANEWARRAY(int index, short dimensions) { + super(org.apache.bcel.Constants.MULTIANEWARRAY, index); + if (dimensions < 1) { + throw new ClassGenException("Invalid dimensions value: " + + dimensions); + } + this.dimensions = dimensions; + length = 4; + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeShort(index); + out.writeByte(dimensions); + } - public MULTIANEWARRAY(int index, short dimensions) { - super(org.apache.bcel.Constants.MULTIANEWARRAY, index); - if (dimensions < 1) { - throw new ClassGenException("Invalid dimensions value: " + dimensions); - } - this.dimensions = dimensions; - length = 4; - } + /** + * Read needed data (i.e., no. dimension) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + super.initFromFile(bytes, wide); + dimensions = bytes.readByte(); + length = 4; + } + /** + * @return number of dimensions to be created + */ + public final short getDimensions() { + return dimensions; + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); - out.writeShort(index); - out.writeByte(dimensions); - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + index + " " + dimensions; + } + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(ConstantPool cp) { + return super.toString(cp) + " " + dimensions; + } - /** - * Read needed data (i.e., no. dimension) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - super.initFromFile(bytes, wide); - dimensions = bytes.readByte(); - length = 4; - } + /** + * Also works for instructions whose stack effect depends on the constant + * pool entry they reference. + * + * @return Number of words consumed from stack by this instruction + */ + @Override + public int consumeStack(ConstantPoolGen cpg) { + return dimensions; + } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; + System.arraycopy( + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, + 0, + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; + return cs; + } - /** - * @return number of dimensions to be created - */ - public final short getDimensions() { - return dimensions; - } + @Override + public ObjectType getLoadClassType(ConstantPoolGen cpg) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } - - /** - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - return super.toString(verbose) + " " + index + " " + dimensions; - } - - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString( ConstantPool cp ) { - return super.toString(cp) + " " + dimensions; - } - - - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words consumed from stack by this instruction - */ - public int consumeStack( ConstantPoolGen cpg ) { - return dimensions; - } - - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - return cs; - } - - - public ObjectType getLoadClassType( ConstantPoolGen cpg ) { - Type t = getType(cpg); - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - return (t instanceof ObjectType) ? (ObjectType) t : null; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitMULTIANEWARRAY(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitMULTIANEWARRAY(this); + } } diff --git a/src/org/apache/bcel/generic/MethodGen.java b/src/org/apache/bcel/generic/MethodGen.java index ff816d5..5704f06 100644 --- a/src/org/apache/bcel/generic/MethodGen.java +++ b/src/org/apache/bcel/generic/MethodGen.java @@ -21,6 +21,7 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Stack; + import org.apache.bcel.Constants; import org.apache.bcel.classfile.Attribute; import org.apache.bcel.classfile.Code; @@ -34,1053 +35,1074 @@ import org.apache.bcel.classfile.Method; import org.apache.bcel.classfile.Utility; import org.apache.bcel.util.BCELComparator; -/** +/** * Template class for building up a method. This is done by defining exception * handlers, adding thrown exceptions, local variables and attributes, whereas * the `LocalVariableTable' and `LineNumberTable' attributes will be set * automatically for the code. Use stripAttributes() if you don't like this. - * + * * While generating code it may be necessary to insert NOP operations. You can - * use the `removeNOPs' method to get rid off them. - * The resulting method object can be obtained via the `getMethod()' method. - * + * use the `removeNOPs' method to get rid off them. The resulting method object + * can be obtained via the `getMethod()' method. + * * @version $Id: MethodGen.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @author Patrick C. Beard [setMaxStack()] - * @see InstructionList - * @see Method + * @author M. Dahm + * @author Patrick C. Beard + * [setMaxStack()] + * @see InstructionList + * @see Method */ public class MethodGen extends FieldGenOrMethodGen { - private String class_name; - private Type[] arg_types; - private String[] arg_names; - private int max_locals; - private int max_stack; - private InstructionList il; - private boolean strip_attributes; - private List variable_vec = new ArrayList(); - private List line_number_vec = new ArrayList(); - private List exception_vec = new ArrayList(); - private List throws_vec = new ArrayList(); - private List code_attrs_vec = new ArrayList(); - private static BCELComparator _cmp = new BCELComparator() { - - public boolean equals( Object o1, Object o2 ) { - MethodGen THIS = (MethodGen) o1; - MethodGen THAT = (MethodGen) o2; - return THIS.getName().equals(THAT.getName()) - && THIS.getSignature().equals(THAT.getSignature()); - } - - - public int hashCode( Object o ) { - MethodGen THIS = (MethodGen) o; - return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); - } - }; - - - /** - * Declare method. If the method is non-static the constructor - * automatically declares a local variable `$this' in slot 0. The - * actual code is contained in the `il' parameter, which may further - * manipulated by the user. But he must take care not to remove any - * instruction (handles) that are still referenced from this object. - * - * For example one may not add a local variable and later remove the - * instructions it refers to without causing havoc. It is safe - * however if you remove that local variable, too. - * - * @param access_flags access qualifiers - * @param return_type method type - * @param arg_types argument types - * @param arg_names argument names (if this is null, default names will be provided - * for them) - * @param method_name name of method - * @param class_name class name containing this method (may be null, if you don't care) - * @param il instruction list associated with this method, may be null only for - * abstract or native methods - * @param cp constant pool - */ - public MethodGen(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, - String method_name, String class_name, InstructionList il, ConstantPoolGen cp) { - setAccessFlags(access_flags); - setType(return_type); - setArgumentTypes(arg_types); - setArgumentNames(arg_names); - setName(method_name); - setClassName(class_name); - setInstructionList(il); - setConstantPool(cp); - boolean abstract_ = isAbstract() || isNative(); - InstructionHandle start = null; - InstructionHandle end = null; - if (!abstract_) { - start = il.getStart(); - end = il.getEnd(); - /* Add local variables, namely the implicit `this' and the arguments - */ - if (!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0 - addLocalVariable("this", new ObjectType(class_name), start, end); - } - } - if (arg_types != null) { - int size = arg_types.length; - for (int i = 0; i < size; i++) { - if (Type.VOID == arg_types[i]) { - throw new ClassGenException("'void' is an illegal argument type for a method"); - } - } - if (arg_names != null) { // Names for variables provided? - if (size != arg_names.length) { - throw new ClassGenException("Mismatch in argument array lengths: " + size - + " vs. " + arg_names.length); - } - } else { // Give them dummy names - arg_names = new String[size]; - for (int i = 0; i < size; i++) { - arg_names[i] = "arg" + i; - } - setArgumentNames(arg_names); - } - if (!abstract_) { - for (int i = 0; i < size; i++) { - addLocalVariable(arg_names[i], arg_types[i], start, end); - } - } - } - } - - - /** - * Instantiate from existing method. - * - * @param m method - * @param class_name class name containing this method - * @param cp constant pool - */ - public MethodGen(Method m, String class_name, ConstantPoolGen cp) { - this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), Type.getArgumentTypes(m - .getSignature()), null /* may be overridden anyway */ - , m.getName(), class_name, - ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0) - ? new InstructionList(m.getCode().getCode()) - : null, cp); - Attribute[] attributes = m.getAttributes(); - for (int i = 0; i < attributes.length; i++) { - Attribute a = attributes[i]; - if (a instanceof Code) { - Code c = (Code) a; - setMaxStack(c.getMaxStack()); - setMaxLocals(c.getMaxLocals()); - CodeException[] ces = c.getExceptionTable(); - if (ces != null) { - for (int j = 0; j < ces.length; j++) { - CodeException ce = ces[j]; - int type = ce.getCatchType(); - ObjectType c_type = null; - if (type > 0) { - String cen = m.getConstantPool().getConstantString(type, - Constants.CONSTANT_Class); - c_type = new ObjectType(cen); - } - int end_pc = ce.getEndPC(); - int length = m.getCode().getCode().length; - InstructionHandle end; - if (length == end_pc) { // May happen, because end_pc is exclusive - end = il.getEnd(); - } else { - end = il.findHandle(end_pc); - end = end.getPrev(); // Make it inclusive - } - addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce - .getHandlerPC()), c_type); - } - } - Attribute[] c_attributes = c.getAttributes(); - for (int j = 0; j < c_attributes.length; j++) { - a = c_attributes[j]; - if (a instanceof LineNumberTable) { - LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable(); - for (int k = 0; k < ln.length; k++) { - LineNumber l = ln[k]; - InstructionHandle ih = il.findHandle(l.getStartPC()); - if (ih != null) { - addLineNumber(ih, l.getLineNumber()); - } - } - } else if (a instanceof LocalVariableTable) { - LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable(); - removeLocalVariables(); - for (int k = 0; k < lv.length; k++) { - LocalVariable l = lv[k]; - InstructionHandle start = il.findHandle(l.getStartPC()); - InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); - // Repair malformed handles - if (null == start) { - start = il.getStart(); - } - if (null == end) { - end = il.getEnd(); - } - addLocalVariable(l.getName(), Type.getType(l.getSignature()), l - .getIndex(), start, end); - } - } else { - addCodeAttribute(a); - } - } - } else if (a instanceof ExceptionTable) { - String[] names = ((ExceptionTable) a).getExceptionNames(); - for (int j = 0; j < names.length; j++) { - addException(names[j]); - } - } else { - addAttribute(a); - } - } - } - - - /** - * Adds a local variable to this method. - * - * @param name variable name - * @param type variable type - * @param slot the index of the local variable, if type is long or double, the next available - * index is slot+2 - * @param start from where the variable is valid - * @param end until where the variable is valid - * @return new local variable object - * @see LocalVariable - */ - public LocalVariableGen addLocalVariable( String name, Type type, int slot, - InstructionHandle start, InstructionHandle end ) { - byte t = type.getType(); - if (t != Constants.T_ADDRESS) { - int add = type.getSize(); - if (slot + add > max_locals) { - max_locals = slot + add; - } - LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); - int i; - if ((i = variable_vec.indexOf(l)) >= 0) { - variable_vec.set(i, l); - } else { - variable_vec.add(l); - } - return l; - } else { - throw new IllegalArgumentException("Can not use " + type - + " as type for local variable"); - } - } - - - /** - * Adds a local variable to this method and assigns an index automatically. - * - * @param name variable name - * @param type variable type - * @param start from where the variable is valid, if this is null, - * it is valid from the start - * @param end until where the variable is valid, if this is null, - * it is valid to the end - * @return new local variable object - * @see LocalVariable - */ - public LocalVariableGen addLocalVariable( String name, Type type, InstructionHandle start, - InstructionHandle end ) { - return addLocalVariable(name, type, max_locals, start, end); - } - - - /** - * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable - * with an explicit index argument. - */ - public void removeLocalVariable( LocalVariableGen l ) { - variable_vec.remove(l); - } - - - /** - * Remove all local variables. - */ - public void removeLocalVariables() { - variable_vec.clear(); - } - - - /** - * Sort local variables by index - */ - private static final void sort( LocalVariableGen[] vars, int l, int r ) { - int i = l, j = r; - int m = vars[(l + r) / 2].getIndex(); - LocalVariableGen h; - do { - while (vars[i].getIndex() < m) { - i++; - } - while (m < vars[j].getIndex()) { - j--; - } - if (i <= j) { - h = vars[i]; - vars[i] = vars[j]; - vars[j] = h; // Swap elements - i++; - j--; - } - } while (i <= j); - if (l < j) { - sort(vars, l, j); - } - if (i < r) { - sort(vars, i, r); - } - } - - - /* - * If the range of the variable has not been set yet, it will be set to be valid from - * the start to the end of the instruction list. - * - * @return array of declared local variables sorted by index - */ - public LocalVariableGen[] getLocalVariables() { - int size = variable_vec.size(); - LocalVariableGen[] lg = new LocalVariableGen[size]; - variable_vec.toArray(lg); - for (int i = 0; i < size; i++) { - if (lg[i].getStart() == null) { - lg[i].setStart(il.getStart()); - } - if (lg[i].getEnd() == null) { - lg[i].setEnd(il.getEnd()); - } - } - if (size > 1) { - sort(lg, 0, size - 1); - } - return lg; - } - - - /** - * @return `LocalVariableTable' attribute of all the local variables of this method. - */ - public LocalVariableTable getLocalVariableTable( ConstantPoolGen cp ) { - LocalVariableGen[] lg = getLocalVariables(); - int size = lg.length; - LocalVariable[] lv = new LocalVariable[size]; - for (int i = 0; i < size; i++) { - lv[i] = lg[i].getLocalVariable(cp); - } - return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp - .getConstantPool()); - } - - - /** - * Give an instruction a line number corresponding to the source code line. - * - * @param ih instruction to tag - * @return new line number object - * @see LineNumber - */ - public LineNumberGen addLineNumber( InstructionHandle ih, int src_line ) { - LineNumberGen l = new LineNumberGen(ih, src_line); - line_number_vec.add(l); - return l; - } - - - /** - * Remove a line number. - */ - public void removeLineNumber( LineNumberGen l ) { - line_number_vec.remove(l); - } - - - /** - * Remove all line numbers. - */ - public void removeLineNumbers() { - line_number_vec.clear(); - } - - - /* - * @return array of line numbers - */ - public LineNumberGen[] getLineNumbers() { - LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()]; - line_number_vec.toArray(lg); - return lg; - } - - - /** - * @return `LineNumberTable' attribute of all the local variables of this method. - */ - public LineNumberTable getLineNumberTable( ConstantPoolGen cp ) { - int size = line_number_vec.size(); - LineNumber[] ln = new LineNumber[size]; - try { - for (int i = 0; i < size; i++) { - ln[i] = ((LineNumberGen) line_number_vec.get(i)).getLineNumber(); - } - } catch (ArrayIndexOutOfBoundsException e) { - } // Never occurs - return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp - .getConstantPool()); - } - - - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. - * - * @param start_pc Start of region (inclusive) - * @param end_pc End of region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type class type of handled exception or null if any - * exception is handled - * @return new exception handler object - */ - public CodeExceptionGen addExceptionHandler( InstructionHandle start_pc, - InstructionHandle end_pc, InstructionHandle handler_pc, ObjectType catch_type ) { - if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) { - throw new ClassGenException("Exception handler target is null instruction"); - } - CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type); - exception_vec.add(c); - return c; - } - - - /** - * Remove an exception handler. - */ - public void removeExceptionHandler( CodeExceptionGen c ) { - exception_vec.remove(c); - } - - - /** - * Remove all line numbers. - */ - public void removeExceptionHandlers() { - exception_vec.clear(); - } - - - /* - * @return array of declared exception handlers - */ - public CodeExceptionGen[] getExceptionHandlers() { - CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()]; - exception_vec.toArray(cg); - return cg; - } - - - /** - * @return code exceptions for `Code' attribute - */ - private CodeException[] getCodeExceptions() { - int size = exception_vec.size(); - CodeException[] c_exc = new CodeException[size]; - try { - for (int i = 0; i < size; i++) { - CodeExceptionGen c = (CodeExceptionGen) exception_vec.get(i); - c_exc[i] = c.getCodeException(cp); - } - } catch (ArrayIndexOutOfBoundsException e) { - } - return c_exc; - } - - - /** - * Add an exception possibly thrown by this method. - * - * @param class_name (fully qualified) name of exception - */ - public void addException( String class_name ) { - throws_vec.add(class_name); - } - - - /** - * Remove an exception. - */ - public void removeException( String c ) { - throws_vec.remove(c); - } - - - /** - * Remove all exceptions. - */ - public void removeExceptions() { - throws_vec.clear(); - } - - - /* - * @return array of thrown exceptions - */ - public String[] getExceptions() { - String[] e = new String[throws_vec.size()]; - throws_vec.toArray(e); - return e; - } - - - /** - * @return `Exceptions' attribute of all the exceptions thrown by this method. - */ - private ExceptionTable getExceptionTable( ConstantPoolGen cp ) { - int size = throws_vec.size(); - int[] ex = new int[size]; - try { - for (int i = 0; i < size; i++) { - ex[i] = cp.addClass((String) throws_vec.get(i)); - } - } catch (ArrayIndexOutOfBoundsException e) { - } - return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp.getConstantPool()); - } - - - /** - * Add an attribute to the code. Currently, the JVM knows about the - * LineNumberTable, LocalVariableTable and StackMap attributes, - * where the former two will be generated automatically and the - * latter is used for the MIDP only. Other attributes will be - * ignored by the JVM but do no harm. - * - * @param a attribute to be added - */ - public void addCodeAttribute( Attribute a ) { - code_attrs_vec.add(a); - } - - - /** - * Remove a code attribute. - */ - public void removeCodeAttribute( Attribute a ) { - code_attrs_vec.remove(a); - } - - - /** - * Remove all code attributes. - */ - public void removeCodeAttributes() { - code_attrs_vec.clear(); - } - - - /** - * @return all attributes of this method. - */ - public Attribute[] getCodeAttributes() { - Attribute[] attributes = new Attribute[code_attrs_vec.size()]; - code_attrs_vec.toArray(attributes); - return attributes; - } - - - /** - * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively, - * before calling this method (the same applies for max locals). - * - * @return method object - */ - public Method getMethod() { - String signature = getSignature(); - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(signature); - /* Also updates positions of instructions, i.e., their indices - */ - byte[] byte_code = null; - if (il != null) { - byte_code = il.getByteCode(); - } - LineNumberTable lnt = null; - LocalVariableTable lvt = null; - /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.) - */ - if ((variable_vec.size() > 0) && !strip_attributes) { - addCodeAttribute(lvt = getLocalVariableTable(cp)); - } - if ((line_number_vec.size() > 0) && !strip_attributes) { - addCodeAttribute(lnt = getLineNumberTable(cp)); - } - Attribute[] code_attrs = getCodeAttributes(); - /* Each attribute causes 6 additional header bytes - */ - int attrs_len = 0; - for (int i = 0; i < code_attrs.length; i++) { - attrs_len += (code_attrs[i].getLength() + 6); - } - CodeException[] c_exc = getCodeExceptions(); - int exc_len = c_exc.length * 8; // Every entry takes 8 bytes - Code code = null; - if ((il != null) && !isAbstract() && !isNative()) { - // Remove any stale code attribute - Attribute[] attributes = getAttributes(); - for (int i = 0; i < attributes.length; i++) { - Attribute a = attributes[i]; - if (a instanceof Code) { - removeAttribute(a); - } - } - code = new Code(cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code - 2 + exc_len + // exceptions - 2 + attrs_len, // attributes - max_stack, max_locals, byte_code, c_exc, code_attrs, cp.getConstantPool()); - addAttribute(code); - } - ExceptionTable et = null; - if (throws_vec.size() > 0) { - addAttribute(et = getExceptionTable(cp)); - // Add `Exceptions' if there are "throws" clauses - } - Method m = new Method(access_flags, name_index, signature_index, getAttributes(), cp - .getConstantPool()); - // Undo effects of adding attributes - if (lvt != null) { - removeCodeAttribute(lvt); - } - if (lnt != null) { - removeCodeAttribute(lnt); - } - if (code != null) { - removeAttribute(code); - } - if (et != null) { - removeAttribute(et); - } - return m; - } - - - /** - * Remove all NOPs from the instruction list (if possible) and update every - * object refering to them, i.e., branch instructions, local variables and - * exception handlers. - */ - public void removeNOPs() { - if (il != null) { - InstructionHandle next; - /* Check branch instructions. - */ - for (InstructionHandle ih = il.getStart(); ih != null; ih = next) { - next = ih.next; - if ((next != null) && (ih.getInstruction() instanceof NOP)) { - try { - il.delete(ih); - } catch (TargetLostException e) { - InstructionHandle[] targets = e.getTargets(); - for (int i = 0; i < targets.length; i++) { - InstructionTargeter[] targeters = targets[i].getTargeters(); - for (int j = 0; j < targeters.length; j++) { - targeters[j].updateTarget(targets[i], next); - } - } - } - } - } - } - } - - - /** - * Set maximum number of local variables. - */ - public void setMaxLocals( int m ) { - max_locals = m; - } - - - public int getMaxLocals() { - return max_locals; - } - - - /** - * Set maximum stack size for this method. - */ - public void setMaxStack( int m ) { - max_stack = m; - } - - - public int getMaxStack() { - return max_stack; - } - - - /** @return class that contains this method - */ - public String getClassName() { - return class_name; - } - - - public void setClassName( String class_name ) { - this.class_name = class_name; - } - - - public void setReturnType( Type return_type ) { - setType(return_type); - } - - - public Type getReturnType() { - return getType(); - } - - - public void setArgumentTypes( Type[] arg_types ) { - this.arg_types = arg_types; - } - - - public Type[] getArgumentTypes() { - return (Type[]) arg_types.clone(); - } - - - public void setArgumentType( int i, Type type ) { - arg_types[i] = type; - } - - - public Type getArgumentType( int i ) { - return arg_types[i]; - } - - - public void setArgumentNames( String[] arg_names ) { - this.arg_names = arg_names; - } - - - public String[] getArgumentNames() { - return (String[]) arg_names.clone(); - } - - - public void setArgumentName( int i, String name ) { - arg_names[i] = name; - } - - - public String getArgumentName( int i ) { - return arg_names[i]; - } - - - public InstructionList getInstructionList() { - return il; - } - - - public void setInstructionList( InstructionList il ) { - this.il = il; - } - - - public String getSignature() { - return Type.getMethodSignature(type, arg_types); - } - - - /** - * Computes max. stack size by performing control flow analysis. - */ - public void setMaxStack() { - if (il != null) { - max_stack = getMaxStack(cp, il, getExceptionHandlers()); - } else { - max_stack = 0; - } - } - - - /** - * Compute maximum number of local variables. - */ - public void setMaxLocals() { - if (il != null) { - int max = isStatic() ? 0 : 1; - if (arg_types != null) { - for (int i = 0; i < arg_types.length; i++) { - max += arg_types[i].getSize(); - } - } - for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { - Instruction ins = ih.getInstruction(); - if ((ins instanceof LocalVariableInstruction) || (ins instanceof RET) - || (ins instanceof IINC)) { - int index = ((IndexedInstruction) ins).getIndex() - + ((TypedInstruction) ins).getType(cp).getSize(); - if (index > max) { - max = index; - } - } - } - max_locals = max; - } else { - max_locals = 0; - } - } - - - /** Do not/Do produce attributes code attributesLineNumberTable and - * LocalVariableTable, like javac -O - */ - public void stripAttributes( boolean flag ) { - strip_attributes = flag; - } - - static final class BranchTarget { - - InstructionHandle target; - int stackDepth; - - - BranchTarget(InstructionHandle target, int stackDepth) { - this.target = target; - this.stackDepth = stackDepth; - } - } - - static final class BranchStack { - - Stack branchTargets = new Stack(); - Hashtable visitedTargets = new Hashtable(); - - - public void push( InstructionHandle target, int stackDepth ) { - if (visited(target)) { - return; - } - branchTargets.push(visit(target, stackDepth)); - } - - - public BranchTarget pop() { - if (!branchTargets.empty()) { - BranchTarget bt = (BranchTarget) branchTargets.pop(); - return bt; - } - return null; - } - - - private final BranchTarget visit( InstructionHandle target, int stackDepth ) { - BranchTarget bt = new BranchTarget(target, stackDepth); - visitedTargets.put(target, bt); - return bt; - } - - - private final boolean visited( InstructionHandle target ) { - return (visitedTargets.get(target) != null); - } - } - - - /** - * Computes stack usage of an instruction list by performing control flow analysis. - * - * @return maximum stack depth used by method - */ - public static int getMaxStack( ConstantPoolGen cp, InstructionList il, CodeExceptionGen[] et ) { - BranchStack branchTargets = new BranchStack(); - /* Initially, populate the branch stack with the exception - * handlers, because these aren't (necessarily) branched to - * explicitly. in each case, the stack will have depth 1, - * containing the exception object. - */ - for (int i = 0; i < et.length; i++) { - InstructionHandle handler_pc = et[i].getHandlerPC(); - if (handler_pc != null) { - branchTargets.push(handler_pc, 1); - } - } - int stackDepth = 0, maxStackDepth = 0; - InstructionHandle ih = il.getStart(); - while (ih != null) { - Instruction instruction = ih.getInstruction(); - short opcode = instruction.getOpcode(); - int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); - stackDepth += delta; - if (stackDepth > maxStackDepth) { - maxStackDepth = stackDepth; - } - // choose the next instruction based on whether current is a branch. - if (instruction instanceof BranchInstruction) { - BranchInstruction branch = (BranchInstruction) instruction; - if (instruction instanceof Select) { - // explore all of the select's targets. the default target is handled below. - Select select = (Select) branch; - InstructionHandle[] targets = select.getTargets(); - for (int i = 0; i < targets.length; i++) { - branchTargets.push(targets[i], stackDepth); - } - // nothing to fall through to. - ih = null; - } else if (!(branch instanceof IfInstruction)) { - // if an instruction that comes back to following PC, - // push next instruction, with stack depth reduced by 1. - if (opcode == Constants.JSR || opcode == Constants.JSR_W) { - branchTargets.push(ih.getNext(), stackDepth - 1); - } - ih = null; - } - // for all branches, the target of the branch is pushed on the branch stack. - // conditional branches have a fall through case, selects don't, and - // jsr/jsr_w return to the next instruction. - branchTargets.push(branch.getTarget(), stackDepth); - } else { - // check for instructions that terminate the method. - if (opcode == Constants.ATHROW || opcode == Constants.RET - || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN)) { - ih = null; - } - } - // normal case, go to the next instruction. - if (ih != null) { - ih = ih.getNext(); - } - // if we have no more instructions, see if there are any deferred branches to explore. - if (ih == null) { - BranchTarget bt = branchTargets.pop(); - if (bt != null) { - ih = bt.target; - stackDepth = bt.stackDepth; - } - } - } - return maxStackDepth; - } - - private List observers; - - - /** Add observer for this object. - */ - public void addObserver( MethodObserver o ) { - if (observers == null) { - observers = new ArrayList(); - } - observers.add(o); - } - - - /** Remove observer for this object. - */ - public void removeObserver( MethodObserver o ) { - if (observers != null) { - observers.remove(o); - } - } - - - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if (observers != null) { - for (Iterator e = observers.iterator(); e.hasNext();) { - ((MethodObserver) e.next()).notify(this); - } - } - } - - - /** - * Return string representation close to declaration format, - * `public static void main(String[]) throws IOException', e.g. - * - * @return String representation of the method. - */ - public final String toString() { - String access = Utility.accessToString(access_flags); - String signature = Type.getMethodSignature(type, arg_types); - signature = Utility.methodSignatureToString(signature, name, access, true, - getLocalVariableTable(cp)); - StringBuffer buf = new StringBuffer(signature); - if (throws_vec.size() > 0) { - for (Iterator e = throws_vec.iterator(); e.hasNext();) { - buf.append("\n\t\tthrows ").append(e.next()); - } - } - return buf.toString(); - } - - - /** @return deep copy of this method - */ - public MethodGen copy( String class_name, ConstantPoolGen cp ) { - Method m = ((MethodGen) clone()).getMethod(); - MethodGen mg = new MethodGen(m, class_name, this.cp); - if (this.cp != cp) { - mg.setConstantPool(cp); - mg.getInstructionList().replaceConstantPool(this.cp, cp); - } - return mg; - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return _cmp; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( BCELComparator comparator ) { - _cmp = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two MethodGen objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals( Object obj ) { - return _cmp.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the method's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return _cmp.hashCode(this); - } + /** + * + */ + private static final long serialVersionUID = 1L; + private String class_name; + private Type[] arg_types; + private String[] arg_names; + private int max_locals; + private int max_stack; + private InstructionList il; + private boolean strip_attributes; + private List variable_vec = new ArrayList(); + private List line_number_vec = new ArrayList(); + private List exception_vec = new ArrayList(); + private List throws_vec = new ArrayList(); + private List code_attrs_vec = new ArrayList(); + private static BCELComparator _cmp = new BCELComparator() { + + @Override + public boolean equals(Object o1, Object o2) { + MethodGen THIS = (MethodGen) o1; + MethodGen THAT = (MethodGen) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } + + @Override + public int hashCode(Object o) { + MethodGen THIS = (MethodGen) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; + + /** + * Declare method. If the method is non-static the constructor automatically + * declares a local variable `$this' in slot 0. The actual code is contained + * in the `il' parameter, which may further manipulated by the user. But he + * must take care not to remove any instruction (handles) that are still + * referenced from this object. + * + * For example one may not add a local variable and later remove the + * instructions it refers to without causing havoc. It is safe however if + * you remove that local variable, too. + * + * @param access_flags + * access qualifiers + * @param return_type + * method type + * @param arg_types + * argument types + * @param arg_names + * argument names (if this is null, default names will be + * provided for them) + * @param method_name + * name of method + * @param class_name + * class name containing this method (may be null, if you don't + * care) + * @param il + * instruction list associated with this method, may be null only + * for abstract or native methods + * @param cp + * constant pool + */ + public MethodGen(int access_flags, Type return_type, Type[] arg_types, + String[] arg_names, String method_name, String class_name, + InstructionList il, ConstantPoolGen cp) { + setAccessFlags(access_flags); + setType(return_type); + setArgumentTypes(arg_types); + setArgumentNames(arg_names); + setName(method_name); + setClassName(class_name); + setInstructionList(il); + setConstantPool(cp); + boolean abstract_ = isAbstract() || isNative(); + InstructionHandle start = null; + InstructionHandle end = null; + if (!abstract_) { + start = il.getStart(); + end = il.getEnd(); + /* + * Add local variables, namely the implicit `this' and the arguments + */ + if (!isStatic() && (class_name != null)) { // Instance method -> + // `this' is local var 0 + addLocalVariable("this", new ObjectType(class_name), start, end); + } + } + if (arg_types != null) { + int size = arg_types.length; + for (int i = 0; i < size; i++) { + if (Type.VOID == arg_types[i]) { + throw new ClassGenException( + "'void' is an illegal argument type for a method"); + } + } + if (arg_names != null) { // Names for variables provided? + if (size != arg_names.length) { + throw new ClassGenException( + "Mismatch in argument array lengths: " + size + + " vs. " + arg_names.length); + } + } else { // Give them dummy names + arg_names = new String[size]; + for (int i = 0; i < size; i++) { + arg_names[i] = "arg" + i; + } + setArgumentNames(arg_names); + } + if (!abstract_) { + for (int i = 0; i < size; i++) { + addLocalVariable(arg_names[i], arg_types[i], start, end); + } + } + } + } + + /** + * Instantiate from existing method. + * + * @param m + * method + * @param class_name + * class name containing this method + * @param cp + * constant pool + */ + public MethodGen(Method m, String class_name, ConstantPoolGen cp) { + this( + m.getAccessFlags(), + Type.getReturnType(m.getSignature()), + Type.getArgumentTypes(m.getSignature()), + null /* may be overridden anyway */ + , + m.getName(), + class_name, + ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0) ? new InstructionList( + m.getCode().getCode()) : null, cp); + Attribute[] attributes = m.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + Attribute a = attributes[i]; + if (a instanceof Code) { + Code c = (Code) a; + setMaxStack(c.getMaxStack()); + setMaxLocals(c.getMaxLocals()); + CodeException[] ces = c.getExceptionTable(); + if (ces != null) { + for (int j = 0; j < ces.length; j++) { + CodeException ce = ces[j]; + int type = ce.getCatchType(); + ObjectType c_type = null; + if (type > 0) { + String cen = m.getConstantPool().getConstantString( + type, Constants.CONSTANT_Class); + c_type = new ObjectType(cen); + } + int end_pc = ce.getEndPC(); + int length = m.getCode().getCode().length; + InstructionHandle end; + if (length == end_pc) { // May happen, because end_pc is + // exclusive + end = il.getEnd(); + } else { + end = il.findHandle(end_pc); + end = end.getPrev(); // Make it inclusive + } + addExceptionHandler(il.findHandle(ce.getStartPC()), + end, il.findHandle(ce.getHandlerPC()), c_type); + } + } + Attribute[] c_attributes = c.getAttributes(); + for (int j = 0; j < c_attributes.length; j++) { + a = c_attributes[j]; + if (a instanceof LineNumberTable) { + LineNumber[] ln = ((LineNumberTable) a) + .getLineNumberTable(); + for (int k = 0; k < ln.length; k++) { + LineNumber l = ln[k]; + InstructionHandle ih = il + .findHandle(l.getStartPC()); + if (ih != null) { + addLineNumber(ih, l.getLineNumber()); + } + } + } else if (a instanceof LocalVariableTable) { + LocalVariable[] lv = ((LocalVariableTable) a) + .getLocalVariableTable(); + removeLocalVariables(); + for (int k = 0; k < lv.length; k++) { + LocalVariable l = lv[k]; + InstructionHandle start = il.findHandle(l + .getStartPC()); + InstructionHandle end = il.findHandle(l + .getStartPC() + l.getLength()); + // Repair malformed handles + if (null == start) { + start = il.getStart(); + } + if (null == end) { + end = il.getEnd(); + } + addLocalVariable(l.getName(), + Type.getType(l.getSignature()), + l.getIndex(), start, end); + } + } else { + addCodeAttribute(a); + } + } + } else if (a instanceof ExceptionTable) { + String[] names = ((ExceptionTable) a).getExceptionNames(); + for (int j = 0; j < names.length; j++) { + addException(names[j]); + } + } else { + addAttribute(a); + } + } + } + + /** + * Adds a local variable to this method. + * + * @param name + * variable name + * @param type + * variable type + * @param slot + * the index of the local variable, if type is long or double, + * the next available index is slot+2 + * @param start + * from where the variable is valid + * @param end + * until where the variable is valid + * @return new local variable object + * @see LocalVariable + */ + public LocalVariableGen addLocalVariable(String name, Type type, int slot, + InstructionHandle start, InstructionHandle end) { + byte t = type.getType(); + if (t != Constants.T_ADDRESS) { + int add = type.getSize(); + if (slot + add > max_locals) { + max_locals = slot + add; + } + LocalVariableGen l = new LocalVariableGen(slot, name, type, start, + end); + int i; + if ((i = variable_vec.indexOf(l)) >= 0) { + variable_vec.set(i, l); + } else { + variable_vec.add(l); + } + return l; + } else { + throw new IllegalArgumentException("Can not use " + type + + " as type for local variable"); + } + } + + /** + * Adds a local variable to this method and assigns an index automatically. + * + * @param name + * variable name + * @param type + * variable type + * @param start + * from where the variable is valid, if this is null, it is valid + * from the start + * @param end + * until where the variable is valid, if this is null, it is + * valid to the end + * @return new local variable object + * @see LocalVariable + */ + public LocalVariableGen addLocalVariable(String name, Type type, + InstructionHandle start, InstructionHandle end) { + return addLocalVariable(name, type, max_locals, start, end); + } + + /** + * Remove a local variable, its slot will not be reused, if you do not use + * addLocalVariable with an explicit index argument. + */ + public void removeLocalVariable(LocalVariableGen l) { + variable_vec.remove(l); + } + + /** + * Remove all local variables. + */ + public void removeLocalVariables() { + variable_vec.clear(); + } + + /** + * Sort local variables by index + */ + private static final void sort(LocalVariableGen[] vars, int l, int r) { + int i = l, j = r; + int m = vars[(l + r) / 2].getIndex(); + LocalVariableGen h; + do { + while (vars[i].getIndex() < m) { + i++; + } + while (m < vars[j].getIndex()) { + j--; + } + if (i <= j) { + h = vars[i]; + vars[i] = vars[j]; + vars[j] = h; // Swap elements + i++; + j--; + } + } while (i <= j); + if (l < j) { + sort(vars, l, j); + } + if (i < r) { + sort(vars, i, r); + } + } + + /* + * If the range of the variable has not been set yet, it will be set to be + * valid from the start to the end of the instruction list. + * + * @return array of declared local variables sorted by index + */ + public LocalVariableGen[] getLocalVariables() { + int size = variable_vec.size(); + LocalVariableGen[] lg = new LocalVariableGen[size]; + variable_vec.toArray(lg); + for (int i = 0; i < size; i++) { + if (lg[i].getStart() == null) { + lg[i].setStart(il.getStart()); + } + if (lg[i].getEnd() == null) { + lg[i].setEnd(il.getEnd()); + } + } + if (size > 1) { + sort(lg, 0, size - 1); + } + return lg; + } + + /** + * @return `LocalVariableTable' attribute of all the local variables of this + * method. + */ + public LocalVariableTable getLocalVariableTable(ConstantPoolGen cp) { + LocalVariableGen[] lg = getLocalVariables(); + int size = lg.length; + LocalVariable[] lv = new LocalVariable[size]; + for (int i = 0; i < size; i++) { + lv[i] = lg[i].getLocalVariable(cp); + } + return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), + 2 + lv.length * 10, lv, cp.getConstantPool()); + } + + /** + * Give an instruction a line number corresponding to the source code line. + * + * @param ih + * instruction to tag + * @return new line number object + * @see LineNumber + */ + public LineNumberGen addLineNumber(InstructionHandle ih, int src_line) { + LineNumberGen l = new LineNumberGen(ih, src_line); + line_number_vec.add(l); + return l; + } + + /** + * Remove a line number. + */ + public void removeLineNumber(LineNumberGen l) { + line_number_vec.remove(l); + } + + /** + * Remove all line numbers. + */ + public void removeLineNumbers() { + line_number_vec.clear(); + } + + /* + * @return array of line numbers + */ + public LineNumberGen[] getLineNumbers() { + LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()]; + line_number_vec.toArray(lg); + return lg; + } + + /** + * @return `LineNumberTable' attribute of all the local variables of this + * method. + */ + public LineNumberTable getLineNumberTable(ConstantPoolGen cp) { + int size = line_number_vec.size(); + LineNumber[] ln = new LineNumber[size]; + try { + for (int i = 0; i < size; i++) { + ln[i] = line_number_vec.get(i).getLineNumber(); + } + } catch (ArrayIndexOutOfBoundsException e) { + } // Never occurs + return new LineNumberTable(cp.addUtf8("LineNumberTable"), + 2 + ln.length * 4, ln, cp.getConstantPool()); + } + + /** + * Add an exception handler, i.e., specify region where a handler is active + * and an instruction where the actual handling is done. + * + * @param start_pc + * Start of region (inclusive) + * @param end_pc + * End of region (inclusive) + * @param handler_pc + * Where handling is done + * @param catch_type + * class type of handled exception or null if any exception is + * handled + * @return new exception handler object + */ + public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc, + InstructionHandle end_pc, InstructionHandle handler_pc, + ObjectType catch_type) { + if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) { + throw new ClassGenException( + "Exception handler target is null instruction"); + } + CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, + catch_type); + exception_vec.add(c); + return c; + } + + /** + * Remove an exception handler. + */ + public void removeExceptionHandler(CodeExceptionGen c) { + exception_vec.remove(c); + } + + /** + * Remove all line numbers. + */ + public void removeExceptionHandlers() { + exception_vec.clear(); + } + + /* + * @return array of declared exception handlers + */ + public CodeExceptionGen[] getExceptionHandlers() { + CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()]; + exception_vec.toArray(cg); + return cg; + } + + /** + * @return code exceptions for `Code' attribute + */ + private CodeException[] getCodeExceptions() { + int size = exception_vec.size(); + CodeException[] c_exc = new CodeException[size]; + try { + for (int i = 0; i < size; i++) { + CodeExceptionGen c = exception_vec.get(i); + c_exc[i] = c.getCodeException(cp); + } + } catch (ArrayIndexOutOfBoundsException e) { + } + return c_exc; + } + + /** + * Add an exception possibly thrown by this method. + * + * @param class_name + * (fully qualified) name of exception + */ + public void addException(String class_name) { + throws_vec.add(class_name); + } + + /** + * Remove an exception. + */ + public void removeException(String c) { + throws_vec.remove(c); + } + + /** + * Remove all exceptions. + */ + public void removeExceptions() { + throws_vec.clear(); + } + + /* + * @return array of thrown exceptions + */ + public String[] getExceptions() { + String[] e = new String[throws_vec.size()]; + throws_vec.toArray(e); + return e; + } + + /** + * @return `Exceptions' attribute of all the exceptions thrown by this + * method. + */ + private ExceptionTable getExceptionTable(ConstantPoolGen cp) { + int size = throws_vec.size(); + int[] ex = new int[size]; + try { + for (int i = 0; i < size; i++) { + ex[i] = cp.addClass(throws_vec.get(i)); + } + } catch (ArrayIndexOutOfBoundsException e) { + } + return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, + cp.getConstantPool()); + } + + /** + * Add an attribute to the code. Currently, the JVM knows about the + * LineNumberTable, LocalVariableTable and StackMap attributes, where the + * former two will be generated automatically and the latter is used for the + * MIDP only. Other attributes will be ignored by the JVM but do no harm. + * + * @param a + * attribute to be added + */ + public void addCodeAttribute(Attribute a) { + code_attrs_vec.add(a); + } + + /** + * Remove a code attribute. + */ + public void removeCodeAttribute(Attribute a) { + code_attrs_vec.remove(a); + } + + /** + * Remove all code attributes. + */ + public void removeCodeAttributes() { + code_attrs_vec.clear(); + } + + /** + * @return all attributes of this method. + */ + public Attribute[] getCodeAttributes() { + Attribute[] attributes = new Attribute[code_attrs_vec.size()]; + code_attrs_vec.toArray(attributes); + return attributes; + } + + /** + * Get method object. Never forget to call setMaxStack() or + * setMaxStack(max), respectively, before calling this method (the same + * applies for max locals). + * + * @return method object + */ + public Method getMethod() { + String signature = getSignature(); + int name_index = cp.addUtf8(name); + int signature_index = cp.addUtf8(signature); + /* + * Also updates positions of instructions, i.e., their indices + */ + byte[] byte_code = null; + if (il != null) { + byte_code = il.getByteCode(); + } + LineNumberTable lnt = null; + LocalVariableTable lvt = null; + /* + * Create LocalVariableTable and LineNumberTable attributes (for + * debuggers, e.g.) + */ + if ((variable_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lvt = getLocalVariableTable(cp)); + } + if ((line_number_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lnt = getLineNumberTable(cp)); + } + Attribute[] code_attrs = getCodeAttributes(); + /* + * Each attribute causes 6 additional header bytes + */ + int attrs_len = 0; + for (int i = 0; i < code_attrs.length; i++) { + attrs_len += (code_attrs[i].getLength() + 6); + } + CodeException[] c_exc = getCodeExceptions(); + int exc_len = c_exc.length * 8; // Every entry takes 8 bytes + Code code = null; + if ((il != null) && !isAbstract() && !isNative()) { + // Remove any stale code attribute + Attribute[] attributes = getAttributes(); + for (int i = 0; i < attributes.length; i++) { + Attribute a = attributes[i]; + if (a instanceof Code) { + removeAttribute(a); + } + } + code = new Code(cp.addUtf8("Code"), 8 + byte_code.length + // prologue + // byte + // code + 2 + exc_len + // exceptions + 2 + attrs_len, // attributes + max_stack, max_locals, byte_code, c_exc, code_attrs, + cp.getConstantPool()); + addAttribute(code); + } + ExceptionTable et = null; + if (throws_vec.size() > 0) { + addAttribute(et = getExceptionTable(cp)); + // Add `Exceptions' if there are "throws" clauses + } + Method m = new Method(access_flags, name_index, signature_index, + getAttributes(), cp.getConstantPool()); + // Undo effects of adding attributes + if (lvt != null) { + removeCodeAttribute(lvt); + } + if (lnt != null) { + removeCodeAttribute(lnt); + } + if (code != null) { + removeAttribute(code); + } + if (et != null) { + removeAttribute(et); + } + return m; + } + + /** + * Remove all NOPs from the instruction list (if possible) and update every + * object refering to them, i.e., branch instructions, local variables and + * exception handlers. + */ + public void removeNOPs() { + if (il != null) { + InstructionHandle next; + /* + * Check branch instructions. + */ + for (InstructionHandle ih = il.getStart(); ih != null; ih = next) { + next = ih.next; + if ((next != null) && (ih.getInstruction() instanceof NOP)) { + try { + il.delete(ih); + } catch (TargetLostException e) { + InstructionHandle[] targets = e.getTargets(); + for (int i = 0; i < targets.length; i++) { + InstructionTargeter[] targeters = targets[i] + .getTargeters(); + for (int j = 0; j < targeters.length; j++) { + targeters[j].updateTarget(targets[i], next); + } + } + } + } + } + } + } + + /** + * Set maximum number of local variables. + */ + public void setMaxLocals(int m) { + max_locals = m; + } + + public int getMaxLocals() { + return max_locals; + } + + /** + * Set maximum stack size for this method. + */ + public void setMaxStack(int m) { + max_stack = m; + } + + public int getMaxStack() { + return max_stack; + } + + /** + * @return class that contains this method + */ + public String getClassName() { + return class_name; + } + + public void setClassName(String class_name) { + this.class_name = class_name; + } + + public void setReturnType(Type return_type) { + setType(return_type); + } + + public Type getReturnType() { + return getType(); + } + + public void setArgumentTypes(Type[] arg_types) { + this.arg_types = arg_types; + } + + public Type[] getArgumentTypes() { + return arg_types.clone(); + } + + public void setArgumentType(int i, Type type) { + arg_types[i] = type; + } + + public Type getArgumentType(int i) { + return arg_types[i]; + } + + public void setArgumentNames(String[] arg_names) { + this.arg_names = arg_names; + } + + public String[] getArgumentNames() { + return arg_names.clone(); + } + + public void setArgumentName(int i, String name) { + arg_names[i] = name; + } + + public String getArgumentName(int i) { + return arg_names[i]; + } + + public InstructionList getInstructionList() { + return il; + } + + public void setInstructionList(InstructionList il) { + this.il = il; + } + + @Override + public String getSignature() { + return Type.getMethodSignature(type, arg_types); + } + + /** + * Computes max. stack size by performing control flow analysis. + */ + public void setMaxStack() { + if (il != null) { + max_stack = getMaxStack(cp, il, getExceptionHandlers()); + } else { + max_stack = 0; + } + } + + /** + * Compute maximum number of local variables. + */ + public void setMaxLocals() { + if (il != null) { + int max = isStatic() ? 0 : 1; + if (arg_types != null) { + for (int i = 0; i < arg_types.length; i++) { + max += arg_types[i].getSize(); + } + } + for (InstructionHandle ih = il.getStart(); ih != null; ih = ih + .getNext()) { + Instruction ins = ih.getInstruction(); + if ((ins instanceof LocalVariableInstruction) + || (ins instanceof RET) || (ins instanceof IINC)) { + int index = ((IndexedInstruction) ins).getIndex() + + ((TypedInstruction) ins).getType(cp).getSize(); + if (index > max) { + max = index; + } + } + } + max_locals = max; + } else { + max_locals = 0; + } + } + + /** + * Do not/Do produce attributes code attributesLineNumberTable and + * LocalVariableTable, like javac -O + */ + public void stripAttributes(boolean flag) { + strip_attributes = flag; + } + + static final class BranchTarget { + + InstructionHandle target; + int stackDepth; + + BranchTarget(InstructionHandle target, int stackDepth) { + this.target = target; + this.stackDepth = stackDepth; + } + } + + static final class BranchStack { + + Stack branchTargets = new Stack(); + Hashtable visitedTargets = new Hashtable(); + + public void push(InstructionHandle target, int stackDepth) { + if (visited(target)) { + return; + } + branchTargets.push(visit(target, stackDepth)); + } + + public BranchTarget pop() { + if (!branchTargets.empty()) { + BranchTarget bt = branchTargets.pop(); + return bt; + } + return null; + } + + private final BranchTarget visit(InstructionHandle target, + int stackDepth) { + BranchTarget bt = new BranchTarget(target, stackDepth); + visitedTargets.put(target, bt); + return bt; + } + + private final boolean visited(InstructionHandle target) { + return (visitedTargets.get(target) != null); + } + } + + /** + * Computes stack usage of an instruction list by performing control flow + * analysis. + * + * @return maximum stack depth used by method + */ + public static int getMaxStack(ConstantPoolGen cp, InstructionList il, + CodeExceptionGen[] et) { + BranchStack branchTargets = new BranchStack(); + /* + * Initially, populate the branch stack with the exception handlers, + * because these aren't (necessarily) branched to explicitly. in each + * case, the stack will have depth 1, containing the exception object. + */ + for (int i = 0; i < et.length; i++) { + InstructionHandle handler_pc = et[i].getHandlerPC(); + if (handler_pc != null) { + branchTargets.push(handler_pc, 1); + } + } + int stackDepth = 0, maxStackDepth = 0; + InstructionHandle ih = il.getStart(); + while (ih != null) { + Instruction instruction = ih.getInstruction(); + short opcode = instruction.getOpcode(); + int delta = instruction.produceStack(cp) + - instruction.consumeStack(cp); + stackDepth += delta; + if (stackDepth > maxStackDepth) { + maxStackDepth = stackDepth; + } + // choose the next instruction based on whether current is a branch. + if (instruction instanceof BranchInstruction) { + BranchInstruction branch = (BranchInstruction) instruction; + if (instruction instanceof Select) { + // explore all of the select's targets. the default target + // is handled below. + Select select = (Select) branch; + InstructionHandle[] targets = select.getTargets(); + for (int i = 0; i < targets.length; i++) { + branchTargets.push(targets[i], stackDepth); + } + // nothing to fall through to. + ih = null; + } else if (!(branch instanceof IfInstruction)) { + // if an instruction that comes back to following PC, + // push next instruction, with stack depth reduced by 1. + if (opcode == Constants.JSR || opcode == Constants.JSR_W) { + branchTargets.push(ih.getNext(), stackDepth - 1); + } + ih = null; + } + // for all branches, the target of the branch is pushed on the + // branch stack. + // conditional branches have a fall through case, selects don't, + // and + // jsr/jsr_w return to the next instruction. + branchTargets.push(branch.getTarget(), stackDepth); + } else { + // check for instructions that terminate the method. + if (opcode == Constants.ATHROW + || opcode == Constants.RET + || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN)) { + ih = null; + } + } + // normal case, go to the next instruction. + if (ih != null) { + ih = ih.getNext(); + } + // if we have no more instructions, see if there are any deferred + // branches to explore. + if (ih == null) { + BranchTarget bt = branchTargets.pop(); + if (bt != null) { + ih = bt.target; + stackDepth = bt.stackDepth; + } + } + } + return maxStackDepth; + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(MethodObserver o) { + if (observers == null) { + observers = new ArrayList(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(MethodObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (Iterator e = observers.iterator(); e.hasNext();) { + e.next().notify(this); + } + } + } + + /** + * Return string representation close to declaration format, `public static + * void main(String[]) throws IOException', e.g. + * + * @return String representation of the method. + */ + @Override + public final String toString() { + String access = Utility.accessToString(access_flags); + String signature = Type.getMethodSignature(type, arg_types); + signature = Utility.methodSignatureToString(signature, name, access, + true, getLocalVariableTable(cp)); + StringBuffer buf = new StringBuffer(signature); + if (throws_vec.size() > 0) { + for (Iterator e = throws_vec.iterator(); e.hasNext();) { + buf.append("\n\t\tthrows ").append(e.next()); + } + } + return buf.toString(); + } + + /** + * @return deep copy of this method + */ + public MethodGen copy(String class_name, ConstantPoolGen cp) { + Method m = ((MethodGen) clone()).getMethod(); + MethodGen mg = new MethodGen(m, class_name, this.cp); + if (this.cp != cp) { + mg.setConstantPool(cp); + mg.getInstructionList().replaceConstantPool(this.cp, cp); + } + return mg; + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + + /** + * @param comparator + * Comparison strategy object + */ + public static void setComparator(BCELComparator comparator) { + _cmp = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * MethodGen objects are said to be equal when their names and signatures + * are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return _cmp.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the method's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); + } } diff --git a/src/org/apache/bcel/generic/MethodObserver.java b/src/org/apache/bcel/generic/MethodObserver.java index dae3bf4..442af3b 100644 --- a/src/org/apache/bcel/generic/MethodObserver.java +++ b/src/org/apache/bcel/generic/MethodObserver.java @@ -17,13 +17,13 @@ package org.apache.bcel.generic; /** - * Implement this interface if you're interested in changes to a MethodGen object - * and register yourself with addObserver(). - * + * Implement this interface if you're interested in changes to a MethodGen + * object and register yourself with addObserver(). + * * @version $Id: MethodObserver.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface MethodObserver { - public void notify( MethodGen method ); + public void notify(MethodGen method); } diff --git a/src/org/apache/bcel/generic/NEW.java b/src/org/apache/bcel/generic/NEW.java index 705a6cd..3c39d51 100644 --- a/src/org/apache/bcel/generic/NEW.java +++ b/src/org/apache/bcel/generic/NEW.java @@ -18,59 +18,69 @@ package org.apache.bcel.generic; import org.apache.bcel.ExceptionConstants; -/** +/** * NEW - Create new object - *
          Stack: ... -> ..., objectref
          - * + * + *
          + * Stack: ... -> ..., objectref
          + * 
          + * * @version $Id: NEW.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class NEW extends CPInstruction implements LoadClass, AllocationInstruction, - ExceptionThrower, StackProducer { +public class NEW extends CPInstruction implements LoadClass, + AllocationInstruction, ExceptionThrower, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - NEW() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + NEW() { + } - public NEW(int index) { - super(org.apache.bcel.Constants.NEW, index); - } + public NEW(int index) { + super(org.apache.bcel.Constants.NEW, index); + } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; + System.arraycopy( + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, + 0, + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.INSTANTIATION_ERROR; + cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; + return cs; + } - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.INSTANTIATION_ERROR; - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - return cs; - } + @Override + public ObjectType getLoadClassType(ConstantPoolGen cpg) { + return (ObjectType) getType(cpg); + } - - public ObjectType getLoadClassType( ConstantPoolGen cpg ) { - return (ObjectType) getType(cpg); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitNEW(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitNEW(this); + } } diff --git a/src/org/apache/bcel/generic/NEWARRAY.java b/src/org/apache/bcel/generic/NEWARRAY.java index 276a4ee..2323811 100644 --- a/src/org/apache/bcel/generic/NEWARRAY.java +++ b/src/org/apache/bcel/generic/NEWARRAY.java @@ -20,101 +20,107 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** - * NEWARRAY - Create new array of basic type (int, short, ...) - *
          Stack: ..., count -> ..., arrayref
          +/** + * NEWARRAY - Create new array of basic type (int, short, ...) + * + *
          + * Stack: ..., count -> ..., arrayref
          + * 
          + * * type must be one of T_INT, T_SHORT, ... * * @version $Id: NEWARRAY.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class NEWARRAY extends Instruction implements AllocationInstruction, ExceptionThrower, - StackProducer { +public class NEWARRAY extends Instruction implements AllocationInstruction, + ExceptionThrower, StackProducer { - private byte type; + /** + * + */ + private static final long serialVersionUID = 1L; + private byte type; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + NEWARRAY() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - NEWARRAY() { - } + public NEWARRAY(byte type) { + super(org.apache.bcel.Constants.NEWARRAY, (short) 2); + this.type = type; + } + public NEWARRAY(BasicType type) { + this(type.getType()); + } - public NEWARRAY(byte type) { - super(org.apache.bcel.Constants.NEWARRAY, (short) 2); - this.type = type; - } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + out.writeByte(type); + } + /** + * @return numeric code for basic element type + */ + public final byte getTypecode() { + return type; + } - public NEWARRAY(BasicType type) { - this(type.getType()); - } + /** + * @return type of constructed array + */ + public final Type getType() { + return new ArrayType(BasicType.getType(type), 1); + } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + + org.apache.bcel.Constants.TYPE_NAMES[type]; + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); - out.writeByte(type); - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + type = bytes.readByte(); + length = 2; + } + @Override + public Class[] getExceptions() { + return new Class[] { org.apache.bcel.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION }; + } - /** - * @return numeric code for basic element type - */ - public final byte getTypecode() { - return type; - } - - - /** - * @return type of constructed array - */ - public final Type getType() { - return new ArrayType(BasicType.getType(type), 1); - } - - - /** - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - return super.toString(verbose) + " " + org.apache.bcel.Constants.TYPE_NAMES[type]; - } - - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - type = bytes.readByte(); - length = 2; - } - - - public Class[] getExceptions() { - return new Class[] { - org.apache.bcel.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION - }; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitNEWARRAY(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitNEWARRAY(this); + } } diff --git a/src/org/apache/bcel/generic/NOP.java b/src/org/apache/bcel/generic/NOP.java index bf69664..2816704 100644 --- a/src/org/apache/bcel/generic/NOP.java +++ b/src/org/apache/bcel/generic/NOP.java @@ -18,26 +18,32 @@ package org.apache.bcel.generic; /** * NOP - Do nothing - * + * * @version $Id: NOP.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class NOP extends Instruction { - public NOP() { - super(org.apache.bcel.Constants.NOP, (short) 1); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public NOP() { + super(org.apache.bcel.Constants.NOP, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitNOP(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitNOP(this); + } } diff --git a/src/org/apache/bcel/generic/NamedAndTyped.java b/src/org/apache/bcel/generic/NamedAndTyped.java index aefa3df..ccfc98f 100644 --- a/src/org/apache/bcel/generic/NamedAndTyped.java +++ b/src/org/apache/bcel/generic/NamedAndTyped.java @@ -19,20 +19,17 @@ package org.apache.bcel.generic; /** * Denote entity that has both name and type. This is true for local variables, * methods and fields. - * + * * @version $Id: NamedAndTyped.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface NamedAndTyped { - public String getName(); + public String getName(); + public Type getType(); - public Type getType(); + public void setName(String name); - - public void setName( String name ); - - - public void setType( Type type ); + public void setType(Type type); } diff --git a/src/org/apache/bcel/generic/ObjectType.java b/src/org/apache/bcel/generic/ObjectType.java index 2db0afa..885fe4f 100644 --- a/src/org/apache/bcel/generic/ObjectType.java +++ b/src/org/apache/bcel/generic/ObjectType.java @@ -20,136 +20,147 @@ import org.apache.bcel.Constants; import org.apache.bcel.Repository; import org.apache.bcel.classfile.JavaClass; -/** +/** * Denotes reference such as java.lang.String. - * + * * @version $Id: ObjectType.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ObjectType extends ReferenceType { - private String class_name; // Class name of type + /** + * + */ + private static final long serialVersionUID = 1L; + private String class_name; // Class name of type + /** + * @param class_name + * fully qualified class name, e.g. java.lang.String + */ + public ObjectType(String class_name) { + super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); + this.class_name = class_name.replace('/', '.'); + } - /** - * @param class_name fully qualified class name, e.g. java.lang.String - */ - public ObjectType(String class_name) { - super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); - this.class_name = class_name.replace('/', '.'); - } + /** + * @return name of referenced class + */ + public String getClassName() { + return class_name; + } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return class_name.hashCode(); + } - /** @return name of referenced class - */ - public String getClassName() { - return class_name; - } + /** + * @return true if both type objects refer to the same class. + */ + @Override + public boolean equals(Object type) { + return (type instanceof ObjectType) ? ((ObjectType) type).class_name + .equals(class_name) : false; + } + /** + * If "this" doesn't reference a class, it references an interface or a + * non-existant entity. + * + * @deprecated this method returns an inaccurate result if the class or + * interface referenced cannot be found: use + * referencesClassExact() instead + */ + @Deprecated + public boolean referencesClass() { + try { + JavaClass jc = Repository.lookupClass(class_name); + return jc.isClass(); + } catch (ClassNotFoundException e) { + return false; + } + } - /** @return a hash code value for the object. - */ - public int hashCode() { - return class_name.hashCode(); - } + /** + * If "this" doesn't reference an interface, it references a class or a + * non-existant entity. + * + * @deprecated this method returns an inaccurate result if the class or + * interface referenced cannot be found: use + * referencesInterfaceExact() instead + */ + @Deprecated + public boolean referencesInterface() { + try { + JavaClass jc = Repository.lookupClass(class_name); + return !jc.isClass(); + } catch (ClassNotFoundException e) { + return false; + } + } + /** + * Return true if this type references a class, false if it references an + * interface. + * + * @return true if the type references a class, false if it references an + * interface + * @throws ClassNotFoundException + * if the class or interface referenced by this type can't be + * found + */ + public boolean referencesClassExact() throws ClassNotFoundException { + JavaClass jc = Repository.lookupClass(class_name); + return jc.isClass(); + } - /** @return true if both type objects refer to the same class. - */ - public boolean equals( Object type ) { - return (type instanceof ObjectType) - ? ((ObjectType) type).class_name.equals(class_name) - : false; - } + /** + * Return true if this type references an interface, false if it references + * a class. + * + * @return true if the type references an interface, false if it references + * a class + * @throws ClassNotFoundException + * if the class or interface referenced by this type can't be + * found + */ + public boolean referencesInterfaceExact() throws ClassNotFoundException { + JavaClass jc = Repository.lookupClass(class_name); + return !jc.isClass(); + } + /** + * Return true if this type is a subclass of given ObjectType. + * + * @throws ClassNotFoundException + * if any of this class's superclasses can't be found + */ + public boolean subclassOf(ObjectType superclass) + throws ClassNotFoundException { + if (this.referencesInterface() || superclass.referencesInterface()) { + return false; + } + return Repository.instanceOf(this.class_name, superclass.class_name); + } - /** - * If "this" doesn't reference a class, it references an interface - * or a non-existant entity. - * @deprecated this method returns an inaccurate result - * if the class or interface referenced cannot - * be found: use referencesClassExact() instead - */ - public boolean referencesClass() { - try { - JavaClass jc = Repository.lookupClass(class_name); - return jc.isClass(); - } catch (ClassNotFoundException e) { - return false; - } - } - - - /** - * If "this" doesn't reference an interface, it references a class - * or a non-existant entity. - * @deprecated this method returns an inaccurate result - * if the class or interface referenced cannot - * be found: use referencesInterfaceExact() instead - */ - public boolean referencesInterface() { - try { - JavaClass jc = Repository.lookupClass(class_name); - return !jc.isClass(); - } catch (ClassNotFoundException e) { - return false; - } - } - - - /** - * Return true if this type references a class, - * false if it references an interface. - * @return true if the type references a class, false if - * it references an interface - * @throws ClassNotFoundException if the class or interface - * referenced by this type can't be found - */ - public boolean referencesClassExact() throws ClassNotFoundException { - JavaClass jc = Repository.lookupClass(class_name); - return jc.isClass(); - } - - - /** - * Return true if this type references an interface, - * false if it references a class. - * @return true if the type references an interface, false if - * it references a class - * @throws ClassNotFoundException if the class or interface - * referenced by this type can't be found - */ - public boolean referencesInterfaceExact() throws ClassNotFoundException { - JavaClass jc = Repository.lookupClass(class_name); - return !jc.isClass(); - } - - - /** - * Return true if this type is a subclass of given ObjectType. - * @throws ClassNotFoundException if any of this class's superclasses - * can't be found - */ - public boolean subclassOf( ObjectType superclass ) throws ClassNotFoundException { - if (this.referencesInterface() || superclass.referencesInterface()) { - return false; - } - return Repository.instanceOf(this.class_name, superclass.class_name); - } - - - /** - * Java Virtual Machine Specification edition 2, 5.4.4 Access Control - * @throws ClassNotFoundException if the class referenced by this type - * can't be found - */ - public boolean accessibleTo( ObjectType accessor ) throws ClassNotFoundException { - JavaClass jc = Repository.lookupClass(class_name); - if (jc.isPublic()) { - return true; - } else { - JavaClass acc = Repository.lookupClass(accessor.class_name); - return acc.getPackageName().equals(jc.getPackageName()); - } - } + /** + * Java Virtual Machine Specification edition 2, 5.4.4 Access Control + * + * @throws ClassNotFoundException + * if the class referenced by this type can't be found + */ + public boolean accessibleTo(ObjectType accessor) + throws ClassNotFoundException { + JavaClass jc = Repository.lookupClass(class_name); + if (jc.isPublic()) { + return true; + } else { + JavaClass acc = Repository.lookupClass(accessor.class_name); + return acc.getPackageName().equals(jc.getPackageName()); + } + } } diff --git a/src/org/apache/bcel/generic/POP.java b/src/org/apache/bcel/generic/POP.java index 0d8c672..58df478 100644 --- a/src/org/apache/bcel/generic/POP.java +++ b/src/org/apache/bcel/generic/POP.java @@ -18,31 +18,39 @@ package org.apache.bcel.generic; /** * POP - Pop top operand stack word - * - *
          Stack: ..., word -> ...
          - * + * + *
          + * Stack: ..., word -> ...
          + * 
          + * * @version $Id: POP.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class POP extends StackInstruction implements PopInstruction { - public POP() { - super(org.apache.bcel.Constants.POP); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public POP() { + super(org.apache.bcel.Constants.POP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitStackInstruction(this); - v.visitPOP(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitStackInstruction(this); + v.visitPOP(this); + } } diff --git a/src/org/apache/bcel/generic/POP2.java b/src/org/apache/bcel/generic/POP2.java index 20b4e7a..685c9e8 100644 --- a/src/org/apache/bcel/generic/POP2.java +++ b/src/org/apache/bcel/generic/POP2.java @@ -18,31 +18,39 @@ package org.apache.bcel.generic; /** * POP2 - Pop two top operand stack words - * - *
          Stack: ..., word2, word1 -> ...
          - * + * + *
          + * Stack: ..., word2, word1 -> ...
          + * 
          + * * @version $Id: POP2.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class POP2 extends StackInstruction implements PopInstruction { - public POP2() { - super(org.apache.bcel.Constants.POP2); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public POP2() { + super(org.apache.bcel.Constants.POP2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitStackInstruction(this); - v.visitPOP2(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitStackInstruction(this); + v.visitPOP2(this); + } } diff --git a/src/org/apache/bcel/generic/PUSH.java b/src/org/apache/bcel/generic/PUSH.java index 3759d13..7fcbafb 100644 --- a/src/org/apache/bcel/generic/PUSH.java +++ b/src/org/apache/bcel/generic/PUSH.java @@ -18,161 +18,171 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; -/** +/** * Wrapper class for push operations, which are implemented either as BIPUSH, * LDC or xCONST_n instructions. - * + * * @version $Id: PUSH.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public final class PUSH implements CompoundInstruction, VariableLengthInstruction, - InstructionConstants { +public final class PUSH implements CompoundInstruction, + VariableLengthInstruction, InstructionConstants { - private Instruction instruction; + private Instruction instruction; + /** + * This constructor also applies for values of type short, char, byte + * + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, int value) { + if ((value >= -1) && (value <= 5)) { + instruction = INSTRUCTIONS[Constants.ICONST_0 + value]; + } else if ((value >= -128) && (value <= 127)) { + instruction = new BIPUSH((byte) value); + } else if ((value >= -32768) && (value <= 32767)) { + instruction = new SIPUSH((short) value); + } else { + instruction = new LDC(cp.addInteger(value)); + } + } - /** - * This constructor also applies for values of type short, char, byte - * - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, int value) { - if ((value >= -1) && (value <= 5)) { - instruction = INSTRUCTIONS[Constants.ICONST_0 + value]; - } else if ((value >= -128) && (value <= 127)) { - instruction = new BIPUSH((byte) value); - } else if ((value >= -32768) && (value <= 32767)) { - instruction = new SIPUSH((short) value); - } else { - instruction = new LDC(cp.addInteger(value)); - } - } + /** + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, boolean value) { + instruction = INSTRUCTIONS[Constants.ICONST_0 + (value ? 1 : 0)]; + } + /** + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, float value) { + if (value == 0.0) { + instruction = FCONST_0; + } else if (value == 1.0) { + instruction = FCONST_1; + } else if (value == 2.0) { + instruction = FCONST_2; + } else { + instruction = new LDC(cp.addFloat(value)); + } + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, boolean value) { - instruction = INSTRUCTIONS[Constants.ICONST_0 + (value ? 1 : 0)]; - } + /** + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, long value) { + if (value == 0) { + instruction = LCONST_0; + } else if (value == 1) { + instruction = LCONST_1; + } else { + instruction = new LDC2_W(cp.addLong(value)); + } + } + /** + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, double value) { + if (value == 0.0) { + instruction = DCONST_0; + } else if (value == 1.0) { + instruction = DCONST_1; + } else { + instruction = new LDC2_W(cp.addDouble(value)); + } + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, float value) { - if (value == 0.0) { - instruction = FCONST_0; - } else if (value == 1.0) { - instruction = FCONST_1; - } else if (value == 2.0) { - instruction = FCONST_2; - } else { - instruction = new LDC(cp.addFloat(value)); - } - } + /** + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, String value) { + if (value == null) { + instruction = ACONST_NULL; + } else { + instruction = new LDC(cp.addString(value)); + } + } + /** + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, Number value) { + if ((value instanceof Integer) || (value instanceof Short) + || (value instanceof Byte)) { + instruction = new PUSH(cp, value.intValue()).instruction; + } else if (value instanceof Double) { + instruction = new PUSH(cp, value.doubleValue()).instruction; + } else if (value instanceof Float) { + instruction = new PUSH(cp, value.floatValue()).instruction; + } else if (value instanceof Long) { + instruction = new PUSH(cp, value.longValue()).instruction; + } else { + throw new ClassGenException("What's this: " + value); + } + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, long value) { - if (value == 0) { - instruction = LCONST_0; - } else if (value == 1) { - instruction = LCONST_1; - } else { - instruction = new LDC2_W(cp.addLong(value)); - } - } + /** + * creates a push object from a Character value. Warning: Make sure not to + * attempt to allow autoboxing to create this value parameter, as an + * alternative constructor will be called + * + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, Character value) { + this(cp, value.charValue()); + } + /** + * @param cp + * Constant pool + * @param value + * to be pushed + */ + public PUSH(ConstantPoolGen cp, Boolean value) { + this(cp, value.booleanValue()); + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, double value) { - if (value == 0.0) { - instruction = DCONST_0; - } else if (value == 1.0) { - instruction = DCONST_1; - } else { - instruction = new LDC2_W(cp.addDouble(value)); - } - } + @Override + public final InstructionList getInstructionList() { + return new InstructionList(instruction); + } + public final Instruction getInstruction() { + return instruction; + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, String value) { - if (value == null) { - instruction = ACONST_NULL; - } else { - instruction = new LDC(cp.addString(value)); - } - } - - - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Number value) { - if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) { - instruction = new PUSH(cp, value.intValue()).instruction; - } else if (value instanceof Double) { - instruction = new PUSH(cp, value.doubleValue()).instruction; - } else if (value instanceof Float) { - instruction = new PUSH(cp, value.floatValue()).instruction; - } else if (value instanceof Long) { - instruction = new PUSH(cp, value.longValue()).instruction; - } else { - throw new ClassGenException("What's this: " + value); - } - } - - - /** - * creates a push object from a Character value. Warning: Make sure not to attempt to allow - * autoboxing to create this value parameter, as an alternative constructor will be called - * - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Character value) { - this(cp, value.charValue()); - } - - - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Boolean value) { - this(cp, value.booleanValue()); - } - - - public final InstructionList getInstructionList() { - return new InstructionList(instruction); - } - - - public final Instruction getInstruction() { - return instruction; - } - - - /** - * @return mnemonic for instruction - */ - public String toString() { - return instruction.toString() + " (PUSH)"; - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString() { + return instruction.toString() + " (PUSH)"; + } } diff --git a/src/org/apache/bcel/generic/PUTFIELD.java b/src/org/apache/bcel/generic/PUTFIELD.java index 6c5b28a..392d954 100644 --- a/src/org/apache/bcel/generic/PUTFIELD.java +++ b/src/org/apache/bcel/generic/PUTFIELD.java @@ -19,62 +19,76 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.ExceptionConstants; -/** +/** * PUTFIELD - Put field in object - *
          Stack: ..., objectref, value -> ...
          + * + *
          + * Stack: ..., objectref, value -> ...
          + * 
          + * * OR - *
          Stack: ..., objectref, value.word1, value.word2 -> ...
          - * + * + *
          + * Stack: ..., objectref, value.word1, value.word2 -> ...
          + * 
          + * * @version $Id: PUTFIELD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class PUTFIELD extends FieldInstruction implements PopInstruction, ExceptionThrower { +public class PUTFIELD extends FieldInstruction implements PopInstruction, + ExceptionThrower { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - PUTFIELD() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + PUTFIELD() { + } - public PUTFIELD(int index) { - super(Constants.PUTFIELD, index); - } + public PUTFIELD(int index) { + super(Constants.PUTFIELD, index); + } + @Override + public int consumeStack(ConstantPoolGen cpg) { + return getFieldSize(cpg) + 1; + } - public int consumeStack( ConstantPoolGen cpg ) { - return getFieldSize(cpg) + 1; - } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; + return cs; + } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitPUTFIELD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitPUTFIELD(this); + } } diff --git a/src/org/apache/bcel/generic/PUTSTATIC.java b/src/org/apache/bcel/generic/PUTSTATIC.java index 5afd569..9ab5689 100644 --- a/src/org/apache/bcel/generic/PUTSTATIC.java +++ b/src/org/apache/bcel/generic/PUTSTATIC.java @@ -19,61 +19,75 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; import org.apache.bcel.ExceptionConstants; -/** +/** * PUTSTATIC - Put static field in class - *
          Stack: ..., value -> ...
          + * + *
          + * Stack: ..., value -> ...
          + * 
          + * * OR - *
          Stack: ..., value.word1, value.word2 -> ...
          - * + * + *
          + * Stack: ..., value.word1, value.word2 -> ...
          + * 
          + * * @version $Id: PUTSTATIC.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class PUTSTATIC extends FieldInstruction implements ExceptionThrower, PopInstruction { +public class PUTSTATIC extends FieldInstruction implements ExceptionThrower, + PopInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - PUTSTATIC() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + PUTSTATIC() { + } - public PUTSTATIC(int index) { - super(Constants.PUTSTATIC, index); - } + public PUTSTATIC(int index) { + super(Constants.PUTSTATIC, index); + } + @Override + public int consumeStack(ConstantPoolGen cpg) { + return getFieldSize(cpg); + } - public int consumeStack( ConstantPoolGen cpg ) { - return getFieldSize(cpg); - } + @Override + public Class[] getExceptions() { + Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, + 0, cs, 0, + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; + return cs; + } - - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0, - ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitPUTSTATIC(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitPUTSTATIC(this); + } } diff --git a/src/org/apache/bcel/generic/PopInstruction.java b/src/org/apache/bcel/generic/PopInstruction.java index 65c81ee..209be34 100644 --- a/src/org/apache/bcel/generic/PopInstruction.java +++ b/src/org/apache/bcel/generic/PopInstruction.java @@ -19,9 +19,9 @@ package org.apache.bcel.generic; /** * Denotes an unparameterized instruction to pop a value on top from the stack, * such as ISTORE, POP, PUTSTATIC. - * + * * @version $Id: PopInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see ISTORE * @see POP */ diff --git a/src/org/apache/bcel/generic/PushInstruction.java b/src/org/apache/bcel/generic/PushInstruction.java index 8a74105..fc94439 100644 --- a/src/org/apache/bcel/generic/PushInstruction.java +++ b/src/org/apache/bcel/generic/PushInstruction.java @@ -17,12 +17,12 @@ package org.apache.bcel.generic; /** - * Denotes an unparameterized instruction to produce a value on top of the stack, - * such as ILOAD, LDC, SIPUSH, DUP, ICONST, etc. - * + * Denotes an unparameterized instruction to produce a value on top of the + * stack, such as ILOAD, LDC, SIPUSH, DUP, ICONST, etc. + * * @version $Id: PushInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - + * @author M. Dahm + * * @see ILOAD * @see ICONST * @see LDC diff --git a/src/org/apache/bcel/generic/RET.java b/src/org/apache/bcel/generic/RET.java index 2182d36..7e4d78a 100644 --- a/src/org/apache/bcel/generic/RET.java +++ b/src/org/apache/bcel/generic/RET.java @@ -20,120 +20,129 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * RET - Return from subroutine - * - *
          Stack: ... -> ...
          - * + * + *
          + * Stack: ... -> ...
          + * 
          + * * @version $Id: RET.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class RET extends Instruction implements IndexedInstruction, TypedInstruction { +public class RET extends Instruction implements IndexedInstruction, + TypedInstruction { - private boolean wide; - private int index; // index to local variable containg the return address + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean wide; + private int index; // index to local variable containg the return address + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + RET() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - RET() { - } + public RET(int index) { + super(org.apache.bcel.Constants.RET, (short) 2); + setIndex(index); // May set wide as side effect + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + if (wide) { + out.writeByte(org.apache.bcel.Constants.WIDE); + } + out.writeByte(opcode); + if (wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } - public RET(int index) { - super(org.apache.bcel.Constants.RET, (short) 2); - setIndex(index); // May set wide as side effect - } + private final void setWide() { + wide = index > org.apache.bcel.Constants.MAX_BYTE; + if (wide) { + length = 4; // Including the wide byte + } else { + length = 2; + } + } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + this.wide = wide; + if (wide) { + index = bytes.readUnsignedShort(); + length = 4; + } else { + index = bytes.readUnsignedByte(); + length = 2; + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - if (wide) { - out.writeByte(org.apache.bcel.Constants.WIDE); - } - out.writeByte(opcode); - if (wide) { - out.writeShort(index); - } else { - out.writeByte(index); - } - } + /** + * @return index of local variable containg the return address + */ + @Override + public final int getIndex() { + return index; + } + /** + * Set index of local variable containg the return address + */ + @Override + public final void setIndex(int n) { + if (n < 0) { + throw new ClassGenException("Negative index value: " + n); + } + index = n; + setWide(); + } - private final void setWide() { - wide = index > org.apache.bcel.Constants.MAX_BYTE; - if (wide) { - length = 4; // Including the wide byte - } else { - length = 2; - } - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + index; + } + /** + * @return return address type + */ + @Override + public Type getType(ConstantPoolGen cp) { + return ReturnaddressType.NO_TARGET; + } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - this.wide = wide; - if (wide) { - index = bytes.readUnsignedShort(); - length = 4; - } else { - index = bytes.readUnsignedByte(); - length = 2; - } - } - - - /** - * @return index of local variable containg the return address - */ - public final int getIndex() { - return index; - } - - - /** - * Set index of local variable containg the return address - */ - public final void setIndex( int n ) { - if (n < 0) { - throw new ClassGenException("Negative index value: " + n); - } - index = n; - setWide(); - } - - - /** - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - return super.toString(verbose) + " " + index; - } - - - /** @return return address type - */ - public Type getType( ConstantPoolGen cp ) { - return ReturnaddressType.NO_TARGET; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitRET(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitRET(this); + } } diff --git a/src/org/apache/bcel/generic/RETURN.java b/src/org/apache/bcel/generic/RETURN.java index 3e71689..e2dc937 100644 --- a/src/org/apache/bcel/generic/RETURN.java +++ b/src/org/apache/bcel/generic/RETURN.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** - * RETURN - Return from void method - *
          Stack: ... -> <empty>
          - * +/** + * RETURN - Return from void method + * + *
          + * Stack: ... -> <empty>
          + * 
          + * * @version $Id: RETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class RETURN extends ReturnInstruction { - public RETURN() { - super(org.apache.bcel.Constants.RETURN); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public RETURN() { + super(org.apache.bcel.Constants.RETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitRETURN(this); + } } diff --git a/src/org/apache/bcel/generic/ReferenceType.java b/src/org/apache/bcel/generic/ReferenceType.java index 605b6e3..b61db28 100644 --- a/src/org/apache/bcel/generic/ReferenceType.java +++ b/src/org/apache/bcel/generic/ReferenceType.java @@ -22,309 +22,364 @@ import org.apache.bcel.classfile.JavaClass; /** * Super class for object and array types. - * + * * @version $Id: ReferenceType.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class ReferenceType extends Type { - protected ReferenceType(byte t, String s) { - super(t, s); - } + /** + * + */ + private static final long serialVersionUID = 1L; + protected ReferenceType(byte t, String s) { + super(t, s); + } - /** Class is non-abstract but not instantiable from the outside - */ - ReferenceType() { - super(Constants.T_OBJECT, ""); - } + /** + * Class is non-abstract but not instantiable from the outside + */ + ReferenceType() { + super(Constants.T_OBJECT, ""); + } + /** + * Return true iff this type is castable to another type t as defined in the + * JVM specification. The case where this is Type.NULL is not defined (see + * the CHECKCAST definition in the JVM specification). However, because e.g. + * CHECKCAST doesn't throw a ClassCastException when casting a null + * reference to any Object, true is returned in this case. + * + * @throws ClassNotFoundException + * if any classes or interfaces required to determine assignment + * compatibility can't be found + */ + public boolean isCastableTo(Type t) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return true; // If this is ever changed in isAssignmentCompatible() + } + return isAssignmentCompatibleWith(t); + /* + * Yes, it's true: It's the same definition. See vmspec2 AASTORE / + * CHECKCAST definitions. + */ + } - /** - * Return true iff this type is castable to another type t as defined in - * the JVM specification. The case where this is Type.NULL is not - * defined (see the CHECKCAST definition in the JVM specification). - * However, because e.g. CHECKCAST doesn't throw a - * ClassCastException when casting a null reference to any Object, - * true is returned in this case. - * - * @throws ClassNotFoundException if any classes or interfaces required - * to determine assignment compatibility can't be found - */ - public boolean isCastableTo( Type t ) throws ClassNotFoundException { - if (this.equals(Type.NULL)) { - return true; // If this is ever changed in isAssignmentCompatible() - } - return isAssignmentCompatibleWith(t); - /* Yes, it's true: It's the same definition. - * See vmspec2 AASTORE / CHECKCAST definitions. - */ - } + /** + * Return true iff this is assignment compatible with another type t as + * defined in the JVM specification; see the AASTORE definition there. + * + * @throws ClassNotFoundException + * if any classes or interfaces required to determine assignment + * compatibility can't be found + */ + public boolean isAssignmentCompatibleWith(Type t) + throws ClassNotFoundException { + if (!(t instanceof ReferenceType)) { + return false; + } + ReferenceType T = (ReferenceType) t; + if (this.equals(Type.NULL)) { + return true; // This is not explicitely stated, but clear. Isn't it? + } + /* + * If this is a class type then + */ + if ((this instanceof ObjectType) + && (((ObjectType) this).referencesClassExact())) { + /* + * If T is a class type, then this must be the same class as T, or + * this must be a subclass of T; + */ + if ((T instanceof ObjectType) + && (((ObjectType) T).referencesClassExact())) { + if (this.equals(T)) { + return true; + } + if (Repository.instanceOf(((ObjectType) this).getClassName(), + ((ObjectType) T).getClassName())) { + return true; + } + } + /* + * If T is an interface type, this must implement interface T. + */ + if ((T instanceof ObjectType) + && (((ObjectType) T).referencesInterfaceExact())) { + if (Repository.implementationOf( + ((ObjectType) this).getClassName(), + ((ObjectType) T).getClassName())) { + return true; + } + } + } + /* + * If this is an interface type, then: + */ + if ((this instanceof ObjectType) + && (((ObjectType) this).referencesInterfaceExact())) { + /* + * If T is a class type, then T must be Object (2.4.7). + */ + if ((T instanceof ObjectType) + && (((ObjectType) T).referencesClassExact())) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + /* + * If T is an interface type, then T must be the same interface as + * this or a superinterface of this (2.13.2). + */ + if ((T instanceof ObjectType) + && (((ObjectType) T).referencesInterfaceExact())) { + if (this.equals(T)) { + return true; + } + if (Repository.implementationOf( + ((ObjectType) this).getClassName(), + ((ObjectType) T).getClassName())) { + return true; + } + } + } + /* + * If this is an array type, namely, the type SC[], that is, an array of + * components of type SC, then: + */ + if (this instanceof ArrayType) { + /* + * If T is a class type, then T must be Object (�2.4.7). + */ + if ((T instanceof ObjectType) + && (((ObjectType) T).referencesClassExact())) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + /* + * If T is an array type TC[], that is, an array of components of + * type TC, then one of the following must be true: + */ + if (T instanceof ArrayType) { + /* + * TC and SC are the same primitive type (�2.4.1). + */ + Type sc = ((ArrayType) this).getElementType(); + Type tc = ((ArrayType) T).getElementType(); + if (sc instanceof BasicType && tc instanceof BasicType + && sc.equals(tc)) { + return true; + } + /* + * TC and SC are reference types (�2.4.6), and type SC is + * assignable to TC by these runtime rules. + */ + if (tc instanceof ReferenceType && sc instanceof ReferenceType + && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { + return true; + } + } + /* + * If T is an interface type, T must be one of the interfaces + * implemented by arrays (�2.15). + */ + // TODO: Check if this is still valid or find a way to dynamically + // find out which + // interfaces arrays implement. However, as of the JVM specification + // edition 2, there + // are at least two different pages where assignment compatibility + // is defined and + // on one of them "interfaces implemented by arrays" is exchanged + // with "'Cloneable' or + // 'java.io.Serializable'" + if ((T instanceof ObjectType) + && (((ObjectType) T).referencesInterfaceExact())) { + for (int ii = 0; ii < Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS.length; ii++) { + if (T.equals(new ObjectType( + Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS[ii]))) { + return true; + } + } + } + } + return false; // default. + } + /** + * This commutative operation returns the first common superclass (narrowest + * ReferenceType referencing a class, not an interface). If one of the types + * is a superclass of the other, the former is returned. If "this" is + * Type.NULL, then t is returned. If t is Type.NULL, then "this" is + * returned. If "this" equals t ['this.equals(t)'] "this" is returned. If + * "this" or t is an ArrayType, then Type.OBJECT is returned; unless their + * dimensions match. Then an ArrayType of the same number of dimensions is + * returned, with its basic type being the first common super class of the + * basic types of "this" and t. If "this" or t is a ReferenceType + * referencing an interface, then Type.OBJECT is returned. If not all of the + * two classes' superclasses cannot be found, "null" is returned. See the + * JVM specification edition 2, "�4.9.2 The Bytecode Verifier". + * + * @throws ClassNotFoundException + * on failure to find superclasses of this type, or the type + * passed as a parameter + */ + public ReferenceType getFirstCommonSuperclass(ReferenceType t) + throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL)) { + return this; + } + if (this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there + * is no object referenced by Type.NULL so we can also say all the + * objects referenced by Type.NULL were derived from + * java.lang.Object. However, the Java Language's "instanceof" + * operator proves us wrong: "null" is not referring to an instance + * of java.lang.Object :) + */ + } + /* + * This code is from a bug report by Konstantin Shagin + * + */ + if ((this instanceof ArrayType) && (t instanceof ArrayType)) { + ArrayType arrType1 = (ArrayType) this; + ArrayType arrType2 = (ArrayType) t; + if ((arrType1.getDimensions() == arrType2.getDimensions()) + && arrType1.getBasicType() instanceof ObjectType + && arrType2.getBasicType() instanceof ObjectType) { + return new ArrayType( + ((ObjectType) arrType1.getBasicType()).getFirstCommonSuperclass((ObjectType) arrType2 + .getBasicType()), arrType1.getDimensions()); + } + } + if ((this instanceof ArrayType) || (t instanceof ArrayType)) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of + // every ArrayType? + } + if (((this instanceof ObjectType) && ((ObjectType) this) + .referencesInterface()) + || ((t instanceof ObjectType) && ((ObjectType) t) + .referencesInterface())) { + return Type.OBJECT; + // TODO: The above line is correct comparing to the vmspec2. But one + // could + // make class file verification a bit stronger here by using the + // notion of + // superinterfaces or even castability or assignment compatibility. + } + // this and t are ObjectTypes, see above. + ObjectType thiz = (ObjectType) this; + ObjectType other = (ObjectType) t; + JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); + JavaClass[] other_sups = Repository.getSuperClasses(other + .getClassName()); + if ((thiz_sups == null) || (other_sups == null)) { + return null; + } + // Waaahh... + JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; + System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); + System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); + this_sups[0] = Repository.lookupClass(thiz.getClassName()); + t_sups[0] = Repository.lookupClass(other.getClassName()); + for (int i = 0; i < t_sups.length; i++) { + for (int j = 0; j < this_sups.length; j++) { + if (this_sups[j].equals(t_sups[i])) { + return new ObjectType(this_sups[j].getClassName()); + } + } + } + // Huh? Did you ask for Type.OBJECT's superclass?? + return null; + } - /** - * Return true iff this is assignment compatible with another type t - * as defined in the JVM specification; see the AASTORE definition - * there. - * @throws ClassNotFoundException if any classes or interfaces required - * to determine assignment compatibility can't be found - */ - public boolean isAssignmentCompatibleWith( Type t ) throws ClassNotFoundException { - if (!(t instanceof ReferenceType)) { - return false; - } - ReferenceType T = (ReferenceType) t; - if (this.equals(Type.NULL)) { - return true; // This is not explicitely stated, but clear. Isn't it? - } - /* If this is a class type then - */ - if ((this instanceof ObjectType) && (((ObjectType) this).referencesClassExact())) { - /* If T is a class type, then this must be the same class as T, - or this must be a subclass of T; - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { - if (this.equals(T)) { - return true; - } - if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T) - .getClassName())) { - return true; - } - } - /* If T is an interface type, this must implement interface T. - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { - if (Repository.implementationOf(((ObjectType) this).getClassName(), - ((ObjectType) T).getClassName())) { - return true; - } - } - } - /* If this is an interface type, then: - */ - if ((this instanceof ObjectType) && (((ObjectType) this).referencesInterfaceExact())) { - /* If T is a class type, then T must be Object (2.4.7). - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { - if (T.equals(Type.OBJECT)) { - return true; - } - } - /* If T is an interface type, then T must be the same interface - * as this or a superinterface of this (2.13.2). - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { - if (this.equals(T)) { - return true; - } - if (Repository.implementationOf(((ObjectType) this).getClassName(), - ((ObjectType) T).getClassName())) { - return true; - } - } - } - /* If this is an array type, namely, the type SC[], that is, an - * array of components of type SC, then: - */ - if (this instanceof ArrayType) { - /* If T is a class type, then T must be Object (�2.4.7). - */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { - if (T.equals(Type.OBJECT)) { - return true; - } - } - /* If T is an array type TC[], that is, an array of components - * of type TC, then one of the following must be true: - */ - if (T instanceof ArrayType) { - /* TC and SC are the same primitive type (�2.4.1). - */ - Type sc = ((ArrayType) this).getElementType(); - Type tc = ((ArrayType) T).getElementType(); - if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) { - return true; - } - /* TC and SC are reference types (�2.4.6), and type SC is - * assignable to TC by these runtime rules. - */ - if (tc instanceof ReferenceType && sc instanceof ReferenceType - && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { - return true; - } - } - /* If T is an interface type, T must be one of the interfaces implemented by arrays (�2.15). */ - // TODO: Check if this is still valid or find a way to dynamically find out which - // interfaces arrays implement. However, as of the JVM specification edition 2, there - // are at least two different pages where assignment compatibility is defined and - // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or - // 'java.io.Serializable'" - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { - for (int ii = 0; ii < Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS.length; ii++) { - if (T.equals(new ObjectType(Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS[ii]))) { - return true; - } - } - } - } - return false; // default. - } - - - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType - * referencing a class, not an interface). - * If one of the types is a superclass of the other, the former is returned. - * If "this" is Type.NULL, then t is returned. - * If t is Type.NULL, then "this" is returned. - * If "this" equals t ['this.equals(t)'] "this" is returned. - * If "this" or t is an ArrayType, then Type.OBJECT is returned; - * unless their dimensions match. Then an ArrayType of the same - * number of dimensions is returned, with its basic type being the - * first common super class of the basic types of "this" and t. - * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. - * If not all of the two classes' superclasses cannot be found, "null" is returned. - * See the JVM specification edition 2, "�4.9.2 The Bytecode Verifier". - * - * @throws ClassNotFoundException on failure to find superclasses of this - * type, or the type passed as a parameter - */ - public ReferenceType getFirstCommonSuperclass( ReferenceType t ) throws ClassNotFoundException { - if (this.equals(Type.NULL)) { - return t; - } - if (t.equals(Type.NULL)) { - return this; - } - if (this.equals(t)) { - return this; - /* - * TODO: Above sounds a little arbitrary. On the other hand, there is - * no object referenced by Type.NULL so we can also say all the objects - * referenced by Type.NULL were derived from java.lang.Object. - * However, the Java Language's "instanceof" operator proves us wrong: - * "null" is not referring to an instance of java.lang.Object :) - */ - } - /* This code is from a bug report by Konstantin Shagin */ - if ((this instanceof ArrayType) && (t instanceof ArrayType)) { - ArrayType arrType1 = (ArrayType) this; - ArrayType arrType2 = (ArrayType) t; - if ((arrType1.getDimensions() == arrType2.getDimensions()) - && arrType1.getBasicType() instanceof ObjectType - && arrType2.getBasicType() instanceof ObjectType) { - return new ArrayType(((ObjectType) arrType1.getBasicType()) - .getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), arrType1 - .getDimensions()); - } - } - if ((this instanceof ArrayType) || (t instanceof ArrayType)) { - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - } - if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) - || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) { - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - } - // this and t are ObjectTypes, see above. - ObjectType thiz = (ObjectType) this; - ObjectType other = (ObjectType) t; - JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - if ((thiz_sups == null) || (other_sups == null)) { - return null; - } - // Waaahh... - JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - for (int i = 0; i < t_sups.length; i++) { - for (int j = 0; j < this_sups.length; j++) { - if (this_sups[j].equals(t_sups[i])) { - return new ObjectType(this_sups[j].getClassName()); - } - } - } - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } - - - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType - * referencing a class, not an interface). - * If one of the types is a superclass of the other, the former is returned. - * If "this" is Type.NULL, then t is returned. - * If t is Type.NULL, then "this" is returned. - * If "this" equals t ['this.equals(t)'] "this" is returned. - * If "this" or t is an ArrayType, then Type.OBJECT is returned. - * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. - * If not all of the two classes' superclasses cannot be found, "null" is returned. - * See the JVM specification edition 2, "�4.9.2 The Bytecode Verifier". - * - * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has - * slightly changed semantics. - * @throws ClassNotFoundException on failure to find superclasses of this - * type, or the type passed as a parameter - */ - public ReferenceType firstCommonSuperclass( ReferenceType t ) throws ClassNotFoundException { - if (this.equals(Type.NULL)) { - return t; - } - if (t.equals(Type.NULL)) { - return this; - } - if (this.equals(t)) { - return this; - /* - * TODO: Above sounds a little arbitrary. On the other hand, there is - * no object referenced by Type.NULL so we can also say all the objects - * referenced by Type.NULL were derived from java.lang.Object. - * However, the Java Language's "instanceof" operator proves us wrong: - * "null" is not referring to an instance of java.lang.Object :) - */ - } - if ((this instanceof ArrayType) || (t instanceof ArrayType)) { - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - } - if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) - || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) { - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - } - // this and t are ObjectTypes, see above. - ObjectType thiz = (ObjectType) this; - ObjectType other = (ObjectType) t; - JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - if ((thiz_sups == null) || (other_sups == null)) { - return null; - } - // Waaahh... - JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - for (int i = 0; i < t_sups.length; i++) { - for (int j = 0; j < this_sups.length; j++) { - if (this_sups[j].equals(t_sups[i])) { - return new ObjectType(this_sups[j].getClassName()); - } - } - } - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } + /** + * This commutative operation returns the first common superclass (narrowest + * ReferenceType referencing a class, not an interface). If one of the types + * is a superclass of the other, the former is returned. If "this" is + * Type.NULL, then t is returned. If t is Type.NULL, then "this" is + * returned. If "this" equals t ['this.equals(t)'] "this" is returned. If + * "this" or t is an ArrayType, then Type.OBJECT is returned. If "this" or t + * is a ReferenceType referencing an interface, then Type.OBJECT is + * returned. If not all of the two classes' superclasses cannot be found, + * "null" is returned. See the JVM specification edition 2, + * "�4.9.2 The Bytecode Verifier". + * + * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has + * slightly changed semantics. + * @throws ClassNotFoundException + * on failure to find superclasses of this type, or the type + * passed as a parameter + */ + @Deprecated + public ReferenceType firstCommonSuperclass(ReferenceType t) + throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL)) { + return this; + } + if (this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there + * is no object referenced by Type.NULL so we can also say all the + * objects referenced by Type.NULL were derived from + * java.lang.Object. However, the Java Language's "instanceof" + * operator proves us wrong: "null" is not referring to an instance + * of java.lang.Object :) + */ + } + if ((this instanceof ArrayType) || (t instanceof ArrayType)) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of + // every ArrayType? + } + if (((this instanceof ObjectType) && ((ObjectType) this) + .referencesInterface()) + || ((t instanceof ObjectType) && ((ObjectType) t) + .referencesInterface())) { + return Type.OBJECT; + // TODO: The above line is correct comparing to the vmspec2. But one + // could + // make class file verification a bit stronger here by using the + // notion of + // superinterfaces or even castability or assignment compatibility. + } + // this and t are ObjectTypes, see above. + ObjectType thiz = (ObjectType) this; + ObjectType other = (ObjectType) t; + JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); + JavaClass[] other_sups = Repository.getSuperClasses(other + .getClassName()); + if ((thiz_sups == null) || (other_sups == null)) { + return null; + } + // Waaahh... + JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; + System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); + System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); + this_sups[0] = Repository.lookupClass(thiz.getClassName()); + t_sups[0] = Repository.lookupClass(other.getClassName()); + for (int i = 0; i < t_sups.length; i++) { + for (int j = 0; j < this_sups.length; j++) { + if (this_sups[j].equals(t_sups[i])) { + return new ObjectType(this_sups[j].getClassName()); + } + } + } + // Huh? Did you ask for Type.OBJECT's superclass?? + return null; + } } diff --git a/src/org/apache/bcel/generic/ReturnInstruction.java b/src/org/apache/bcel/generic/ReturnInstruction.java index cb10a12..509de9e 100644 --- a/src/org/apache/bcel/generic/ReturnInstruction.java +++ b/src/org/apache/bcel/generic/ReturnInstruction.java @@ -21,59 +21,62 @@ import org.apache.bcel.ExceptionConstants; /** * Super class for the xRETURN family of instructions. - * + * * @version $Id: ReturnInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class ReturnInstruction extends Instruction implements ExceptionThrower, - TypedInstruction, StackConsumer { +public abstract class ReturnInstruction extends Instruction implements + ExceptionThrower, TypedInstruction, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ReturnInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ReturnInstruction() { + } - /** - * @param opcode of instruction - */ - protected ReturnInstruction(short opcode) { - super(opcode, (short) 1); - } + /** + * @param opcode + * of instruction + */ + protected ReturnInstruction(short opcode) { + super(opcode, (short) 1); + } + public Type getType() { + switch (opcode) { + case Constants.IRETURN: + return Type.INT; + case Constants.LRETURN: + return Type.LONG; + case Constants.FRETURN: + return Type.FLOAT; + case Constants.DRETURN: + return Type.DOUBLE; + case Constants.ARETURN: + return Type.OBJECT; + case Constants.RETURN: + return Type.VOID; + default: // Never reached + throw new ClassGenException("Unknown type " + opcode); + } + } - public Type getType() { - switch (opcode) { - case Constants.IRETURN: - return Type.INT; - case Constants.LRETURN: - return Type.LONG; - case Constants.FRETURN: - return Type.FLOAT; - case Constants.DRETURN: - return Type.DOUBLE; - case Constants.ARETURN: - return Type.OBJECT; - case Constants.RETURN: - return Type.VOID; - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); - } - } + @Override + public Class[] getExceptions() { + return new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; + } - - public Class[] getExceptions() { - return new Class[] { - ExceptionConstants.ILLEGAL_MONITOR_STATE - }; - } - - - /** @return type associated with the instruction - */ - public Type getType( ConstantPoolGen cp ) { - return getType(); - } + /** + * @return type associated with the instruction + */ + @Override + public Type getType(ConstantPoolGen cp) { + return getType(); + } } diff --git a/src/org/apache/bcel/generic/ReturnaddressType.java b/src/org/apache/bcel/generic/ReturnaddressType.java index 6b272dd..8847ac8 100644 --- a/src/org/apache/bcel/generic/ReturnaddressType.java +++ b/src/org/apache/bcel/generic/ReturnaddressType.java @@ -18,65 +18,69 @@ package org.apache.bcel.generic; import org.apache.bcel.Constants; -/** +/** * Returnaddress, the type JSR or JSR_W instructions push upon the stack. - * + * * see vmspec2 3.3.3 + * * @version $Id: ReturnaddressType.java 386056 2006-03-15 11:31:56Z tcurdt $ * @author Enver Haase */ public class ReturnaddressType extends Type { - public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); - private InstructionHandle returnTarget; + /** + * + */ + private static final long serialVersionUID = 1L; + public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); + private InstructionHandle returnTarget; + /** + * A Returnaddress [that doesn't know where to return to]. + */ + private ReturnaddressType() { + super(Constants.T_ADDRESS, ""); + } - /** - * A Returnaddress [that doesn't know where to return to]. - */ - private ReturnaddressType() { - super(Constants.T_ADDRESS, ""); - } + /** + * Creates a ReturnaddressType object with a target. + */ + public ReturnaddressType(InstructionHandle returnTarget) { + super(Constants.T_ADDRESS, ""); + this.returnTarget = returnTarget; + } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + if (returnTarget == null) { + return 0; + } + return returnTarget.hashCode(); + } - /** - * Creates a ReturnaddressType object with a target. - */ - public ReturnaddressType(InstructionHandle returnTarget) { - super(Constants.T_ADDRESS, ""); - this.returnTarget = returnTarget; - } + /** + * Returns if the two Returnaddresses refer to the same target. + */ + @Override + public boolean equals(Object rat) { + if (!(rat instanceof ReturnaddressType)) { + return false; + } + ReturnaddressType that = (ReturnaddressType) rat; + if (this.returnTarget == null || that.returnTarget == null) { + return that.returnTarget == this.returnTarget; + } + return that.returnTarget.equals(this.returnTarget); + } - - /** @return a hash code value for the object. - */ - public int hashCode() { - if (returnTarget == null) { - return 0; - } - return returnTarget.hashCode(); - } - - - /** - * Returns if the two Returnaddresses refer to the same target. - */ - public boolean equals( Object rat ) { - if (!(rat instanceof ReturnaddressType)) { - return false; - } - ReturnaddressType that = (ReturnaddressType) rat; - if (this.returnTarget == null || that.returnTarget == null) { - return that.returnTarget == this.returnTarget; - } - return that.returnTarget.equals(this.returnTarget); - } - - - /** - * @return the target of this ReturnaddressType - */ - public InstructionHandle getTarget() { - return returnTarget; - } + /** + * @return the target of this ReturnaddressType + */ + public InstructionHandle getTarget() { + return returnTarget; + } } diff --git a/src/org/apache/bcel/generic/SALOAD.java b/src/org/apache/bcel/generic/SALOAD.java index 0665469..1cdf688 100644 --- a/src/org/apache/bcel/generic/SALOAD.java +++ b/src/org/apache/bcel/generic/SALOAD.java @@ -16,33 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * SALOAD - Load short from array - *
          Stack: ..., arrayref, index -> ..., value
          - * + * + *
          + * Stack: ..., arrayref, index -> ..., value
          + * 
          + * * @version $Id: SALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class SALOAD extends ArrayInstruction implements StackProducer { - public SALOAD() { - super(org.apache.bcel.Constants.SALOAD); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public SALOAD() { + super(org.apache.bcel.Constants.SALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitSALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitSALOAD(this); + } } diff --git a/src/org/apache/bcel/generic/SASTORE.java b/src/org/apache/bcel/generic/SASTORE.java index 164ee44..2cab8c0 100644 --- a/src/org/apache/bcel/generic/SASTORE.java +++ b/src/org/apache/bcel/generic/SASTORE.java @@ -18,31 +18,40 @@ package org.apache.bcel.generic; /** * SASTORE - Store into short array - *
          Stack: ..., arrayref, index, value -> ...
          - * + * + *
          + * Stack: ..., arrayref, index, value -> ...
          + * 
          + * * @version $Id: SASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class SASTORE extends ArrayInstruction implements StackConsumer { - public SASTORE() { - super(org.apache.bcel.Constants.SASTORE); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public SASTORE() { + super(org.apache.bcel.Constants.SASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitSASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitSASTORE(this); + } } diff --git a/src/org/apache/bcel/generic/SIPUSH.java b/src/org/apache/bcel/generic/SIPUSH.java index 45cdce0..6647d61 100644 --- a/src/org/apache/bcel/generic/SIPUSH.java +++ b/src/org/apache/bcel/generic/SIPUSH.java @@ -22,82 +22,89 @@ import org.apache.bcel.util.ByteSequence; /** * SIPUSH - Push short - * - *
          Stack: ... -> ..., value
          - * + * + *
          + * Stack: ... -> ..., value
          + * 
          + * * @version $Id: SIPUSH.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class SIPUSH extends Instruction implements ConstantPushInstruction { - private short b; + /** + * + */ + private static final long serialVersionUID = 1L; + private short b; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + SIPUSH() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - SIPUSH() { - } + public SIPUSH(short b) { + super(org.apache.bcel.Constants.SIPUSH, (short) 3); + this.b = b; + } + /** + * Dump instruction as short code to stream out. + */ + @Override + public void dump(DataOutputStream out) throws IOException { + super.dump(out); + out.writeShort(b); + } - public SIPUSH(short b) { - super(org.apache.bcel.Constants.SIPUSH, (short) 3); - this.b = b; - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + return super.toString(verbose) + " " + b; + } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + length = 3; + b = bytes.readShort(); + } - /** - * Dump instruction as short code to stream out. - */ - public void dump( DataOutputStream out ) throws IOException { - super.dump(out); - out.writeShort(b); - } + @Override + public Number getValue() { + return new Integer(b); + } + /** + * @return Type.SHORT + */ + @Override + public Type getType(ConstantPoolGen cp) { + return Type.SHORT; + } - /** - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - return super.toString(verbose) + " " + b; - } - - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - length = 3; - b = bytes.readShort(); - } - - - public Number getValue() { - return new Integer(b); - } - - - /** @return Type.SHORT - */ - public Type getType( ConstantPoolGen cp ) { - return Type.SHORT; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitSIPUSH(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitSIPUSH(this); + } } diff --git a/src/org/apache/bcel/generic/SWAP.java b/src/org/apache/bcel/generic/SWAP.java index a58e6fb..ce28366 100644 --- a/src/org/apache/bcel/generic/SWAP.java +++ b/src/org/apache/bcel/generic/SWAP.java @@ -16,32 +16,42 @@ */ package org.apache.bcel.generic; -/** +/** * SWAP - Swa top operand stack word - *
          Stack: ..., word2, word1 -> ..., word1, word2
          - * + * + *
          + * Stack: ..., word2, word1 -> ..., word1, word2
          + * 
          + * * @version $Id: SWAP.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public class SWAP extends StackInstruction implements StackConsumer, StackProducer { +public class SWAP extends StackInstruction implements StackConsumer, + StackProducer { - public SWAP() { - super(org.apache.bcel.Constants.SWAP); - } + /** + * + */ + private static final long serialVersionUID = 1L; + public SWAP() { + super(org.apache.bcel.Constants.SWAP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitStackInstruction(this); - v.visitSWAP(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitStackInstruction(this); + v.visitSWAP(this); + } } diff --git a/src/org/apache/bcel/generic/SWITCH.java b/src/org/apache/bcel/generic/SWITCH.java index 01982fa..3a8937f 100644 --- a/src/org/apache/bcel/generic/SWITCH.java +++ b/src/org/apache/bcel/generic/SWITCH.java @@ -16,138 +16,138 @@ */ package org.apache.bcel.generic; -/** +/** * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or * TABLESWITCH instruction, depending on whether the match values (int[]) can be * sorted with no gaps between the numbers. - * + * * @version $Id: SWITCH.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class SWITCH implements CompoundInstruction { - private int[] match; - private InstructionHandle[] targets; - private Select instruction; - private int match_length; + private int[] match; + private InstructionHandle[] targets; + private Select instruction; + private int match_length; + /** + * Template for switch() constructs. If the match array can be sorted in + * ascending order with gaps no larger than max_gap between the numbers, a + * TABLESWITCH instruction is generated, and a LOOKUPSWITCH otherwise. The + * former may be more efficient, but needs more space. + * + * Note, that the key array always will be sorted, though we leave the + * original arrays unaltered. + * + * @param match + * array of match values (case 2: ... case 7: ..., etc.) + * @param targets + * the instructions to be branched to for each case + * @param target + * the default target + * @param max_gap + * maximum gap that may between case branches + */ + public SWITCH(int[] match, InstructionHandle[] targets, + InstructionHandle target, int max_gap) { + this.match = match.clone(); + this.targets = targets.clone(); + if ((match_length = match.length) < 2) { + instruction = new TABLESWITCH(match, targets, target); + } else { + sort(0, match_length - 1); + if (matchIsOrdered(max_gap)) { + fillup(max_gap, target); + instruction = new TABLESWITCH(this.match, this.targets, target); + } else { + instruction = new LOOKUPSWITCH(this.match, this.targets, target); + } + } + } - /** - * Template for switch() constructs. If the match array can be - * sorted in ascending order with gaps no larger than max_gap - * between the numbers, a TABLESWITCH instruction is generated, and - * a LOOKUPSWITCH otherwise. The former may be more efficient, but - * needs more space. - * - * Note, that the key array always will be sorted, though we leave - * the original arrays unaltered. - * - * @param match array of match values (case 2: ... case 7: ..., etc.) - * @param targets the instructions to be branched to for each case - * @param target the default target - * @param max_gap maximum gap that may between case branches - */ - public SWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target, int max_gap) { - this.match = (int[]) match.clone(); - this.targets = (InstructionHandle[]) targets.clone(); - if ((match_length = match.length) < 2) { - instruction = new TABLESWITCH(match, targets, target); - } else { - sort(0, match_length - 1); - if (matchIsOrdered(max_gap)) { - fillup(max_gap, target); - instruction = new TABLESWITCH(this.match, this.targets, target); - } else { - instruction = new LOOKUPSWITCH(this.match, this.targets, target); - } - } - } + public SWITCH(int[] match, InstructionHandle[] targets, + InstructionHandle target) { + this(match, targets, target, 1); + } + private final void fillup(int max_gap, InstructionHandle target) { + int max_size = match_length + match_length * max_gap; + int[] m_vec = new int[max_size]; + InstructionHandle[] t_vec = new InstructionHandle[max_size]; + int count = 1; + m_vec[0] = match[0]; + t_vec[0] = targets[0]; + for (int i = 1; i < match_length; i++) { + int prev = match[i - 1]; + int gap = match[i] - prev; + for (int j = 1; j < gap; j++) { + m_vec[count] = prev + j; + t_vec[count] = target; + count++; + } + m_vec[count] = match[i]; + t_vec[count] = targets[i]; + count++; + } + match = new int[count]; + targets = new InstructionHandle[count]; + System.arraycopy(m_vec, 0, match, 0, count); + System.arraycopy(t_vec, 0, targets, 0, count); + } - public SWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) { - this(match, targets, target, 1); - } + /** + * Sort match and targets array with QuickSort. + */ + private final void sort(int l, int r) { + int i = l, j = r; + int h, m = match[(l + r) / 2]; + InstructionHandle h2; + do { + while (match[i] < m) { + i++; + } + while (m < match[j]) { + j--; + } + if (i <= j) { + h = match[i]; + match[i] = match[j]; + match[j] = h; // Swap elements + h2 = targets[i]; + targets[i] = targets[j]; + targets[j] = h2; // Swap instructions, too + i++; + j--; + } + } while (i <= j); + if (l < j) { + sort(l, j); + } + if (i < r) { + sort(i, r); + } + } + /** + * @return match is sorted in ascending order with no gap bigger than + * max_gap? + */ + private final boolean matchIsOrdered(int max_gap) { + for (int i = 1; i < match_length; i++) { + if (match[i] - match[i - 1] > max_gap) { + return false; + } + } + return true; + } - private final void fillup( int max_gap, InstructionHandle target ) { - int max_size = match_length + match_length * max_gap; - int[] m_vec = new int[max_size]; - InstructionHandle[] t_vec = new InstructionHandle[max_size]; - int count = 1; - m_vec[0] = match[0]; - t_vec[0] = targets[0]; - for (int i = 1; i < match_length; i++) { - int prev = match[i - 1]; - int gap = match[i] - prev; - for (int j = 1; j < gap; j++) { - m_vec[count] = prev + j; - t_vec[count] = target; - count++; - } - m_vec[count] = match[i]; - t_vec[count] = targets[i]; - count++; - } - match = new int[count]; - targets = new InstructionHandle[count]; - System.arraycopy(m_vec, 0, match, 0, count); - System.arraycopy(t_vec, 0, targets, 0, count); - } + @Override + public final InstructionList getInstructionList() { + return new InstructionList(instruction); + } - - /** - * Sort match and targets array with QuickSort. - */ - private final void sort( int l, int r ) { - int i = l, j = r; - int h, m = match[(l + r) / 2]; - InstructionHandle h2; - do { - while (match[i] < m) { - i++; - } - while (m < match[j]) { - j--; - } - if (i <= j) { - h = match[i]; - match[i] = match[j]; - match[j] = h; // Swap elements - h2 = targets[i]; - targets[i] = targets[j]; - targets[j] = h2; // Swap instructions, too - i++; - j--; - } - } while (i <= j); - if (l < j) { - sort(l, j); - } - if (i < r) { - sort(i, r); - } - } - - - /** - * @return match is sorted in ascending order with no gap bigger than max_gap? - */ - private final boolean matchIsOrdered( int max_gap ) { - for (int i = 1; i < match_length; i++) { - if (match[i] - match[i - 1] > max_gap) { - return false; - } - } - return true; - } - - - public final InstructionList getInstructionList() { - return new InstructionList(instruction); - } - - - public final Instruction getInstruction() { - return instruction; - } + public final Instruction getInstruction() { + return instruction; + } } diff --git a/src/org/apache/bcel/generic/Select.java b/src/org/apache/bcel/generic/Select.java index 213a674..19213d4 100644 --- a/src/org/apache/bcel/generic/Select.java +++ b/src/org/apache/bcel/generic/Select.java @@ -20,217 +20,235 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions. * - *

          We use our super's target property as the default target. - * + *

          + * We use our super's target property as the default target. + * * @version $Id: Select.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see LOOKUPSWITCH * @see TABLESWITCH * @see InstructionList */ -public abstract class Select extends BranchInstruction implements VariableLengthInstruction, - StackProducer { +public abstract class Select extends BranchInstruction implements + VariableLengthInstruction, StackProducer { - protected int[] match; // matches, i.e., case 1: ... - protected int[] indices; // target offsets - protected InstructionHandle[] targets; // target objects in instruction list - protected int fixed_length; // fixed length defined by subclasses - protected int match_length; // number of cases - protected int padding = 0; // number of pad bytes for alignment + /** + * + */ + private static final long serialVersionUID = 1L; + protected int[] match; // matches, i.e., case 1: ... + protected int[] indices; // target offsets + protected InstructionHandle[] targets; // target objects in instruction list + protected int fixed_length; // fixed length defined by subclasses + protected int match_length; // number of cases + protected int padding = 0; // number of pad bytes for alignment + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + Select() { + } - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - Select() { - } + /** + * (Match, target) pairs for switch. `Match' and `targets' must have the + * same length of course. + * + * @param match + * array of matching values + * @param targets + * instruction targets + * @param defaultTarget + * default instruction target + */ + Select(short opcode, int[] match, InstructionHandle[] targets, + InstructionHandle defaultTarget) { + super(opcode, defaultTarget); + this.targets = targets; + for (int i = 0; i < targets.length; i++) { + notifyTarget(null, targets[i], this); + } + this.match = match; + if ((match_length = match.length) != targets.length) { + throw new ClassGenException( + "Match and target array have not the same length"); + } + indices = new int[match_length]; + } + /** + * Since this is a variable length instruction, it may shift the following + * instructions which then need to update their position. + * + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset + * additional offset caused by preceding (variable length) + * instructions + * @param max_offset + * the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + @Override + protected int updatePosition(int offset, int max_offset) { + position += offset; // Additional offset caused by preceding SWITCHs, + // GOTOs, etc. + short old_length = length; + /* + * Alignment on 4-byte-boundary, + 1, because of tag byte. + */ + padding = (4 - ((position + 1) % 4)) % 4; + length = (short) (fixed_length + padding); // Update length + return length - old_length; + } - /** - * (Match, target) pairs for switch. - * `Match' and `targets' must have the same length of course. - * - * @param match array of matching values - * @param targets instruction targets - * @param defaultTarget default instruction target - */ - Select(short opcode, int[] match, InstructionHandle[] targets, InstructionHandle defaultTarget) { - super(opcode, defaultTarget); - this.targets = targets; - for (int i = 0; i < targets.length; i++) { - notifyTarget(null, targets[i], this); - } - this.match = match; - if ((match_length = match.length) != targets.length) { - throw new ClassGenException("Match and target array have not the same length"); - } - indices = new int[match_length]; - } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + out.writeByte(opcode); + for (int i = 0; i < padding; i++) { + out.writeByte(0); + } + index = getTargetOffset(); // Write default target offset + out.writeInt(index); + } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad + // bytes + for (int i = 0; i < padding; i++) { + bytes.readByte(); + } + // Default branch target common for both cases (TABLESWITCH, + // LOOKUPSWITCH) + index = bytes.readInt(); + } - /** - * Since this is a variable length instruction, it may shift the following - * instructions which then need to update their position. - * - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition( int offset, int max_offset ) { - position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc. - short old_length = length; - /* Alignment on 4-byte-boundary, + 1, because of tag byte. - */ - padding = (4 - ((position + 1) % 4)) % 4; - length = (short) (fixed_length + padding); // Update length - return length - old_length; - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(boolean verbose) { + StringBuffer buf = new StringBuffer(super.toString(verbose)); + if (verbose) { + for (int i = 0; i < match_length; i++) { + String s = "null"; + if (targets[i] != null) { + s = targets[i].getInstruction().toString(); + } + buf.append("(").append(match[i]).append(", ").append(s) + .append(" = {").append(indices[i]).append("})"); + } + } else { + buf.append(" ..."); + } + return buf.toString(); + } + /** + * Set branch target for `i'th case + */ + public void setTarget(int i, InstructionHandle target) { + notifyTarget(targets[i], target, this); + targets[i] = target; + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - out.writeByte(opcode); - for (int i = 0; i < padding; i++) { - out.writeByte(0); - } - index = getTargetOffset(); // Write default target offset - out.writeInt(index); - } + /** + * @param old_ih + * old target + * @param new_ih + * new target + */ + @Override + public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { + boolean targeted = false; + if (target == old_ih) { + targeted = true; + setTarget(new_ih); + } + for (int i = 0; i < targets.length; i++) { + if (targets[i] == old_ih) { + targeted = true; + setTarget(i, new_ih); + } + } + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih); + } + } + /** + * @return true, if ih is target of this instruction + */ + @Override + public boolean containsTarget(InstructionHandle ih) { + if (target == ih) { + return true; + } + for (int i = 0; i < targets.length; i++) { + if (targets[i] == ih) { + return true; + } + } + return false; + } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes - for (int i = 0; i < padding; i++) { - bytes.readByte(); - } - // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH) - index = bytes.readInt(); - } + @Override + protected Object clone() throws CloneNotSupportedException { + Select copy = (Select) super.clone(); + copy.match = match.clone(); + copy.indices = indices.clone(); + copy.targets = targets.clone(); + return copy; + } + /** + * Inform targets that they're not targeted anymore. + */ + @Override + void dispose() { + super.dispose(); + for (int i = 0; i < targets.length; i++) { + targets[i].removeTargeter(this); + } + } - /** - * @return mnemonic for instruction - */ - public String toString( boolean verbose ) { - StringBuffer buf = new StringBuffer(super.toString(verbose)); - if (verbose) { - for (int i = 0; i < match_length; i++) { - String s = "null"; - if (targets[i] != null) { - s = targets[i].getInstruction().toString(); - } - buf.append("(").append(match[i]).append(", ").append(s).append(" = {").append( - indices[i]).append("})"); - } - } else { - buf.append(" ..."); - } - return buf.toString(); - } + /** + * @return array of match indices + */ + public int[] getMatchs() { + return match; + } + /** + * @return array of match target offsets + */ + public int[] getIndices() { + return indices; + } - /** - * Set branch target for `i'th case - */ - public void setTarget( int i, InstructionHandle target ) { - notifyTarget(targets[i], target, this); - targets[i] = target; - } - - - /** - * @param old_ih old target - * @param new_ih new target - */ - public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { - boolean targeted = false; - if (target == old_ih) { - targeted = true; - setTarget(new_ih); - } - for (int i = 0; i < targets.length; i++) { - if (targets[i] == old_ih) { - targeted = true; - setTarget(i, new_ih); - } - } - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih); - } - } - - - /** - * @return true, if ih is target of this instruction - */ - public boolean containsTarget( InstructionHandle ih ) { - if (target == ih) { - return true; - } - for (int i = 0; i < targets.length; i++) { - if (targets[i] == ih) { - return true; - } - } - return false; - } - - - protected Object clone() throws CloneNotSupportedException { - Select copy = (Select) super.clone(); - copy.match = (int[]) match.clone(); - copy.indices = (int[]) indices.clone(); - copy.targets = (InstructionHandle[]) targets.clone(); - return copy; - } - - - /** - * Inform targets that they're not targeted anymore. - */ - void dispose() { - super.dispose(); - for (int i = 0; i < targets.length; i++) { - targets[i].removeTargeter(this); - } - } - - - /** - * @return array of match indices - */ - public int[] getMatchs() { - return match; - } - - - /** - * @return array of match target offsets - */ - public int[] getIndices() { - return indices; - } - - - /** - * @return array of match targets - */ - public InstructionHandle[] getTargets() { - return targets; - } + /** + * @return array of match targets + */ + public InstructionHandle[] getTargets() { + return targets; + } } diff --git a/src/org/apache/bcel/generic/StackConsumer.java b/src/org/apache/bcel/generic/StackConsumer.java index a7689fa..e1460ad 100644 --- a/src/org/apache/bcel/generic/StackConsumer.java +++ b/src/org/apache/bcel/generic/StackConsumer.java @@ -18,13 +18,14 @@ package org.apache.bcel.generic; /** * Denote an instruction that may consume a value from the stack. - * + * * @version $Id: StackConsumer.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface StackConsumer { - /** @return how many words are consumed from stack - */ - public int consumeStack( ConstantPoolGen cpg ); + /** + * @return how many words are consumed from stack + */ + public int consumeStack(ConstantPoolGen cpg); } diff --git a/src/org/apache/bcel/generic/StackInstruction.java b/src/org/apache/bcel/generic/StackInstruction.java index 1b232b7..277bffd 100644 --- a/src/org/apache/bcel/generic/StackInstruction.java +++ b/src/org/apache/bcel/generic/StackInstruction.java @@ -18,31 +18,36 @@ package org.apache.bcel.generic; /** * Super class for stack operations like DUP and POP. - * + * * @version $Id: StackInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class StackInstruction extends Instruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - StackInstruction() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + StackInstruction() { + } - /** - * @param opcode instruction opcode - */ - protected StackInstruction(short opcode) { - super(opcode, (short) 1); - } + /** + * @param opcode + * instruction opcode + */ + protected StackInstruction(short opcode) { + super(opcode, (short) 1); + } - - /** @return Type.UNKNOWN - */ - public Type getType( ConstantPoolGen cp ) { - return Type.UNKNOWN; - } + /** + * @return Type.UNKNOWN + */ + public Type getType(ConstantPoolGen cp) { + return Type.UNKNOWN; + } } diff --git a/src/org/apache/bcel/generic/StackProducer.java b/src/org/apache/bcel/generic/StackProducer.java index dab3fd8..783b3d4 100644 --- a/src/org/apache/bcel/generic/StackProducer.java +++ b/src/org/apache/bcel/generic/StackProducer.java @@ -17,15 +17,16 @@ package org.apache.bcel.generic; /** - * Denote an instruction that may produce a value on top of the stack - * (this excludes DUP_X1, e.g.) - * + * Denote an instruction that may produce a value on top of the stack (this + * excludes DUP_X1, e.g.) + * * @version $Id: StackProducer.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface StackProducer { - /** @return how many words are produced on stack - */ - public int produceStack( ConstantPoolGen cpg ); + /** + * @return how many words are produced on stack + */ + public int produceStack(ConstantPoolGen cpg); } diff --git a/src/org/apache/bcel/generic/StoreInstruction.java b/src/org/apache/bcel/generic/StoreInstruction.java index 0dc2e6f..1b3ae70 100644 --- a/src/org/apache/bcel/generic/StoreInstruction.java +++ b/src/org/apache/bcel/generic/StoreInstruction.java @@ -17,47 +17,56 @@ package org.apache.bcel.generic; /** - * Denotes an unparameterized instruction to store a value into a local variable, - * e.g. ISTORE. - * + * Denotes an unparameterized instruction to store a value into a local + * variable, e.g. ISTORE. + * * @version $Id: StoreInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ -public abstract class StoreInstruction extends LocalVariableInstruction implements PopInstruction { +public abstract class StoreInstruction extends LocalVariableInstruction + implements PopInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - StoreInstruction(short canon_tag, short c_tag) { - super(canon_tag, c_tag); - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. tag and length + * are defined in readInstruction and initFromFile, respectively. + */ + StoreInstruction(short canon_tag, short c_tag) { + super(canon_tag, c_tag); + } - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ASTORE_0, e.g. - * @param n local variable index (unsigned short) - */ - protected StoreInstruction(short opcode, short c_tag, int n) { - super(opcode, c_tag, n); - } + /** + * @param opcode + * Instruction opcode + * @param c_tag + * Instruction number for compact version, ASTORE_0, e.g. + * @param n + * local variable index (unsigned short) + */ + protected StoreInstruction(short opcode, short c_tag, int n) { + super(opcode, c_tag, n); + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLocalVariableInstruction(this); - v.visitStoreInstruction(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLocalVariableInstruction(this); + v.visitStoreInstruction(this); + } } diff --git a/src/org/apache/bcel/generic/TABLESWITCH.java b/src/org/apache/bcel/generic/TABLESWITCH.java index 58f2d49..eb0677c 100644 --- a/src/org/apache/bcel/generic/TABLESWITCH.java +++ b/src/org/apache/bcel/generic/TABLESWITCH.java @@ -20,88 +20,103 @@ import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.util.ByteSequence; -/** +/** * TABLESWITCH - Switch within given range of values, i.e., low..high - * + * * @version $Id: TABLESWITCH.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm * @see SWITCH */ public class TABLESWITCH extends Select { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - TABLESWITCH() { - } + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + TABLESWITCH() { + } - /** - * @param match sorted array of match values, match[0] must be low value, - * match[match_length - 1] high value - * @param targets where to branch for matched values - * @param defaultTarget default branch - */ - public TABLESWITCH(int[] match, InstructionHandle[] targets, InstructionHandle defaultTarget) { - super(org.apache.bcel.Constants.TABLESWITCH, match, targets, defaultTarget); - length = (short) (13 + match_length * 4); /* Alignment remainder assumed - * 0 here, until dump time */ - fixed_length = length; - } + /** + * @param match + * sorted array of match values, match[0] must be low value, + * match[match_length - 1] high value + * @param targets + * where to branch for matched values + * @param defaultTarget + * default branch + */ + public TABLESWITCH(int[] match, InstructionHandle[] targets, + InstructionHandle defaultTarget) { + super(org.apache.bcel.Constants.TABLESWITCH, match, targets, + defaultTarget); + length = (short) (13 + match_length * 4); /* + * Alignment remainder assumed 0 + * here, until dump time + */ + fixed_length = length; + } + /** + * Dump instruction as byte code to stream out. + * + * @param out + * Output stream + */ + @Override + public void dump(DataOutputStream out) throws IOException { + super.dump(out); + int low = (match_length > 0) ? match[0] : 0; + out.writeInt(low); + int high = (match_length > 0) ? match[match_length - 1] : 0; + out.writeInt(high); + for (int i = 0; i < match_length; i++) { + out.writeInt(indices[i] = getTargetOffset(targets[i])); + } + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( DataOutputStream out ) throws IOException { - super.dump(out); - int low = (match_length > 0) ? match[0] : 0; - out.writeInt(low); - int high = (match_length > 0) ? match[match_length - 1] : 0; - out.writeInt(high); - for (int i = 0; i < match_length; i++) { - out.writeInt(indices[i] = getTargetOffset(targets[i])); - } - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(ByteSequence bytes, boolean wide) + throws IOException { + super.initFromFile(bytes, wide); + int low = bytes.readInt(); + int high = bytes.readInt(); + match_length = high - low + 1; + fixed_length = (short) (13 + match_length * 4); + length = (short) (fixed_length + padding); + match = new int[match_length]; + indices = new int[match_length]; + targets = new InstructionHandle[match_length]; + for (int i = low; i <= high; i++) { + match[i - low] = i; + } + for (int i = 0; i < match_length; i++) { + indices[i] = bytes.readInt(); + } + } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - super.initFromFile(bytes, wide); - int low = bytes.readInt(); - int high = bytes.readInt(); - match_length = high - low + 1; - fixed_length = (short) (13 + match_length * 4); - length = (short) (fixed_length + padding); - match = new int[match_length]; - indices = new int[match_length]; - targets = new InstructionHandle[match_length]; - for (int i = low; i <= high; i++) { - match[i - low] = i; - } - for (int i = 0; i < match_length; i++) { - indices[i] = bytes.readInt(); - } - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept( Visitor v ) { - v.visitVariableLengthInstruction(this); - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitTABLESWITCH(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v + * Visitor object + */ + @Override + public void accept(Visitor v) { + v.visitVariableLengthInstruction(this); + v.visitStackProducer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitTABLESWITCH(this); + } } diff --git a/src/org/apache/bcel/generic/TargetLostException.java b/src/org/apache/bcel/generic/TargetLostException.java index 051d0ee..42d00b6 100644 --- a/src/org/apache/bcel/generic/TargetLostException.java +++ b/src/org/apache/bcel/generic/TargetLostException.java @@ -20,48 +20,51 @@ package org.apache.bcel.generic; * Thrown by InstructionList.remove() when one or multiple disposed instruction * are still being referenced by a InstructionTargeter object. I.e. the * InstructionTargeter has to be notified that (one of) the InstructionHandle it - * is referencing is being removed from the InstructionList and thus not valid anymore. - * + * is referencing is being removed from the InstructionList and thus not valid + * anymore. + * * Making this an exception instead of a return value forces the user to handle * these case explicitely in a try { ... } catch. The following code illustrates * how this may be done: - * + * *

            *     ...
            *     try {
          - *	il.delete(start_ih, end_ih);
          + * il.delete(start_ih, end_ih);
            *     } catch(TargetLostException e) {
            *       InstructionHandle[] targets = e.getTargets();
          - *	 for(int i=0; i < targets.length; i++) {
          - *	   InstructionTargeter[] targeters = targets[i].getTargeters();
          + *  for(int i=0; i < targets.length; i++) {
          + *    InstructionTargeter[] targeters = targets[i].getTargeters();
            *     
          - *	   for(int j=0; j < targeters.length; j++)
          - *	     targeters[j].updateTarget(targets[i], new_target);
          + *    for(int j=0; j < targeters.length; j++)
          + *      targeters[j].updateTarget(targets[i], new_target);
            *       }
            *     }
            * 
          - * + * * @see InstructionHandle * @see InstructionList * @see InstructionTargeter * @version $Id: TargetLostException.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class TargetLostException extends Exception { - private InstructionHandle[] targets; + /** + * + */ + private static final long serialVersionUID = 1L; + private InstructionHandle[] targets; + TargetLostException(InstructionHandle[] t, String mesg) { + super(mesg); + targets = t; + } - TargetLostException(InstructionHandle[] t, String mesg) { - super(mesg); - targets = t; - } - - - /** - * @return list of instructions still being targeted. - */ - public InstructionHandle[] getTargets() { - return targets; - } + /** + * @return list of instructions still being targeted. + */ + public InstructionHandle[] getTargets() { + return targets; + } } diff --git a/src/org/apache/bcel/generic/Type.java b/src/org/apache/bcel/generic/Type.java index 91b2b98..5cd5ad7 100644 --- a/src/org/apache/bcel/generic/Type.java +++ b/src/org/apache/bcel/generic/Type.java @@ -18,293 +18,323 @@ package org.apache.bcel.generic; import java.util.ArrayList; import java.util.List; + import org.apache.bcel.Constants; import org.apache.bcel.classfile.ClassFormatException; import org.apache.bcel.classfile.Utility; -/** - * Abstract super class for all possible java types, namely basic types - * such as int, object types like String and array types, e.g. int[] - * +/** + * Abstract super class for all possible java types, namely basic types such as + * int, object types like String and array types, e.g. int[] + * * @version $Id: Type.java 393344 2006-04-12 00:38:34Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public abstract class Type implements java.io.Serializable { - protected byte type; - protected String signature; // signature for the type - /** Predefined constants - */ - public static final BasicType VOID = new BasicType(Constants.T_VOID); - public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); - public static final BasicType INT = new BasicType(Constants.T_INT); - public static final BasicType SHORT = new BasicType(Constants.T_SHORT); - public static final BasicType BYTE = new BasicType(Constants.T_BYTE); - public static final BasicType LONG = new BasicType(Constants.T_LONG); - public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); - public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); - public static final BasicType CHAR = new BasicType(Constants.T_CHAR); - public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); - public static final ObjectType CLASS = new ObjectType("java.lang.Class"); - public static final ObjectType STRING = new ObjectType("java.lang.String"); - public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); - public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); - public static final Type[] NO_ARGS = new Type[0]; - public static final ReferenceType NULL = new ReferenceType() { - }; - public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, "") { - }; + /** + * + */ + private static final long serialVersionUID = 1L; + protected byte type; + protected String signature; // signature for the type + /** + * Predefined constants + */ + public static final BasicType VOID = new BasicType(Constants.T_VOID); + public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); + public static final BasicType INT = new BasicType(Constants.T_INT); + public static final BasicType SHORT = new BasicType(Constants.T_SHORT); + public static final BasicType BYTE = new BasicType(Constants.T_BYTE); + public static final BasicType LONG = new BasicType(Constants.T_LONG); + public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); + public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); + public static final BasicType CHAR = new BasicType(Constants.T_CHAR); + public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); + public static final ObjectType CLASS = new ObjectType("java.lang.Class"); + public static final ObjectType STRING = new ObjectType("java.lang.String"); + public static final ObjectType STRINGBUFFER = new ObjectType( + "java.lang.StringBuffer"); + public static final ObjectType THROWABLE = new ObjectType( + "java.lang.Throwable"); + public static final Type[] NO_ARGS = new Type[0]; + public static final ReferenceType NULL = new ReferenceType() { + /** + * + */ + private static final long serialVersionUID = 1L; + }; + public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, + "") { - protected Type(byte t, String s) { - type = t; - signature = s; - } + /** + * + */ + private static final long serialVersionUID = 1L; + }; + protected Type(byte t, String s) { + type = t; + signature = s; + } - /** - * @return hashcode of Type - */ - public int hashCode() { - return type ^ signature.hashCode(); - } - - - /** - * @return whether the Types are equal - */ - public boolean equals(Object o) { - if (o instanceof Type) { - Type t = (Type)o; - return (type == t.type) && signature.equals(t.signature); - } - return false; - } - - - /** - * @return signature for given type. - */ - public String getSignature() { - return signature; - } + /** + * @return hashcode of Type + */ + @Override + public int hashCode() { + return type ^ signature.hashCode(); + } + /** + * @return whether the Types are equal + */ + @Override + public boolean equals(Object o) { + if (o instanceof Type) { + Type t = (Type) o; + return (type == t.type) && signature.equals(t.signature); + } + return false; + } - /** - * @return type as defined in Constants - */ - public byte getType() { - return type; - } + /** + * @return signature for given type. + */ + public String getSignature() { + return signature; + } + /** + * @return type as defined in Constants + */ + public byte getType() { + return type; + } - /** - * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise) - */ - public int getSize() { - switch (type) { - case Constants.T_DOUBLE: - case Constants.T_LONG: - return 2; - case Constants.T_VOID: - return 0; - default: - return 1; - } - } + /** + * @return stack size of this type (2 for long and double, 0 for void, 1 + * otherwise) + */ + public int getSize() { + switch (type) { + case Constants.T_DOUBLE: + case Constants.T_LONG: + return 2; + case Constants.T_VOID: + return 0; + default: + return 1; + } + } + /** + * @return Type string, e.g. `int[]' + */ + @Override + public String toString() { + return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN))) ? signature + : Utility.signatureToString(signature, false); + } - /** - * @return Type string, e.g. `int[]' - */ - public String toString() { - return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN))) ? signature : Utility - .signatureToString(signature, false); - } + /** + * Convert type to Java method signature, e.g. int[] f(java.lang.String x) + * becomes (Ljava/lang/String;)[I + * + * @param return_type + * what the method returns + * @param arg_types + * what are the argument types + * @return method signature for given type(s). + */ + public static String getMethodSignature(Type return_type, Type[] arg_types) { + StringBuffer buf = new StringBuffer("("); + int length = (arg_types == null) ? 0 : arg_types.length; + for (int i = 0; i < length; i++) { + buf.append(arg_types[i].getSignature()); + } + buf.append(')'); + buf.append(return_type.getSignature()); + return buf.toString(); + } + private static ThreadLocal consumed_chars = new ThreadLocal() { - /** - * Convert type to Java method signature, e.g. int[] f(java.lang.String x) - * becomes (Ljava/lang/String;)[I - * - * @param return_type what the method returns - * @param arg_types what are the argument types - * @return method signature for given type(s). - */ - public static String getMethodSignature( Type return_type, Type[] arg_types ) { - StringBuffer buf = new StringBuffer("("); - int length = (arg_types == null) ? 0 : arg_types.length; - for (int i = 0; i < length; i++) { - buf.append(arg_types[i].getSignature()); - } - buf.append(')'); - buf.append(return_type.getSignature()); - return buf.toString(); - } + @Override + protected Integer initialValue() { + return new Integer(0); + } + };// int consumed_chars=0; // Remember position in string, see + // getArgumentTypes - private static ThreadLocal consumed_chars = new ThreadLocal() { + private static int unwrap(ThreadLocal tl) { + return tl.get().intValue(); + } - protected Object initialValue() { - return new Integer(0); - } - };//int consumed_chars=0; // Remember position in string, see getArgumentTypes + private static void wrap(ThreadLocal tl, int value) { + tl.set(new Integer(value)); + } + /** + * Convert signature to a Type object. + * + * @param signature + * signature string such as Ljava/lang/String; + * @return type object + */ + public static final Type getType(String signature) + throws StringIndexOutOfBoundsException { + byte type = Utility.typeOfSignature(signature); + if (type <= Constants.T_VOID) { + // corrected concurrent private static field acess + wrap(consumed_chars, 1); + return BasicType.getType(type); + } else if (type == Constants.T_ARRAY) { + int dim = 0; + do { // Count dimensions + dim++; + } while (signature.charAt(dim) == '['); + // Recurse, but just once, if the signature is ok + Type t = getType(signature.substring(dim)); + // corrected concurrent private static field acess + // consumed_chars += dim; // update counter - is replaced by + int _temp = unwrap(consumed_chars) + dim; + wrap(consumed_chars, _temp); + return new ArrayType(t, dim); + } else { // type == T_REFERENCE + int index = signature.indexOf(';'); // Look for closing `;' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + + signature); + } + // corrected concurrent private static field acess + wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are + // removed + return new ObjectType(signature.substring(1, index).replace('/', + '.')); + } + } - private static int unwrap( ThreadLocal tl ) { - return ((Integer) tl.get()).intValue(); - } + /** + * Convert return value of a method (signature) to a Type object. + * + * @param signature + * signature string such as (Ljava/lang/String;)V + * @return return type + */ + public static Type getReturnType(String signature) { + try { + // Read return type after `)' + int index = signature.lastIndexOf(')') + 1; + return getType(signature.substring(index)); + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + + signature); + } + } + /** + * Convert arguments of a method (signature) to an array of Type objects. + * + * @param signature + * signature string such as (Ljava/lang/String;)V + * @return array of argument types + */ + public static Type[] getArgumentTypes(String signature) { + List vec = new ArrayList(); + int index; + Type[] types; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + vec.add(getType(signature.substring(index))); + // corrected concurrent private static field acess + index += unwrap(consumed_chars); // update position + } + } catch (StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + + signature); + } + types = new Type[vec.size()]; + vec.toArray(types); + return types; + } - private static void wrap( ThreadLocal tl, int value ) { - tl.set(new Integer(value)); - } + /** + * Convert runtime java.lang.Class to BCEL Type object. + * + * @param cl + * Java class + * @return corresponding Type object + */ + public static Type getType(java.lang.Class cl) { + if (cl == null) { + throw new IllegalArgumentException("Class must not be null"); + } + /* + * That's an amzingly easy case, because getName() returns the + * signature. That's what we would have liked anyway. + */ + if (cl.isArray()) { + return getType(cl.getName()); + } else if (cl.isPrimitive()) { + if (cl == Integer.TYPE) { + return INT; + } else if (cl == Void.TYPE) { + return VOID; + } else if (cl == Double.TYPE) { + return DOUBLE; + } else if (cl == Float.TYPE) { + return FLOAT; + } else if (cl == Boolean.TYPE) { + return BOOLEAN; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Short.TYPE) { + return SHORT; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Long.TYPE) { + return LONG; + } else if (cl == Character.TYPE) { + return CHAR; + } else { + throw new IllegalStateException( + "Ooops, what primitive type is " + cl); + } + } else { // "Real" class + return new ObjectType(cl.getName()); + } + } + /** + * Convert runtime java.lang.Class[] to BCEL Type objects. + * + * @param classes + * an array of runtime class objects + * @return array of corresponding Type objects + */ + public static Type[] getTypes(java.lang.Class[] classes) { + Type[] ret = new Type[classes.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = getType(classes[i]); + } + return ret; + } - /** - * Convert signature to a Type object. - * @param signature signature string such as Ljava/lang/String; - * @return type object - */ - public static final Type getType( String signature ) throws StringIndexOutOfBoundsException { - byte type = Utility.typeOfSignature(signature); - if (type <= Constants.T_VOID) { - //corrected concurrent private static field acess - wrap(consumed_chars, 1); - return BasicType.getType(type); - } else if (type == Constants.T_ARRAY) { - int dim = 0; - do { // Count dimensions - dim++; - } while (signature.charAt(dim) == '['); - // Recurse, but just once, if the signature is ok - Type t = getType(signature.substring(dim)); - //corrected concurrent private static field acess - // consumed_chars += dim; // update counter - is replaced by - int _temp = unwrap(consumed_chars) + dim; - wrap(consumed_chars, _temp); - return new ArrayType(t, dim); - } else { // type == T_REFERENCE - int index = signature.indexOf(';'); // Look for closing `;' - if (index < 0) { - throw new ClassFormatException("Invalid signature: " + signature); - } - //corrected concurrent private static field acess - wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed - return new ObjectType(signature.substring(1, index).replace('/', '.')); - } - } - - - /** - * Convert return value of a method (signature) to a Type object. - * - * @param signature signature string such as (Ljava/lang/String;)V - * @return return type - */ - public static Type getReturnType( String signature ) { - try { - // Read return type after `)' - int index = signature.lastIndexOf(')') + 1; - return getType(signature.substring(index)); - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - - /** - * Convert arguments of a method (signature) to an array of Type objects. - * @param signature signature string such as (Ljava/lang/String;)V - * @return array of argument types - */ - public static Type[] getArgumentTypes( String signature ) { - List vec = new ArrayList(); - int index; - Type[] types; - try { // Read all declarations between for `(' and `)' - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - index = 1; // current string position - while (signature.charAt(index) != ')') { - vec.add(getType(signature.substring(index))); - //corrected concurrent private static field acess - index += unwrap(consumed_chars); // update position - } - } catch (StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - types = new Type[vec.size()]; - vec.toArray(types); - return types; - } - - - /** Convert runtime java.lang.Class to BCEL Type object. - * @param cl Java class - * @return corresponding Type object - */ - public static Type getType( java.lang.Class cl ) { - if (cl == null) { - throw new IllegalArgumentException("Class must not be null"); - } - /* That's an amzingly easy case, because getName() returns - * the signature. That's what we would have liked anyway. - */ - if (cl.isArray()) { - return getType(cl.getName()); - } else if (cl.isPrimitive()) { - if (cl == Integer.TYPE) { - return INT; - } else if (cl == Void.TYPE) { - return VOID; - } else if (cl == Double.TYPE) { - return DOUBLE; - } else if (cl == Float.TYPE) { - return FLOAT; - } else if (cl == Boolean.TYPE) { - return BOOLEAN; - } else if (cl == Byte.TYPE) { - return BYTE; - } else if (cl == Short.TYPE) { - return SHORT; - } else if (cl == Byte.TYPE) { - return BYTE; - } else if (cl == Long.TYPE) { - return LONG; - } else if (cl == Character.TYPE) { - return CHAR; - } else { - throw new IllegalStateException("Ooops, what primitive type is " + cl); - } - } else { // "Real" class - return new ObjectType(cl.getName()); - } - } - - - /** - * Convert runtime java.lang.Class[] to BCEL Type objects. - * @param classes an array of runtime class objects - * @return array of corresponding Type objects - */ - public static Type[] getTypes( java.lang.Class[] classes ) { - Type[] ret = new Type[classes.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = getType(classes[i]); - } - return ret; - } - - - public static String getSignature( java.lang.reflect.Method meth ) { - StringBuffer sb = new StringBuffer("("); - Class[] params = meth.getParameterTypes(); // avoid clone - for (int j = 0; j < params.length; j++) { - sb.append(getType(params[j]).getSignature()); - } - sb.append(")"); - sb.append(getType(meth.getReturnType()).getSignature()); - return sb.toString(); - } + public static String getSignature(java.lang.reflect.Method meth) { + StringBuffer sb = new StringBuffer("("); + Class[] params = meth.getParameterTypes(); // avoid clone + for (int j = 0; j < params.length; j++) { + sb.append(getType(params[j]).getSignature()); + } + sb.append(")"); + sb.append(getType(meth.getReturnType()).getSignature()); + return sb.toString(); + } } diff --git a/src/org/apache/bcel/generic/TypedInstruction.java b/src/org/apache/bcel/generic/TypedInstruction.java index dc9899f..98d0e43 100644 --- a/src/org/apache/bcel/generic/TypedInstruction.java +++ b/src/org/apache/bcel/generic/TypedInstruction.java @@ -17,13 +17,13 @@ package org.apache.bcel.generic; /** - * Get the type associated with an instruction, int for ILOAD, or the type - * of the field of a PUTFIELD instruction, e.g.. - * + * Get the type associated with an instruction, int for ILOAD, or the type of + * the field of a PUTFIELD instruction, e.g.. + * * @version $Id: TypedInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface TypedInstruction { - public Type getType( ConstantPoolGen cpg ); + public Type getType(ConstantPoolGen cpg); } diff --git a/src/org/apache/bcel/generic/UnconditionalBranch.java b/src/org/apache/bcel/generic/UnconditionalBranch.java index 1bdfba4..74266b7 100644 --- a/src/org/apache/bcel/generic/UnconditionalBranch.java +++ b/src/org/apache/bcel/generic/UnconditionalBranch.java @@ -18,10 +18,10 @@ package org.apache.bcel.generic; /** * Denotes an instruction to perform an unconditional branch, i.e., GOTO, JSR. - * + * * @version $Id: UnconditionalBranch.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - + * @author M. Dahm + * * @see GOTO * @see JSR */ diff --git a/src/org/apache/bcel/generic/VariableLengthInstruction.java b/src/org/apache/bcel/generic/VariableLengthInstruction.java index bc9402e..f05aa29 100644 --- a/src/org/apache/bcel/generic/VariableLengthInstruction.java +++ b/src/org/apache/bcel/generic/VariableLengthInstruction.java @@ -17,12 +17,13 @@ package org.apache.bcel.generic; /** - * Denotes an instruction to be a variable length instruction, such as - * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH. - * - * @version $Id: VariableLengthInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - + * Denotes an instruction to be a variable length instruction, such as GOTO, + * JSR, LOOKUPSWITCH and TABLESWITCH. + * + * @version $Id: VariableLengthInstruction.java 386056 2006-03-15 11:31:56Z + * tcurdt $ + * @author M. Dahm + * * @see GOTO * @see JSR * @see LOOKUPSWITCH diff --git a/src/org/apache/bcel/generic/Visitor.java b/src/org/apache/bcel/generic/Visitor.java index 6178f66..e2588e2 100644 --- a/src/org/apache/bcel/generic/Visitor.java +++ b/src/org/apache/bcel/generic/Visitor.java @@ -17,552 +17,372 @@ package org.apache.bcel.generic; /** - * Interface implementing the Visitor pattern programming style. - * I.e., a class that implements this interface can handle all types of - * instructions with the properly typed methods just by calling the accept() - * method. - * + * Interface implementing the Visitor pattern programming style. I.e., a class + * that implements this interface can handle all types of instructions with the + * properly typed methods just by calling the accept() method. + * * @version $Id: Visitor.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public interface Visitor { - public void visitStackInstruction( StackInstruction obj ); + public void visitStackInstruction(StackInstruction obj); + public void visitLocalVariableInstruction(LocalVariableInstruction obj); - public void visitLocalVariableInstruction( LocalVariableInstruction obj ); + public void visitBranchInstruction(BranchInstruction obj); + public void visitLoadClass(LoadClass obj); - public void visitBranchInstruction( BranchInstruction obj ); + public void visitFieldInstruction(FieldInstruction obj); + public void visitIfInstruction(IfInstruction obj); - public void visitLoadClass( LoadClass obj ); + public void visitConversionInstruction(ConversionInstruction obj); + public void visitPopInstruction(PopInstruction obj); - public void visitFieldInstruction( FieldInstruction obj ); + public void visitStoreInstruction(StoreInstruction obj); + public void visitTypedInstruction(TypedInstruction obj); - public void visitIfInstruction( IfInstruction obj ); + public void visitSelect(Select obj); + public void visitJsrInstruction(JsrInstruction obj); - public void visitConversionInstruction( ConversionInstruction obj ); + public void visitGotoInstruction(GotoInstruction obj); + public void visitUnconditionalBranch(UnconditionalBranch obj); - public void visitPopInstruction( PopInstruction obj ); + public void visitPushInstruction(PushInstruction obj); + public void visitArithmeticInstruction(ArithmeticInstruction obj); - public void visitStoreInstruction( StoreInstruction obj ); + public void visitCPInstruction(CPInstruction obj); + public void visitInvokeInstruction(InvokeInstruction obj); - public void visitTypedInstruction( TypedInstruction obj ); + public void visitArrayInstruction(ArrayInstruction obj); + public void visitAllocationInstruction(AllocationInstruction obj); - public void visitSelect( Select obj ); + public void visitReturnInstruction(ReturnInstruction obj); + public void visitFieldOrMethod(FieldOrMethod obj); - public void visitJsrInstruction( JsrInstruction obj ); + public void visitConstantPushInstruction(ConstantPushInstruction obj); + public void visitExceptionThrower(ExceptionThrower obj); - public void visitGotoInstruction( GotoInstruction obj ); + public void visitLoadInstruction(LoadInstruction obj); + public void visitVariableLengthInstruction(VariableLengthInstruction obj); - public void visitUnconditionalBranch( UnconditionalBranch obj ); + public void visitStackProducer(StackProducer obj); + public void visitStackConsumer(StackConsumer obj); - public void visitPushInstruction( PushInstruction obj ); + public void visitACONST_NULL(ACONST_NULL obj); + public void visitGETSTATIC(GETSTATIC obj); - public void visitArithmeticInstruction( ArithmeticInstruction obj ); + public void visitIF_ICMPLT(IF_ICMPLT obj); + public void visitMONITOREXIT(MONITOREXIT obj); - public void visitCPInstruction( CPInstruction obj ); + public void visitIFLT(IFLT obj); + public void visitLSTORE(LSTORE obj); - public void visitInvokeInstruction( InvokeInstruction obj ); + public void visitPOP2(POP2 obj); + public void visitBASTORE(BASTORE obj); - public void visitArrayInstruction( ArrayInstruction obj ); + public void visitISTORE(ISTORE obj); + public void visitCHECKCAST(CHECKCAST obj); - public void visitAllocationInstruction( AllocationInstruction obj ); + public void visitFCMPG(FCMPG obj); + public void visitI2F(I2F obj); - public void visitReturnInstruction( ReturnInstruction obj ); + public void visitATHROW(ATHROW obj); + public void visitDCMPL(DCMPL obj); - public void visitFieldOrMethod( FieldOrMethod obj ); + public void visitARRAYLENGTH(ARRAYLENGTH obj); + public void visitDUP(DUP obj); - public void visitConstantPushInstruction( ConstantPushInstruction obj ); + public void visitINVOKESTATIC(INVOKESTATIC obj); + public void visitLCONST(LCONST obj); - public void visitExceptionThrower( ExceptionThrower obj ); + public void visitDREM(DREM obj); + public void visitIFGE(IFGE obj); - public void visitLoadInstruction( LoadInstruction obj ); + public void visitCALOAD(CALOAD obj); + public void visitLASTORE(LASTORE obj); - public void visitVariableLengthInstruction( VariableLengthInstruction obj ); + public void visitI2D(I2D obj); + public void visitDADD(DADD obj); - public void visitStackProducer( StackProducer obj ); + public void visitINVOKESPECIAL(INVOKESPECIAL obj); + public void visitIAND(IAND obj); - public void visitStackConsumer( StackConsumer obj ); + public void visitPUTFIELD(PUTFIELD obj); + public void visitILOAD(ILOAD obj); - public void visitACONST_NULL( ACONST_NULL obj ); + public void visitDLOAD(DLOAD obj); + public void visitDCONST(DCONST obj); - public void visitGETSTATIC( GETSTATIC obj ); + public void visitNEW(NEW obj); + public void visitIFNULL(IFNULL obj); - public void visitIF_ICMPLT( IF_ICMPLT obj ); + public void visitLSUB(LSUB obj); + public void visitL2I(L2I obj); - public void visitMONITOREXIT( MONITOREXIT obj ); + public void visitISHR(ISHR obj); + public void visitTABLESWITCH(TABLESWITCH obj); - public void visitIFLT( IFLT obj ); + public void visitIINC(IINC obj); + public void visitDRETURN(DRETURN obj); - public void visitLSTORE( LSTORE obj ); + public void visitFSTORE(FSTORE obj); + public void visitDASTORE(DASTORE obj); - public void visitPOP2( POP2 obj ); + public void visitIALOAD(IALOAD obj); + public void visitDDIV(DDIV obj); - public void visitBASTORE( BASTORE obj ); + public void visitIF_ICMPGE(IF_ICMPGE obj); + public void visitLAND(LAND obj); - public void visitISTORE( ISTORE obj ); + public void visitIDIV(IDIV obj); + public void visitLOR(LOR obj); - public void visitCHECKCAST( CHECKCAST obj ); + public void visitCASTORE(CASTORE obj); + public void visitFREM(FREM obj); - public void visitFCMPG( FCMPG obj ); + public void visitLDC(LDC obj); + public void visitBIPUSH(BIPUSH obj); - public void visitI2F( I2F obj ); + public void visitDSTORE(DSTORE obj); + public void visitF2L(F2L obj); - public void visitATHROW( ATHROW obj ); + public void visitFMUL(FMUL obj); + public void visitLLOAD(LLOAD obj); - public void visitDCMPL( DCMPL obj ); + public void visitJSR(JSR obj); + public void visitFSUB(FSUB obj); - public void visitARRAYLENGTH( ARRAYLENGTH obj ); + public void visitSASTORE(SASTORE obj); + public void visitALOAD(ALOAD obj); - public void visitDUP( DUP obj ); + public void visitDUP2_X2(DUP2_X2 obj); + public void visitRETURN(RETURN obj); - public void visitINVOKESTATIC( INVOKESTATIC obj ); + public void visitDALOAD(DALOAD obj); + public void visitSIPUSH(SIPUSH obj); - public void visitLCONST( LCONST obj ); + public void visitDSUB(DSUB obj); + public void visitL2F(L2F obj); - public void visitDREM( DREM obj ); + public void visitIF_ICMPGT(IF_ICMPGT obj); + public void visitF2D(F2D obj); - public void visitIFGE( IFGE obj ); + public void visitI2L(I2L obj); + public void visitIF_ACMPNE(IF_ACMPNE obj); - public void visitCALOAD( CALOAD obj ); + public void visitPOP(POP obj); + public void visitI2S(I2S obj); - public void visitLASTORE( LASTORE obj ); + public void visitIFEQ(IFEQ obj); + public void visitSWAP(SWAP obj); - public void visitI2D( I2D obj ); + public void visitIOR(IOR obj); + public void visitIREM(IREM obj); - public void visitDADD( DADD obj ); + public void visitIASTORE(IASTORE obj); + public void visitNEWARRAY(NEWARRAY obj); - public void visitINVOKESPECIAL( INVOKESPECIAL obj ); + public void visitINVOKEINTERFACE(INVOKEINTERFACE obj); + public void visitINEG(INEG obj); - public void visitIAND( IAND obj ); + public void visitLCMP(LCMP obj); + public void visitJSR_W(JSR_W obj); - public void visitPUTFIELD( PUTFIELD obj ); + public void visitMULTIANEWARRAY(MULTIANEWARRAY obj); + public void visitDUP_X2(DUP_X2 obj); - public void visitILOAD( ILOAD obj ); + public void visitSALOAD(SALOAD obj); + public void visitIFNONNULL(IFNONNULL obj); - public void visitDLOAD( DLOAD obj ); + public void visitDMUL(DMUL obj); + public void visitIFNE(IFNE obj); - public void visitDCONST( DCONST obj ); + public void visitIF_ICMPLE(IF_ICMPLE obj); + public void visitLDC2_W(LDC2_W obj); - public void visitNEW( NEW obj ); + public void visitGETFIELD(GETFIELD obj); + public void visitLADD(LADD obj); - public void visitIFNULL( IFNULL obj ); + public void visitNOP(NOP obj); + public void visitFALOAD(FALOAD obj); - public void visitLSUB( LSUB obj ); + public void visitINSTANCEOF(INSTANCEOF obj); + public void visitIFLE(IFLE obj); - public void visitL2I( L2I obj ); + public void visitLXOR(LXOR obj); + public void visitLRETURN(LRETURN obj); - public void visitISHR( ISHR obj ); + public void visitFCONST(FCONST obj); + public void visitIUSHR(IUSHR obj); - public void visitTABLESWITCH( TABLESWITCH obj ); + public void visitBALOAD(BALOAD obj); + public void visitDUP2(DUP2 obj); - public void visitIINC( IINC obj ); + public void visitIF_ACMPEQ(IF_ACMPEQ obj); + public void visitIMPDEP1(IMPDEP1 obj); - public void visitDRETURN( DRETURN obj ); + public void visitMONITORENTER(MONITORENTER obj); + public void visitLSHL(LSHL obj); - public void visitFSTORE( FSTORE obj ); + public void visitDCMPG(DCMPG obj); + public void visitD2L(D2L obj); - public void visitDASTORE( DASTORE obj ); + public void visitIMPDEP2(IMPDEP2 obj); + public void visitL2D(L2D obj); - public void visitIALOAD( IALOAD obj ); + public void visitRET(RET obj); + public void visitIFGT(IFGT obj); - public void visitDDIV( DDIV obj ); + public void visitIXOR(IXOR obj); + public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj); - public void visitIF_ICMPGE( IF_ICMPGE obj ); + public void visitFASTORE(FASTORE obj); + public void visitIRETURN(IRETURN obj); - public void visitLAND( LAND obj ); + public void visitIF_ICMPNE(IF_ICMPNE obj); + public void visitFLOAD(FLOAD obj); - public void visitIDIV( IDIV obj ); + public void visitLDIV(LDIV obj); + public void visitPUTSTATIC(PUTSTATIC obj); - public void visitLOR( LOR obj ); + public void visitAALOAD(AALOAD obj); + public void visitD2I(D2I obj); - public void visitCASTORE( CASTORE obj ); + public void visitIF_ICMPEQ(IF_ICMPEQ obj); + public void visitAASTORE(AASTORE obj); - public void visitFREM( FREM obj ); + public void visitARETURN(ARETURN obj); + public void visitDUP2_X1(DUP2_X1 obj); - public void visitLDC( LDC obj ); + public void visitFNEG(FNEG obj); + public void visitGOTO_W(GOTO_W obj); - public void visitBIPUSH( BIPUSH obj ); + public void visitD2F(D2F obj); + public void visitGOTO(GOTO obj); - public void visitDSTORE( DSTORE obj ); + public void visitISUB(ISUB obj); + public void visitF2I(F2I obj); - public void visitF2L( F2L obj ); + public void visitDNEG(DNEG obj); + public void visitICONST(ICONST obj); - public void visitFMUL( FMUL obj ); + public void visitFDIV(FDIV obj); + public void visitI2B(I2B obj); - public void visitLLOAD( LLOAD obj ); + public void visitLNEG(LNEG obj); + public void visitLREM(LREM obj); - public void visitJSR( JSR obj ); + public void visitIMUL(IMUL obj); + public void visitIADD(IADD obj); - public void visitFSUB( FSUB obj ); + public void visitLSHR(LSHR obj); + public void visitLOOKUPSWITCH(LOOKUPSWITCH obj); - public void visitSASTORE( SASTORE obj ); + public void visitDUP_X1(DUP_X1 obj); + public void visitFCMPL(FCMPL obj); - public void visitALOAD( ALOAD obj ); + public void visitI2C(I2C obj); + public void visitLMUL(LMUL obj); - public void visitDUP2_X2( DUP2_X2 obj ); + public void visitLUSHR(LUSHR obj); + public void visitISHL(ISHL obj); - public void visitRETURN( RETURN obj ); + public void visitLALOAD(LALOAD obj); + public void visitASTORE(ASTORE obj); - public void visitDALOAD( DALOAD obj ); + public void visitANEWARRAY(ANEWARRAY obj); + public void visitFRETURN(FRETURN obj); - public void visitSIPUSH( SIPUSH obj ); + public void visitFADD(FADD obj); - - public void visitDSUB( DSUB obj ); - - - public void visitL2F( L2F obj ); - - - public void visitIF_ICMPGT( IF_ICMPGT obj ); - - - public void visitF2D( F2D obj ); - - - public void visitI2L( I2L obj ); - - - public void visitIF_ACMPNE( IF_ACMPNE obj ); - - - public void visitPOP( POP obj ); - - - public void visitI2S( I2S obj ); - - - public void visitIFEQ( IFEQ obj ); - - - public void visitSWAP( SWAP obj ); - - - public void visitIOR( IOR obj ); - - - public void visitIREM( IREM obj ); - - - public void visitIASTORE( IASTORE obj ); - - - public void visitNEWARRAY( NEWARRAY obj ); - - - public void visitINVOKEINTERFACE( INVOKEINTERFACE obj ); - - - public void visitINEG( INEG obj ); - - - public void visitLCMP( LCMP obj ); - - - public void visitJSR_W( JSR_W obj ); - - - public void visitMULTIANEWARRAY( MULTIANEWARRAY obj ); - - - public void visitDUP_X2( DUP_X2 obj ); - - - public void visitSALOAD( SALOAD obj ); - - - public void visitIFNONNULL( IFNONNULL obj ); - - - public void visitDMUL( DMUL obj ); - - - public void visitIFNE( IFNE obj ); - - - public void visitIF_ICMPLE( IF_ICMPLE obj ); - - - public void visitLDC2_W( LDC2_W obj ); - - - public void visitGETFIELD( GETFIELD obj ); - - - public void visitLADD( LADD obj ); - - - public void visitNOP( NOP obj ); - - - public void visitFALOAD( FALOAD obj ); - - - public void visitINSTANCEOF( INSTANCEOF obj ); - - - public void visitIFLE( IFLE obj ); - - - public void visitLXOR( LXOR obj ); - - - public void visitLRETURN( LRETURN obj ); - - - public void visitFCONST( FCONST obj ); - - - public void visitIUSHR( IUSHR obj ); - - - public void visitBALOAD( BALOAD obj ); - - - public void visitDUP2( DUP2 obj ); - - - public void visitIF_ACMPEQ( IF_ACMPEQ obj ); - - - public void visitIMPDEP1( IMPDEP1 obj ); - - - public void visitMONITORENTER( MONITORENTER obj ); - - - public void visitLSHL( LSHL obj ); - - - public void visitDCMPG( DCMPG obj ); - - - public void visitD2L( D2L obj ); - - - public void visitIMPDEP2( IMPDEP2 obj ); - - - public void visitL2D( L2D obj ); - - - public void visitRET( RET obj ); - - - public void visitIFGT( IFGT obj ); - - - public void visitIXOR( IXOR obj ); - - - public void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj ); - - - public void visitFASTORE( FASTORE obj ); - - - public void visitIRETURN( IRETURN obj ); - - - public void visitIF_ICMPNE( IF_ICMPNE obj ); - - - public void visitFLOAD( FLOAD obj ); - - - public void visitLDIV( LDIV obj ); - - - public void visitPUTSTATIC( PUTSTATIC obj ); - - - public void visitAALOAD( AALOAD obj ); - - - public void visitD2I( D2I obj ); - - - public void visitIF_ICMPEQ( IF_ICMPEQ obj ); - - - public void visitAASTORE( AASTORE obj ); - - - public void visitARETURN( ARETURN obj ); - - - public void visitDUP2_X1( DUP2_X1 obj ); - - - public void visitFNEG( FNEG obj ); - - - public void visitGOTO_W( GOTO_W obj ); - - - public void visitD2F( D2F obj ); - - - public void visitGOTO( GOTO obj ); - - - public void visitISUB( ISUB obj ); - - - public void visitF2I( F2I obj ); - - - public void visitDNEG( DNEG obj ); - - - public void visitICONST( ICONST obj ); - - - public void visitFDIV( FDIV obj ); - - - public void visitI2B( I2B obj ); - - - public void visitLNEG( LNEG obj ); - - - public void visitLREM( LREM obj ); - - - public void visitIMUL( IMUL obj ); - - - public void visitIADD( IADD obj ); - - - public void visitLSHR( LSHR obj ); - - - public void visitLOOKUPSWITCH( LOOKUPSWITCH obj ); - - - public void visitDUP_X1( DUP_X1 obj ); - - - public void visitFCMPL( FCMPL obj ); - - - public void visitI2C( I2C obj ); - - - public void visitLMUL( LMUL obj ); - - - public void visitLUSHR( LUSHR obj ); - - - public void visitISHL( ISHL obj ); - - - public void visitLALOAD( LALOAD obj ); - - - public void visitASTORE( ASTORE obj ); - - - public void visitANEWARRAY( ANEWARRAY obj ); - - - public void visitFRETURN( FRETURN obj ); - - - public void visitFADD( FADD obj ); - - - public void visitBREAKPOINT( BREAKPOINT obj ); + public void visitBREAKPOINT(BREAKPOINT obj); } diff --git a/src/org/apache/bcel/util/BCELComparator.java b/src/org/apache/bcel/util/BCELComparator.java index 9404bd3..89770c1 100644 --- a/src/org/apache/bcel/util/BCELComparator.java +++ b/src/org/apache/bcel/util/BCELComparator.java @@ -25,21 +25,20 @@ package org.apache.bcel.util; */ public interface BCELComparator { - /** - * Compare two objects and return what THIS.equals(THAT) should return - * - * @param THIS - * @param THAT - * @return true if and only if THIS equals THAT - */ - public boolean equals( Object THIS, Object THAT ); + /** + * Compare two objects and return what THIS.equals(THAT) should return + * + * @param THIS + * @param THAT + * @return true if and only if THIS equals THAT + */ + public boolean equals(Object THIS, Object THAT); - - /** - * Return hashcode for THIS.hashCode() - * - * @param THIS - * @return hashcode for THIS.hashCode() - */ - public int hashCode( Object THIS ); + /** + * Return hashcode for THIS.hashCode() + * + * @param THIS + * @return hashcode for THIS.hashCode() + */ + public int hashCode(Object THIS); } diff --git a/src/org/apache/bcel/util/BCELFactory.java b/src/org/apache/bcel/util/BCELFactory.java index 73ae23c..ea52018 100644 --- a/src/org/apache/bcel/util/BCELFactory.java +++ b/src/org/apache/bcel/util/BCELFactory.java @@ -56,271 +56,281 @@ import org.apache.bcel.generic.Select; import org.apache.bcel.generic.Type; /** - * Factory creates il.append() statements, and sets instruction targets. - * A helper class for BCELifier. - * + * Factory creates il.append() statements, and sets instruction targets. A + * helper class for BCELifier. + * * @see BCELifier * @version $Id: BCELFactory.java 410087 2006-05-29 12:12:19Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ class BCELFactory extends EmptyVisitor { - private MethodGen _mg; - private PrintWriter _out; - private ConstantPoolGen _cp; + private MethodGen _mg; + private PrintWriter _out; + private ConstantPoolGen _cp; + BCELFactory(MethodGen mg, PrintWriter out) { + _mg = mg; + _cp = mg.getConstantPool(); + _out = out; + } - BCELFactory(MethodGen mg, PrintWriter out) { - _mg = mg; - _cp = mg.getConstantPool(); - _out = out; - } + private Map branch_map = new HashMap(); // Map - private Map branch_map = new HashMap(); // Map + public void start() { + if (!_mg.isAbstract() && !_mg.isNative()) { + for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih + .getNext()) { + Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { + branch_map.put(i, ih); // memorize container + } + if (ih.hasTargeters()) { + if (i instanceof BranchInstruction) { + _out.println(" InstructionHandle ih_" + + ih.getPosition() + ";"); + } else { + _out.print(" InstructionHandle ih_" + + ih.getPosition() + " = "); + } + } else { + _out.print(" "); + } + if (!visitInstruction(i)) { + i.accept(this); + } + } + updateBranchTargets(); + updateExceptionHandlers(); + } + } + private boolean visitInstruction(Instruction i) { + short opcode = i.getOpcode(); + if ((InstructionConstants.INSTRUCTIONS[opcode] != null) + && !(i instanceof ConstantPushInstruction) + && !(i instanceof ReturnInstruction)) { // Handled below + _out.println("il.append(InstructionConstants." + + i.getName().toUpperCase(Locale.ENGLISH) + ");"); + return true; + } + return false; + } - public void start() { - if (!_mg.isAbstract() && !_mg.isNative()) { - for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih - .getNext()) { - Instruction i = ih.getInstruction(); - if (i instanceof BranchInstruction) { - branch_map.put(i, ih); // memorize container - } - if (ih.hasTargeters()) { - if (i instanceof BranchInstruction) { - _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); - } else { - _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); - } - } else { - _out.print(" "); - } - if (!visitInstruction(i)) { - i.accept(this); - } - } - updateBranchTargets(); - updateExceptionHandlers(); - } - } + @Override + public void visitLocalVariableInstruction(LocalVariableInstruction i) { + short opcode = i.getOpcode(); + Type type = i.getType(_cp); + if (opcode == Constants.IINC) { + _out.println("il.append(new IINC(" + i.getIndex() + ", " + + ((IINC) i).getIncrement() + "));"); + } else { + String kind = (opcode < Constants.ISTORE) ? "Load" : "Store"; + _out.println("il.append(_factory.create" + kind + "(" + + BCELifier.printType(type) + ", " + i.getIndex() + "));"); + } + } + @Override + public void visitArrayInstruction(ArrayInstruction i) { + short opcode = i.getOpcode(); + Type type = i.getType(_cp); + String kind = (opcode < Constants.IASTORE) ? "Load" : "Store"; + _out.println("il.append(_factory.createArray" + kind + "(" + + BCELifier.printType(type) + "));"); + } - private boolean visitInstruction( Instruction i ) { - short opcode = i.getOpcode(); - if ((InstructionConstants.INSTRUCTIONS[opcode] != null) - && !(i instanceof ConstantPushInstruction) && !(i instanceof ReturnInstruction)) { // Handled below - _out.println("il.append(InstructionConstants." - + i.getName().toUpperCase(Locale.ENGLISH) + ");"); - return true; - } - return false; - } + @Override + public void visitFieldInstruction(FieldInstruction i) { + short opcode = i.getOpcode(); + String class_name = i.getClassName(_cp); + String field_name = i.getFieldName(_cp); + Type type = i.getFieldType(_cp); + _out.println("il.append(_factory.createFieldAccess(\"" + class_name + + "\", \"" + field_name + "\", " + BCELifier.printType(type) + + ", " + "Constants." + + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + + "));"); + } + @Override + public void visitInvokeInstruction(InvokeInstruction i) { + short opcode = i.getOpcode(); + String class_name = i.getClassName(_cp); + String method_name = i.getMethodName(_cp); + Type type = i.getReturnType(_cp); + Type[] arg_types = i.getArgumentTypes(_cp); + _out.println("il.append(_factory.createInvoke(\"" + class_name + + "\", \"" + method_name + "\", " + BCELifier.printType(type) + + ", " + BCELifier.printArgumentTypes(arg_types) + ", " + + "Constants." + + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + + "));"); + } - public void visitLocalVariableInstruction( LocalVariableInstruction i ) { - short opcode = i.getOpcode(); - Type type = i.getType(_cp); - if (opcode == Constants.IINC) { - _out.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement() - + "));"); - } else { - String kind = (opcode < Constants.ISTORE) ? "Load" : "Store"; - _out.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type) - + ", " + i.getIndex() + "));"); - } - } + @Override + public void visitAllocationInstruction(AllocationInstruction i) { + Type type; + if (i instanceof CPInstruction) { + type = ((CPInstruction) i).getType(_cp); + } else { + type = ((NEWARRAY) i).getType(); + } + short opcode = ((Instruction) i).getOpcode(); + int dim = 1; + switch (opcode) { + case Constants.NEW: + _out.println("il.append(_factory.createNew(\"" + + ((ObjectType) type).getClassName() + "\"));"); + break; + case Constants.MULTIANEWARRAY: + dim = ((MULTIANEWARRAY) i).getDimensions(); + case Constants.ANEWARRAY: + case Constants.NEWARRAY: + if (type instanceof ArrayType) { + type = ((ArrayType) type).getBasicType(); + } + _out.println("il.append(_factory.createNewArray(" + + BCELifier.printType(type) + ", (short) " + dim + "));"); + break; + default: + throw new RuntimeException("Oops: " + opcode); + } + } + private void createConstant(Object value) { + String embed = value.toString(); + if (value instanceof String) { + embed = '"' + Utility.convertString(value.toString()) + '"'; + } else if (value instanceof Character) { + embed = "(char)0x" + + Integer.toHexString(((Character) value).charValue()); + } + _out.println("il.append(new PUSH(_cp, " + embed + "));"); + } - public void visitArrayInstruction( ArrayInstruction i ) { - short opcode = i.getOpcode(); - Type type = i.getType(_cp); - String kind = (opcode < Constants.IASTORE) ? "Load" : "Store"; - _out.println("il.append(_factory.createArray" + kind + "(" + BCELifier.printType(type) - + "));"); - } + @Override + public void visitLDC(LDC i) { + createConstant(i.getValue(_cp)); + } + @Override + public void visitLDC2_W(LDC2_W i) { + createConstant(i.getValue(_cp)); + } - public void visitFieldInstruction( FieldInstruction i ) { - short opcode = i.getOpcode(); - String class_name = i.getClassName(_cp); - String field_name = i.getFieldName(_cp); - Type type = i.getFieldType(_cp); - _out.println("il.append(_factory.createFieldAccess(\"" + class_name + "\", \"" + field_name - + "\", " + BCELifier.printType(type) + ", " + "Constants." - + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + "));"); - } + @Override + public void visitConstantPushInstruction(ConstantPushInstruction i) { + createConstant(i.getValue()); + } + @Override + public void visitINSTANCEOF(INSTANCEOF i) { + Type type = i.getType(_cp); + _out.println("il.append(new INSTANCEOF(_cp.addClass(" + + BCELifier.printType(type) + ")));"); + } - public void visitInvokeInstruction( InvokeInstruction i ) { - short opcode = i.getOpcode(); - String class_name = i.getClassName(_cp); - String method_name = i.getMethodName(_cp); - Type type = i.getReturnType(_cp); - Type[] arg_types = i.getArgumentTypes(_cp); - _out.println("il.append(_factory.createInvoke(\"" + class_name + "\", \"" + method_name - + "\", " + BCELifier.printType(type) + ", " - + BCELifier.printArgumentTypes(arg_types) + ", " + "Constants." - + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + "));"); - } + @Override + public void visitCHECKCAST(CHECKCAST i) { + Type type = i.getType(_cp); + _out.println("il.append(_factory.createCheckCast(" + + BCELifier.printType(type) + "));"); + } + @Override + public void visitReturnInstruction(ReturnInstruction i) { + Type type = i.getType(_cp); + _out.println("il.append(_factory.createReturn(" + + BCELifier.printType(type) + "));"); + } - public void visitAllocationInstruction( AllocationInstruction i ) { - Type type; - if (i instanceof CPInstruction) { - type = ((CPInstruction) i).getType(_cp); - } else { - type = ((NEWARRAY) i).getType(); - } - short opcode = ((Instruction) i).getOpcode(); - int dim = 1; - switch (opcode) { - case Constants.NEW: - _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName() - + "\"));"); - break; - case Constants.MULTIANEWARRAY: - dim = ((MULTIANEWARRAY) i).getDimensions(); - case Constants.ANEWARRAY: - case Constants.NEWARRAY: - if (type instanceof ArrayType) { - type = ((ArrayType) type).getBasicType(); - } - _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type) - + ", (short) " + dim + "));"); - break; - default: - throw new RuntimeException("Oops: " + opcode); - } - } + // Memorize BranchInstructions that need an update + private List branches = new ArrayList(); + @Override + public void visitBranchInstruction(BranchInstruction bi) { + BranchHandle bh = (BranchHandle) branch_map.get(bi); + int pos = bh.getPosition(); + String name = bi.getName() + "_" + pos; + if (bi instanceof Select) { + Select s = (Select) bi; + branches.add(bi); + StringBuffer args = new StringBuffer("new int[] { "); + int[] matchs = s.getMatchs(); + for (int i = 0; i < matchs.length; i++) { + args.append(matchs[i]); + if (i < matchs.length - 1) { + args.append(", "); + } + } + args.append(" }"); + _out.print("Select " + name + " = new " + + bi.getName().toUpperCase(Locale.ENGLISH) + "(" + args + + ", new InstructionHandle[] { "); + for (int i = 0; i < matchs.length; i++) { + _out.print("null"); + if (i < matchs.length - 1) { + _out.print(", "); + } + } + _out.println(" }, null);"); + } else { + int t_pos = bh.getTarget().getPosition(); + String target; + if (pos > t_pos) { + target = "ih_" + t_pos; + } else { + branches.add(bi); + target = "null"; + } + _out.println(" BranchInstruction " + name + + " = _factory.createBranchInstruction(" + "Constants." + + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target + + ");"); + } + if (bh.hasTargeters()) { + _out.println(" ih_" + pos + " = il.append(" + name + ");"); + } else { + _out.println(" il.append(" + name + ");"); + } + } - private void createConstant( Object value ) { - String embed = value.toString(); - if (value instanceof String) { - embed = '"' + Utility.convertString(value.toString()) + '"'; - } else if (value instanceof Character) { - embed = "(char)0x" + Integer.toHexString(((Character) value).charValue()); - } - _out.println("il.append(new PUSH(_cp, " + embed + "));"); - } + @Override + public void visitRET(RET i) { + _out.println("il.append(new RET(" + i.getIndex() + ")));"); + } + private void updateBranchTargets() { + for (Iterator i = branches.iterator(); i.hasNext();) { + BranchInstruction bi = i.next(); + BranchHandle bh = (BranchHandle) branch_map.get(bi); + int pos = bh.getPosition(); + String name = bi.getName() + "_" + pos; + int t_pos = bh.getTarget().getPosition(); + _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); + if (bi instanceof Select) { + InstructionHandle[] ihs = ((Select) bi).getTargets(); + for (int j = 0; j < ihs.length; j++) { + t_pos = ihs[j].getPosition(); + _out.println(" " + name + ".setTarget(" + j + ", ih_" + + t_pos + ");"); + } + } + } + } - public void visitLDC( LDC i ) { - createConstant(i.getValue(_cp)); - } - - - public void visitLDC2_W( LDC2_W i ) { - createConstant(i.getValue(_cp)); - } - - - public void visitConstantPushInstruction( ConstantPushInstruction i ) { - createConstant(i.getValue()); - } - - - public void visitINSTANCEOF( INSTANCEOF i ) { - Type type = i.getType(_cp); - _out.println("il.append(new INSTANCEOF(_cp.addClass(" + BCELifier.printType(type) + ")));"); - } - - - public void visitCHECKCAST( CHECKCAST i ) { - Type type = i.getType(_cp); - _out.println("il.append(_factory.createCheckCast(" + BCELifier.printType(type) + "));"); - } - - - public void visitReturnInstruction( ReturnInstruction i ) { - Type type = i.getType(_cp); - _out.println("il.append(_factory.createReturn(" + BCELifier.printType(type) + "));"); - } - - // Memorize BranchInstructions that need an update - private List branches = new ArrayList(); - - - public void visitBranchInstruction( BranchInstruction bi ) { - BranchHandle bh = (BranchHandle) branch_map.get(bi); - int pos = bh.getPosition(); - String name = bi.getName() + "_" + pos; - if (bi instanceof Select) { - Select s = (Select) bi; - branches.add(bi); - StringBuffer args = new StringBuffer("new int[] { "); - int[] matchs = s.getMatchs(); - for (int i = 0; i < matchs.length; i++) { - args.append(matchs[i]); - if (i < matchs.length - 1) { - args.append(", "); - } - } - args.append(" }"); - _out.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH) - + "(" + args + ", new InstructionHandle[] { "); - for (int i = 0; i < matchs.length; i++) { - _out.print("null"); - if (i < matchs.length - 1) { - _out.print(", "); - } - } - _out.println(" }, null);"); - } else { - int t_pos = bh.getTarget().getPosition(); - String target; - if (pos > t_pos) { - target = "ih_" + t_pos; - } else { - branches.add(bi); - target = "null"; - } - _out.println(" BranchInstruction " + name + " = _factory.createBranchInstruction(" - + "Constants." + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target - + ");"); - } - if (bh.hasTargeters()) { - _out.println(" ih_" + pos + " = il.append(" + name + ");"); - } else { - _out.println(" il.append(" + name + ");"); - } - } - - - public void visitRET( RET i ) { - _out.println("il.append(new RET(" + i.getIndex() + ")));"); - } - - - private void updateBranchTargets() { - for (Iterator i = branches.iterator(); i.hasNext();) { - BranchInstruction bi = (BranchInstruction) i.next(); - BranchHandle bh = (BranchHandle) branch_map.get(bi); - int pos = bh.getPosition(); - String name = bi.getName() + "_" + pos; - int t_pos = bh.getTarget().getPosition(); - _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); - if (bi instanceof Select) { - InstructionHandle[] ihs = ((Select) bi).getTargets(); - for (int j = 0; j < ihs.length; j++) { - t_pos = ihs[j].getPosition(); - _out.println(" " + name + ".setTarget(" + j + ", ih_" + t_pos + ");"); - } - } - } - } - - - private void updateExceptionHandlers() { - CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); - for (int i = 0; i < handlers.length; i++) { - CodeExceptionGen h = handlers[i]; - String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h - .getCatchType()); - _out.println(" method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition() - + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_" - + h.getHandlerPC().getPosition() + ", " + type + ");"); - } - } + private void updateExceptionHandlers() { + CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); + for (int i = 0; i < handlers.length; i++) { + CodeExceptionGen h = handlers[i]; + String type = (h.getCatchType() == null) ? "null" : BCELifier + .printType(h.getCatchType()); + _out.println(" method.addExceptionHandler(" + "ih_" + + h.getStartPC().getPosition() + ", " + "ih_" + + h.getEndPC().getPosition() + ", " + "ih_" + + h.getHandlerPC().getPosition() + ", " + type + ");"); + } + } } diff --git a/src/org/apache/bcel/util/BCELifier.java b/src/org/apache/bcel/util/BCELifier.java index c4ebbe2..a10b5da 100644 --- a/src/org/apache/bcel/util/BCELifier.java +++ b/src/org/apache/bcel/util/BCELifier.java @@ -32,237 +32,245 @@ import org.apache.bcel.generic.ConstantPoolGen; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.Type; -/** - * This class takes a given JavaClass object and converts it to a - * Java program that creates that very class using BCEL. This - * gives new users of BCEL a useful example showing how things - * are done with BCEL. It does not cover all features of BCEL, - * but tries to mimic hand-written code as close as possible. - * +/** + * This class takes a given JavaClass object and converts it to a Java program + * that creates that very class using BCEL. This gives new users of BCEL a + * useful example showing how things are done with BCEL. It does not cover all + * features of BCEL, but tries to mimic hand-written code as close as possible. + * * @version $Id: BCELifier.java 394939 2006-04-18 13:23:49Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class BCELifier extends org.apache.bcel.classfile.EmptyVisitor { - private static final int FLAG_FOR_UNKNOWN = -1; - private static final int FLAG_FOR_CLASS = 0; - private static final int FLAG_FOR_METHOD = 1; - private JavaClass _clazz; - private PrintWriter _out; - private ConstantPoolGen _cp; + private static final int FLAG_FOR_UNKNOWN = -1; + private static final int FLAG_FOR_CLASS = 0; + private static final int FLAG_FOR_METHOD = 1; + private JavaClass _clazz; + private PrintWriter _out; + private ConstantPoolGen _cp; + /** + * @param clazz + * Java class to "decompile" + * @param out + * where to output Java program + */ + public BCELifier(JavaClass clazz, OutputStream out) { + _clazz = clazz; + _out = new PrintWriter(out); + _cp = new ConstantPoolGen(_clazz.getConstantPool()); + } - /** @param clazz Java class to "decompile" - * @param out where to output Java program - */ - public BCELifier(JavaClass clazz, OutputStream out) { - _clazz = clazz; - _out = new PrintWriter(out); - _cp = new ConstantPoolGen(_clazz.getConstantPool()); - } + /** + * Start Java code generation + */ + public void start() { + visitJavaClass(_clazz); + _out.flush(); + } + @Override + public void visitJavaClass(JavaClass clazz) { + String class_name = clazz.getClassName(); + String super_name = clazz.getSuperclassName(); + String package_name = clazz.getPackageName(); + String inter = Utility.printArray(clazz.getInterfaceNames(), false, + true); + if (!"".equals(package_name)) { + class_name = class_name.substring(package_name.length() + 1); + _out.println("package " + package_name + ";"); + _out.println(); + } + _out.println("import org.apache.bcel.generic.*;"); + _out.println("import org.apache.bcel.classfile.*;"); + _out.println("import org.apache.bcel.*;"); + _out.println("import java.io.*;"); + _out.println(); + _out.println("public class " + class_name + + "Creator implements Constants {"); + _out.println(" private InstructionFactory _factory;"); + _out.println(" private ConstantPoolGen _cp;"); + _out.println(" private ClassGen _cg;"); + _out.println(); + _out.println(" public " + class_name + "Creator() {"); + _out.println(" _cg = new ClassGen(\"" + + (("".equals(package_name)) ? class_name : package_name + "." + + class_name) + "\", \"" + super_name + "\", " + "\"" + + clazz.getSourceFileName() + "\", " + + printFlags(clazz.getAccessFlags(), FLAG_FOR_CLASS) + ", " + + "new String[] { " + inter + " });"); + _out.println(); + _out.println(" _cp = _cg.getConstantPool();"); + _out.println(" _factory = new InstructionFactory(_cg, _cp);"); + _out.println(" }"); + _out.println(); + printCreate(); + Field[] fields = clazz.getFields(); + if (fields.length > 0) { + _out.println(" private void createFields() {"); + _out.println(" FieldGen field;"); + for (int i = 0; i < fields.length; i++) { + fields[i].accept(this); + } + _out.println(" }"); + _out.println(); + } + Method[] methods = clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + _out.println(" private void createMethod_" + i + "() {"); + methods[i].accept(this); + _out.println(" }"); + _out.println(); + } + printMain(); + _out.println("}"); + } - /** Start Java code generation - */ - public void start() { - visitJavaClass(_clazz); - _out.flush(); - } + private void printCreate() { + _out.println(" public void create(OutputStream out) throws IOException {"); + Field[] fields = _clazz.getFields(); + if (fields.length > 0) { + _out.println(" createFields();"); + } + Method[] methods = _clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + _out.println(" createMethod_" + i + "();"); + } + _out.println(" _cg.getJavaClass().dump(out);"); + _out.println(" }"); + _out.println(); + } + private void printMain() { + String class_name = _clazz.getClassName(); + _out.println(" public static void main(String[] args) throws Exception {"); + _out.println(" " + class_name + "Creator creator = new " + + class_name + "Creator();"); + _out.println(" creator.create(new FileOutputStream(\"" + class_name + + ".class\"));"); + _out.println(" }"); + } - public void visitJavaClass( JavaClass clazz ) { - String class_name = clazz.getClassName(); - String super_name = clazz.getSuperclassName(); - String package_name = clazz.getPackageName(); - String inter = Utility.printArray(clazz.getInterfaceNames(), false, true); - if (!"".equals(package_name)) { - class_name = class_name.substring(package_name.length() + 1); - _out.println("package " + package_name + ";"); - _out.println(); - } - _out.println("import org.apache.bcel.generic.*;"); - _out.println("import org.apache.bcel.classfile.*;"); - _out.println("import org.apache.bcel.*;"); - _out.println("import java.io.*;"); - _out.println(); - _out.println("public class " + class_name + "Creator implements Constants {"); - _out.println(" private InstructionFactory _factory;"); - _out.println(" private ConstantPoolGen _cp;"); - _out.println(" private ClassGen _cg;"); - _out.println(); - _out.println(" public " + class_name + "Creator() {"); - _out.println(" _cg = new ClassGen(\"" - + (("".equals(package_name)) ? class_name : package_name + "." + class_name) - + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", " - + printFlags(clazz.getAccessFlags(), FLAG_FOR_CLASS) + ", " + "new String[] { " - + inter + " });"); - _out.println(); - _out.println(" _cp = _cg.getConstantPool();"); - _out.println(" _factory = new InstructionFactory(_cg, _cp);"); - _out.println(" }"); - _out.println(); - printCreate(); - Field[] fields = clazz.getFields(); - if (fields.length > 0) { - _out.println(" private void createFields() {"); - _out.println(" FieldGen field;"); - for (int i = 0; i < fields.length; i++) { - fields[i].accept(this); - } - _out.println(" }"); - _out.println(); - } - Method[] methods = clazz.getMethods(); - for (int i = 0; i < methods.length; i++) { - _out.println(" private void createMethod_" + i + "() {"); - methods[i].accept(this); - _out.println(" }"); - _out.println(); - } - printMain(); - _out.println("}"); - } + @Override + public void visitField(Field field) { + _out.println(); + _out.println(" field = new FieldGen(" + + printFlags(field.getAccessFlags()) + ", " + + printType(field.getSignature()) + ", \"" + field.getName() + + "\", _cp);"); + ConstantValue cv = field.getConstantValue(); + if (cv != null) { + String value = cv.toString(); + _out.println(" field.setInitValue(" + value + ")"); + } + _out.println(" _cg.addField(field.getField());"); + } + @Override + public void visitMethod(Method method) { + MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); + Type result_type = mg.getReturnType(); + Type[] arg_types = mg.getArgumentTypes(); + _out.println(" InstructionList il = new InstructionList();"); + _out.println(" MethodGen method = new MethodGen(" + + printFlags(method.getAccessFlags(), FLAG_FOR_METHOD) + ", " + + printType(result_type) + ", " + printArgumentTypes(arg_types) + + ", " + "new String[] { " + + Utility.printArray(mg.getArgumentNames(), false, true) + + " }, \"" + method.getName() + "\", \"" + + _clazz.getClassName() + "\", il, _cp);"); + _out.println(); + BCELFactory factory = new BCELFactory(mg, _out); + factory.start(); + _out.println(" method.setMaxStack();"); + _out.println(" method.setMaxLocals();"); + _out.println(" _cg.addMethod(method.getMethod());"); + _out.println(" il.dispose();"); + } - private void printCreate() { - _out.println(" public void create(OutputStream out) throws IOException {"); - Field[] fields = _clazz.getFields(); - if (fields.length > 0) { - _out.println(" createFields();"); - } - Method[] methods = _clazz.getMethods(); - for (int i = 0; i < methods.length; i++) { - _out.println(" createMethod_" + i + "();"); - } - _out.println(" _cg.getJavaClass().dump(out);"); - _out.println(" }"); - _out.println(); - } + static String printFlags(int flags) { + return printFlags(flags, FLAG_FOR_UNKNOWN); + } + static String printFlags(int flags, int reason) { + if (flags == 0) { + return "0"; + } + StringBuffer buf = new StringBuffer(); + for (int i = 0, pow = 1; pow <= Constants.MAX_ACC_FLAG; i++) { + if ((flags & pow) != 0) { + if ((pow == Constants.ACC_SYNCHRONIZED) + && (reason == FLAG_FOR_CLASS)) { + buf.append("ACC_SUPER | "); + } else if ((pow == Constants.ACC_VOLATILE) + && (reason == FLAG_FOR_METHOD)) { + buf.append("ACC_BRIDGE | "); + } else if ((pow == Constants.ACC_TRANSIENT) + && (reason == FLAG_FOR_METHOD)) { + buf.append("ACC_VARARGS | "); + } else { + buf.append("ACC_") + .append(Constants.ACCESS_NAMES[i] + .toUpperCase(Locale.ENGLISH)).append(" | "); + } + } + pow <<= 1; + } + String str = buf.toString(); + return str.substring(0, str.length() - 3); + } - private void printMain() { - String class_name = _clazz.getClassName(); - _out.println(" public static void main(String[] args) throws Exception {"); - _out.println(" " + class_name + "Creator creator = new " + class_name + "Creator();"); - _out.println(" creator.create(new FileOutputStream(\"" + class_name + ".class\"));"); - _out.println(" }"); - } + static String printArgumentTypes(Type[] arg_types) { + if (arg_types.length == 0) { + return "Type.NO_ARGS"; + } + StringBuffer args = new StringBuffer(); + for (int i = 0; i < arg_types.length; i++) { + args.append(printType(arg_types[i])); + if (i < arg_types.length - 1) { + args.append(", "); + } + } + return "new Type[] { " + args.toString() + " }"; + } + static String printType(Type type) { + return printType(type.getSignature()); + } - public void visitField( Field field ) { - _out.println(); - _out.println(" field = new FieldGen(" + printFlags(field.getAccessFlags()) + ", " - + printType(field.getSignature()) + ", \"" + field.getName() + "\", _cp);"); - ConstantValue cv = field.getConstantValue(); - if (cv != null) { - String value = cv.toString(); - _out.println(" field.setInitValue(" + value + ")"); - } - _out.println(" _cg.addField(field.getField());"); - } + static String printType(String signature) { + Type type = Type.getType(signature); + byte t = type.getType(); + if (t <= Constants.T_VOID) { + return "Type." + + Constants.TYPE_NAMES[t].toUpperCase(Locale.ENGLISH); + } else if (type.toString().equals("java.lang.String")) { + return "Type.STRING"; + } else if (type.toString().equals("java.lang.Object")) { + return "Type.OBJECT"; + } else if (type.toString().equals("java.lang.StringBuffer")) { + return "Type.STRINGBUFFER"; + } else if (type instanceof ArrayType) { + ArrayType at = (ArrayType) type; + return "new ArrayType(" + printType(at.getBasicType()) + ", " + + at.getDimensions() + ")"; + } else { + return "new ObjectType(\"" + + Utility.signatureToString(signature, false) + "\")"; + } + } - - public void visitMethod( Method method ) { - MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); - Type result_type = mg.getReturnType(); - Type[] arg_types = mg.getArgumentTypes(); - _out.println(" InstructionList il = new InstructionList();"); - _out.println(" MethodGen method = new MethodGen(" - + printFlags(method.getAccessFlags(), FLAG_FOR_METHOD) + ", " - + printType(result_type) + ", " + printArgumentTypes(arg_types) + ", " - + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true) - + " }, \"" + method.getName() + "\", \"" + _clazz.getClassName() + "\", il, _cp);"); - _out.println(); - BCELFactory factory = new BCELFactory(mg, _out); - factory.start(); - _out.println(" method.setMaxStack();"); - _out.println(" method.setMaxLocals();"); - _out.println(" _cg.addMethod(method.getMethod());"); - _out.println(" il.dispose();"); - } - - - static String printFlags( int flags ) { - return printFlags(flags, FLAG_FOR_UNKNOWN); - } - - - static String printFlags( int flags, int reason ) { - if (flags == 0) { - return "0"; - } - StringBuffer buf = new StringBuffer(); - for (int i = 0, pow = 1; pow <= Constants.MAX_ACC_FLAG; i++) { - if ((flags & pow) != 0) { - if ((pow == Constants.ACC_SYNCHRONIZED) && (reason == FLAG_FOR_CLASS)) { - buf.append("ACC_SUPER | "); - } else if ((pow == Constants.ACC_VOLATILE) && (reason == FLAG_FOR_METHOD)) { - buf.append("ACC_BRIDGE | "); - } else if ((pow == Constants.ACC_TRANSIENT) && (reason == FLAG_FOR_METHOD)) { - buf.append("ACC_VARARGS | "); - } else { - buf.append("ACC_") - .append(Constants.ACCESS_NAMES[i].toUpperCase(Locale.ENGLISH)).append( - " | "); - } - } - pow <<= 1; - } - String str = buf.toString(); - return str.substring(0, str.length() - 3); - } - - - static String printArgumentTypes( Type[] arg_types ) { - if (arg_types.length == 0) { - return "Type.NO_ARGS"; - } - StringBuffer args = new StringBuffer(); - for (int i = 0; i < arg_types.length; i++) { - args.append(printType(arg_types[i])); - if (i < arg_types.length - 1) { - args.append(", "); - } - } - return "new Type[] { " + args.toString() + " }"; - } - - - static String printType( Type type ) { - return printType(type.getSignature()); - } - - - static String printType( String signature ) { - Type type = Type.getType(signature); - byte t = type.getType(); - if (t <= Constants.T_VOID) { - return "Type." + Constants.TYPE_NAMES[t].toUpperCase(Locale.ENGLISH); - } else if (type.toString().equals("java.lang.String")) { - return "Type.STRING"; - } else if (type.toString().equals("java.lang.Object")) { - return "Type.OBJECT"; - } else if (type.toString().equals("java.lang.StringBuffer")) { - return "Type.STRINGBUFFER"; - } else if (type instanceof ArrayType) { - ArrayType at = (ArrayType) type; - return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions() - + ")"; - } else { - return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")"; - } - } - - - /** Default main method - */ - public static void main( String[] argv ) throws Exception { - JavaClass java_class; - String name = argv[0]; - if ((java_class = Repository.lookupClass(name)) == null) { - java_class = new ClassParser(name).parse(); // May throw IOException - } - BCELifier bcelifier = new BCELifier(java_class, System.out); - bcelifier.start(); - } + /** + * Default main method + */ + public static void main(String[] argv) throws Exception { + JavaClass java_class; + String name = argv[0]; + if ((java_class = Repository.lookupClass(name)) == null) { + java_class = new ClassParser(name).parse(); // May throw IOException + } + BCELifier bcelifier = new BCELifier(java_class, System.out); + bcelifier.start(); + } } diff --git a/src/org/apache/bcel/util/ByteSequence.java b/src/org/apache/bcel/util/ByteSequence.java index e82ab2c..918827d 100644 --- a/src/org/apache/bcel/util/ByteSequence.java +++ b/src/org/apache/bcel/util/ByteSequence.java @@ -20,49 +20,44 @@ import java.io.ByteArrayInputStream; import java.io.DataInputStream; /** - * Utility class that implements a sequence of bytes which can be read - * via the `readByte()' method. This is used to implement a wrapper for the - * Java byte code stream to gain some more readability. - * + * Utility class that implements a sequence of bytes which can be read via the + * `readByte()' method. This is used to implement a wrapper for the Java byte + * code stream to gain some more readability. + * * @version $Id: ByteSequence.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public final class ByteSequence extends DataInputStream { - private ByteArrayStream byte_stream; + private ByteArrayStream byte_stream; + public ByteSequence(byte[] bytes) { + super(new ByteArrayStream(bytes)); + byte_stream = (ByteArrayStream) in; + } - public ByteSequence(byte[] bytes) { - super(new ByteArrayStream(bytes)); - byte_stream = (ByteArrayStream) in; - } + public final int getIndex() { + return byte_stream.getPosition(); + } + final void unreadByte() { + byte_stream.unreadByte(); + } - public final int getIndex() { - return byte_stream.getPosition(); - } + private static final class ByteArrayStream extends ByteArrayInputStream { + ByteArrayStream(byte[] bytes) { + super(bytes); + } - final void unreadByte() { - byte_stream.unreadByte(); - } + final int getPosition() { + return pos; + } // is protected in ByteArrayInputStream - private static final class ByteArrayStream extends ByteArrayInputStream { - - ByteArrayStream(byte[] bytes) { - super(bytes); - } - - - final int getPosition() { - return pos; - } // is protected in ByteArrayInputStream - - - final void unreadByte() { - if (pos > 0) { - pos--; - } - } - } + final void unreadByte() { + if (pos > 0) { + pos--; + } + } + } } diff --git a/src/org/apache/bcel/util/ClassPath.java b/src/org/apache/bcel/util/ClassPath.java index 2950df0..76c42b2 100644 --- a/src/org/apache/bcel/util/ClassPath.java +++ b/src/org/apache/bcel/util/ClassPath.java @@ -34,380 +34,392 @@ import java.util.zip.ZipFile; /** * Responsible for loading (class) files from the CLASSPATH. Inspired by * sun.tools.ClassPath. - * + * * @version $Id: ClassPath.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ClassPath implements Serializable { - /** + /** * */ private static final long serialVersionUID = 1L; public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath(); - private PathEntry[] paths; - private String class_path; + private PathEntry[] paths; + private String class_path; + /** + * Search for classes in given path. + */ + public ClassPath(String class_path) { + this.class_path = class_path; + List vec = new ArrayList(); + for (StringTokenizer tok = new StringTokenizer(class_path, + System.getProperty("path.separator")); tok.hasMoreTokens();) { + String path = tok.nextToken(); + if (!path.equals("")) { + File file = new File(path); + try { + if (file.exists()) { + if (file.isDirectory()) { + vec.add(new Dir(path)); + } else { + vec.add(new Zip(new ZipFile(file))); + } + } + } catch (IOException e) { + System.err + .println("CLASSPATH component " + file + ": " + e); + } + } + } + paths = new PathEntry[vec.size()]; + vec.toArray(paths); + } - /** - * Search for classes in given path. - */ - public ClassPath(String class_path) { - this.class_path = class_path; - List vec = new ArrayList(); - for (StringTokenizer tok = new StringTokenizer(class_path, System - .getProperty("path.separator")); tok.hasMoreTokens();) { - String path = tok.nextToken(); - if (!path.equals("")) { - File file = new File(path); - try { - if (file.exists()) { - if (file.isDirectory()) { - vec.add(new Dir(path)); - } else { - vec.add(new Zip(new ZipFile(file))); - } - } - } catch (IOException e) { - System.err.println("CLASSPATH component " + file + ": " + e); - } - } - } - paths = new PathEntry[vec.size()]; - vec.toArray(paths); - } + /** + * Search for classes in CLASSPATH. + * + * @deprecated Use SYSTEM_CLASS_PATH constant + */ + @Deprecated + public ClassPath() { + this(getClassPath()); + } + /** + * @return used class path string + */ + @Override + public String toString() { + return class_path; + } - /** - * Search for classes in CLASSPATH. - * @deprecated Use SYSTEM_CLASS_PATH constant - */ - public ClassPath() { - this(getClassPath()); - } + @Override + public int hashCode() { + return class_path.hashCode(); + } + @Override + public boolean equals(Object o) { + if (o instanceof ClassPath) { + return class_path.equals(((ClassPath) o).class_path); + } + return false; + } - /** @return used class path string - */ - public String toString() { - return class_path; - } + private static final void getPathComponents(String path, List list) { + if (path != null) { + StringTokenizer tok = new StringTokenizer(path, File.pathSeparator); + while (tok.hasMoreTokens()) { + String name = tok.nextToken(); + File file = new File(name); + if (file.exists()) { + list.add(name); + } + } + } + } + /** + * Checks for class path components in the following properties: + * "java.class.path", "sun.boot.class.path", "java.ext.dirs" + * + * @return class path as used by default by BCEL + */ + public static final String getClassPath() { + String class_path = System.getProperty("java.class.path"); + String boot_path = System.getProperty("sun.boot.class.path"); + String ext_path = System.getProperty("java.ext.dirs"); + List list = new ArrayList(); + getPathComponents(class_path, list); + getPathComponents(boot_path, list); + List dirs = new ArrayList(); + getPathComponents(ext_path, dirs); + for (Iterator e = dirs.iterator(); e.hasNext();) { + File ext_dir = new File(e.next()); + String[] extensions = ext_dir.list(new FilenameFilter() { - public int hashCode() { - return class_path.hashCode(); - } + @Override + public boolean accept(File dir, String name) { + name = name.toLowerCase(Locale.ENGLISH); + return name.endsWith(".zip") || name.endsWith(".jar"); + } + }); + if (extensions != null) { + for (int i = 0; i < extensions.length; i++) { + list.add(ext_dir.getPath() + File.separatorChar + + extensions[i]); + } + } + } + StringBuffer buf = new StringBuffer(); + for (Iterator e = list.iterator(); e.hasNext();) { + buf.append(e.next()); + if (e.hasNext()) { + buf.append(File.pathSeparatorChar); + } + } + return buf.toString().intern(); + } + /** + * @param name + * fully qualified class name, e.g. java.lang.String + * @return input stream for class + */ + public InputStream getInputStream(String name) throws IOException { + return getInputStream(name.replace('.', '/'), ".class"); + } - public boolean equals( Object o ) { - if (o instanceof ClassPath) { - return class_path.equals(((ClassPath) o).class_path); - } - return false; - } + /** + * Return stream for class or resource on CLASSPATH. + * + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suff, e.g. .java + * @return input stream for file on class path + */ + public InputStream getInputStream(String name, String suffix) + throws IOException { + InputStream is = null; + try { + is = getClass().getClassLoader().getResourceAsStream(name + suffix); + } catch (Exception e) { + } + if (is != null) { + return is; + } + return getClassFile(name, suffix).getInputStream(); + } + /** + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suff, e.g. .java + * @return class file for the java class + */ + public ClassFile getClassFile(String name, String suffix) + throws IOException { + for (int i = 0; i < paths.length; i++) { + ClassFile cf; + if ((cf = paths[i].getClassFile(name, suffix)) != null) { + return cf; + } + } + throw new IOException("Couldn't find: " + name + suffix); + } - private static final void getPathComponents( String path, List list ) { - if (path != null) { - StringTokenizer tok = new StringTokenizer(path, File.pathSeparator); - while (tok.hasMoreTokens()) { - String name = tok.nextToken(); - File file = new File(name); - if (file.exists()) { - list.add(name); - } - } - } - } + /** + * @param name + * fully qualified class name, e.g. java.lang.String + * @return input stream for class + */ + public ClassFile getClassFile(String name) throws IOException { + return getClassFile(name, ".class"); + } + /** + * @param name + * fully qualified file name, e.g. java/lang/String + * @param suffix + * file name ends with suffix, e.g. .java + * @return byte array for file on class path + */ + public byte[] getBytes(String name, String suffix) throws IOException { + DataInputStream dis = null; + try { + InputStream is = getInputStream(name, suffix); + if (is == null) { + throw new IOException("Couldn't find: " + name + suffix); + } + dis = new DataInputStream(is); + byte[] bytes = new byte[is.available()]; + dis.readFully(bytes); + return bytes; + } finally { + if (dis != null) { + dis.close(); + } + } + } - /** Checks for class path components in the following properties: - * "java.class.path", "sun.boot.class.path", "java.ext.dirs" - * - * @return class path as used by default by BCEL - */ - public static final String getClassPath() { - String class_path = System.getProperty("java.class.path"); - String boot_path = System.getProperty("sun.boot.class.path"); - String ext_path = System.getProperty("java.ext.dirs"); - List list = new ArrayList(); - getPathComponents(class_path, list); - getPathComponents(boot_path, list); - List dirs = new ArrayList(); - getPathComponents(ext_path, dirs); - for (Iterator e = dirs.iterator(); e.hasNext();) { - File ext_dir = new File((String) e.next()); - String[] extensions = ext_dir.list(new FilenameFilter() { + /** + * @return byte array for class + */ + public byte[] getBytes(String name) throws IOException { + return getBytes(name, ".class"); + } - public boolean accept( File dir, String name ) { - name = name.toLowerCase(Locale.ENGLISH); - return name.endsWith(".zip") || name.endsWith(".jar"); - } - }); - if (extensions != null) { - for (int i = 0; i < extensions.length; i++) { - list.add(ext_dir.getPath() + File.separatorChar + extensions[i]); - } - } - } - StringBuffer buf = new StringBuffer(); - for (Iterator e = list.iterator(); e.hasNext();) { - buf.append((String) e.next()); - if (e.hasNext()) { - buf.append(File.pathSeparatorChar); - } - } - return buf.toString().intern(); - } + /** + * @param name + * name of file to search for, e.g. java/lang/String.java + * @return full (canonical) path for file + */ + public String getPath(String name) throws IOException { + int index = name.lastIndexOf('.'); + String suffix = ""; + if (index > 0) { + suffix = name.substring(index); + name = name.substring(0, index); + } + return getPath(name, suffix); + } + /** + * @param name + * name of file to search for, e.g. java/lang/String + * @param suffix + * file name suffix, e.g. .java + * @return full (canonical) path for file, if it exists + */ + public String getPath(String name, String suffix) throws IOException { + return getClassFile(name, suffix).getPath(); + } - /** - * @param name fully qualified class name, e.g. java.lang.String - * @return input stream for class - */ - public InputStream getInputStream( String name ) throws IOException { - return getInputStream(name.replace('.', '/'), ".class"); - } + private static abstract class PathEntry implements Serializable { - - /** - * Return stream for class or resource on CLASSPATH. - * - * @param name fully qualified file name, e.g. java/lang/String - * @param suffix file name ends with suff, e.g. .java - * @return input stream for file on class path - */ - public InputStream getInputStream( String name, String suffix ) throws IOException { - InputStream is = null; - try { - is = getClass().getClassLoader().getResourceAsStream(name + suffix); - } catch (Exception e) { - } - if (is != null) { - return is; - } - return getClassFile(name, suffix).getInputStream(); - } - - - /** - * @param name fully qualified file name, e.g. java/lang/String - * @param suffix file name ends with suff, e.g. .java - * @return class file for the java class - */ - public ClassFile getClassFile( String name, String suffix ) throws IOException { - for (int i = 0; i < paths.length; i++) { - ClassFile cf; - if ((cf = paths[i].getClassFile(name, suffix)) != null) { - return cf; - } - } - throw new IOException("Couldn't find: " + name + suffix); - } - - - /** - * @param name fully qualified class name, e.g. java.lang.String - * @return input stream for class - */ - public ClassFile getClassFile( String name ) throws IOException { - return getClassFile(name, ".class"); - } - - - /** - * @param name fully qualified file name, e.g. java/lang/String - * @param suffix file name ends with suffix, e.g. .java - * @return byte array for file on class path - */ - public byte[] getBytes( String name, String suffix ) throws IOException { - DataInputStream dis = null; - try { - InputStream is = getInputStream(name, suffix); - if (is == null) { - throw new IOException("Couldn't find: " + name + suffix); - } - dis = new DataInputStream(is); - byte[] bytes = new byte[is.available()]; - dis.readFully(bytes); - return bytes; - } finally { - if (dis != null) { - dis.close(); - } - } - } - - - /** - * @return byte array for class - */ - public byte[] getBytes( String name ) throws IOException { - return getBytes(name, ".class"); - } - - - /** - * @param name name of file to search for, e.g. java/lang/String.java - * @return full (canonical) path for file - */ - public String getPath( String name ) throws IOException { - int index = name.lastIndexOf('.'); - String suffix = ""; - if (index > 0) { - suffix = name.substring(index); - name = name.substring(0, index); - } - return getPath(name, suffix); - } - - - /** - * @param name name of file to search for, e.g. java/lang/String - * @param suffix file name suffix, e.g. .java - * @return full (canonical) path for file, if it exists - */ - public String getPath( String name, String suffix ) throws IOException { - return getClassFile(name, suffix).getPath(); - } - - private static abstract class PathEntry implements Serializable { - - /** + /** * */ private static final long serialVersionUID = 1L; - abstract ClassFile getClassFile( String name, String suffix ) throws IOException; - } + abstract ClassFile getClassFile(String name, String suffix) + throws IOException; + } - /** Contains information about file/ZIP entry of the Java class. - */ - public interface ClassFile { + /** + * Contains information about file/ZIP entry of the Java class. + */ + public interface ClassFile { - /** @return input stream for class file. - */ - public abstract InputStream getInputStream() throws IOException; + /** + * @return input stream for class file. + */ + public abstract InputStream getInputStream() throws IOException; + /** + * @return canonical path to class file. + */ + public abstract String getPath(); - /** @return canonical path to class file. - */ - public abstract String getPath(); + /** + * @return base path of found class, i.e. class is contained relative to + * that path, which may either denote a directory, or zip file + */ + public abstract String getBase(); + /** + * @return modification time of class file. + */ + public abstract long getTime(); - /** @return base path of found class, i.e. class is contained relative - * to that path, which may either denote a directory, or zip file - */ - public abstract String getBase(); + /** + * @return size of class file. + */ + public abstract long getSize(); + } + private static class Dir extends PathEntry { - /** @return modification time of class file. - */ - public abstract long getTime(); - - - /** @return size of class file. - */ - public abstract long getSize(); - } - - private static class Dir extends PathEntry { - - /** + /** * */ private static final long serialVersionUID = 1L; private String dir; + Dir(String d) { + dir = d; + } - Dir(String d) { - dir = d; - } + @Override + ClassFile getClassFile(String name, String suffix) throws IOException { + final File file = new File(dir + File.separatorChar + + name.replace('.', File.separatorChar) + suffix); + return file.exists() ? new ClassFile() { + @Override + public InputStream getInputStream() throws IOException { + return new FileInputStream(file); + } - ClassFile getClassFile( String name, String suffix ) throws IOException { - final File file = new File(dir + File.separatorChar - + name.replace('.', File.separatorChar) + suffix); - return file.exists() ? new ClassFile() { + @Override + public String getPath() { + try { + return file.getCanonicalPath(); + } catch (IOException e) { + return null; + } + } - public InputStream getInputStream() throws IOException { - return new FileInputStream(file); - } + @Override + public long getTime() { + return file.lastModified(); + } + @Override + public long getSize() { + return file.length(); + } - public String getPath() { - try { - return file.getCanonicalPath(); - } catch (IOException e) { - return null; - } - } + @Override + public String getBase() { + return dir; + } + } : null; + } + @Override + public String toString() { + return dir; + } + } - public long getTime() { - return file.lastModified(); - } + private static class Zip extends PathEntry { - - public long getSize() { - return file.length(); - } - - - public String getBase() { - return dir; - } - } : null; - } - - - public String toString() { - return dir; - } - } - - private static class Zip extends PathEntry { - - /** + /** * */ private static final long serialVersionUID = 1L; private ZipFile zip; + Zip(ZipFile z) { + zip = z; + } - Zip(ZipFile z) { - zip = z; - } + @Override + ClassFile getClassFile(String name, String suffix) throws IOException { + final ZipEntry entry = zip + .getEntry(name.replace('.', '/') + suffix); + return (entry != null) ? new ClassFile() { + @Override + public InputStream getInputStream() throws IOException { + return zip.getInputStream(entry); + } - ClassFile getClassFile( String name, String suffix ) throws IOException { - final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix); - return (entry != null) ? new ClassFile() { + @Override + public String getPath() { + return entry.toString(); + } - public InputStream getInputStream() throws IOException { - return zip.getInputStream(entry); - } + @Override + public long getTime() { + return entry.getTime(); + } + @Override + public long getSize() { + return entry.getSize(); + } - public String getPath() { - return entry.toString(); - } - - - public long getTime() { - return entry.getTime(); - } - - - public long getSize() { - return entry.getSize(); - } - - - public String getBase() { - return zip.getName(); - } - } : null; - } - } + @Override + public String getBase() { + return zip.getName(); + } + } : null; + } + } } diff --git a/src/org/apache/bcel/util/ClassQueue.java b/src/org/apache/bcel/util/ClassQueue.java index 04391be..8b761a4 100644 --- a/src/org/apache/bcel/util/ClassQueue.java +++ b/src/org/apache/bcel/util/ClassQueue.java @@ -19,38 +19,34 @@ package org.apache.bcel.util; import java.util.LinkedList; import org.apache.bcel.classfile.JavaClass; -/** - * Utility class implementing a (typesafe) queue of JavaClass - * objects. - * +/** + * Utility class implementing a (typesafe) queue of JavaClass objects. + * * @version $Id: ClassQueue.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm + * @author M. Dahm */ public class ClassQueue implements java.io.Serializable { - /** + /** * */ private static final long serialVersionUID = 1L; protected LinkedList vec = new LinkedList(); + public void enqueue(JavaClass clazz) { + vec.addLast(clazz); + } - public void enqueue( JavaClass clazz ) { - vec.addLast(clazz); - } + public JavaClass dequeue() { + return vec.removeFirst(); + } + public boolean empty() { + return vec.isEmpty(); + } - public JavaClass dequeue() { - return (JavaClass) vec.removeFirst(); - } - - - public boolean empty() { - return vec.isEmpty(); - } - - - public String toString() { - return vec.toString(); - } + @Override + public String toString() { + return vec.toString(); + } } diff --git a/src/org/apache/bcel/util/Repository.java b/src/org/apache/bcel/util/Repository.java index 306fe35..3d33a7c 100644 --- a/src/org/apache/bcel/util/Repository.java +++ b/src/org/apache/bcel/util/Repository.java @@ -19,10 +19,10 @@ package org.apache.bcel.util; import org.apache.bcel.classfile.JavaClass; /** - * Abstract definition of a class repository. Instances may be used - * to load classes from different sources and may be used in the + * Abstract definition of a class repository. Instances may be used to load + * classes from different sources and may be used in the * Repository.setRepository method. - * + * * @see org.apache.bcel.Repository * @version $Id: Repository.java 386056 2006-03-15 11:31:56Z tcurdt $ * @author M. Dahm @@ -30,44 +30,42 @@ import org.apache.bcel.classfile.JavaClass; */ public interface Repository extends java.io.Serializable { - /** - * Store the provided class under "clazz.getClassName()" - */ - public void storeClass( JavaClass clazz ); + /** + * Store the provided class under "clazz.getClassName()" + */ + public void storeClass(JavaClass clazz); + /** + * Remove class from repository + */ + public void removeClass(JavaClass clazz); - /** - * Remove class from repository - */ - public void removeClass( JavaClass clazz ); + /** + * Find the class with the name provided, if the class isn't there, return + * NULL. + */ + public JavaClass findClass(String className); + /** + * Find the class with the name provided, if the class isn't there, make an + * attempt to load it. + */ + public JavaClass loadClass(String className) + throws java.lang.ClassNotFoundException; - /** - * Find the class with the name provided, if the class - * isn't there, return NULL. - */ - public JavaClass findClass( String className ); + /** + * Find the JavaClass instance for the given run-time class object + */ + public JavaClass loadClass(Class clazz) + throws java.lang.ClassNotFoundException; + /** + * Clear all entries from cache. + */ + public void clear(); - /** - * Find the class with the name provided, if the class - * isn't there, make an attempt to load it. - */ - public JavaClass loadClass( String className ) throws java.lang.ClassNotFoundException; - - - /** - * Find the JavaClass instance for the given run-time class object - */ - public JavaClass loadClass( Class clazz ) throws java.lang.ClassNotFoundException; - - - /** Clear all entries from cache. - */ - public void clear(); - - - /** Get the ClassPath associated with this Repository - */ - public ClassPath getClassPath(); + /** + * Get the ClassPath associated with this Repository + */ + public ClassPath getClassPath(); } diff --git a/src/org/apache/bcel/util/SyntheticRepository.java b/src/org/apache/bcel/util/SyntheticRepository.java index b0da8b2..784fa05 100644 --- a/src/org/apache/bcel/util/SyntheticRepository.java +++ b/src/org/apache/bcel/util/SyntheticRepository.java @@ -26,169 +26,177 @@ import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.JavaClass; /** - * This repository is used in situations where a Class is created - * outside the realm of a ClassLoader. Classes are loaded from - * the file systems using the paths specified in the given - * class path. By default, this is the value returned by - * ClassPath.getClassPath(). - *
          - * It is designed to be used as a singleton, however it - * can also be used with custom classpaths. - * - /** - * Abstract definition of a class repository. Instances may be used - * to load classes from different sources and may be used in the + * This repository is used in situations where a Class is created outside the + * realm of a ClassLoader. Classes are loaded from the file systems using the + * paths specified in the given class path. By default, this is the value + * returned by ClassPath.getClassPath().
          + * It is designed to be used as a singleton, however it can also be used with + * custom classpaths. + * + * /** Abstract definition of a class repository. Instances may be used to load + * classes from different sources and may be used in the * Repository.setRepository method. - * + * * @see org.apache.bcel.Repository - * + * * @version $Id: SyntheticRepository.java 386056 2006-03-15 11:31:56Z tcurdt $ * @author M. Dahm * @author David Dixon-Peugh */ public class SyntheticRepository implements Repository { - /** + /** * */ private static final long serialVersionUID = 1L; - private static Map _instances = new HashMap(); // CLASSPATH X REPOSITORY - private ClassPath _path = null; - private Map> _loadedClasses = new HashMap>(); // CLASSNAME X JAVACLASS + private static Map _instances = new HashMap(); // CLASSPATH + // X + // REPOSITORY + private ClassPath _path = null; + private Map> _loadedClasses = new HashMap>(); // CLASSNAME + // X + // JAVACLASS + private SyntheticRepository(ClassPath path) { + _path = path; + } - private SyntheticRepository(ClassPath path) { - _path = path; - } + public static SyntheticRepository getInstance() { + return getInstance(ClassPath.SYSTEM_CLASS_PATH); + } + public static SyntheticRepository getInstance(ClassPath classPath) { + SyntheticRepository rep = _instances.get(classPath); + if (rep == null) { + rep = new SyntheticRepository(classPath); + _instances.put(classPath, rep); + } + return rep; + } - public static SyntheticRepository getInstance() { - return getInstance(ClassPath.SYSTEM_CLASS_PATH); - } + /** + * Store a new JavaClass instance into this Repository. + */ + @Override + public void storeClass(JavaClass clazz) { + _loadedClasses.put(clazz.getClassName(), new SoftReference( + clazz)); + clazz.setRepository(this); + } + /** + * Remove class from repository + */ + @Override + public void removeClass(JavaClass clazz) { + _loadedClasses.remove(clazz.getClassName()); + } - public static SyntheticRepository getInstance( ClassPath classPath ) { - SyntheticRepository rep = (SyntheticRepository) _instances.get(classPath); - if (rep == null) { - rep = new SyntheticRepository(classPath); - _instances.put(classPath, rep); - } - return rep; - } + /** + * Find an already defined (cached) JavaClass object by name. + */ + @Override + public JavaClass findClass(String className) { + SoftReference ref = _loadedClasses.get(className); + if (ref == null) { + return null; + } + return (JavaClass) ref.get(); + } + /** + * Find a JavaClass object by name. If it is already in this Repository, the + * Repository version is returned. Otherwise, the Repository's classpath is + * searched for the class (and it is added to the Repository if found). + * + * @param className + * the name of the class + * @return the JavaClass object + * @throws ClassNotFoundException + * if the class is not in the Repository, and could not be found + * on the classpath + */ + @Override + public JavaClass loadClass(String className) throws ClassNotFoundException { + if (className == null || className.equals("")) { + throw new IllegalArgumentException("Invalid class name " + + className); + } + className = className.replace('/', '.'); // Just in case, canonical form + JavaClass clazz = findClass(className); + if (clazz != null) { + return clazz; + } + try { + return loadClass(_path.getInputStream(className), className); + } catch (IOException e) { + throw new ClassNotFoundException( + "Exception while looking for class " + className + ": " + + e.toString()); + } + } - /** - * Store a new JavaClass instance into this Repository. - */ - public void storeClass( JavaClass clazz ) { - _loadedClasses.put(clazz.getClassName(), new SoftReference(clazz)); - clazz.setRepository(this); - } + /** + * Find the JavaClass object for a runtime Class object. If a class with the + * same name is already in this Repository, the Repository version is + * returned. Otherwise, getResourceAsStream() is called on the Class object + * to find the class's representation. If the representation is found, it is + * added to the Repository. + * + * @see Class + * @param clazz + * the runtime Class object + * @return JavaClass object for given runtime class + * @throws ClassNotFoundException + * if the class is not in the Repository, and its representation + * could not be found + */ + @Override + public JavaClass loadClass(Class clazz) throws ClassNotFoundException { + String className = clazz.getName(); + JavaClass repositoryClass = findClass(className); + if (repositoryClass != null) { + return repositoryClass; + } + String name = className; + int i = name.lastIndexOf('.'); + if (i > 0) { + name = name.substring(i + 1); + } + return loadClass(clazz.getResourceAsStream(name + ".class"), className); + } + private JavaClass loadClass(InputStream is, String className) + throws ClassNotFoundException { + try { + if (is != null) { + ClassParser parser = new ClassParser(is, className); + JavaClass clazz = parser.parse(); + storeClass(clazz); + return clazz; + } + } catch (IOException e) { + throw new ClassNotFoundException( + "Exception while looking for class " + className + ": " + + e.toString()); + } + throw new ClassNotFoundException("SyntheticRepository could not load " + + className); + } - /** - * Remove class from repository - */ - public void removeClass( JavaClass clazz ) { - _loadedClasses.remove(clazz.getClassName()); - } + /** + * ClassPath associated with the Repository. + */ + @Override + public ClassPath getClassPath() { + return _path; + } - - /** - * Find an already defined (cached) JavaClass object by name. - */ - public JavaClass findClass( String className ) { - SoftReference ref = (SoftReference) _loadedClasses.get(className); - if (ref == null) { - return null; - } - return (JavaClass) ref.get(); - } - - - /** - * Find a JavaClass object by name. - * If it is already in this Repository, the Repository version - * is returned. Otherwise, the Repository's classpath is searched for - * the class (and it is added to the Repository if found). - * - * @param className the name of the class - * @return the JavaClass object - * @throws ClassNotFoundException if the class is not in the - * Repository, and could not be found on the classpath - */ - public JavaClass loadClass( String className ) throws ClassNotFoundException { - if (className == null || className.equals("")) { - throw new IllegalArgumentException("Invalid class name " + className); - } - className = className.replace('/', '.'); // Just in case, canonical form - JavaClass clazz = findClass(className); - if (clazz != null) { - return clazz; - } - try { - return loadClass(_path.getInputStream(className), className); - } catch (IOException e) { - throw new ClassNotFoundException("Exception while looking for class " + className - + ": " + e.toString()); - } - } - - - /** - * Find the JavaClass object for a runtime Class object. - * If a class with the same name is already in this Repository, - * the Repository version is returned. Otherwise, getResourceAsStream() - * is called on the Class object to find the class's representation. - * If the representation is found, it is added to the Repository. - * - * @see Class - * @param clazz the runtime Class object - * @return JavaClass object for given runtime class - * @throws ClassNotFoundException if the class is not in the - * Repository, and its representation could not be found - */ - public JavaClass loadClass( Class clazz ) throws ClassNotFoundException { - String className = clazz.getName(); - JavaClass repositoryClass = findClass(className); - if (repositoryClass != null) { - return repositoryClass; - } - String name = className; - int i = name.lastIndexOf('.'); - if (i > 0) { - name = name.substring(i + 1); - } - return loadClass(clazz.getResourceAsStream(name + ".class"), className); - } - - - private JavaClass loadClass( InputStream is, String className ) throws ClassNotFoundException { - try { - if (is != null) { - ClassParser parser = new ClassParser(is, className); - JavaClass clazz = parser.parse(); - storeClass(clazz); - return clazz; - } - } catch (IOException e) { - throw new ClassNotFoundException("Exception while looking for class " + className - + ": " + e.toString()); - } - throw new ClassNotFoundException("SyntheticRepository could not load " + className); - } - - - /** ClassPath associated with the Repository. - */ - public ClassPath getClassPath() { - return _path; - } - - - /** Clear all entries from cache. - */ - public void clear() { - _loadedClasses.clear(); - } + /** + * Clear all entries from cache. + */ + @Override + public void clear() { + _loadedClasses.clear(); + } }