aboutsummaryrefslogtreecommitdiffstats
path: root/bcel-builder/src/main
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2019-01-24 12:41:06 -0800
committerAndy Clement <aclement@pivotal.io>2019-01-24 12:41:06 -0800
commit9659cfe976a424a20e7b840152a13d266e794226 (patch)
tree0ae99f276260be65a84660bc37bd7ebbed908e63 /bcel-builder/src/main
parent52c4cbfa1b8bcc0d2c7ac50c77203e516b335205 (diff)
downloadaspectj-9659cfe976a424a20e7b840152a13d266e794226.tar.gz
aspectj-9659cfe976a424a20e7b840152a13d266e794226.zip
mavenizing bcel-builder - complete
Diffstat (limited to 'bcel-builder/src/main')
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java685
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java396
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java150
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java260
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java55
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java213
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java99
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java268
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java69
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java249
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java180
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java388
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java196
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java149
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java109
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java112
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java107
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java116
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java87
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java108
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java111
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java88
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java132
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java108
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java132
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java121
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java87
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java111
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java157
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java66
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java111
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java816
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java120
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java109
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java131
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java171
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java87
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java199
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java136
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java201
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java232
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java181
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java837
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java120
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java276
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java267
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java230
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java136
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java273
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java112
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Modifiers.java140
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java664
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModuleMainClass.java106
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java126
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java118
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java131
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java65
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java310
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java58
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java169
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java190
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java210
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java172
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java185
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java215
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java1094
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java73
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java176
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java84
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java79
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java135
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java116
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java75
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java98
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java51
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java45
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java36
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java137
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeTypeAnnos.java105
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java51
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java45
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisTypeAnnos.java36
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/SimpleElementValue.java330
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/TypeAnnotationGen.java405
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java156
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java111
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java134
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java637
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java68
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java202
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java245
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java158
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java112
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java133
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java121
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java127
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java247
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java454
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java338
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java108
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java27
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java224
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java379
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java771
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java189
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java278
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java1287
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java291
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java92
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java70
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java129
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java137
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java112
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java130
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java44
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java220
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java96
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java183
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java1169
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java161
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java132
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java365
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java102
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java181
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java138
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java45
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java101
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java508
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java82
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java67
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java394
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java584
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java75
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java268
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java98
-rw-r--r--bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java195
136 files changed, 28559 insertions, 0 deletions
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java
new file mode 100644
index 000000000..c75496527
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Constants.java
@@ -0,0 +1,685 @@
+package org.aspectj.apache.bcel;
+
+import org.aspectj.apache.bcel.generic.Type;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * Constants for the project, mostly defined in the JVM specification.
+ *
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Andy Clement
+ */
+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_1_6 = 50;
+ public final static short MINOR_1_6 = 0;
+ public final static short MAJOR_1_7 = 51;
+ public final static short MINOR_1_7 = 0;
+ public final static short MAJOR_1_8 = 52;
+ public final static short MINOR_1_8 = 0;
+ public final static short MAJOR_1_9 = 53;
+ public final static short MINOR_1_9 = 0;
+ public final static short MAJOR_10 = 54;
+ public final static short MINOR_10 = 0;
+ public final static short MAJOR_11 = 55;
+ public final static short MINOR_11 = 0;
+ // Defaults
+ public final static short MAJOR = MAJOR_1_1;
+ 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 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;
+
+ 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_TRANSIENT = 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 int ACC_MODULE = 0x8000;
+ public final static short ACC_BRIDGE = 0x0040;
+ public final static short ACC_VARARGS = 0x0080;
+
+ // Module related
+ // Indicates that any module which depends on the current module,
+ // implicitly declares a dependence on the module indicated by this entry.
+ public final static int MODULE_ACC_TRANSITIVE = 0x0020;
+ // Indicates that this dependence is mandatory in the static phase, i.e., at
+ // compile time, but is optional in the dynamic phase, i.e., at run time.
+ public final static int MODULE_ACC_STATIC_PHASE = 0x0040;
+ // Indicates that this dependence was not explicitly or implicitly declared
+ // in the source of the module declaration.
+ public final static int MODULE_ACC_SYNTHETIC = 0x1000;
+ // Indicates that this dependence was implicitly declared in the source of
+ // the module declaration
+ public final static int MODULE_ACC_MANDATED = 0x8000;
+
+ // Applies to classes compiled by new compilers only
+ public final static short ACC_SUPER = 0x0020;
+
+ public final static short MAX_ACC_FLAG = ACC_STRICT;
+
+ public final static String[] ACCESS_NAMES = { "public", "private", "protected", "static", "final", "synchronized", "volatile",
+ "transient", "native", "interface", "abstract", "strictfp" };
+
+ /** 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 byte CONSTANT_MethodHandle = 15;
+ public final static byte CONSTANT_MethodType = 16;
+ public final static byte CONSTANT_Dynamic = 17;
+ public final static byte CONSTANT_InvokeDynamic = 18;
+
+ public final static byte CONSTANT_Module = 19;
+ public final static byte CONSTANT_Package = 20;
+
+
+ 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","","","CONSTANT_MethodHandle","CONSTANT_MethodType","","CONSTANT_InvokeDynamic",
+ // J9:
+ "CONSTANT_Module", "CONSTANT_Package"};
+
+ /**
+ * The name of the static initializer, also called &quot;class initialization method&quot; or &quot;interface initialization
+ * method&quot;. This is &quot;&lt;clinit&gt;&quot;.
+ */
+ public final static String STATIC_INITIALIZER_NAME = "<clinit>";
+
+ /**
+ * The name of every constructor method in a class, also called &quot;instance initialization method&quot;. This is
+ * &quot;&lt;init&gt;&quot;.
+ */
+ public final static String CONSTRUCTOR_NAME = "<init>";
+
+ /** The names of the interfaces implemented by arrays */
+ public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = { "java.lang.Cloneable", "java.io.Serializable" };
+
+ /**
+ * 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
+
+ /**
+ * 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 INVOKEDYNAMIC = 186;
+ 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;
+
+ /**
+ * 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;
+
+ /**
+ * For internal purposes only.
+ */
+ public static final short PUSH = 4711;
+ public static final short SWITCH = 4712;
+
+ /**
+ * Illegal codes
+ */
+ public static final short UNDEFINED = '/' - '0'; // -1;
+ public static final short UNPREDICTABLE = '.' - '0';// -2;
+ public static final short RESERVED = -3;
+ public static final String ILLEGAL_OPCODE = "<illegal opcode>";
+ public static final String ILLEGAL_TYPE = "<illegal type>";
+
+ 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;
+
+ 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 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 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 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 };
+
+ public static int PUSH_INST = 0x0001;
+ public static int CONSTANT_INST = 0x0002;
+ public static long LOADCLASS_INST = 0x0004;
+ public static int CP_INST = 0x0008;
+ public static int INDEXED = 0x0010;
+ public static int LOAD_INST = 0x0020; // load instruction
+ public static int LV_INST = 0x0040; // local variable instruction
+ public static int POP_INST = 0x0080;
+ public static int STORE_INST = 0x0100;
+ public static long STACK_INST = 0x0200;
+ public static long BRANCH_INSTRUCTION = 0x0400;
+ public static long TARGETER_INSTRUCTION = 0x0800;
+ public static long NEGATABLE = 0x1000;
+ public static long IF_INST = 0x2000;
+ public static long JSR_INSTRUCTION = 0x4000;
+ public static long RET_INST = 0x8000;
+ public static long EXCEPTION_THROWER = 0x10000;
+
+ public static final byte[] iLen = new byte[256];
+ public static final byte UNDEFINED_LENGTH = 'X' - '0';
+ public static final byte VARIABLE_LENGTH = 'V' - '0';
+ public static final byte[] stackEntriesProduced = new byte[256];
+ public static final Type[] types = new Type[256];
+ public static final long[] instFlags = new long[256];
+
+ public static final Class<Throwable>[][] instExcs = new Class[256][];
+
+ static final Object _unused = ConstantsInitializer.initialize();
+
+ /**
+ * 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 */
+ };
+
+ /**
+ * 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", "invokedynamic", "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 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_RUNTIME_VISIBLE_ANNOTATIONS = 12;
+ public static final byte ATTR_RUNTIME_INVISIBLE_ANNOTATIONS = 13;
+ public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = 14;
+ public static final byte ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = 15;
+ public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 16;
+ public static final byte ATTR_ENCLOSING_METHOD = 17;
+ public static final byte ATTR_ANNOTATION_DEFAULT = 18;
+ public static final byte ATTR_BOOTSTRAPMETHODS = 19;
+ public static final byte ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 20;
+ public static final byte ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 21;
+ public static final byte ATTR_METHOD_PARAMETERS = 22;
+
+ // J9:
+ public static final byte ATTR_MODULE = 23;
+ public static final byte ATTR_MODULE_PACKAGES = 24;
+ public static final byte ATTR_MODULE_MAIN_CLASS = 25;
+
+ // J11:
+ public static final byte ATTR_NEST_HOST = 26;
+ public static final byte ATTR_NEST_MEMBERS = 27;
+
+ public static final short KNOWN_ATTRIBUTES = 28;
+
+ public static final String[] ATTRIBUTE_NAMES = {
+ "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable",
+ "InnerClasses", "Synthetic", "Deprecated", "PMGClass", "Signature", "StackMap",
+ "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations",
+ "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod",
+ "AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations",
+ "MethodParameters", "Module", "ModulePackages", "ModuleMainClass", "NestHost", "NestMembers"
+ };
+
+ /**
+ * 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/bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java
new file mode 100644
index 000000000..b9bc0d49f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ConstantsInitializer.java
@@ -0,0 +1,396 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel;
+
+import org.aspectj.apache.bcel.generic.Type;
+
+public class ConstantsInitializer {
+
+ public static Object initialize() {
+ Constants.types[Constants.ILOAD] = Type.INT;
+ Constants.types[Constants.ISTORE] = Type.INT;
+ Constants.types[Constants.ILOAD_0] = Type.INT;
+ Constants.types[Constants.ISTORE_0] = Type.INT;
+ Constants.types[Constants.ILOAD_1] = Type.INT;
+ Constants.types[Constants.ISTORE_1] = Type.INT;
+ Constants.types[Constants.ILOAD_2] = Type.INT;
+ Constants.types[Constants.ISTORE_2] = Type.INT;
+ Constants.types[Constants.ILOAD_3] = Type.INT;
+ Constants.types[Constants.ISTORE_3] = Type.INT;
+ Constants.types[Constants.LLOAD] = Type.LONG;
+ Constants.types[Constants.LSTORE] = Type.LONG;
+ Constants.types[Constants.LLOAD_0] = Type.LONG;
+ Constants.types[Constants.LSTORE_0] = Type.LONG;
+ Constants.types[Constants.LLOAD_1] = Type.LONG;
+ Constants.types[Constants.LSTORE_1] = Type.LONG;
+ Constants.types[Constants.LLOAD_2] = Type.LONG;
+ Constants.types[Constants.LSTORE_2] = Type.LONG;
+ Constants.types[Constants.LLOAD_3] = Type.LONG;
+ Constants.types[Constants.LSTORE_3] = Type.LONG;
+ Constants.types[Constants.DLOAD] = Type.DOUBLE;
+ Constants.types[Constants.DSTORE] = Type.DOUBLE;
+ Constants.types[Constants.DLOAD_0] = Type.DOUBLE;
+ Constants.types[Constants.DSTORE_0] = Type.DOUBLE;
+ Constants.types[Constants.DLOAD_1] = Type.DOUBLE;
+ Constants.types[Constants.DSTORE_1] = Type.DOUBLE;
+ Constants.types[Constants.DLOAD_2] = Type.DOUBLE;
+ Constants.types[Constants.DSTORE_2] = Type.DOUBLE;
+ Constants.types[Constants.DLOAD_3] = Type.DOUBLE;
+ Constants.types[Constants.DSTORE_3] = Type.DOUBLE;
+ Constants.types[Constants.FLOAD] = Type.FLOAT;
+ Constants.types[Constants.FSTORE] = Type.FLOAT;
+ Constants.types[Constants.FLOAD_0] = Type.FLOAT;
+ Constants.types[Constants.FSTORE_0] = Type.FLOAT;
+ Constants.types[Constants.FLOAD_1] = Type.FLOAT;
+ Constants.types[Constants.FSTORE_1] = Type.FLOAT;
+ Constants.types[Constants.FLOAD_2] = Type.FLOAT;
+ Constants.types[Constants.FSTORE_2] = Type.FLOAT;
+ Constants.types[Constants.FLOAD_3] = Type.FLOAT;
+ Constants.types[Constants.FSTORE_3] = Type.FLOAT;
+ Constants.types[Constants.ALOAD] = Type.OBJECT;
+ Constants.types[Constants.ASTORE] = Type.OBJECT;
+ Constants.types[Constants.ALOAD_0] = Type.OBJECT;
+ Constants.types[Constants.ASTORE_0] = Type.OBJECT;
+ Constants.types[Constants.ALOAD_1] = Type.OBJECT;
+ Constants.types[Constants.ASTORE_1] = Type.OBJECT;
+ Constants.types[Constants.ALOAD_2] = Type.OBJECT;
+ Constants.types[Constants.ASTORE_2] = Type.OBJECT;
+ Constants.types[Constants.ALOAD_3] = Type.OBJECT;
+ Constants.types[Constants.ASTORE_3] = Type.OBJECT;
+
+ // INSTRUCTION_FLAGS - set for all
+ Constants.instFlags[Constants.NOP] = 0;
+ Constants.instFlags[Constants.ACONST_NULL] = Constants.PUSH_INST;
+ Constants.instFlags[Constants.ICONST_M1] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.ICONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.ICONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.ICONST_2] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.ICONST_3] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.ICONST_4] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.ICONST_5] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.LCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.LCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.FCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.FCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.FCONST_2] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.DCONST_0] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.DCONST_1] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+
+ Constants.instFlags[Constants.BIPUSH] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+ Constants.instFlags[Constants.SIPUSH] = Constants.PUSH_INST | Constants.CONSTANT_INST;
+
+ Constants.instFlags[Constants.LDC] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST
+ | Constants.INDEXED;
+
+ Constants.instFlags[Constants.LDC_W] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST
+ | Constants.INDEXED;
+
+ Constants.instFlags[Constants.LDC2_W] = Constants.EXCEPTION_THROWER | Constants.PUSH_INST | Constants.CP_INST
+ | Constants.INDEXED;
+
+ // the next five could be 'wide' prefixed and so have longer lengths
+ Constants.instFlags[Constants.ILOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.LLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.FLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.DLOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.ALOAD] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST;
+ for (int ii = Constants.ILOAD_0; ii <= Constants.ALOAD_3; ii++) {
+ Constants.instFlags[ii] = Constants.INDEXED | Constants.LOAD_INST | Constants.PUSH_INST | Constants.LV_INST;
+ }
+
+ // the next five could be 'wide' prefixed and so have longer lengths
+ Constants.instFlags[Constants.ISTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.LSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.FSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.DSTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST;
+ Constants.instFlags[Constants.ASTORE] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST;
+ for (int ii = Constants.ISTORE_0; ii <= Constants.ASTORE_3; ii++) {
+ Constants.instFlags[ii] = Constants.INDEXED | Constants.STORE_INST | Constants.POP_INST | Constants.LV_INST;
+ }
+
+ Constants.instFlags[Constants.IDIV] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.IDIV] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION };
+ Constants.instFlags[Constants.IREM] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.IREM] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION };
+ Constants.instFlags[Constants.LDIV] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.LDIV] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION };
+ Constants.instFlags[Constants.LREM] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.LREM] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION };
+
+ Constants.instFlags[Constants.ARRAYLENGTH] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.ARRAYLENGTH] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION };
+ Constants.instFlags[Constants.ATHROW] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.ATHROW] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.THROWABLE };
+
+ Constants.instFlags[Constants.AALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.AALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.IALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.IALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.BALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.BALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.FALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.FALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.DALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.DALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.CALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.CALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.LALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.LALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.SALOAD] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.SALOAD] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+
+ Constants.instFlags[Constants.AASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.AASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.IASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.IASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.BASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.BASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.FASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.FASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.DASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.DASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.CASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.CASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.LASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.LASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+ Constants.instFlags[Constants.SASTORE] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.SASTORE] = org.aspectj.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+
+ // stack instructions
+ Constants.instFlags[Constants.DUP] = Constants.PUSH_INST | Constants.STACK_INST;
+ Constants.instFlags[Constants.DUP_X1] = Constants.STACK_INST; // TODO fixme - aren't these two push/stack producers?
+ // (although peculiar ones...)
+ Constants.instFlags[Constants.DUP_X2] = Constants.STACK_INST;
+ Constants.instFlags[Constants.DUP2] = Constants.PUSH_INST | Constants.STACK_INST;
+ Constants.instFlags[Constants.DUP2_X1] = Constants.STACK_INST; // TODO fixme - aren't these two push/stack producers?
+ // (although peculiar ones...)
+ Constants.instFlags[Constants.DUP2_X2] = Constants.STACK_INST;
+ Constants.instFlags[Constants.POP] = Constants.STACK_INST | Constants.POP_INST;
+ Constants.instFlags[Constants.POP2] = Constants.STACK_INST | Constants.POP_INST;
+ Constants.instFlags[Constants.SWAP] = Constants.STACK_INST;
+
+ Constants.instFlags[Constants.MONITORENTER] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.MONITORENTER] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION };
+ Constants.instFlags[Constants.MONITOREXIT] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.MONITOREXIT] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION };
+
+ // branching instructions
+ Constants.instFlags[Constants.GOTO] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION;
+ Constants.instFlags[Constants.GOTO_W] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION;
+ Constants.instFlags[Constants.JSR] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.JSR_INSTRUCTION;
+ Constants.instFlags[Constants.JSR_W] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.JSR_INSTRUCTION;
+
+ Constants.instFlags[Constants.IFGT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE
+ | Constants.IF_INST;
+ Constants.instFlags[Constants.IFLE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE
+ | Constants.IF_INST;
+ Constants.instFlags[Constants.IFNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE
+ | Constants.IF_INST;
+ Constants.instFlags[Constants.IFEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE
+ | Constants.IF_INST;
+ Constants.instFlags[Constants.IFGE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE
+ | Constants.IF_INST;
+ Constants.instFlags[Constants.IFLT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE
+ | Constants.IF_INST;
+ Constants.instFlags[Constants.IFNULL] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION | Constants.NEGATABLE
+ | Constants.IF_INST;
+ Constants.instFlags[Constants.IFNONNULL] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ACMPEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ACMPNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ICMPEQ] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ICMPGE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ICMPGT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ICMPLE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ICMPLT] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+ Constants.instFlags[Constants.IF_ICMPNE] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION
+ | Constants.NEGATABLE | Constants.IF_INST;
+
+ Constants.instFlags[Constants.LOOKUPSWITCH] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION;
+ Constants.instFlags[Constants.TABLESWITCH] = Constants.BRANCH_INSTRUCTION | Constants.TARGETER_INSTRUCTION;
+
+ // fixme these class arrays should be constants
+ Constants.instFlags[Constants.ARETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.ARETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE };
+ Constants.instFlags[Constants.DRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.DRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE };
+ Constants.instFlags[Constants.FRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.FRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE };
+ Constants.instFlags[Constants.IRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.IRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE };
+ Constants.instFlags[Constants.LRETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.LRETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE };
+ Constants.instFlags[Constants.RETURN] = Constants.RET_INST | Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.RETURN] = new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE };
+
+ Constants.instFlags[Constants.NEW] = Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER | Constants.CP_INST
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.NEW] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_FOR_ALLOCATIONS;
+ Constants.instFlags[Constants.NEWARRAY] = Constants.EXCEPTION_THROWER;
+ Constants.instExcs[Constants.NEWARRAY] = new Class[] { org.aspectj.apache.bcel.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION };
+
+ Constants.types[Constants.IINC] = Type.INT;
+ Constants.instFlags[Constants.IINC] = Constants.LV_INST | Constants.INDEXED;
+ Constants.instFlags[Constants.RET] = Constants.INDEXED;
+
+ Constants.instFlags[Constants.ANEWARRAY] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.ANEWARRAY] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY;
+ Constants.instFlags[Constants.CHECKCAST] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.CHECKCAST] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_CHECKCAST;
+ Constants.instFlags[Constants.INSTANCEOF] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.INSTANCEOF] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION;
+ Constants.instFlags[Constants.MULTIANEWARRAY] = Constants.CP_INST | Constants.LOADCLASS_INST | Constants.EXCEPTION_THROWER
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.MULTIANEWARRAY] = ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY; // fixme i
+ // think
+ // this
+ // is a
+ // stackproducer, old
+ // bcel says no...
+
+ Constants.instFlags[Constants.GETFIELD] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.GETFIELD] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD;
+ Constants.instFlags[Constants.GETSTATIC] = Constants.PUSH_INST | Constants.EXCEPTION_THROWER | Constants.LOADCLASS_INST
+ | Constants.CP_INST | Constants.INDEXED;
+ Constants.instExcs[Constants.GETSTATIC] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC;
+ Constants.instFlags[Constants.PUTFIELD] = Constants.POP_INST | Constants.EXCEPTION_THROWER | Constants.LOADCLASS_INST
+ | Constants.CP_INST | Constants.INDEXED;
+ Constants.instExcs[Constants.PUTFIELD] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD;
+ Constants.instFlags[Constants.PUTSTATIC] = Constants.EXCEPTION_THROWER | Constants.POP_INST | Constants.CP_INST
+ | Constants.LOADCLASS_INST | Constants.INDEXED;
+ Constants.instExcs[Constants.PUTSTATIC] = ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC;
+
+ Constants.instFlags[Constants.INVOKEINTERFACE] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.INVOKEINTERFACE] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKEINTERFACE;
+ Constants.instFlags[Constants.INVOKESPECIAL] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.INVOKESPECIAL] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL;
+ Constants.instFlags[Constants.INVOKESTATIC] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.INVOKESTATIC] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESTATIC;
+ Constants.instFlags[Constants.INVOKEVIRTUAL] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST
+ | Constants.INDEXED;
+ Constants.instExcs[Constants.INVOKEVIRTUAL] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL;
+
+ Constants.instFlags[Constants.INVOKEDYNAMIC] = Constants.EXCEPTION_THROWER | Constants.CP_INST | Constants.LOADCLASS_INST
+ | Constants.INDEXED;
+ // TBD
+ // Constants.instExcs[Constants.INVOKEDYNAMIC] = ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL;
+
+ //@formatter:off
+ char[] lengths = // . = varies in length, / = undefined
+ ("1111111111111111" + // nop > dconst_1
+ "2323322222111111" + // bipush > lload_1
+ "1111111111111111" + // lload_2 > laload
+ "1111112222211111" + // faload > lstore_0
+ "1111111111111111" + // lstore_1 > iastore
+ "1111111111111111" + // lastore > swap
+ "1111111111111111" + // iadd > ddiv
+ "1111111111111111" + // irem > land
+ "1111311111111111" + // ior > d2l
+ "1111111113333333" + // d2f > if_icmpeq
+ "3333333332..1111" + // if_icmpne > dreturn
+ "1133333335532311" + // areturn > athrow
+ "3311.433551/////").toCharArray(); // checkcast >
+ //@formatter:on
+ int count = 0;
+ for (; count < lengths.length; count++) {
+ Constants.iLen[count] = (byte) (lengths[count] - 48);
+ }
+ while (count < 256) {
+ Constants.iLen[count] = Constants.UNDEFINED;
+ count++;
+ }
+ Constants.iLen[Constants.BREAKPOINT] = 1;
+ Constants.iLen[Constants.IMPDEP1] = 1;
+ Constants.iLen[Constants.IMPDEP2] = 1;
+
+ char[] producesOnStack = ("0111111112211122" + // nop > dconst_1
+ "1111212121111122" + // bipush > lload_1
+ "2211112222111112" + // lload_2 > laload
+ "1211110000000000" + // faload > lstore_0
+ "0000000000000000" + // lstore_1 > iastore
+ "0000000002344562" + // lastore > swap
+ "1212121212121212" + // iadd > ddiv
+ "1212121212121212" + // irem > land
+ "1212021211212212" + // ior > d2l
+ "1111111110000000" + // d2f > if_icmpeq
+ "0000000010000000" + // if_icmpne > dreturn
+ "00.0.0.....11111" + // areturn > athrow
+ "11000100010/").toCharArray(); // checkcast >
+ count = 0;
+ for (; count < producesOnStack.length; count++) {
+ Constants.stackEntriesProduced[count] = (byte) (producesOnStack[count] - 48);
+ }
+ while (count < 256) {
+ Constants.iLen[count] = Constants.UNDEFINED;
+ count++;
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java
new file mode 100644
index 000000000..cf3d81308
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/ExceptionConstants.java
@@ -0,0 +1,150 @@
+package org.aspectj.apache.bcel;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * Exception constants.
+ *
+ * @version $Id: ExceptionConstants.java,v 1.5 2009/09/14 20:29:10 aclement Exp $
+ * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase">E. Haase</A>
+ */
+@SuppressWarnings("rawtypes")
+public interface ExceptionConstants {
+ /**
+ * The mother of all exceptions
+ */
+ public static final Class<Throwable> THROWABLE = Throwable.class;
+
+ /**
+ * Super class of any run-time exception
+ */
+ public static final Class<RuntimeException> RUNTIME_EXCEPTION = RuntimeException.class;
+
+ /**
+ * Super class of any linking exception (aka Linkage Error)
+ */
+ public static final Class<LinkageError> LINKING_EXCEPTION = LinkageError.class;
+
+ /**
+ * Linking Exceptions
+ */
+ public static final Class<ClassCircularityError> CLASS_CIRCULARITY_ERROR = ClassCircularityError.class;
+ public static final Class<ClassFormatError> CLASS_FORMAT_ERROR = ClassFormatError.class;
+ public static final Class<ExceptionInInitializerError> EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class;
+ public static final Class<IncompatibleClassChangeError> INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class;
+ public static final Class<AbstractMethodError> ABSTRACT_METHOD_ERROR = AbstractMethodError.class;
+ public static final Class<IllegalAccessError> ILLEGAL_ACCESS_ERROR = IllegalAccessError.class;
+ public static final Class<InstantiationError> INSTANTIATION_ERROR = InstantiationError.class;
+ public static final Class<NoSuchFieldError> NO_SUCH_FIELD_ERROR = NoSuchFieldError.class;
+ public static final Class<NoSuchMethodError> NO_SUCH_METHOD_ERROR = NoSuchMethodError.class;
+ public static final Class<NoClassDefFoundError> NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class;
+ public static final Class<UnsatisfiedLinkError> UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class;
+ public static final Class<VerifyError> 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<NullPointerException> NULL_POINTER_EXCEPTION = NullPointerException.class;
+ public static final Class<ArrayIndexOutOfBoundsException> ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class;
+ public static final Class<ArithmeticException> ARITHMETIC_EXCEPTION = ArithmeticException.class;
+ public static final Class<NegativeArraySizeException> NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class;
+ public static final Class<ClassCastException> CLASS_CAST_EXCEPTION = ClassCastException.class;
+ public static final Class<IllegalMonitorStateException> 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_CLASS_AND_INTERFACE_RESOLUTION_MULTIANEWARRAY = { NO_CLASS_DEF_FOUND_ERROR,
+ CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR,
+ NEGATIVE_ARRAY_SIZE_EXCEPTION, ILLEGAL_ACCESS_ERROR };
+ public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_ANEWARRAY = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR,
+ VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR,
+ NEGATIVE_ARRAY_SIZE_EXCEPTION }; // Chapter 5.1
+ public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_CHECKCAST = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR,
+ VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR, CLASS_CAST_EXCEPTION }; // Chapter
+ // 5.1
+ public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION_FOR_ALLOCATIONS = { NO_CLASS_DEF_FOUND_ERROR,
+ CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR,
+ INSTANTIATION_ERROR, ILLEGAL_ACCESS_ERROR };
+
+ 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_FIELD_AND_METHOD_RESOLUTION_GETFIELD_PUTFIELD = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR,
+ NO_SUCH_METHOD_ERROR, INCOMPATIBLE_CLASS_CHANGE_ERROR, NULL_POINTER_EXCEPTION };
+
+ public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION_GETSTATIC_PUTSTATIC = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR,
+ NO_SUCH_METHOD_ERROR, INCOMPATIBLE_CLASS_CHANGE_ERROR };
+
+ public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKEINTERFACE = { INCOMPATIBLE_CLASS_CHANGE_ERROR,
+ ILLEGAL_ACCESS_ERROR, ABSTRACT_METHOD_ERROR, UNSATISFIED_LINK_ERROR };
+ public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESPECIAL_INVOKEVIRTUAL = { INCOMPATIBLE_CLASS_CHANGE_ERROR,
+ NULL_POINTER_EXCEPTION, ABSTRACT_METHOD_ERROR, UNSATISFIED_LINK_ERROR };
+// public static final Class[] EXCS_INVOKEDYNAMIC = { BOOTSTRAP_METHOD_ERROR};
+
+ public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION_INVOKESTATIC = { INCOMPATIBLE_CLASS_CHANGE_ERROR,
+ UNSATISFIED_LINK_ERROR };
+
+ 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/bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java
new file mode 100644
index 000000000..073355b5b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/Repository.java
@@ -0,0 +1,260 @@
+package org.aspectj.apache.bcel;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.classfile.JavaClass;
+import org.aspectj.apache.bcel.util.ClassPath;
+import org.aspectj.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.
+ *
+ * @see org.aspectj.apache.bcel.util.Repository
+ * @see org.aspectj.apache.bcel.util.SyntheticRepository
+ *
+ * @version $Id: Repository.java,v 1.6 2009/09/09 22:18:20 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public abstract class Repository {
+ private static org.aspectj.apache.bcel.util.Repository _repository = null;
+
+ /**
+ * @return currently used repository instance
+ */
+ public static org.aspectj.apache.bcel.util.Repository getRepository() {
+ if (_repository == null) {
+ _repository = SyntheticRepository.getInstance();
+ }
+ return _repository;
+ }
+
+ /**
+ * Set repository instance to be used for class loading
+ */
+ public static void setRepository(org.aspectj.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, or null if the class could not be found or parsed correctly
+ */
+ public static JavaClass lookupClass(String class_name) {
+ try {
+ JavaClass clazz = getRepository().findClass(class_name);
+
+ if (clazz != null) {
+ return clazz;
+ }
+
+ return getRepository().loadClass(class_name);
+ } catch (ClassNotFoundException ex) {
+ return null;
+ }
+ }
+
+ // /**
+ // * Try to find class source via getResourceAsStream().
+ // *
+ // * @see Class
+ // * @return JavaClass object for given runtime class
+ // */
+ // public static JavaClass lookupClass(Class clazz) {
+ // try {
+ // return getRepository().loadClass(clazz);
+ // } catch (ClassNotFoundException ex) {
+ // return null;
+ // }
+ // }
+
+ /**
+ * @return class file object for given Java class.
+ */
+ public static ClassPath.ClassFile lookupClassFile(String class_name) {
+ try {
+ return ClassPath.getSystemClassPath().getClassFile(class_name);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Clear the repository.
+ */
+ public static void clearCache() {
+ getRepository().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 = getRepository().findClass(clazz.getClassName());
+ getRepository().storeClass(clazz);
+ return old;
+ }
+
+ /**
+ * Remove class with given (fully qualified) name from repository.
+ */
+ public static void removeClass(String clazz) {
+ getRepository().removeClass(getRepository().findClass(clazz));
+ }
+
+ // /**
+ // * Remove given class from repository.
+ // */
+ // public static void removeClass(JavaClass clazz) {
+ // getRepository().removeClass(clazz);
+ // }
+
+ // /**
+ // * @return list of super classes of clazz in ascending order, i.e., Object is always the last element
+ // */
+ // public static JavaClass[] getSuperClasses(JavaClass clazz) {
+ // return clazz.getSuperClasses();
+ // }
+ //
+ // /**
+ // * @return list of super classes of clazz in ascending order, i.e., Object is always the last element. return "null", if class
+ // * cannot be found.
+ // */
+ // public static JavaClass[] getSuperClasses(String class_name) {
+ // JavaClass jc = lookupClass(class_name);
+ // return jc == null ? null : 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).
+ // */
+ // public static JavaClass[] getInterfaces(JavaClass clazz) {
+ // return clazz.getAllInterfaces();
+ // }
+
+ // /**
+ // * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces, and so
+ // on
+ // */
+ // public static JavaClass[] getInterfaces(String class_name) {
+ // return getInterfaces(lookupClass(class_name));
+ // }
+
+ /**
+ * Equivalent to runtime "instanceof" operator.
+ *
+ * @return true, if clazz is an instance of super_class
+ */
+ public static boolean instanceOf(JavaClass clazz, JavaClass super_class) {
+ return clazz.instanceOf(super_class);
+ }
+
+ /**
+ * @return true, if clazz is an instance of super_class
+ */
+ public static boolean instanceOf(String clazz, String super_class) {
+ return instanceOf(lookupClass(clazz), lookupClass(super_class));
+ }
+
+ // /**
+ // * @return true, if clazz is an instance of super_class
+ // */
+ // public static boolean instanceOf(JavaClass clazz, String super_class) {
+ // return instanceOf(clazz, lookupClass(super_class));
+ // }
+
+ // /**
+ // * @return true, if clazz is an instance of super_class
+ // */
+ // public static boolean instanceOf(String clazz, JavaClass super_class) {
+ // return instanceOf(lookupClass(clazz), super_class);
+ // }
+
+ /**
+ * @return true, if clazz is an implementation of interface inter
+ */
+ public static boolean implementationOf(JavaClass clazz, JavaClass inter) {
+ return clazz.implementationOf(inter);
+ }
+
+ /**
+ * @return true, if clazz is an implementation of interface inter
+ */
+ public static boolean implementationOf(String clazz, String inter) {
+ return implementationOf(lookupClass(clazz), lookupClass(inter));
+ }
+
+ //
+ // /**
+ // * @return true, if clazz is an implementation of interface inter
+ // */
+ // public static boolean implementationOf(JavaClass clazz, String inter) {
+ // return implementationOf(clazz, lookupClass(inter));
+ // }
+
+ // /**
+ // * @return true, if clazz is an implementation of interface inter
+ // */
+ // public static boolean implementationOf(String clazz, JavaClass inter) {
+ // return implementationOf(lookupClass(clazz), inter);
+ // }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java
new file mode 100644
index 000000000..bd5a7251f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AnnotationDefault.java
@@ -0,0 +1,55 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
+
+/**
+ * This attribute is attached to a method and indicates the default
+ * value for an annotation element.
+ */
+public class AnnotationDefault extends Attribute {
+
+ private ElementValue value;
+
+ public AnnotationDefault(int nameIndex, int len, DataInputStream dis, ConstantPool cpool) throws IOException {
+ this(nameIndex, len, ElementValue.readElementValue(dis,cpool), cpool);
+ }
+
+ private AnnotationDefault(int nameIndex, int len, ElementValue value, ConstantPool cpool) {
+ super(Constants.ATTR_ANNOTATION_DEFAULT, nameIndex, len, cpool);
+ this.value = value;
+ }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ // is this next line sufficient?
+ // return (EnclosingMethod)clone();
+ }
+
+ public final ElementValue getElementValue() { return value; }
+
+ public final void dump(DataOutputStream dos) throws IOException {
+ super.dump(dos);
+ value.dump(dos);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitAnnotationDefault(this);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java
new file mode 100644
index 000000000..daeb59a38
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Attribute.java
@@ -0,0 +1,213 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos;
+
+/**
+ * Abstract super class for <em>Attribute</em> objects. Currently the <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>,
+ * <em>Exceptiontable</em>, <em>LineNumberTable</em>, <em>LocalVariableTable</em>, <em>InnerClasses</em> and <em>Synthetic</em>
+ * attributes are supported. The <em>Unknown</em> attribute stands for non-standard-attributes.
+ *
+ * @version $Id: Attribute.java,v 1.9 2009/12/09 18:01:31 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @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 {
+ public final static Attribute[] NoAttributes = new Attribute[0];
+
+ protected byte tag; // Tag to distinguish subclasses
+ protected int nameIndex;
+ protected int length;
+ protected ConstantPool cpool;
+
+ protected Attribute(byte tag, int nameIndex, int length, ConstantPool cpool) {
+ this.tag = tag;
+ this.nameIndex = nameIndex;
+ this.length = length;
+ this.cpool = cpool;
+ }
+
+ public void dump(DataOutputStream file) throws IOException {
+ file.writeShort(nameIndex);
+ file.writeInt(length);
+ }
+
+ // OPTIMIZE how about just reading them in and storing them until we need to decode what they really are?
+ public static final Attribute readAttribute(DataInputStream file, ConstantPool cpool) throws IOException {
+ byte tag = Constants.ATTR_UNKNOWN;
+ int idx = file.readUnsignedShort();
+ String name = cpool.getConstantUtf8(idx).getValue();
+ int len = 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;
+ break;
+ }
+ }
+ switch (tag) {
+ case Constants.ATTR_UNKNOWN:
+ return new Unknown(idx, len, file, cpool);
+ case Constants.ATTR_CONSTANT_VALUE:
+ return new ConstantValue(idx, len, file, cpool);
+ case Constants.ATTR_SOURCE_FILE:
+ return new SourceFile(idx, len, file, cpool);
+ case Constants.ATTR_CODE:
+ return new Code(idx, len, file, cpool);
+ case Constants.ATTR_EXCEPTIONS:
+ return new ExceptionTable(idx, len, file, cpool);
+ case Constants.ATTR_LINE_NUMBER_TABLE:
+ return new LineNumberTable(idx, len, file, cpool);
+ case Constants.ATTR_LOCAL_VARIABLE_TABLE:
+ return new LocalVariableTable(idx, len, file, cpool);
+ case Constants.ATTR_INNER_CLASSES:
+ return new InnerClasses(idx, len, file, cpool);
+ case Constants.ATTR_SYNTHETIC:
+ return new Synthetic(idx, len, file, cpool);
+ case Constants.ATTR_DEPRECATED:
+ return new Deprecated(idx, len, file, cpool);
+ case Constants.ATTR_SIGNATURE:
+ return new Signature(idx, len, file, cpool);
+ case Constants.ATTR_STACK_MAP:
+ return new StackMap(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS:
+ return new RuntimeVisAnnos(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS:
+ return new RuntimeInvisAnnos(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS:
+ return new RuntimeVisParamAnnos(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS:
+ return new RuntimeInvisParamAnnos(idx, len, file, cpool);
+ case Constants.ATTR_ANNOTATION_DEFAULT:
+ return new AnnotationDefault(idx, len, file, cpool);
+ case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE:
+ return new LocalVariableTypeTable(idx, len, file, cpool);
+ case Constants.ATTR_ENCLOSING_METHOD:
+ return new EnclosingMethod(idx, len, file, cpool);
+ case Constants.ATTR_BOOTSTRAPMETHODS:
+ return new BootstrapMethods(idx,len,file,cpool);
+ case Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:
+ return new RuntimeVisTypeAnnos(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS:
+ return new RuntimeInvisTypeAnnos(idx, len, file, cpool);
+ case Constants.ATTR_METHOD_PARAMETERS:
+ return new MethodParameters(idx, len, file, cpool);
+ case Constants.ATTR_MODULE:
+ return new Module(idx, len, file, cpool);
+ case Constants.ATTR_MODULE_PACKAGES:
+ return new ModulePackages(idx, len, file, cpool);
+ case Constants.ATTR_MODULE_MAIN_CLASS:
+ return new ModuleMainClass(idx, len, file, cpool);
+ case Constants.ATTR_NEST_HOST:
+ return new NestHost(idx, len, file, cpool);
+ case Constants.ATTR_NEST_MEMBERS:
+ return new NestMembers(idx, len, file, cpool);
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getName() {
+ return cpool.getConstantUtf8(nameIndex).getValue();
+ }
+
+ public final int getLength() {
+ return length;
+ }
+
+ public final int getNameIndex() {
+ return nameIndex;
+ }
+
+ public final byte getTag() {
+ return tag;
+ }
+
+ public final ConstantPool getConstantPool() {
+ return cpool;
+ }
+
+ @Override
+ public String toString() {
+ return Constants.ATTRIBUTE_NAMES[tag];
+ }
+
+ @Override
+ public abstract void accept(ClassVisitor v);
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java
new file mode 100644
index 000000000..45d1597a7
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/AttributeUtils.java
@@ -0,0 +1,99 @@
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+public class AttributeUtils {
+
+ public static Attribute[] readAttributes(DataInputStream dataInputstream, ConstantPool cpool) {
+ try {
+ int length = dataInputstream.readUnsignedShort();
+ if (length == 0) {
+ return Attribute.NoAttributes;
+ }
+ Attribute[] attrs = new Attribute[length];
+ for (int i = 0; i < length; i++) {
+ attrs[i] = Attribute.readAttribute(dataInputstream, cpool);
+ }
+ return attrs;
+ } catch (IOException e) {
+ throw new ClassFormatException("IOException whilst reading set of attributes: " + e.toString());
+ }
+ }
+
+ /** Write (serialize) a set of attributes into a specified output stream */
+ public static void writeAttributes(Attribute[] attributes, DataOutputStream file) throws IOException {
+ if (attributes == null) {
+ file.writeShort(0);
+ } else {
+ file.writeShort(attributes.length);
+ for (int i = 0; i < attributes.length; i++) {
+ attributes[i].dump(file);
+ }
+ }
+ }
+
+ public static Signature getSignatureAttribute(Attribute[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].tag == Constants.ATTR_SIGNATURE) {
+ return (Signature) attributes[i];
+ }
+ }
+ return null;
+ }
+
+ public static Code getCodeAttribute(Attribute[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].tag == Constants.ATTR_CODE) {
+ return (Code) attributes[i];
+ }
+ }
+ return null;
+ }
+
+ public static ExceptionTable getExceptionTableAttribute(Attribute[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].tag == Constants.ATTR_EXCEPTIONS) {
+ return (ExceptionTable) attributes[i];
+ }
+ }
+ return null;
+ }
+
+ public static ConstantValue getConstantValueAttribute(Attribute[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) {
+ return (ConstantValue) attributes[i];
+ }
+ }
+ return null;
+ }
+
+ public static void accept(Attribute[] attributes, ClassVisitor visitor) {
+ for (int i = 0; i < attributes.length; i++) {
+ attributes[i].accept(visitor);
+ }
+ }
+
+ public static boolean hasSyntheticAttribute(Attribute[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].tag == Constants.ATTR_SYNTHETIC) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static SourceFile getSourceFileAttribute(Attribute[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].tag == Constants.ATTR_SOURCE_FILE) {
+ return (SourceFile) attributes[i];
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java
new file mode 100644
index 000000000..f708c0cab
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/BootstrapMethods.java
@@ -0,0 +1,268 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Represents the BootstrapMethods attribute in Java 7 classes.
+ *
+ * @author Andy Clement
+ */
+public final class BootstrapMethods extends Attribute {
+
+ // if 'isInPackedState' then this data needs unpacking
+ private boolean isInPackedState = false;
+ private byte[] data; // discarded once unpacked
+
+ private int numBootstrapMethods;
+ private BootstrapMethod[] bootstrapMethods;
+
+ public BootstrapMethods(BootstrapMethods c) {
+ this(c.getNameIndex(), c.getLength(), c.getBootstrapMethods(), c.getConstantPool());
+ }
+
+ public BootstrapMethods(int nameIndex, int length, BootstrapMethod[] lineNumberTable, ConstantPool constantPool) {
+ super(Constants.ATTR_BOOTSTRAPMETHODS, nameIndex, length, constantPool);
+ setBootstrapMethods(lineNumberTable);
+ isInPackedState = false;
+ }
+
+ public final void setBootstrapMethods(BootstrapMethod[] bootstrapMethods) {
+ this.data = null;
+ this.isInPackedState = false;
+ this.bootstrapMethods = bootstrapMethods;
+ this.numBootstrapMethods = bootstrapMethods==null?0:bootstrapMethods.length;
+ }
+
+ BootstrapMethods(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
+ this(name_index, length, (BootstrapMethod[])null, constant_pool);
+ data = new byte[length];
+ file.readFully(data);
+ isInPackedState = true;
+ }
+
+ public static class BootstrapMethod {
+ private int bootstrapMethodRef;
+ private int[] bootstrapArguments;
+
+ BootstrapMethod(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort(), readBootstrapArguments(file));
+ }
+
+ private static int[] readBootstrapArguments(DataInputStream dis) throws IOException {
+ int numBootstrapMethods = dis.readUnsignedShort();
+ int[] bootstrapArguments = new int[numBootstrapMethods];
+ for (int i=0;i<numBootstrapMethods;i++) {
+ bootstrapArguments[i] = dis.readUnsignedShort();
+ }
+ return bootstrapArguments;
+ }
+
+ public BootstrapMethod(int bootstrapMethodRef, int[] bootstrapArguments) {
+ this.bootstrapMethodRef = bootstrapMethodRef;
+ this.bootstrapArguments = bootstrapArguments;
+ }
+
+ public int getBootstrapMethodRef() {
+ return bootstrapMethodRef;
+ }
+
+ public int[] getBootstrapArguments() {
+ return bootstrapArguments;
+ }
+
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeShort(bootstrapMethodRef);
+ int len = bootstrapArguments.length;
+ file.writeShort(len);
+ for (int i=0;i<len;i++) {
+ file.writeShort(bootstrapArguments[i]);
+ }
+ }
+
+ public final int getLength() {
+ return 2 /*bootstrapMethodRef*/+
+ 2 /*number of arguments*/+
+ 2 * bootstrapArguments.length;
+ }
+
+ }
+
+ // Unpacks the byte array into the table
+ private void unpack() {
+ if (isInPackedState) {
+ try {
+ ByteArrayInputStream bs = new ByteArrayInputStream(data);
+ DataInputStream dis = new DataInputStream(bs);
+ numBootstrapMethods = dis.readUnsignedShort();
+ bootstrapMethods = new BootstrapMethod[numBootstrapMethods];
+ for (int i = 0; i < numBootstrapMethods; i++) {
+ bootstrapMethods[i] = new BootstrapMethod(dis);
+ }
+ dis.close();
+ data = null; // throw it away now
+ } catch (IOException e) {
+ throw new RuntimeException("Unpacking of LineNumberTable attribute failed");
+ }
+ isInPackedState = false;
+ }
+ }
+
+ /**
+ * 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(ClassVisitor v) {
+ unpack();
+ v.visitBootstrapMethods(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);
+ if (isInPackedState) {
+ file.write(data);
+ } else {
+ int blen = bootstrapMethods.length;
+ file.writeShort(blen);
+ for (int i = 0; i < blen; i++) {
+ bootstrapMethods[i].dump(file);
+ }
+ }
+ }
+
+ public final BootstrapMethod[] getBootstrapMethods() {
+ unpack();
+ return bootstrapMethods;
+ }
+
+
+ /**
+ * @return String representation.
+ */
+ @Override
+ public final String toString() {
+ unpack();
+ StringBuffer buf = new StringBuffer();
+ StringBuffer line = new StringBuffer();
+
+ for (int i = 0; i < numBootstrapMethods; i++) {
+ BootstrapMethod bm = bootstrapMethods[i];
+ line.append("BootstrapMethod[").append(i).append("]:");
+ int ref = bm.getBootstrapMethodRef();
+ ConstantMethodHandle mh = (ConstantMethodHandle)getConstantPool().getConstant(ref);
+ line.append("#"+ref+":");
+ line.append(ConstantMethodHandle.kindToString(mh.getReferenceKind()));
+ line.append(" ").append(getConstantPool().getConstant(mh.getReferenceIndex()));
+ int [] args = bm.getBootstrapArguments();
+ line.append(" argcount:").append(args==null?0:args.length).append(" ");
+ if (args!=null) {
+ for (int a=0;a<args.length;a++) {
+ line.append(args[a]).append("(").append(getConstantPool().getConstant(args[a])).append(") ");
+ }
+ }
+
+
+ if (i < numBootstrapMethods - 1) {
+ line.append(", ");
+ }
+
+ if (line.length() > 72) {
+ line.append('\n');
+ buf.append(line);
+ line.setLength(0);
+ }
+ }
+
+ buf.append(line);
+
+ return buf.toString();
+ }
+
+
+ /**
+ * @return deep copy of this attribute
+ */
+ // @Override
+ // public Attribute copy(ConstantPool constant_pool) {
+ // unpack();
+ // LineNumberTable newTable = (LineNumberTable) clone();
+ // newTable.table = new LineNumber[tableLength];
+ // for (int i = 0; i < tableLength; i++) {
+ // newTable.table[i] = table[i].copy();
+ // }
+ // newTable.cpool = constant_pool;
+ // return newTable;
+ // }
+ public final int getNumBootstrapMethods () {
+ unpack();
+ return bootstrapMethods.length;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java
new file mode 100644
index 000000000..a958329e5
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassFormatException.java
@@ -0,0 +1,69 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * 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,v 1.3 2008/05/28 23:53:02 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class ClassFormatException extends RuntimeException {
+ public ClassFormatException() { super(); }
+ public ClassFormatException(String s) { super(s); }
+}
+
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java
new file mode 100644
index 000000000..54882beee
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassParser.java
@@ -0,0 +1,249 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Wrapper class that parses a given Java .class file. The method <A
+ * href ="#parse">parse</A> returns a <A href ="JavaClass.html">
+ * JavaClass</A> 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 <A href="ftp://java.sun.com/docs/specs/vmspec.ps">
+ * JVM specification 1.0</a>. See this paper for
+ * further details about the structure of a bytecode file.
+ *
+ * @version $Id: ClassParser.java,v 1.6 2008/05/30 17:29:14 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class ClassParser {
+ private DataInputStream file;
+ private String filename;
+ private int classnameIndex;
+ private int superclassnameIndex;
+ private int major, minor;
+ private int accessflags;
+ private int[] interfaceIndices;
+ private ConstantPool cpool;
+ private Field[] fields;
+ private Method[] methods;
+ private Attribute[] attributes;
+
+ private static final int BUFSIZE = 8192;
+
+ /** Parse class from the given stream */
+ public ClassParser(InputStream file, String filename) {
+ this.filename = filename;
+ if (file instanceof DataInputStream) this.file = (DataInputStream)file;
+ else this.file = new DataInputStream(new BufferedInputStream(file,BUFSIZE));
+ }
+
+ public ClassParser(ByteArrayInputStream baos, String filename) {
+ this.filename = filename;
+ this.file = new DataInputStream(baos);
+ }
+
+ /** Parse class from given .class file */
+ public ClassParser(String file_name) throws IOException {
+ this.filename = file_name;
+ file = new DataInputStream(new BufferedInputStream(new FileInputStream(file_name),BUFSIZE));
+ }
+
+ /**
+ * Parse the given Java class file and return an object that represents
+ * the contained data, i.e., constants, methods, fields and commands.
+ * A <em>ClassFormatException</em> 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).
+ */
+ public JavaClass parse() throws IOException, ClassFormatException {
+ /****************** 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();
+
+ // Read everything of interest, so close the file
+ file.close();
+
+ // Return the information we have gathered in a new object
+ JavaClass jc= new JavaClass(classnameIndex, superclassnameIndex,
+ filename, major, minor, accessflags,
+ cpool, interfaceIndices, fields,
+ methods, attributes);
+ return jc;
+ }
+
+ /** Read information about the attributes of the class */
+ private final void readAttributes() {
+ attributes = AttributeUtils.readAttributes(file,cpool);
+ }
+
+ /** Read information about the class and its super class */
+ private final void readClassInfo() throws IOException {
+ accessflags = file.readUnsignedShort();
+
+ /* Interfaces are implicitely abstract, the flag should be set
+ * according to the JVM specification */
+ if((accessflags & Constants.ACC_INTERFACE) != 0)
+ accessflags |= Constants.ACC_ABSTRACT;
+
+ // don't police it like this... leave higher level verification code to check it.
+// if(((access_flags & Constants.ACC_ABSTRACT) != 0) &&
+// ((access_flags & Constants.ACC_FINAL) != 0 ))
+// throw new ClassFormatException("Class can't be both final and abstract");
+
+ classnameIndex = file.readUnsignedShort();
+ superclassnameIndex = file.readUnsignedShort();
+ }
+
+ private final void readConstantPool() throws IOException {
+ try {
+ cpool = new ConstantPool(file);
+ } catch (ClassFormatException cfe) {
+ // add some context if we can
+ cfe.printStackTrace();
+ if (filename!=null) {
+ String newmessage = "File: '"+filename+"': "+cfe.getMessage();
+ throw new ClassFormatException(newmessage); // this loses the old stack trace but I dont think that matters!
+ }
+ throw cfe;
+ }
+ }
+
+ /** Read information about the fields of the class */
+ private final void readFields() throws IOException, ClassFormatException {
+ int fieldCount = file.readUnsignedShort();
+ if (fieldCount == 0) {
+ fields = Field.NoFields;
+ } else {
+ fields = new Field[fieldCount];
+ for(int i=0; i < fieldCount; i++)
+ fields[i] = new Field(file, cpool);
+ }
+ }
+
+ /** Check whether the header of the file is ok. Of course, this has
+ * to be the first action on successive file reads */
+ private final void readID() throws IOException {
+ int magic = 0xCAFEBABE;
+ if (file.readInt() != magic)
+ throw new ClassFormatException(filename + " is not a Java .class file");
+ }
+
+ private static final int[] NO_INTERFACES = new int[0];
+
+ /** Read information about the interfaces implemented by this class */
+ private final void readInterfaces() throws IOException {
+ int interfacesCount = file.readUnsignedShort();
+ if (interfacesCount==0) {
+ interfaceIndices = NO_INTERFACES;
+ } else {
+ interfaceIndices = new int[interfacesCount];
+ for(int i=0; i < interfacesCount; i++)
+ interfaceIndices[i] = file.readUnsignedShort();
+ }
+ }
+
+ /** Read information about the methods of the class */
+ private final void readMethods() throws IOException {
+ int methodsCount = file.readUnsignedShort();
+ if (methodsCount==0) {
+ methods = Method.NoMethods;
+ } else {
+ methods = new Method[methodsCount];
+ for(int i=0; i < methodsCount; i++)
+ methods[i] = new Method(file, cpool);
+ }
+ }
+
+ /** Read major and minor version of compiler which created the file */
+ private final void readVersion() throws IOException {
+ minor = file.readUnsignedShort();
+ major = file.readUnsignedShort();
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java
new file mode 100644
index 000000000..5c60f818f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ClassVisitor.java
@@ -0,0 +1,180 @@
+package org.aspectj.apache.bcel.classfile;
+
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * 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.
+ *
+ * Implemented by wish of <A HREF="http://www.inf.fu-berlin.de/~bokowski">Boris Bokowski</A>.
+ *
+ * @version $Id: ClassVisitor.java,v 1.4 2009/09/15 19:40:13 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public interface ClassVisitor {
+ public void visitCode(Code obj);
+
+ public void visitCodeException(CodeException obj);
+
+ public void visitConstantClass(ConstantClass obj);
+
+ public void visitConstantDouble(ConstantDouble obj);
+
+ public void visitConstantFieldref(ConstantFieldref obj);
+
+ public void visitConstantFloat(ConstantFloat obj);
+
+ public void visitConstantInteger(ConstantInteger obj);
+
+ public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj);
+
+ public void visitConstantLong(ConstantLong obj);
+
+ public void visitConstantMethodref(ConstantMethodref obj);
+
+ public void visitConstantMethodHandle(ConstantMethodHandle obj);
+
+ public void visitConstantNameAndType(ConstantNameAndType obj);
+
+ public void visitConstantMethodType(ConstantMethodType obj);
+
+ public void visitConstantInvokeDynamic(ConstantInvokeDynamic obj);
+
+ public void visitConstantDynamic(ConstantDynamic obj);
+
+ public void visitConstantPool(ConstantPool obj);
+
+ public void visitConstantString(ConstantString obj);
+
+ public void visitConstantModule(ConstantModule obj);
+
+ public void visitConstantPackage(ConstantPackage obj);
+
+ public void visitConstantUtf8(ConstantUtf8 obj);
+
+ public void visitConstantValue(ConstantValue 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 visitBootstrapMethods(BootstrapMethods obj);
+
+ public void visitUnknown(Unknown obj);
+
+ public void visitStackMap(StackMap obj);
+
+ public void visitStackMapEntry(StackMapEntry obj);
+
+ public void visitEnclosingMethod(EnclosingMethod obj);
+
+ public void visitRuntimeVisibleAnnotations(RuntimeVisAnnos obj);
+
+ public void visitRuntimeInvisibleAnnotations(RuntimeInvisAnnos obj);
+
+ public void visitRuntimeVisibleParameterAnnotations(RuntimeVisParamAnnos obj);
+
+ public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisParamAnnos obj);
+
+ public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos obj);
+
+ public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos obj);
+
+ public void visitAnnotationDefault(AnnotationDefault obj);
+
+ public void visitLocalVariableTypeTable(LocalVariableTypeTable obj);
+
+ public void visitMethodParameters(MethodParameters methodParameters);
+
+ // J9:
+ public void visitModule(Module module);
+ public void visitModulePackages(ModulePackages modulePackage);
+ public void visitModuleMainClass(ModuleMainClass moduleMainClass);
+
+ // J11:
+ public void visitNestHost(NestHost nestHost);
+ public void visitNestMembers(NestMembers nestMembers);
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java
new file mode 100644
index 000000000..b714e6cab
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Code.java
@@ -0,0 +1,388 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents a chunk of Java byte code contained in a method. It is instantiated by the
+ * <em>Attribute.readAttribute()</em> method. A <em>Code</em> attribute contains informations about operand stack, local variables,
+ * byte code and the exceptions handled within this method.
+ *
+ * This attribute has attributes itself, namely <em>LineNumberTable</em> which is used for debugging purposes and
+ * <em>LocalVariableTable</em> which contains information about the local variables.
+ *
+ * @version $Id: Code.java,v 1.9 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Attribute
+ * @see CodeException
+ * @see LineNumberTable
+ * @see LocalVariableTable
+ */
+public final class Code extends Attribute {
+ private int maxStack; // Maximum size of stack used by this method
+ private int maxLocals; // Number of local variables
+ private byte[] code; // Actual byte code
+ private CodeException[] exceptionTable;
+ private Attribute[] attributes;
+ private static final CodeException[] NO_EXCEPTIONS = new CodeException[] {};
+
+ /**
+ * 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());
+ }
+
+ 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);
+
+ int len = file.readInt();
+ code = new byte[len]; // 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.
+ */
+ len = file.readUnsignedShort();
+ if (len == 0) {
+ exceptionTable = NO_EXCEPTIONS;
+ } else {
+ exceptionTable = new CodeException[len];
+ for (int i = 0; i < len; i++) {
+ exceptionTable[i] = new CodeException(file);
+ }
+ }
+
+ // Read all attributes, eg: LineNumberTable, LocalVariableTable
+ attributes = AttributeUtils.readAttributes(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 <em>Code</em>
+ * @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.maxStack = max_stack;
+ this.maxLocals = max_locals;
+
+ setCode(code);
+ setExceptionTable(exception_table);
+ setAttributes(attributes); // Overwrites 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(ClassVisitor 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(maxStack);
+ file.writeShort(maxLocals);
+ file.writeInt(code.length);
+ file.write(code, 0, code.length);
+
+ file.writeShort(exceptionTable.length);
+ for (int i = 0; i < exceptionTable.length; i++) {
+ exceptionTable[i].dump(file);
+ }
+
+ file.writeShort(attributes.length);
+ for (int i = 0; i < attributes.length; i++) {
+ attributes[i].dump(file);
+ }
+ }
+
+ /**
+ * @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.length; i++) {
+ if (attributes[i].tag == Constants.ATTR_LINE_NUMBER_TABLE) {
+ return (LineNumberTable) attributes[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return LocalVariableTable of Code, if it has one
+ */
+ public LocalVariableTable getLocalVariableTable() {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].tag == Constants.ATTR_LOCAL_VARIABLE_TABLE) {
+ return (LocalVariableTable) attributes[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return Actual byte code of the method.
+ */
+ public final byte[] getCode() {
+ return code;
+ }
+
+ /**
+ * @return Table of handled exceptions.
+ * @see CodeException
+ */
+ public final CodeException[] getExceptionTable() {
+ return exceptionTable;
+ }
+
+ /**
+ * @return Number of local variables.
+ */
+ public final int getMaxLocals() {
+ return maxLocals;
+ }
+
+ /**
+ * @return Maximum size of stack used by this method.
+ */
+
+ public final int getMaxStack() {
+ return maxStack;
+ }
+
+ /**
+ * @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 == null ? 0 : code.length) /* byte-code */
+ + 2 /* exception-table length */
+ + 8 * (exceptionTable == null ? 0 : exceptionTable.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;
+ if (attributes != null) {
+ for (int i = 0; i < attributes.length; i++) {
+ len += attributes[i].length + 6 /* attribute header size */;
+ }
+ }
+ return len + getInternalLength();
+ }
+
+ /**
+ * @param attributes.
+ */
+ public final void setAttributes(Attribute[] attributes) {
+ this.attributes = attributes;
+ length = calculateLength(); // Adjust length
+ }
+
+ /**
+ * @param code byte code
+ */
+ public final void setCode(byte[] code) {
+ this.code = code;
+ }
+
+ /**
+ * @param exception_table exception table
+ */
+ public final void setExceptionTable(CodeException[] exception_table) {
+ this.exceptionTable = exception_table;
+ }
+
+ /**
+ * @param max_locals maximum number of local variables
+ */
+ public final void setMaxLocals(int max_locals) {
+ this.maxLocals = max_locals;
+ }
+
+ /**
+ * @param max_stack maximum stack size
+ */
+ public final void setMaxStack(int max_stack) {
+ this.maxStack = max_stack;
+ }
+
+ /**
+ * @return String representation of code chunk.
+ */
+ public final String toString(boolean verbose) {
+ StringBuffer buf;
+
+ buf = new StringBuffer("Code(max_stack = " + maxStack + ", max_locals = " + maxLocals + ", code_length = " + code.length
+ + ")\n" + Utility.codeToString(code, cpool, 0, -1, verbose));
+
+ if (exceptionTable.length > 0) {
+ buf.append("\nException handler(s) = \n" + "From\tTo\tHandler\tType\n");
+
+ for (int i = 0; i < exceptionTable.length; i++) {
+ buf.append(exceptionTable[i].toString(cpool, verbose) + "\n");
+ }
+ }
+
+ if (attributes.length > 0) {
+ buf.append("\nAttribute(s) = \n");
+
+ for (int i = 0; i < attributes.length; i++) {
+ buf.append(attributes[i].toString() + "\n");
+ }
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * @return String representation of code chunk.
+ */
+ @Override
+ public final String toString() {
+ return toString(true);
+ }
+
+ // /**
+ // * @return deep copy of this attribute
+ // */
+ // public Attribute copy(ConstantPool constant_pool) {
+ // Code c = (Code)clone();
+ // c.code = (byte[])code.clone();
+ // c.cpool = constant_pool;
+ //
+ // c.exceptionTable = new CodeException[exceptionTable.length];
+ // for(int i=0; i < exceptionTable.length; i++)
+ // c.exceptionTable[i] = exceptionTable[i].copy();
+ //
+ // c.attributes = new Attribute[attributes.length];
+ // for(int i=0; i < attributes.length; i++)
+ // c.attributes[i] = attributes[i].copy(constant_pool);
+ //
+ // return c;
+ // }
+
+ /**
+ * Returns the same as toString(true) except that the attribute information isn't included (line numbers). Can be used to check
+ * whether two pieces of code are equivalent.
+ */
+ public String getCodeString() {
+ StringBuffer codeString = new StringBuffer();
+ codeString.append("Code(max_stack = ").append(maxStack);
+ codeString.append(", max_locals = ").append(maxLocals);
+ codeString.append(", code_length = ").append(code.length).append(")\n");
+ codeString.append(Utility.codeToString(code, cpool, 0, -1, true));
+ if (exceptionTable.length > 0) {
+ codeString.append("\n").append("Exception entries = ").append(exceptionTable.length).append("\n");
+ for (int i = 0; i < exceptionTable.length; i++) {
+ CodeException exc = exceptionTable[i];
+ int type = exc.getCatchType();
+ String name = "finally";
+ if (type != 0) {
+ name = this.cpool.getConstantString(type, Constants.CONSTANT_Class);
+ }
+ codeString.append(name).append("[");
+ codeString.append(exc.getStartPC()).append(">").append(exc.getEndPC()).append("]\n");
+ }
+ }
+ return codeString.toString();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java
new file mode 100644
index 000000000..72b4d539e
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/CodeException.java
@@ -0,0 +1,196 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.apache.bcel.Constants;
+import java.io.*;
+
+/**
+ * This class represents an entry in the exception table of the <em>Code</em>
+ * attribute and is used only there. It contains a range in which a
+ * particular exception handler is active.
+ *
+ * @version $Id: CodeException.java,v 1.3 2008/05/28 23:53:02 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Code
+ */
+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.
+ */
+
+ public CodeException(CodeException c) {
+ this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType());
+ }
+
+ CodeException(DataInputStream file) throws IOException {
+ start_pc = file.readUnsignedShort();
+ end_pc = file.readUnsignedShort();
+ handler_pc = file.readUnsignedShort();
+ catch_type = file.readUnsignedShort();
+ }
+
+ 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;
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitCodeException(this);
+ }
+
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeShort(start_pc);
+ file.writeShort(end_pc);
+ file.writeShort(handler_pc);
+ file.writeShort(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; }
+
+ /**
+ * @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; }
+
+ /**
+ * @param catch_type.
+ */
+ 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 = "<Any exception>(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;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java
new file mode 100644
index 000000000..d391b75ea
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Constant.java
@@ -0,0 +1,149 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * 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,v 1.5 2009/09/10 15:35:04 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public abstract class Constant implements Cloneable, Node {
+
+ protected byte tag;
+
+ Constant(byte tag) {
+ this.tag = tag;
+ }
+
+ public final byte getTag() {
+ return tag;
+ }
+
+ @Override
+ public String toString() {
+ return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
+ }
+
+ public abstract void accept(ClassVisitor v);
+
+ public abstract void dump(DataOutputStream dataOutputStream) throws IOException;
+
+ public abstract Object getValue();
+
+ public Constant copy() {
+ try {
+ return (Constant) super.clone();
+ } catch (CloneNotSupportedException e) {
+ }
+
+ return null;
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ static final Constant readConstant(DataInputStream dis) throws IOException, ClassFormatException {
+ byte b = dis.readByte();
+ switch (b) {
+ case Constants.CONSTANT_Class:
+ return new ConstantClass(dis);
+ case Constants.CONSTANT_NameAndType:
+ return new ConstantNameAndType(dis);
+ case Constants.CONSTANT_Utf8:
+ return new ConstantUtf8(dis);
+ case Constants.CONSTANT_Fieldref:
+ return new ConstantFieldref(dis);
+ case Constants.CONSTANT_Methodref:
+ return new ConstantMethodref(dis);
+ case Constants.CONSTANT_InterfaceMethodref:
+ return new ConstantInterfaceMethodref(dis);
+ case Constants.CONSTANT_String:
+ return new ConstantString(dis);
+ case Constants.CONSTANT_Integer:
+ return new ConstantInteger(dis);
+ case Constants.CONSTANT_Float:
+ return new ConstantFloat(dis);
+ case Constants.CONSTANT_Long:
+ return new ConstantLong(dis);
+ case Constants.CONSTANT_Double:
+ return new ConstantDouble(dis);
+ case Constants.CONSTANT_MethodHandle:
+ return new ConstantMethodHandle(dis);
+ case Constants.CONSTANT_MethodType:
+ return new ConstantMethodType(dis);
+ case Constants.CONSTANT_InvokeDynamic:
+ return new ConstantInvokeDynamic(dis);
+ case Constants.CONSTANT_Module:
+ return new ConstantModule(dis);
+ case Constants.CONSTANT_Package:
+ return new ConstantPackage(dis);
+ case Constants.CONSTANT_Dynamic:
+ return new ConstantDynamic(dis);
+ default:
+ throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java
new file mode 100644
index 000000000..a476c4d15
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantCP.java
@@ -0,0 +1,109 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Abstract super class for Fieldref and Methodref constants.
+ *
+ * @version $Id: ConstantCP.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see ConstantFieldref
+ * @see ConstantMethodref
+ * @see ConstantInterfaceMethodref
+ */
+public abstract class ConstantCP extends Constant {
+
+ protected int classIndex, nameAndTypeIndex;
+
+ ConstantCP(byte tag, DataInputStream file) throws IOException {
+ this(tag, file.readUnsignedShort(), file.readUnsignedShort());
+ }
+
+ protected ConstantCP(byte tag, int classIndex, int nameAndTypeIndex) {
+ super(tag);
+ this.classIndex = classIndex;
+ this.nameAndTypeIndex = nameAndTypeIndex;
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(classIndex);
+ file.writeShort(nameAndTypeIndex);
+ }
+
+ public final int getClassIndex() {
+ return classIndex;
+ }
+
+ public final int getNameAndTypeIndex() {
+ return nameAndTypeIndex;
+ }
+
+ public String getClass(ConstantPool cp) {
+ return cp.constantToString(classIndex, Constants.CONSTANT_Class);
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(classIndex = " + classIndex + ", nameAndTypeIndex = " + nameAndTypeIndex + ")";
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java
new file mode 100644
index 000000000..883f3b25f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantClass.java
@@ -0,0 +1,112 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a (external) class.
+ *
+ * @version $Id: ConstantClass.java,v 1.6 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Andy Clement
+ */
+public final class ConstantClass extends Constant {
+ private int nameIndex;
+
+ ConstantClass(DataInputStream file) throws IOException {
+ super(Constants.CONSTANT_Class);
+ this.nameIndex = file.readUnsignedShort();
+ }
+
+ public ConstantClass(int nameIndex) {
+ super(Constants.CONSTANT_Class);
+ this.nameIndex = nameIndex;
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantClass(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(nameIndex);
+ }
+
+ public final int getNameIndex() {
+ return nameIndex;
+ }
+
+ @Override
+ public Integer getValue() {
+ return nameIndex;
+ }
+
+ public String getClassname(ConstantPool cpool) {
+ return cpool.getConstantUtf8(nameIndex).getValue();
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(name_index = " + nameIndex + ")";
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java
new file mode 100644
index 000000000..813aec72a
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDouble.java
@@ -0,0 +1,107 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a Double object.
+ *
+ * @version $Id: ConstantDouble.java,v 1.6 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Andy Clement
+ */
+public final class ConstantDouble extends Constant implements SimpleConstant {
+ private double value;
+
+ public ConstantDouble(double value) {
+ super(Constants.CONSTANT_Double);
+ this.value = value;
+ }
+
+ ConstantDouble(DataInputStream file) throws IOException {
+ this(file.readDouble());
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantDouble(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeDouble(value);
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(bytes = " + value + ")";
+ }
+
+ @Override
+ public Double getValue() {
+ return value;
+ }
+
+ public String getStringValue() {
+ return Double.toString(value);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java
new file mode 100644
index 000000000..40100f83b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantDynamic.java
@@ -0,0 +1,116 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to the name and signature of a field or method.
+ *
+ * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.10
+ *
+ * @author Andy Clement
+ * @see Constant
+ */
+public final class ConstantDynamic extends Constant {
+ private final int bootstrapMethodAttrIndex;
+ private final int nameAndTypeIndex;
+
+ ConstantDynamic(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort(), file.readUnsignedShort());
+ }
+
+ public ConstantDynamic(int readUnsignedShort, int nameAndTypeIndex) {
+ super(Constants.CONSTANT_InvokeDynamic);
+ this.bootstrapMethodAttrIndex = readUnsignedShort;
+ this.nameAndTypeIndex = nameAndTypeIndex;
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(bootstrapMethodAttrIndex);
+ file.writeShort(nameAndTypeIndex);
+ }
+
+ public final int getNameAndTypeIndex() {
+ return nameAndTypeIndex;
+ }
+
+ public final int getBootstrapMethodAttrIndex() {
+ return bootstrapMethodAttrIndex;
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + ",nameAndTypeIndex=" + nameAndTypeIndex + ")";
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantDynamic(this);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java
new file mode 100644
index 000000000..056f3e3fd
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFieldref.java
@@ -0,0 +1,87 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents a constant pool reference to a field.
+ *
+ * @version $Id: ConstantFieldref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class ConstantFieldref extends ConstantCP {
+
+ ConstantFieldref(DataInputStream file) throws IOException {
+ super(Constants.CONSTANT_Fieldref, file);
+ }
+
+ public ConstantFieldref(int class_index, int name_and_type_index) {
+ super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index);
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantFieldref(this);
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java
new file mode 100644
index 000000000..985c28125
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantFloat.java
@@ -0,0 +1,108 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a float object.
+ *
+ * @version $Id: ConstantFloat.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
+ */
+public final class ConstantFloat extends Constant implements SimpleConstant {
+ private float floatValue;
+
+ public ConstantFloat(float floatValue) {
+ super(Constants.CONSTANT_Float);
+ this.floatValue = floatValue;
+ }
+
+ ConstantFloat(DataInputStream file) throws IOException {
+ this(file.readFloat());
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantFloat(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeFloat(floatValue);
+ }
+
+ @Override
+ public final Float getValue() {
+ return floatValue;
+ }
+
+ public final String getStringValue() {
+ return Float.toString(floatValue);
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(bytes = " + floatValue + ")";
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java
new file mode 100644
index 000000000..415706eed
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInteger.java
@@ -0,0 +1,111 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to an int object.
+ *
+ * @version $Id: ConstantInteger.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
+ */
+public final class ConstantInteger extends Constant implements SimpleConstant {
+ private int intValue;
+
+ public ConstantInteger(int intValue) {
+ super(Constants.CONSTANT_Integer);
+ this.intValue = intValue;
+ }
+
+ ConstantInteger(DataInputStream file) throws IOException {
+ this(file.readInt());
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantInteger(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeInt(intValue);
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(bytes = " + intValue + ")";
+ }
+
+ @Override
+ public Integer getValue() {
+ return intValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public String getStringValue() {
+ return Integer.toString(intValue);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java
new file mode 100644
index 000000000..b973c726e
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInterfaceMethodref.java
@@ -0,0 +1,88 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents a constant pool reference to an interface method.
+ *
+ * @version $Id: ConstantInterfaceMethodref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class ConstantInterfaceMethodref extends ConstantCP {
+
+ ConstantInterfaceMethodref(DataInputStream file) throws IOException {
+ super(Constants.CONSTANT_InterfaceMethodref, file);
+ }
+
+ public ConstantInterfaceMethodref(int classIndex, int nameAndTypeIndex) {
+ super(Constants.CONSTANT_InterfaceMethodref, classIndex, nameAndTypeIndex);
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantInterfaceMethodref(this);
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java
new file mode 100644
index 000000000..0d263aa65
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantInvokeDynamic.java
@@ -0,0 +1,132 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to the name and signature of a field or method.
+ *
+ * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.10
+ *
+ * @author Andy Clement
+ * @see Constant
+ */
+public final class ConstantInvokeDynamic extends Constant {
+ private final int bootstrapMethodAttrIndex;
+ private final int nameAndTypeIndex;
+
+ ConstantInvokeDynamic(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort(), file.readUnsignedShort());
+ }
+
+ public ConstantInvokeDynamic(int readUnsignedShort, int nameAndTypeIndex) {
+ super(Constants.CONSTANT_InvokeDynamic);
+ this.bootstrapMethodAttrIndex = readUnsignedShort;
+ this.nameAndTypeIndex = nameAndTypeIndex;
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(bootstrapMethodAttrIndex);
+ file.writeShort(nameAndTypeIndex);
+ }
+//
+// public final byte getReferenceKind() {
+// return bootstrapMethodAttrIndex;
+// }
+//
+// public final String getName(ConstantPool cp) {
+// return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8);
+// }
+//
+// public final int getSignatureIndex() {
+// return referenceIndex;
+// }
+//
+// public final String getSignature(ConstantPool cp) {
+// return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8);
+// }
+
+ public final int getNameAndTypeIndex() {
+ return nameAndTypeIndex;
+ }
+
+ public final int getBootstrapMethodAttrIndex() {
+ return bootstrapMethodAttrIndex;
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + ",nameAndTypeIndex=" + nameAndTypeIndex + ")";
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantInvokeDynamic(this);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java
new file mode 100644
index 000000000..1d56b98a3
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantLong.java
@@ -0,0 +1,108 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a long object.
+ *
+ * @version $Id: ConstantLong.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
+ */
+public final class ConstantLong extends Constant implements SimpleConstant {
+ private long longValue;
+
+ public ConstantLong(long longValue) {
+ super(Constants.CONSTANT_Long);
+ this.longValue = longValue;
+ }
+
+ ConstantLong(DataInputStream file) throws IOException {
+ this(file.readLong());
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantLong(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeLong(longValue);
+ }
+
+ @Override
+ public final Long getValue() {
+ return longValue;
+ }
+
+ public final String getStringValue() {
+ return Long.toString(longValue);
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(longValue = " + longValue + ")";
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java
new file mode 100644
index 000000000..712a13f4c
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodHandle.java
@@ -0,0 +1,132 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to the name and signature of a field or method.
+ *
+ * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.8
+ *
+ * @author Andy Clement
+ * @see Constant
+ */
+public final class ConstantMethodHandle extends Constant {
+ private byte referenceKind;
+ private int referenceIndex;
+
+ ConstantMethodHandle(DataInputStream file) throws IOException {
+ this(file.readByte(), file.readUnsignedShort());
+ }
+
+ public ConstantMethodHandle(byte referenceKind, int referenceIndex) {
+ super(Constants.CONSTANT_MethodHandle);
+ this.referenceKind = referenceKind;
+ this.referenceIndex = referenceIndex;
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeByte(referenceKind);
+ file.writeShort(referenceIndex);
+ }
+
+ public final byte getReferenceKind() {
+ return referenceKind;
+ }
+
+ public final int getReferenceIndex() {
+ return referenceIndex;
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(referenceKind=" + referenceKind + ",referenceIndex=" + referenceIndex + ")";
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantMethodHandle(this);
+ }
+
+ public static String kindToString(byte kind) {
+ switch (kind) {
+ case 1: return "getfield";
+ case 2: return "getstatic";
+ case 3: return "putfield";
+ case 4: return "putstatic";
+ case 5: return "invokevirtual";
+ case 6: return "invokestatic";
+ case 7: return "invokespecial";
+ case 8: return "newinvokespecial";
+ case 9: return "invokeinterface";
+ default:
+ return "nyi";
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java
new file mode 100644
index 000000000..867e7eb0a
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodType.java
@@ -0,0 +1,121 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to the name and signature of a field or method.
+ *
+ * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.9
+ *
+ * @author Andy Clement
+ * @see Constant
+ */
+public final class ConstantMethodType extends Constant {
+ private int descriptorIndex;
+
+ ConstantMethodType(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort());
+ }
+
+ public ConstantMethodType(int descriptorIndex) {
+ super(Constants.CONSTANT_MethodType);
+ this.descriptorIndex = descriptorIndex;
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(descriptorIndex);
+ }
+
+ public final int getDescriptorIndex() {
+ return descriptorIndex;
+ }
+
+// public final String getName(ConstantPool cp) {
+// return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8);
+// }
+//
+// public final int getSignatureIndex() {
+// return referenceIndex;
+// }
+//
+// public final String getSignature(ConstantPool cp) {
+// return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8);
+// }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(descriptorIndex=" + descriptorIndex + ")";
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantMethodType(this);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java
new file mode 100644
index 000000000..29b37c5d7
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantMethodref.java
@@ -0,0 +1,87 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents a constant pool reference to a method.
+ *
+ * @version $Id: ConstantMethodref.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class ConstantMethodref extends ConstantCP {
+
+ ConstantMethodref(DataInputStream file) throws IOException {
+ super(Constants.CONSTANT_Methodref, file);
+ }
+
+ public ConstantMethodref(int class_index, int name_and_type_index) {
+ super(Constants.CONSTANT_Methodref, class_index, name_and_type_index);
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantMethodref(this);
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java
new file mode 100644
index 000000000..efe4d3a1b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantModule.java
@@ -0,0 +1,111 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2017 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Represents a module.
+ *
+ * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.11
+ *
+ * @author Andy Clement
+ */
+public final class ConstantModule extends Constant {
+
+ private int nameIndex;
+
+ ConstantModule(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort());
+ }
+
+ public ConstantModule(int nameIndex) {
+ super(Constants.CONSTANT_Module);
+ this.nameIndex = nameIndex;
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantModule(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(nameIndex);
+ }
+
+ @Override
+ public Integer getValue() {
+ return nameIndex;
+ }
+
+ public final int getNameIndex() {
+ return nameIndex;
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(name_index = " + nameIndex + ")";
+ }
+
+ public String getModuleName(ConstantPool cpool) {
+ Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8);
+ return ((ConstantUtf8) c).getValue();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java
new file mode 100644
index 000000000..8af80fab2
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantNameAndType.java
@@ -0,0 +1,157 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to the name and signature of a field or method.
+ *
+ * @version $Id: ConstantNameAndType.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
+ */
+public final class ConstantNameAndType extends Constant {
+ private int name_index; // Name of field/method
+ private int signature_index; // and its signature.
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @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);
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(name_index = " + name_index + ", signature_index = " + signature_index + ")";
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java
new file mode 100644
index 000000000..70e9b1d0d
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantObject.java
@@ -0,0 +1,66 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * This interface denotes those constants that have a "natural" value, such as ConstantLong, ConstantString, etc..
+ *
+ * @version $Id: ConstantObject.java,v 1.4 2009/09/10 03:59:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
+ */
+public interface ConstantObject {
+ public abstract Object getConstantValue(ConstantPool cp);
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java
new file mode 100644
index 000000000..70f22c749
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPackage.java
@@ -0,0 +1,111 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2017 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Represents a module.
+ *
+ * See http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.4.12
+ *
+ * @author Andy Clement
+ */
+public final class ConstantPackage extends Constant {
+
+ private int nameIndex;
+
+ ConstantPackage(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort());
+ }
+
+ public ConstantPackage(int nameIndex) {
+ super(Constants.CONSTANT_Package);
+ this.nameIndex = nameIndex;
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantPackage(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(nameIndex);
+ }
+
+ @Override
+ public Integer getValue() {
+ return nameIndex;
+ }
+
+ public final int getNameIndex() {
+ return nameIndex;
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(name_index = " + nameIndex + ")";
+ }
+
+ public String getPackageName(ConstantPool cpool) {
+ Constant c = cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8);
+ return ((ConstantUtf8) c).getValue();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java
new file mode 100644
index 000000000..0430e28ba
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantPool.java
@@ -0,0 +1,816 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.generic.ArrayType;
+import org.aspectj.apache.bcel.generic.ObjectType;
+
+/**
+ * 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.
+ */
+public class ConstantPool implements Node {
+ private Constant[] pool;
+ private int poolSize; // number of entries in the pool (could be < pool.length as the array is resized in 'chunks')
+
+ private Map<String, Integer> utf8Cache = new HashMap<String, Integer>();
+ private Map<String, Integer> methodCache = new HashMap<String, Integer>();
+ private Map<String, Integer> fieldCache = new HashMap<String, Integer>();
+
+ public int getSize() {
+ return poolSize;
+ }
+
+ public ConstantPool() {
+ pool = new Constant[10];
+ poolSize = 0;
+ }
+
+ public ConstantPool(Constant[] constants) {
+ pool = constants;
+ poolSize = (constants == null ? 0 : constants.length);
+ }
+
+ ConstantPool(DataInputStream file) throws IOException {
+ byte tag;
+ poolSize = file.readUnsignedShort();
+ pool = new Constant[poolSize];
+ // pool[0] is unused by the compiler and may be used freely by the implementation
+ for (int i = 1; i < poolSize; i++) {
+ pool[i] = Constant.readConstant(file);
+ tag = pool[i].getTag();
+ if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) {
+ i++;
+ }
+ }
+ }
+
+ public Constant getConstant(int index, byte tag) {
+ Constant c = getConstant(index);
+ // if (c == null) throw new ClassFormatException("Constant pool at index " + index + " is null.");
+ if (c.tag == tag)
+ return c;
+ throw new ClassFormatException("Expected class '" + Constants.CONSTANT_NAMES[tag] + "' at index " + index + " and found "
+ + c);
+ }
+
+ public Constant getConstant(int index) {
+ try {
+ return pool[index];
+ } catch (ArrayIndexOutOfBoundsException aioobe) {
+ throw new ClassFormatException("Index " + index + " into constant pool (size:" + poolSize + ") is invalid");
+ }
+ }
+
+ /**
+ * @return deep copy of this constant pool
+ */
+ public ConstantPool copy() {
+ Constant[] newConstants = new Constant[poolSize]; // use the correct size
+ for (int i = 1; i < poolSize; i++) {
+ if (pool[i] != null) {
+ newConstants[i] = pool[i].copy();
+ }
+ }
+ return new ConstantPool(newConstants);
+ }
+
+ /**
+ * 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 = getConstant(index, tag);
+ int i;
+ /*
+ * 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.
+ */
+ // OPTIMIZE remove the difference - use the an interface and same index methods for string ref id
+ 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).getValue();
+ }
+
+ /**
+ * Resolve constant to a string representation.
+ */
+ public String constantToString(Constant c) {
+ String str;
+ int i;
+
+ switch (c.tag) {
+ case Constants.CONSTANT_Class:
+ i = ((ConstantClass) c).getNameIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = Utility.compactClassName(((ConstantUtf8) c).getValue(), false);
+ break;
+
+ case Constants.CONSTANT_String:
+ i = ((ConstantString) c).getStringIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = "\"" + escape(((ConstantUtf8) c).getValue()) + "\"";
+ break;
+
+ case Constants.CONSTANT_Utf8:
+ case Constants.CONSTANT_Double:
+ case Constants.CONSTANT_Float:
+ case Constants.CONSTANT_Long:
+ case Constants.CONSTANT_Integer:
+ str = ((SimpleConstant) c).getStringValue();
+ 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;
+
+ case Constants.CONSTANT_InvokeDynamic:
+ ConstantInvokeDynamic cID = ((ConstantInvokeDynamic)c);
+ return "#"+cID.getBootstrapMethodAttrIndex()+"."+constantToString(cID.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType);
+
+ case Constants.CONSTANT_MethodHandle:
+ ConstantMethodHandle cMH = ((ConstantMethodHandle)c);
+ return cMH.getReferenceKind()+":"+constantToString(cMH.getReferenceIndex(),Constants.CONSTANT_Methodref);
+
+ case Constants.CONSTANT_MethodType:
+ ConstantMethodType cMT = (ConstantMethodType)c;
+ return constantToString(cMT.getDescriptorIndex(),Constants.CONSTANT_Utf8);
+
+ case Constants.CONSTANT_Module:
+ ConstantModule cM = (ConstantModule)c;
+ return "Module:"+constantToString(cM.getNameIndex(),Constants.CONSTANT_Utf8);
+
+ case Constants.CONSTANT_Package:
+ ConstantPackage cP = (ConstantPackage)c;
+ return "Package:"+constantToString(cP.getNameIndex(),Constants.CONSTANT_Utf8);
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + c.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();
+ }
+
+ public String constantToString(int index, byte tag) {
+ Constant c = getConstant(index, tag);
+ return constantToString(c);
+ }
+
+ public String constantToString(int index) {
+ return constantToString(getConstant(index));
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantPool(this);
+ }
+
+ public Constant[] getConstantPool() {
+ return pool;
+ } // TEMPORARY, DONT LIKE PASSING THIS DATA OUT!
+
+ public void dump(DataOutputStream file) throws IOException {
+ file.writeShort(poolSize);
+ for (int i = 1; i < poolSize; i++)
+ if (pool[i] != null)
+ pool[i].dump(file);
+ }
+
+ public ConstantUtf8 getConstantUtf8(int index) {
+ Constant c = getConstant(index);
+ assert c != null;
+ assert c.tag == Constants.CONSTANT_Utf8;
+ return (ConstantUtf8) c;
+ }
+
+ public ConstantModule getConstantModule(int index) {
+ Constant c = getConstant(index);
+ assert c != null;
+ assert c.tag == Constants.CONSTANT_Module;
+ return (ConstantModule)c;
+ }
+
+ public ConstantPackage getConstantPackage(int index) {
+ Constant c = getConstant(index);
+ assert c != null;
+ assert c.tag == Constants.CONSTANT_Package;
+ return (ConstantPackage)c;
+ }
+
+ public String getConstantString_CONSTANTClass(int index) {
+ ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class);
+ index = c.getNameIndex();
+ return ((ConstantUtf8) getConstant(index, Constants.CONSTANT_Utf8)).getValue();
+ }
+
+ public int getLength() {
+ return poolSize;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = 1; i < poolSize; i++)
+ buf.append(i + ")" + pool[i] + "\n");
+
+ return buf.toString();
+ }
+
+ public int lookupInteger(int n) {
+ for (int i = 1; i < poolSize; i++) {
+ if (pool[i] instanceof ConstantInteger) {
+ ConstantInteger c = (ConstantInteger) pool[i];
+ if (c.getValue() == n)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int lookupUtf8(String string) {
+ Integer pos = utf8Cache.get(string);
+ if (pos != null) {
+ return pos;
+ }
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Utf8) {
+ if (((ConstantUtf8) c).getValue().equals(string)) {
+ utf8Cache.put(string, i);
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public int lookupClass(String classname) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Class) {
+ int cIndex = ((ConstantClass) c).getNameIndex();
+ String cName = ((ConstantUtf8) pool[cIndex]).getValue();
+ if (cName.equals(classname))
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addUtf8(String n) {
+ int ret = lookupUtf8(n);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ret = poolSize;
+ pool[poolSize++] = new ConstantUtf8(n);
+ return ret;
+ }
+
+ public int addInteger(int n) {
+ int ret = lookupInteger(n);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ret = poolSize;
+ pool[poolSize++] = new ConstantInteger(n);
+ return ret;
+ }
+
+ public int addArrayClass(ArrayType type) {
+ return addClass(type.getSignature());
+ }
+
+ public int addClass(ObjectType type) {
+ return addClass(type.getClassName());
+ }
+
+ public int addClass(String classname) {
+ String toAdd = classname.replace('.', '/');
+ int ret = lookupClass(toAdd);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ConstantClass c = new ConstantClass(addUtf8(toAdd));
+ ret = poolSize;
+ pool[poolSize++] = c;
+ return ret;
+ }
+
+ private void adjustSize() {
+ if (poolSize + 3 >= pool.length) {
+ Constant[] cs = pool;
+ pool = new Constant[cs.length + 8];
+ System.arraycopy(cs, 0, pool, 0, cs.length);
+ }
+ if (poolSize == 0)
+ poolSize = 1; // someone about to do something in here!
+ }
+
+ public int addFieldref(String class_name, String field_name, String signature) {
+ int ret = lookupFieldref(class_name, field_name, signature);
+ int class_index, name_and_type_index;
+
+ if (ret != -1)
+ return ret;
+
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(field_name, signature);
+ ret = poolSize;
+ pool[poolSize++] = new ConstantFieldref(class_index, name_and_type_index);
+
+ return ret;
+ }
+
+ public int lookupFieldref(String searchClassname, String searchFieldname, String searchSignature) {
+ searchClassname = searchClassname.replace('.', '/');
+ String k = new StringBuffer().append(searchClassname).append(searchFieldname).append(searchSignature).toString();
+ Integer pos = fieldCache.get(k);
+ if (pos != null)
+ return pos.intValue();
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Fieldref) {
+ ConstantFieldref cfr = (ConstantFieldref) c;
+ ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()];
+
+ // check the class
+ int cIndex = cfr.getClassIndex();
+ ConstantClass cc = (ConstantClass) pool[cIndex];
+ String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue();
+ if (!cName.equals(searchClassname))
+ continue;
+
+ // check the name and type
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue();
+ if (!name.equals(searchFieldname))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue();
+ if (!typeSignature.equals(searchSignature))
+ continue;
+ fieldCache.put(k, new Integer(i));
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addNameAndType(String name, String signature) {
+ int ret = lookupNameAndType(name, signature);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ int name_index = addUtf8(name);
+ int signature_index = addUtf8(signature);
+ ret = poolSize;
+ pool[poolSize++] = new ConstantNameAndType(name_index, signature_index);
+ return ret;
+ }
+
+ public int lookupNameAndType(String searchName, String searchTypeSignature) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_NameAndType) {
+ ConstantNameAndType cnat = (ConstantNameAndType) c;
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue();
+ if (!name.equals(searchName))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue();
+ if (!typeSignature.equals(searchTypeSignature))
+ continue;
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addFloat(float f) {
+ int ret = lookupFloat(f);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ret = poolSize;
+ pool[poolSize++] = new ConstantFloat(f);
+ return ret;
+ }
+
+ public int lookupFloat(float f) {
+ int bits = Float.floatToIntBits(f);
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Float) {
+ ConstantFloat cf = (ConstantFloat) c;
+ if (Float.floatToIntBits(cf.getValue()) == bits)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addDouble(double d) {
+ int ret = lookupDouble(d);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ret = poolSize;
+ pool[poolSize] = new ConstantDouble(d);
+ poolSize += 2;
+ return ret;
+ }
+
+ public int lookupDouble(double d) {
+ long bits = Double.doubleToLongBits(d);
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Double) {
+ ConstantDouble cf = (ConstantDouble) c;
+ if (Double.doubleToLongBits(cf.getValue()) == bits)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addLong(long l) {
+ int ret = lookupLong(l);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ret = poolSize;
+ pool[poolSize] = new ConstantLong(l);
+ poolSize += 2;
+ return ret;
+ }
+
+ public int lookupString(String s) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_String) {
+ ConstantString cs = (ConstantString) c;
+ ConstantUtf8 cu8 = (ConstantUtf8) pool[cs.getStringIndex()];
+ if (cu8.getValue().equals(s))
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addString(String str) {
+ int ret = lookupString(str);
+ if (ret != -1)
+ return ret;
+ int utf8 = addUtf8(str);
+ adjustSize();
+ ConstantString s = new ConstantString(utf8);
+ ret = poolSize;
+ pool[poolSize++] = s;
+ return ret;
+ }
+
+ public int lookupLong(long l) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Long) {
+ ConstantLong cf = (ConstantLong) c;
+ if (cf.getValue() == l)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addConstant(Constant c, ConstantPool cp) {
+ Constant[] constants = cp.getConstantPool();
+ switch (c.getTag()) {
+
+ case Constants.CONSTANT_String: {
+ ConstantString s = (ConstantString) c;
+ ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
+
+ return addString(u8.getValue());
+ }
+
+ case Constants.CONSTANT_Class: {
+ ConstantClass s = (ConstantClass) c;
+ ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
+
+ return addClass(u8.getValue());
+ }
+
+ case Constants.CONSTANT_NameAndType: {
+ ConstantNameAndType n = (ConstantNameAndType) c;
+ ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
+ ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
+
+ return addNameAndType(u8.getValue(), u8_2.getValue());
+ }
+
+ case Constants.CONSTANT_InvokeDynamic: {
+ ConstantInvokeDynamic cid = (ConstantInvokeDynamic)c;
+ int index1 = cid.getBootstrapMethodAttrIndex();
+ ConstantNameAndType cnat = (ConstantNameAndType)constants[cid.getNameAndTypeIndex()];
+ ConstantUtf8 name = (ConstantUtf8) constants[cnat.getNameIndex()];
+ ConstantUtf8 signature = (ConstantUtf8) constants[cnat.getSignatureIndex()];
+ int index2 = addNameAndType(name.getValue(), signature.getValue());
+ return addInvokeDynamic(index1,index2);
+ }
+
+ case Constants.CONSTANT_MethodHandle:
+ ConstantMethodHandle cmh = (ConstantMethodHandle)c;
+ return addMethodHandle(cmh.getReferenceKind(),addConstant(constants[cmh.getReferenceIndex()],cp));
+
+ case Constants.CONSTANT_Utf8:
+ return addUtf8(((ConstantUtf8) c).getValue());
+
+ case Constants.CONSTANT_Double:
+ return addDouble(((ConstantDouble) c).getValue());
+
+ case Constants.CONSTANT_Float:
+ return addFloat(((ConstantFloat) c).getValue());
+
+ case Constants.CONSTANT_Long:
+ return addLong(((ConstantLong) c).getValue());
+
+ case Constants.CONSTANT_Integer:
+ return addInteger(((ConstantInteger) c).getValue());
+
+ case Constants.CONSTANT_MethodType:
+ ConstantMethodType cmt = (ConstantMethodType)c;
+ return addMethodType(addConstant(constants[cmt.getDescriptorIndex()],cp));
+
+ 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.getValue().replace('/', '.');
+
+ u8 = (ConstantUtf8) constants[n.getNameIndex()];
+ String name = u8.getValue();
+
+ u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
+ String signature = u8.getValue();
+
+ switch (c.getTag()) {
+ case Constants.CONSTANT_InterfaceMethodref:
+ return addInterfaceMethodref(class_name, name, signature);
+
+ case Constants.CONSTANT_Methodref:
+ return addMethodref(class_name, name, signature); // OPTIMIZE indicate it should be cached!
+
+ 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);
+ }
+ }
+
+ public int addMethodHandle(byte referenceKind, int referenceIndex) {
+ adjustSize();
+ int ret = poolSize;
+ pool[poolSize++] = new ConstantMethodHandle(referenceKind, referenceIndex);
+ return ret;
+ }
+
+ public int addMethodType(int descriptorIndex) {
+ adjustSize();
+ int ret = poolSize;
+ pool[poolSize++] = new ConstantMethodType(descriptorIndex);
+ return ret;
+ }
+
+ // OPTIMIZE should put it in the cache now
+ 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 = poolSize;
+ pool[poolSize++] = new ConstantMethodref(class_index, name_and_type_index);
+ return ret;
+ }
+
+ public int addInvokeDynamic(int bootstrapMethodIndex, int constantNameAndTypeIndex) {
+ adjustSize();
+ int ret = poolSize;
+ pool[poolSize++] = new ConstantInvokeDynamic(bootstrapMethodIndex, constantNameAndTypeIndex);
+ return ret;
+ }
+
+ public int addInterfaceMethodref(String class_name, String method_name, String signature) {
+ int ret = lookupInterfaceMethodref(class_name, method_name, signature);
+ int class_index, name_and_type_index;
+
+ if (ret != -1)
+ return ret;
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(method_name, signature);
+ ret = poolSize;
+ pool[poolSize++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
+ return ret;
+ }
+
+ public int lookupInterfaceMethodref(String searchClassname, String searchMethodName, String searchSignature) {
+ searchClassname = searchClassname.replace('.', '/');
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_InterfaceMethodref) {
+ ConstantInterfaceMethodref cfr = (ConstantInterfaceMethodref) c;
+
+ ConstantClass cc = (ConstantClass) pool[cfr.getClassIndex()];
+ String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue();
+ if (!cName.equals(searchClassname))
+ continue;
+
+ // check the name and type
+ ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()];
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue();
+ if (!name.equals(searchMethodName))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue();
+ if (!typeSignature.equals(searchSignature))
+ continue;
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int lookupMethodref(String searchClassname, String searchMethodName, String searchSignature) {
+ String key = new StringBuffer().append(searchClassname).append(searchMethodName).append(searchSignature).toString();
+ Integer cached = methodCache.get(key);
+ if (cached != null)
+ return cached.intValue();
+ searchClassname = searchClassname.replace('.', '/');
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Methodref) {
+ ConstantMethodref cfr = (ConstantMethodref) c;
+ ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()];
+
+ // check the class
+ int cIndex = cfr.getClassIndex();
+ ConstantClass cc = (ConstantClass) pool[cIndex];
+ String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue();
+ if (!cName.equals(searchClassname))
+ continue;
+
+ // check the name and type
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue();
+ if (!name.equals(searchMethodName))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue();
+ if (!typeSignature.equals(searchSignature))
+ continue;
+ methodCache.put(key, new Integer(i));
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public ConstantPool getFinalConstantPool() {
+ Constant[] cs = new Constant[poolSize]; // create it the exact size we need
+ System.arraycopy(pool, 0, cs, 0, poolSize);
+ return new ConstantPool(cs);
+ }
+
+ public String getModuleName(int moduleIndex) {
+ return getConstantModule(moduleIndex).getModuleName(this);
+ }
+
+ public String getPackageName(int packageIndex) {
+ return getConstantPackage(packageIndex).getPackageName(this);
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java
new file mode 100644
index 000000000..ef9da55db
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantString.java
@@ -0,0 +1,120 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a String object.
+ *
+ * @version $Id: ConstantString.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
+ */
+public final class ConstantString extends Constant {
+
+ private int stringIndex;
+
+ ConstantString(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort());
+ }
+
+ public ConstantString(int stringIndex) {
+ super(Constants.CONSTANT_String);
+ this.stringIndex = stringIndex;
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantString(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(stringIndex);
+ }
+
+ // OPTIMIZE fix duplication in these next two methods
+ /**
+ * @return the index of the string in the constant pool
+ */
+ @Override
+ public Integer getValue() {
+ return stringIndex;
+ }
+
+ public final int getStringIndex() {
+ return stringIndex;
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(string_index = " + stringIndex + ")";
+ }
+
+ /**
+ * @return the string, as dereferenced using the internal index into the supplied constant pool
+ */
+ public String getString(ConstantPool cpool) {
+ Constant c = cpool.getConstant(stringIndex, Constants.CONSTANT_Utf8);
+ return ((ConstantUtf8) c).getValue();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java
new file mode 100644
index 000000000..f8200db47
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantUtf8.java
@@ -0,0 +1,109 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a Utf8 encoded string.
+ *
+ * @version $Id: ConstantUtf8.java,v 1.5 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
+ */
+public final class ConstantUtf8 extends Constant implements SimpleConstant {
+ private String string;
+
+ ConstantUtf8(DataInputStream file) throws IOException {
+ super(Constants.CONSTANT_Utf8);
+ string = file.readUTF();
+ }
+
+ public ConstantUtf8(String string) {
+ super(Constants.CONSTANT_Utf8);
+ assert string != null;
+ this.string = string;
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantUtf8(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeUTF(string);
+ }
+
+ @Override
+ public final String toString() {
+ return super.toString() + "(\"" + Utility.replace(string, "\n", "\\n") + "\")";
+ }
+
+ @Override
+ public String getValue() {
+ return string;
+ }
+
+ public String getStringValue() {
+ return string;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java
new file mode 100644
index 000000000..730e8aff0
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ConstantValue.java
@@ -0,0 +1,131 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents a constant value, i.e., a default value for initializing a class
+ * field. This class is instantiated by the <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id: ConstantValue.java,v 1.6 2009/09/16 00:43:49 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Attribute
+ */
+public final class ConstantValue extends Attribute {
+ private int constantvalue_index;
+
+ ConstantValue(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
+ this(name_index, length, file.readUnsignedShort(), constant_pool);
+ }
+
+ 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;
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantValue(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ super.dump(file);
+ file.writeShort(constantvalue_index);
+ }
+
+ public final int getConstantValueIndex() {
+ return constantvalue_index;
+ }
+
+ @Override
+ public final String toString() {
+ Constant c = cpool.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).getValue();
+ break;
+ case Constants.CONSTANT_Float:
+ buf = "" + ((ConstantFloat) c).getValue();
+ break;
+ case Constants.CONSTANT_Double:
+ buf = "" + ((ConstantDouble) c).getValue();
+ break;
+ case Constants.CONSTANT_Integer:
+ buf = "" + ((ConstantInteger) c).getValue();
+ break;
+ case Constants.CONSTANT_String:
+ i = ((ConstantString) c).getStringIndex();
+ c = cpool.getConstant(i, Constants.CONSTANT_Utf8);
+ buf = "\"" + Utility.convertString(((ConstantUtf8) c).getValue()) + "\"";
+ break;
+
+ default:
+ throw new IllegalStateException("Type of ConstValue invalid: " + c);
+ }
+
+ return buf;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java
new file mode 100644
index 000000000..21bbbcb46
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Deprecated.java
@@ -0,0 +1,171 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and denotes that this is a deprecated method. It is instantiated from the
+ * <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id: Deprecated.java,v 1.5 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Attribute
+ */
+public final class Deprecated extends Attribute {
+ 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());
+ }
+
+ /**
+ * @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");
+ }
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @return data bytes.
+ */
+ public final byte[] getBytes() {
+ return bytes;
+ }
+
+ /**
+ * @param bytes.
+ */
+ public final void setBytes(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ /**
+ * @return attribute name
+ */
+ @Override
+ 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 = (byte[])bytes.clone();
+ //
+ // c.cpool = constant_pool;
+ // return c;
+ // }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java
new file mode 100644
index 000000000..9e1554ec5
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/EnclosingMethod.java
@@ -0,0 +1,87 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This attribute exists for local or
+ * anonymous classes and ... there can be only one.
+ */
+public class EnclosingMethod extends Attribute {
+
+ // Pointer to the CONSTANT_Class_info structure representing the
+ // innermost class that encloses the declaration of the current class.
+ private int classIndex;
+
+ // If the current class is not immediately enclosed by a method or
+ // constructor, then the value of the method_index item must be zero.
+ // Otherwise, the value of the method_index item must point to a
+ // CONSTANT_NameAndType_info structure representing the name and the
+ // type of a method in the class referenced by the class we point
+ // to in the class_index. *It is the compiler responsibility* to
+ // ensure that the method identified by this index is the closest
+ // lexically enclosing method that includes the local/anonymous class.
+ private int methodIndex;
+
+ // Ctors - and code to read an attribute in.
+ public EnclosingMethod(int nameIndex, int len, DataInputStream dis, ConstantPool cpool) throws IOException {
+ this(nameIndex, len, dis.readUnsignedShort(), dis.readUnsignedShort(), cpool);
+ }
+
+ private EnclosingMethod(int nameIndex, int len, int classIdx,int methodIdx, ConstantPool cpool) {
+ super(Constants.ATTR_ENCLOSING_METHOD, nameIndex, len, cpool);
+ classIndex = classIdx;
+ methodIndex = methodIdx;
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitEnclosingMethod(this);
+ }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ // is this next line sufficient?
+ // return (EnclosingMethod)clone();
+ }
+
+ // Accessors
+ public final int getEnclosingClassIndex() { return classIndex; }
+ public final int getEnclosingMethodIndex(){ return methodIndex;}
+
+ public final void setEnclosingClassIndex(int idx) {classIndex = idx;}
+ public final void setEnclosingMethodIndex(int idx){methodIndex= idx;}
+
+ public final ConstantClass getEnclosingClass() {
+ ConstantClass c =
+ (ConstantClass)cpool.getConstant(classIndex,Constants.CONSTANT_Class);
+ return c;
+ }
+
+ public final ConstantNameAndType getEnclosingMethod() {
+ if (methodIndex == 0) return null;
+ ConstantNameAndType nat =
+ (ConstantNameAndType)cpool.getConstant(methodIndex,Constants.CONSTANT_NameAndType);
+ return nat;
+ }
+
+ public final void dump(DataOutputStream file) throws IOException {
+ super.dump(file);
+ file.writeShort(classIndex);
+ file.writeShort(methodIndex);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java
new file mode 100644
index 000000000..ad7d43f2e
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ExceptionTable.java
@@ -0,0 +1,199 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.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 <em>ExceptionTable</em> for historical reasons; The Java Virtual Machine Specification, Second Edition defines
+ * this attribute using the name <em>Exceptions</em> (which is inconsistent with the other classes).
+ *
+ * @version $Id: ExceptionTable.java,v 1.5 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Code
+ */
+public final class ExceptionTable extends Attribute {
+ 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());
+ }
+
+ /**
+ * @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();
+ }
+
+ /**
+ * 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(ClassVisitor 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]);
+ }
+
+ /**
+ * @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] = cpool.getConstantString(exception_index_table[i], Constants.CONSTANT_Class).replace('/', '.');
+ return names;
+ }
+
+ /**
+ * @param exception_index_table. 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.
+ */
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer("");
+ String str;
+
+ for (int i = 0; i < number_of_exceptions; i++) {
+ str = cpool.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();
+ // c.exception_index_table = (int[])exception_index_table.clone();
+ // c.cpool = constant_pool;
+ // return c;
+ // }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java
new file mode 100644
index 000000000..f34464375
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Field.java
@@ -0,0 +1,136 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.generic.Type;
+
+/**
+ * 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,v 1.6 2009/09/15 03:33:52 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class Field extends FieldOrMethod {
+
+ public static final Field[] NoFields = new Field[0];
+
+ private Type fieldType = null; // lazily initialized
+
+ private Field() {
+ }
+
+ public Field(Field c) {
+ super(c);
+ }
+
+ Field(DataInputStream dis, ConstantPool cpool) throws IOException {
+ super(dis, cpool);
+ }
+
+ public Field(int modifiers, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) {
+ super(modifiers, nameIndex, signatureIndex, attributes, cpool);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitField(this);
+ }
+
+ /**
+ * @return constant value associated with this field (may be null)
+ */
+ public final ConstantValue getConstantValue() {
+ return AttributeUtils.getConstantValueAttribute(attributes);
+ }
+
+ /**
+ * Return string representation close to declaration format, eg: 'public static final short MAX = 100'
+ */
+ @Override
+ public final String toString() {
+ // Get names from constant pool
+ StringBuffer buf = new StringBuffer(Utility.accessToString(modifiers));
+ if (buf.length() > 0) {
+ buf.append(" ");
+ }
+ String signature = Utility.signatureToString(getSignature());
+
+ buf.append(signature).append(" ").append(getName());
+
+ ConstantValue cv = getConstantValue();
+ if (cv != null) {
+ buf.append(" = ").append(cv);
+ }
+
+ // append all attributes that are *not* "ConstantValue"
+ for (Attribute a : attributes) {
+ if (!(a instanceof ConstantValue)) {
+ buf.append(" [").append(a.toString()).append("]");
+ }
+ }
+
+ return buf.toString();
+ }
+
+ /** return the type of the field */
+ public Type getType() {
+ if (fieldType == null) {
+ fieldType = Type.getReturnType(getSignature());
+ }
+ return fieldType;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java
new file mode 100644
index 000000000..a152b616f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/FieldOrMethod.java
@@ -0,0 +1,201 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos;
+
+/**
+ * Abstract super class for fields and methods.
+ *
+ * @version $Id: FieldOrMethod.java,v 1.12 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public abstract class FieldOrMethod extends Modifiers implements Node {
+ protected int nameIndex;
+ protected int signatureIndex;
+ protected Attribute[] attributes;
+
+ protected ConstantPool cpool;
+ private String name; // lazily initialized
+ private String signature; // lazily initialized
+ private AnnotationGen[] annotations; // lazily initialized
+ private String signatureAttributeString = null;
+ private boolean searchedForSignatureAttribute = false;
+
+ protected 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.getModifiers(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c.getConstantPool());
+ }
+
+ protected FieldOrMethod(DataInputStream file, ConstantPool cpool) throws IOException {
+ this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, cpool);
+ attributes = AttributeUtils.readAttributes(file, cpool);
+ }
+
+ protected FieldOrMethod(int accessFlags, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) {
+ this.modifiers = accessFlags;
+ this.nameIndex = nameIndex;
+ this.signatureIndex = signatureIndex;
+ this.cpool = cpool;
+ this.attributes = attributes;
+ }
+
+ /**
+ * @param attributes Collection of object attributes.
+ */
+ public void setAttributes(Attribute[] attributes) {
+ this.attributes = attributes;
+ }
+
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeShort(modifiers);
+ file.writeShort(nameIndex);
+ file.writeShort(signatureIndex);
+ AttributeUtils.writeAttributes(attributes, file);
+ }
+
+ public final Attribute[] getAttributes() {
+ return attributes;
+ }
+
+ public final ConstantPool getConstantPool() {
+ return cpool;
+ }
+
+ public final int getNameIndex() {
+ return nameIndex;
+ }
+
+ public final int getSignatureIndex() {
+ return signatureIndex;
+ }
+
+ public final String getName() {
+ if (name == null) {
+ ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8);
+ name = c.getValue();
+ }
+ return name;
+ }
+
+ public final String getSignature() {
+ if (signature == null) {
+ ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8);
+ signature = c.getValue();
+ }
+ return signature;
+ }
+
+ /**
+ * This will return the contents of a signature attribute attached to a member, or if there is none it will return the same as
+ * 'getSignature()'. Signature attributes are attached to members that were declared generic.
+ */
+ public final String getDeclaredSignature() {
+ if (getGenericSignature() != null)
+ return getGenericSignature();
+ return getSignature();
+ }
+
+ public AnnotationGen[] getAnnotations() {
+ // Ensure we have unpacked any attributes that contain annotations.
+ // We don't remove these annotation attributes from the attributes list, they
+ // remain there.
+ if (annotations == null) {
+ // Find attributes that contain annotation data
+ List<AnnotationGen> accumulatedAnnotations = new ArrayList<AnnotationGen>();
+ for (int i = 0; i < attributes.length; i++) {
+ Attribute attribute = attributes[i];
+ if (attribute instanceof RuntimeAnnos) {
+ RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attribute;
+ accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations());
+ }
+ }
+ if (accumulatedAnnotations.size() == 0) {
+ annotations = AnnotationGen.NO_ANNOTATIONS;
+ } else {
+ annotations = accumulatedAnnotations.toArray(new AnnotationGen[] {});
+ }
+ }
+ return annotations;
+ }
+
+ /**
+ * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be
+ * (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector<Ljava/lang/String>;' Coded for performance -
+ * searches for the attribute only when requested - only searches for it once.
+ */
+ public final String getGenericSignature() {
+ if (!searchedForSignatureAttribute) {
+ Signature sig = AttributeUtils.getSignatureAttribute(attributes);
+ signatureAttributeString = (sig == null ? null : sig.getSignature());
+ searchedForSignatureAttribute = true;
+ }
+ return signatureAttributeString;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java
new file mode 100644
index 000000000..d3b1eb0a8
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClass.java
@@ -0,0 +1,232 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.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.
+ *
+ * @version $Id: InnerClass.java,v 1.4 2009/09/10 15:35:05 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see InnerClasses
+ */
+public final class InnerClass implements Cloneable, Node {
+ 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());
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @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;
+ }
+
+ /**
+ * @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.
+ */
+ public final void setInnerAccessFlags(int inner_access_flags) {
+ this.inner_access_flags = inner_access_flags;
+ }
+
+ /**
+ * @param inner_class_index.
+ */
+ public final void setInnerClassIndex(int inner_class_index) {
+ this.inner_class_index = inner_class_index;
+ }
+
+ /**
+ * @param inner_name_index.
+ */
+ public final void setInnerNameIndex(int inner_name_index) {
+ this.inner_name_index = inner_name_index;
+ }
+
+ /**
+ * @param outer_class_index.
+ */
+ public final void setOuterClassIndex(int outer_class_index) {
+ this.outer_class_index = outer_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 = "<not a member>";
+
+ if (inner_name_index != 0)
+ inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index, Constants.CONSTANT_Utf8)).getValue();
+ else
+ inner_name = "<anonymous>";
+
+ 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;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java
new file mode 100644
index 000000000..0078156ed
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/InnerClasses.java
@@ -0,0 +1,181 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and denotes that this class is an Inner class of another. to the source file of
+ * this class. It is instantiated from the <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id: InnerClasses.java,v 1.5 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Attribute
+ */
+public final class InnerClasses extends Attribute {
+ 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());
+ }
+
+ /**
+ * @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
+ * @param sourcefile_index Index in constant pool to CONSTANT_Utf8
+ */
+ 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);
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @return array of inner class "records"
+ */
+ public final InnerClass[] getInnerClasses() {
+ return inner_classes;
+ }
+
+ /**
+ * @param 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.
+ */
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = 0; i < number_of_classes; i++)
+ buf.append(inner_classes[i].toString(cpool) + "\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.cpool = constant_pool;
+ // return c;
+ // }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java
new file mode 100644
index 000000000..25c415295
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/JavaClass.java
@@ -0,0 +1,837 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.StringTokenizer;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos;
+import org.aspectj.apache.bcel.generic.Type;
+import org.aspectj.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 <a href="ftp://java.sun.com/docs/specs/">JVM specification</a> 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 <a href="../generic/ClassGen.html">ClassGen</a> class.
+ *
+ * @version $Id: JavaClass.java,v 1.22 2009/09/15 19:40:14 aclement Exp $
+ * @see org.aspectj.apache.bcel.generic.ClassGen
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class JavaClass extends Modifiers implements Cloneable, Node {
+
+ private static final String[] NoInterfaceNames = new String[0];
+ private static final Field[] NoFields = new Field[0];
+ private static final Method[] NoMethod = new Method[0];
+ private static final int[] NoInterfaceIndices = new int[0];
+ private static final Attribute[] NoAttributes = new Attribute[0];
+
+ private String fileName;
+ private String packageName;
+ private String sourcefileName;
+ private int classnameIdx;
+ private int superclassnameIdx;
+ private String classname;
+ private String superclassname;
+ private int major, minor;
+ private ConstantPool cpool;
+ private int[] interfaces;
+ private String[] interfacenames;
+ private Field[] fields;
+ private Method[] methods;
+ private Attribute[] attributes;
+ private AnnotationGen[] annotations;
+
+ private boolean isGeneric = false;
+ private boolean isAnonymous = false;
+ private boolean isNested = false;
+ private boolean computedNestedTypeStatus = false;
+
+ // Annotations are collected from certain attributes, don't do it more than necessary!
+ private boolean annotationsOutOfDate = true;
+
+ // state for dealing with generic signature string
+ private String signatureAttributeString = null;
+ private Signature signatureAttribute = null;
+ private boolean searchedForSignatureAttribute = false;
+
+ /**
+ * In cases where we go ahead and create something, use the default SyntheticRepository, because we don't know any better.
+ */
+ private transient org.aspectj.apache.bcel.util.Repository repository = null;
+
+ public JavaClass(int classnameIndex, int superclassnameIndex, String filename, int major, int minor, int access_flags,
+ ConstantPool cpool, int[] interfaces, Field[] fields, Method[] methods, Attribute[] attributes) {
+ if (interfaces == null) {
+ interfaces = NoInterfaceIndices;
+ }
+
+ this.classnameIdx = classnameIndex;
+ this.superclassnameIdx = superclassnameIndex;
+ this.fileName = filename;
+ this.major = major;
+ this.minor = minor;
+ this.modifiers = access_flags;
+ this.cpool = cpool;
+ this.interfaces = interfaces;
+ this.fields = (fields == null ? NoFields : fields);
+ this.methods = (methods == null ? NoMethod : methods);
+ this.attributes = (attributes == null ? NoAttributes : attributes);
+ annotationsOutOfDate = true;
+
+ // Get source file name if available
+ SourceFile sfAttribute = AttributeUtils.getSourceFileAttribute(attributes);
+ sourcefileName = sfAttribute == null ? "<Unknown>" : sfAttribute.getSourceFileName();
+
+ /*
+ * According to the specification the following entries must be of type `ConstantClass' but we check that anyway via the
+ * `ConstPool.getConstant' method.
+ */
+ classname = cpool.getConstantString(classnameIndex, Constants.CONSTANT_Class);
+ classname = Utility.compactClassName(classname, false);
+
+ int index = classname.lastIndexOf('.');
+ if (index < 0) {
+ packageName = "";
+ } else {
+ packageName = classname.substring(0, index);
+ }
+
+ if (superclassnameIndex > 0) { // May be zero -> class is java.lang.Object
+ superclassname = cpool.getConstantString(superclassnameIndex, Constants.CONSTANT_Class);
+ superclassname = Utility.compactClassName(superclassname, false);
+ } else {
+ superclassname = "java.lang.Object";
+ }
+
+ if (interfaces.length == 0) {
+ interfacenames = NoInterfaceNames;
+ } else {
+ interfacenames = new String[interfaces.length];
+ for (int i = 0; i < interfaces.length; i++) {
+ String str = cpool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
+ interfacenames[i] = Utility.compactClassName(str, false);
+ }
+ }
+ }
+
+ /**
+ * 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(ClassVisitor v) {
+ v.visitJavaClass(this);
+ }
+
+ /**
+ * 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();
+ }
+ dump(new DataOutputStream(new FileOutputStream(file)));
+ }
+
+ /**
+ * 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.
+ */
+ public void dump(OutputStream file) throws IOException {
+ dump(new DataOutputStream(file));
+ }
+
+ /**
+ * Dump Java class to output stream in binary format.
+ */
+ public void dump(DataOutputStream file) throws IOException {
+ file.writeInt(0xcafebabe);
+ file.writeShort(minor);
+ file.writeShort(major);
+
+ cpool.dump(file);
+
+ file.writeShort(modifiers);
+ file.writeShort(classnameIdx);
+ file.writeShort(superclassnameIdx);
+
+ 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);
+ }
+
+ AttributeUtils.writeAttributes(attributes, file);
+
+ file.close();
+ }
+
+ public Attribute[] getAttributes() {
+ return attributes;
+ }
+
+ public AnnotationGen[] getAnnotations() {
+ if (annotationsOutOfDate) {
+ // Find attributes that contain annotation data
+ List<AnnotationGen> accumulatedAnnotations = new ArrayList<AnnotationGen>();
+ for (int i = 0; i < attributes.length; i++) {
+ Attribute attribute = attributes[i];
+ if (attribute instanceof RuntimeAnnos) {
+ RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attribute;
+ accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations());
+ }
+ }
+ annotations = accumulatedAnnotations.toArray(new AnnotationGen[] {});
+ annotationsOutOfDate = false;
+ }
+ return annotations;
+ }
+
+ /**
+ * @return Class name.
+ */
+ public String getClassName() {
+ return classname;
+ }
+
+ /**
+ * @return Package name.
+ */
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public int getClassNameIndex() {
+ return classnameIdx;
+ }
+
+ public ConstantPool getConstantPool() {
+ return cpool;
+ }
+
+ /**
+ * @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 fileName;
+ }
+
+ /**
+ * @return Names of implemented interfaces.
+ */
+ public String[] getInterfaceNames() {
+ return interfacenames;
+ }
+
+ /**
+ * @return Indices in constant pool of implemented interfaces.
+ */
+ public int[] getInterfaceIndices() {
+ return interfaces;
+ }
+
+ public int getMajor() {
+ return major;
+ }
+
+ /**
+ * @return Methods of the class.
+ */
+ public Method[] getMethods() {
+ return methods;
+ }
+
+ /**
+ * @return A org.aspectj.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;
+ }
+
+ public Method getMethod(java.lang.reflect.Constructor<?> c) {
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (method.getName().equals("<init>") && c.getModifiers() == method.getModifiers()
+ && Type.getSignature(c).equals(method.getSignature())) {
+ return method;
+ }
+ }
+
+ return null;
+ }
+
+ public Field getField(java.lang.reflect.Field field) {
+ String fieldName = field.getName();
+ for (Field f : fields) {
+ if (f.getName().equals(fieldName)) {
+ return f;
+ }
+ }
+ 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 sourcefileName;
+ }
+
+ /**
+ * @return Superclass name.
+ */
+ public String getSuperclassName() {
+ return superclassname;
+ }
+
+ /**
+ * @return Class name index.
+ */
+ public int getSuperclassNameIndex() {
+ return superclassnameIdx;
+ }
+
+ /**
+ * @param attributes .
+ */
+ public void setAttributes(Attribute[] attributes) {
+ this.attributes = attributes;
+ annotationsOutOfDate = true;
+ }
+
+ /**
+ * @param class_name .
+ */
+ public void setClassName(String class_name) {
+ this.classname = class_name;
+ }
+
+ /**
+ * @param class_name_index .
+ */
+ public void setClassNameIndex(int class_name_index) {
+ this.classnameIdx = class_name_index;
+ }
+
+ /**
+ * @param constant_pool .
+ */
+ public void setConstantPool(ConstantPool constant_pool) {
+ this.cpool = 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.fileName = file_name;
+ }
+
+ /**
+ * @param interface_names .
+ */
+ public void setInterfaceNames(String[] interface_names) {
+ this.interfacenames = interface_names;
+ }
+
+ /**
+ * @param interfaces .
+ */
+ public void setInterfaces(int[] interfaces) {
+ this.interfaces = interfaces;
+ }
+
+ public void setMajor(int major) {
+ this.major = major;
+ }
+
+ public void setMethods(Method[] methods) {
+ this.methods = methods;
+ }
+
+ 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.sourcefileName = source_file_name;
+ }
+
+ /**
+ * @param superclass_name .
+ */
+ public void setSuperclassName(String superclass_name) {
+ this.superclassname = superclass_name;
+ }
+
+ /**
+ * @param superclass_name_index .
+ */
+ public void setSuperclassNameIndex(int superclass_name_index) {
+ this.superclassnameIdx = superclass_name_index;
+ }
+
+ /**
+ * @return String representing class contents.
+ */
+ @Override
+ public String toString() {
+ String access = Utility.accessToString(modifiers, true);
+ access = access.equals("") ? "" : access + " ";
+
+ StringBuffer buf = new StringBuffer(access + Utility.classOrInterface(modifiers) + " " + classname + " extends "
+ + Utility.compactClassName(superclassname, false) + '\n');
+ int size = interfaces.length;
+
+ if (size > 0) {
+ buf.append("implements\t\t");
+
+ for (int i = 0; i < size; i++) {
+ buf.append(interfacenames[i]);
+ if (i < size - 1) {
+ buf.append(", ");
+ }
+ }
+
+ buf.append('\n');
+ }
+
+ buf.append("filename\t\t" + fileName + '\n');
+ buf.append("compiled from\t\t" + sourcefileName + '\n');
+ buf.append("compiler version\t" + major + "." + minor + '\n');
+ buf.append("access flags\t\t" + modifiers + '\n');
+ buf.append("constant pool\t\t" + cpool.getLength() + " entries\n");
+ buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n");
+
+ if (attributes.length > 0) {
+ buf.append("\nAttribute(s):\n");
+ for (int i = 0; i < attributes.length; i++) {
+ buf.append(indent(attributes[i]));
+ }
+ }
+
+ if (annotations != null && annotations.length > 0) {
+ buf.append("\nAnnotation(s):\n");
+ for (int i = 0; i < annotations.length; i++) {
+ buf.append(indent(annotations[i]));
+ }
+ }
+
+ if (fields.length > 0) {
+ buf.append("\n" + fields.length + " fields:\n");
+ for (int i = 0; i < fields.length; i++) {
+ buf.append("\t" + fields[i] + '\n');
+ }
+ }
+
+ if (methods.length > 0) {
+ buf.append("\n" + methods.length + " methods:\n");
+ for (int i = 0; i < methods.length; i++) {
+ buf.append("\t" + methods[i] + '\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" + tok.nextToken() + "\n");
+ }
+
+ return buf.toString();
+ }
+
+ public final boolean isSuper() {
+ return (modifiers & Constants.ACC_SUPER) != 0;
+ }
+
+ public final boolean isClass() {
+ return (modifiers & Constants.ACC_INTERFACE) == 0;
+ }
+
+ public final boolean isAnonymous() {
+ computeNestedTypeStatus();
+ return this.isAnonymous;
+ }
+
+ public final boolean isNested() {
+ computeNestedTypeStatus();
+ return this.isNested;
+ }
+
+ private final void computeNestedTypeStatus() {
+ if (computedNestedTypeStatus) {
+ return;
+ }
+ // Attribute[] attrs = attributes.getAttributes();
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i] instanceof InnerClasses) {
+ InnerClass[] innerClasses = ((InnerClasses) attributes[i]).getInnerClasses();
+ for (int j = 0; j < innerClasses.length; j++) {
+ boolean innerClassAttributeRefersToMe = false;
+ String inner_class_name = cpool.getConstantString(innerClasses[j].getInnerClassIndex(),
+ Constants.CONSTANT_Class);
+ inner_class_name = Utility.compactClassName(inner_class_name);
+ if (inner_class_name.equals(getClassName())) {
+ innerClassAttributeRefersToMe = true;
+ }
+ if (innerClassAttributeRefersToMe) {
+ this.isNested = true;
+ if (innerClasses[j].getInnerNameIndex() == 0) {
+ this.isAnonymous = true;
+ }
+ }
+ }
+ }
+ }
+ this.computedNestedTypeStatus = true;
+ }
+
+ // J5SUPPORT:
+ /**
+ * Returns true if this class represents an annotation, i.e. it was a 'public @interface blahblah' declaration
+ */
+ public final boolean isAnnotation() {
+ return (modifiers & Constants.ACC_ANNOTATION) != 0;
+ }
+
+ /**
+ * Returns true if this class represents an enum type
+ */
+ public final boolean isEnum() {
+ return (modifiers & Constants.ACC_ENUM) != 0;
+ }
+
+ /********************* New repository functionality *********************/
+
+ /**
+ * Gets the ClassRepository which holds its definition. By default this is the same as SyntheticRepository.getInstance();
+ */
+ public org.aspectj.apache.bcel.util.Repository getRepository() {
+ if (repository == null) {
+ repository = SyntheticRepository.getInstance();
+ }
+ return repository;
+ }
+
+ /**
+ * Sets the ClassRepository which loaded the JavaClass. Should be called immediately after parsing is done.
+ */
+ public void setRepository(org.aspectj.apache.bcel.util.Repository repository) {
+ this.repository = repository;
+ }
+
+ /**
+ * Equivalent to runtime "instanceof" operator.
+ *
+ * @return true if this JavaClass is derived from teh super class
+ */
+ public final boolean instanceOf(JavaClass super_class) {
+ 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 clazz is an implementation of interface inter
+ */
+ public boolean implementationOf(JavaClass inter) {
+ if (!inter.isInterface()) {
+ throw new IllegalArgumentException(inter.getClassName() + " is no interface");
+ }
+
+ if (this.equals(inter)) {
+ return true;
+ }
+
+ Collection<JavaClass> superInterfaces = getAllInterfaces();
+
+ for (JavaClass superInterface : superInterfaces) {
+ if (superInterface.equals(inter)) {
+ return true;
+ }
+ }
+ // 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
+ */
+ public JavaClass getSuperClass() {
+ if ("java.lang.Object".equals(getClassName())) {
+ return null;
+ }
+
+ try {
+ return getRepository().loadClass(getSuperclassName());
+ } catch (ClassNotFoundException e) {
+ System.err.println(e);
+ return null;
+ }
+ }
+
+ /**
+ * @return list of super classes of this class in ascending order, i.e., java.lang.Object is always the last element
+ */
+ public JavaClass[] getSuperClasses() {
+ JavaClass clazz = this;
+ List<JavaClass> vec = new ArrayList<JavaClass>();
+ for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) {
+ vec.add(clazz);
+ }
+ return vec.toArray(new JavaClass[vec.size()]);
+ }
+
+ /**
+ * Get interfaces directly implemented by this JavaClass.
+ */
+ public JavaClass[] getInterfaces() {
+ String[] interfaces = getInterfaceNames();
+ JavaClass[] classes = new JavaClass[interfaces.length];
+
+ try {
+ for (int i = 0; i < interfaces.length; i++) {
+ classes[i] = getRepository().loadClass(interfaces[i]);
+ }
+ } catch (ClassNotFoundException e) {
+ System.err.println(e);
+ return null;
+ }
+
+ return classes;
+ }
+
+ /**
+ * Get all interfaces implemented by this JavaClass (transitively).
+ */
+ public Collection<JavaClass> getAllInterfaces() {
+ Queue<JavaClass> queue = new LinkedList<JavaClass>();
+ List<JavaClass> interfaceList = new ArrayList<JavaClass>();
+
+ queue.add(this);
+
+ while (!queue.isEmpty()) {
+ JavaClass clazz = queue.remove();
+
+ JavaClass souper = clazz.getSuperClass();
+ JavaClass[] interfaces = clazz.getInterfaces();
+
+ if (clazz.isInterface()) {
+ interfaceList.add(clazz);
+ } else {
+ if (souper != null) {
+ queue.add(souper);
+ }
+ }
+
+ for (int i = 0; i < interfaces.length; i++) {
+ queue.add(interfaces[i]);
+ }
+ }
+
+ return interfaceList;
+ // return interfaceList.toArray(new JavaClass[interfaceList.size()]);
+ }
+
+ /**
+ * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be
+ * Ljava/util/Vector; the signature attribute will tell us e.g. "<E:>Ljava/lang/Object". We can learn the type variable names,
+ * their bounds, and the true superclass and superinterface types (including any parameterizations) Coded for performance -
+ * searches for the attribute only when requested - only searches for it once.
+ */
+ public final String getGenericSignature() {
+ loadGenericSignatureInfoIfNecessary();
+ return signatureAttributeString;
+ }
+
+ public boolean isGeneric() {
+ loadGenericSignatureInfoIfNecessary();
+ return isGeneric;
+ }
+
+ private void loadGenericSignatureInfoIfNecessary() {
+ if (!searchedForSignatureAttribute) {
+ signatureAttribute = AttributeUtils.getSignatureAttribute(attributes);
+ signatureAttributeString = signatureAttribute == null ? null : signatureAttribute.getSignature();
+ isGeneric = signatureAttribute != null && signatureAttributeString.charAt(0) == '<';
+ searchedForSignatureAttribute = true;
+ }
+ }
+
+ public final Signature getSignatureAttribute() {
+ loadGenericSignatureInfoIfNecessary();
+ return signatureAttribute;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java
new file mode 100644
index 000000000..6b2a64877
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumber.java
@@ -0,0 +1,120 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * 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.
+ *
+ * @version $Id: LineNumber.java,v 1.6 2009/09/09 21:26:54 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Andy Clement
+ * @see LineNumberTable
+ */
+public final class LineNumber implements Node {
+ private int startPC;
+ private int lineNumber;
+
+ public LineNumber(LineNumber c) {
+ this(c.getStartPC(), c.getLineNumber());
+ }
+
+ LineNumber(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort(), file.readUnsignedShort());
+ }
+
+ public LineNumber(int startPC, int lineNumber) {
+ this.startPC = startPC;
+ this.lineNumber = lineNumber;
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitLineNumber(this);
+ }
+
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeShort(startPC);
+ file.writeShort(lineNumber);
+ }
+
+ public final int getLineNumber() {
+ return lineNumber;
+ }
+
+ public final int getStartPC() {
+ return startPC;
+ }
+
+ // public final void setLineNumber(int line_number) {
+ // this.lineNumber = line_number;
+ // }
+ //
+ // public final void setStartPC(int start_pc) {
+ // this.startPC = start_pc;
+ // }
+
+ @Override
+ public final String toString() {
+ return "LineNumber(" + startPC + ", " + lineNumber + ")";
+ }
+
+ public LineNumber copy() {
+ return new LineNumber(this);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java
new file mode 100644
index 000000000..871bfe6bf
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LineNumberTable.java
@@ -0,0 +1,276 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents a table of line numbers for debugging purposes. This attribute is used by the <em>Code</em> attribute. It
+ * contains pairs of PCs and line numbers.
+ *
+ * @version $Id: LineNumberTable.java,v 1.8 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Code changes: asc Feb06 Made unpacking lazy
+ */
+public final class LineNumberTable extends Attribute {
+
+ // if 'isInPackedState' then this data needs unpacking
+ private boolean isInPackedState = false;
+ private byte[] data; // discarded once unpacked
+
+ private int tableLength;
+ private LineNumber[] table;
+
+ /*
+ * 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());
+ }
+
+ public LineNumberTable(int nameIndex, int length, LineNumber[] lineNumberTable, ConstantPool constantPool) {
+ super(Constants.ATTR_LINE_NUMBER_TABLE, nameIndex, length, constantPool);
+ setLineNumberTable(lineNumberTable);
+ isInPackedState = false;
+ }
+
+ /**
+ * Construct object from file stream.
+ *
+ * @param name_index Index of name
+ * @param length Content length in bytes
+ * @param file Input stream
+ * @throws IOException
+ * @param constant_pool Array of constants
+ */
+ LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
+ this(name_index, length, (LineNumber[]) null, constant_pool);
+ data = new byte[length];
+ file.readFully(data);
+ isInPackedState = true;
+ // assert(bytesRead==length)
+ }
+
+ // Unpacks the byte array into the table
+ private void unpack() {
+ if (isInPackedState) {
+ try {
+ ByteArrayInputStream bs = new ByteArrayInputStream(data);
+ DataInputStream dis = new DataInputStream(bs);
+ tableLength = (dis.readUnsignedShort());
+ table = new LineNumber[tableLength];
+ for (int i = 0; i < tableLength; i++) {
+ table[i] = new LineNumber(dis);
+ }
+ dis.close();
+ data = null; // throw it away now
+ } catch (IOException e) {
+ throw new RuntimeException("Unpacking of LineNumberTable attribute failed");
+ }
+ isInPackedState = false;
+ }
+ }
+
+ /**
+ * 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(ClassVisitor v) {
+ unpack();
+ 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);
+ if (isInPackedState) {
+ file.write(data);
+ } else {
+ file.writeShort(tableLength);
+ for (int i = 0; i < tableLength; i++) {
+ table[i].dump(file);
+ }
+ }
+ }
+
+ /**
+ * @return Array of (pc offset, line number) pairs.
+ */
+ public final LineNumber[] getLineNumberTable() {
+ unpack();
+ return table;
+ }
+
+ /**
+ * @param line_number_table.
+ */
+ public final void setLineNumberTable(LineNumber[] line_number_table) {
+ this.data = null;
+ this.isInPackedState = false;
+ this.table = line_number_table;
+ this.tableLength = (line_number_table == null) ? 0 : line_number_table.length;
+ }
+
+ /**
+ * @return String representation.
+ */
+ @Override
+ public final String toString() {
+ unpack();
+ StringBuffer buf = new StringBuffer();
+ StringBuffer line = new StringBuffer();
+
+ for (int i = 0; i < tableLength; i++) {
+ line.append(table[i].toString());
+
+ if (i < tableLength - 1) {
+ line.append(", ");
+ }
+
+ if (line.length() > 72) {
+ line.append('\n');
+ buf.append(line);
+ 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) {
+ unpack();
+ int l = 0, r = tableLength - 1;
+
+ if (r < 0) // array is empty
+ 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 = table[i].getStartPC();
+
+ if (j == pos)
+ return table[i].getLineNumber();
+ else if (pos < j) // else constrain search area
+ r = i - 1;
+ else
+ // pos > j
+ 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 table[min_index].getLineNumber();
+ }
+
+ /**
+ * @return deep copy of this attribute
+ */
+ // @Override
+ // public Attribute copy(ConstantPool constant_pool) {
+ // unpack();
+ // LineNumberTable newTable = (LineNumberTable) clone();
+ // newTable.table = new LineNumber[tableLength];
+ // for (int i = 0; i < tableLength; i++) {
+ // newTable.table[i] = table[i].copy();
+ // }
+ // newTable.cpool = constant_pool;
+ // return newTable;
+ // }
+ public final int getTableLength() {
+ unpack();
+ return tableLength;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java
new file mode 100644
index 000000000..c8d5cd87f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariable.java
@@ -0,0 +1,267 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.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,v 1.5 2009/09/10 15:35:05 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see LocalVariableTable
+ */
+public final class LocalVariable implements Constants, Cloneable, Node {
+
+ 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());
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @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;
+ }
+
+ /**
+ * @return Variable name.
+ */
+ public final String getName() {
+ ConstantUtf8 c;
+
+ c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8);
+ return c.getValue();
+ }
+
+ /**
+ * @return Index in constant pool of variable name.
+ */
+ public final int getNameIndex() {
+ return name_index;
+ }
+
+ /**
+ * @return Signature.
+ */
+ public final String getSignature() {
+ ConstantUtf8 c;
+ c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8);
+ return c.getValue();
+ }
+
+ /**
+ * @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.
+ */
+ public final void setLength(int length) {
+ this.length = length;
+ }
+
+ /**
+ * @param name_index.
+ */
+ public final void setNameIndex(int name_index) {
+ this.name_index = name_index;
+ }
+
+ /**
+ * @param signature_index.
+ */
+ public final void setSignatureIndex(int signature_index) {
+ this.signature_index = signature_index;
+ }
+
+ /**
+ * @param index.
+ */
+ 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.
+ */
+ @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 deep copy of this object
+ */
+ public LocalVariable copy() {
+ try {
+ return (LocalVariable) clone();
+ } catch (CloneNotSupportedException e) {
+ }
+
+ return null;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java
new file mode 100644
index 000000000..e6415dae6
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTable.java
@@ -0,0 +1,230 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents collection of local variables in a method. This attribute is contained in the <em>Code</em> attribute.
+ *
+ * @version $Id: LocalVariableTable.java,v 1.8 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Code
+ * @see LocalVariable Updates: Andy 14Feb06 - Made unpacking of the data lazy, depending on someone actually asking for it.
+ */
+public class LocalVariableTable extends Attribute {
+
+ // if 'isInPackedState' then this data needs unpacking
+ private boolean isInPackedState = false;
+ private byte[] data;
+
+ private int localVariableTableLength;
+ private LocalVariable[] localVariableTable;
+
+ /**
+ * 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 {
+ super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool);
+ data = new byte[length];
+ file.readFully(data);
+ isInPackedState = true;
+ // assert(bytesRead==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(ClassVisitor v) {
+ unpack();
+ 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);
+ if (isInPackedState) {
+ file.write(data);
+ } else {
+ file.writeShort(localVariableTableLength);
+ for (int i = 0; i < localVariableTableLength; i++)
+ localVariableTable[i].dump(file);
+ }
+ }
+
+ /**
+ * @return Array of local variables of method.
+ */
+ public final LocalVariable[] getLocalVariableTable() {
+ unpack();
+ return localVariableTable;
+ }
+
+ /**
+ * @return first matching variable using index
+ */
+ public final LocalVariable getLocalVariable(int index) {
+ unpack();
+ for (int i = 0; i < localVariableTableLength; i++) {
+ if (localVariableTable[i] != null && localVariableTable[i].getIndex() == index) {
+ return localVariableTable[i];
+ }
+ }
+ return null;
+ }
+
+ public final void setLocalVariableTable(LocalVariable[] local_variable_table) {
+ data = null;
+ isInPackedState = false;
+ this.localVariableTable = local_variable_table;
+ localVariableTableLength = (local_variable_table == null) ? 0 : local_variable_table.length;
+ }
+
+ /**
+ * @return String representation.
+ */
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer("");
+ unpack();
+ for (int i = 0; i < localVariableTableLength; i++) {
+ buf.append(localVariableTable[i].toString());
+
+ if (i < localVariableTableLength - 1)
+ buf.append('\n');
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * @return deep copy of this attribute
+ */
+ // public Attribute copy(ConstantPool constant_pool) {
+ // unpack();
+ // LocalVariableTable c = (LocalVariableTable) clone();
+ //
+ // c.localVariableTable = new LocalVariable[localVariableTableLength];
+ // for (int i = 0; i < localVariableTableLength; i++)
+ // c.localVariableTable[i] = localVariableTable[i].copy();
+ //
+ // c.cpool = constant_pool;
+ // return c;
+ // }
+ public final int getTableLength() {
+ unpack();
+ return localVariableTableLength;
+ }
+
+ // ---
+ // Unpacks the byte array into the table
+ private void unpack() {
+ if (!isInPackedState)
+ return;
+ try {
+ ByteArrayInputStream bs = new ByteArrayInputStream(data);
+ DataInputStream dis = new DataInputStream(bs);
+ localVariableTableLength = (dis.readUnsignedShort());
+ localVariableTable = new LocalVariable[localVariableTableLength];
+ for (int i = 0; i < localVariableTableLength; i++)
+ localVariableTable[i] = new LocalVariable(dis, cpool);
+ dis.close();
+ data = null; // throw it away now
+ } catch (IOException e) {
+ throw new RuntimeException("Unpacking of LocalVariableTable attribute failed");
+ }
+ isInPackedState = false;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java
new file mode 100644
index 000000000..ecd7e4383
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/LocalVariableTypeTable.java
@@ -0,0 +1,136 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * Heavily based on LocalVariableTable
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+// The new table is used when generic types are about...
+
+//LocalVariableTable_attribute {
+// u2 attribute_name_index;
+// u4 attribute_length;
+// u2 local_variable_table_length;
+// { u2 start_pc;
+// u2 length;
+// u2 name_index;
+// u2 descriptor_index;
+// u2 index;
+// } local_variable_table[local_variable_table_length];
+// }
+
+//LocalVariableTypeTable_attribute {
+// u2 attribute_name_index;
+// u4 attribute_length;
+// u2 local_variable_type_table_length;
+// {
+// u2 start_pc;
+// u2 length;
+// u2 name_index;
+// u2 signature_index;
+// u2 index;
+// } local_variable_type_table[local_variable_type_table_length];
+// }
+// J5TODO: Needs some testing !
+public class LocalVariableTypeTable extends Attribute {
+ private int local_variable_type_table_length; // Table of local
+ private LocalVariable[] local_variable_type_table; // variables
+
+ public LocalVariableTypeTable(LocalVariableTypeTable c) {
+ this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool());
+ }
+
+ public LocalVariableTypeTable(int name_index, int length, LocalVariable[] local_variable_table, ConstantPool constant_pool) {
+ super(Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool);
+ setLocalVariableTable(local_variable_table);
+ }
+
+ LocalVariableTypeTable(int nameIdx, int len, DataInputStream dis, ConstantPool cpool) throws IOException {
+ this(nameIdx, len, (LocalVariable[]) null, cpool);
+
+ local_variable_type_table_length = (dis.readUnsignedShort());
+ local_variable_type_table = new LocalVariable[local_variable_type_table_length];
+
+ for (int i = 0; i < local_variable_type_table_length; i++)
+ local_variable_type_table[i] = new LocalVariable(dis, cpool);
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitLocalVariableTypeTable(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ super.dump(file);
+ file.writeShort(local_variable_type_table_length);
+ for (int i = 0; i < local_variable_type_table_length; i++)
+ local_variable_type_table[i].dump(file);
+ }
+
+ public final LocalVariable[] getLocalVariableTypeTable() {
+ return local_variable_type_table;
+ }
+
+ public final LocalVariable getLocalVariable(int index) {
+ for (int i = 0; i < local_variable_type_table_length; i++)
+ if (local_variable_type_table[i].getIndex() == index)
+ return local_variable_type_table[i];
+
+ return null;
+ }
+
+ public final void setLocalVariableTable(LocalVariable[] local_variable_table) {
+ this.local_variable_type_table = local_variable_table;
+ local_variable_type_table_length = (local_variable_table == null) ? 0 : local_variable_table.length;
+ }
+
+ /**
+ * @return String representation.
+ */
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer("");
+
+ for (int i = 0; i < local_variable_type_table_length; i++) {
+ buf.append(local_variable_type_table[i].toString());
+
+ if (i < local_variable_type_table_length - 1)
+ buf.append('\n');
+ }
+
+ return buf.toString();
+ }
+
+ // /**
+ // * @return deep copy of this attribute
+ // */
+ // public Attribute copy(ConstantPool constant_pool) {
+ // LocalVariableTypeTable c = (LocalVariableTypeTable)clone();
+ //
+ // c.local_variable_type_table = new LocalVariable[local_variable_type_table_length];
+ // for(int i=0; i < local_variable_type_table_length; i++)
+ // c.local_variable_type_table[i] = local_variable_type_table[i].copy();
+ //
+ // c.cpool = constant_pool;
+ // return c;
+ // }
+
+ public final int getTableLength() {
+ return local_variable_type_table_length;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java
new file mode 100644
index 000000000..46aeac845
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Method.java
@@ -0,0 +1,273 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos;
+import org.aspectj.apache.bcel.generic.Type;
+
+/**
+ * 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,v 1.11 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class Method extends FieldOrMethod {
+
+ public static final AnnotationGen[][] NO_PARAMETER_ANNOTATIONS = new AnnotationGen[][] {};
+
+ public static final Method[] NoMethods = new Method[0];
+
+ private boolean parameterAnnotationsOutOfDate = true;
+ private AnnotationGen[][] unpackedParameterAnnotations;
+
+ private Method() {
+ parameterAnnotationsOutOfDate = true;
+ }
+
+ /**
+ * 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);
+ parameterAnnotationsOutOfDate = true;
+ }
+
+ Method(DataInputStream file, ConstantPool constant_pool) throws IOException {
+ super(file, constant_pool);
+ }
+
+ 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);
+ parameterAnnotationsOutOfDate = true;
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitMethod(this);
+ }
+
+ // CUSTARD mutable or not?
+ @Override
+ public void setAttributes(Attribute[] attributes) {
+ parameterAnnotationsOutOfDate = true;
+ super.setAttributes(attributes);
+ }
+
+ /**
+ * @return Code attribute of method, if any
+ */
+ public final Code getCode() {
+ return AttributeUtils.getCodeAttribute(attributes);
+ }
+
+ public final ExceptionTable getExceptionTable() {
+ return AttributeUtils.getExceptionTableAttribute(attributes);
+ }
+
+ /**
+ * Return LocalVariableTable of code attribute if any (the call is forwarded to the Code attribute)
+ */
+ public final LocalVariableTable getLocalVariableTable() {
+ Code code = getCode();
+ if (code != null)
+ return code.getLocalVariableTable();
+ return null;
+ }
+
+ /**
+ * Return LineNumberTable of code attribute if any (the call is forwarded to the Code attribute)
+ */
+ public final LineNumberTable getLineNumberTable() {
+ Code code = getCode();
+ if (code != null)
+ return code.getLineNumberTable();
+ return null;
+ }
+
+ /**
+ * Return string representation close to declaration format, eg: 'public static void main(String[] args) throws IOException'
+ */
+ @Override
+ public final String toString() {
+ ConstantUtf8 c;
+ String name, signature, access; // Short cuts to constant pool
+ StringBuffer buf;
+
+ access = Utility.accessToString(modifiers);
+
+ // Get name and signature from constant pool
+ c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8);
+ signature = c.getValue();
+
+ c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8);
+ name = c.getValue();
+
+ signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable());
+ buf = new StringBuffer(signature);
+
+ for (int i = 0; i < attributes.length; i++) {
+ Attribute a = attributes[i];
+ if (!((a instanceof Code) || (a instanceof ExceptionTable)))
+ buf.append(" [" + a.toString() + "]");
+ }
+
+ ExceptionTable e = getExceptionTable();
+ if (e != null) {
+ String str = e.toString();
+ if (!str.equals(""))
+ buf.append("\n\t\tthrows " + str);
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * @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());
+ }
+
+ private void ensureParameterAnnotationsUnpacked() {
+ if (!parameterAnnotationsOutOfDate)
+ return;
+ parameterAnnotationsOutOfDate = false;
+
+ int parameterCount = getArgumentTypes().length;
+ if (parameterCount == 0) {
+ unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS;
+ return;
+ }
+
+ RuntimeVisParamAnnos parameterAnnotationsVis = null;
+ RuntimeInvisParamAnnos parameterAnnotationsInvis = null;
+
+ // Find attributes that contain annotation data
+ Attribute[] attrs = getAttributes();
+
+ for (int i = 0; i < attrs.length; i++) {
+ Attribute attribute = attrs[i];
+ if (attribute instanceof RuntimeVisParamAnnos) {
+ parameterAnnotationsVis = (RuntimeVisParamAnnos) attribute;
+ } else if (attribute instanceof RuntimeInvisParamAnnos) {
+ parameterAnnotationsInvis = (RuntimeInvisParamAnnos) attribute;
+ }
+ }
+
+ boolean foundSome = false;
+ // Build a list of annotation arrays, one per argument
+ if (parameterAnnotationsInvis != null || parameterAnnotationsVis != null) {
+ List<AnnotationGen[]> annotationsForEachParameter = new ArrayList<AnnotationGen[]>();
+ AnnotationGen[] visibleOnes = null;
+ AnnotationGen[] invisibleOnes = null;
+ for (int i = 0; i < parameterCount; i++) {
+ int count = 0;
+ visibleOnes = new AnnotationGen[0];
+ invisibleOnes = new AnnotationGen[0];
+ if (parameterAnnotationsVis != null) {
+ visibleOnes = parameterAnnotationsVis.getAnnotationsOnParameter(i);
+ count += visibleOnes.length;
+ }
+ if (parameterAnnotationsInvis != null) {
+ invisibleOnes = parameterAnnotationsInvis.getAnnotationsOnParameter(i);
+ count += invisibleOnes.length;
+ }
+
+ AnnotationGen[] complete = AnnotationGen.NO_ANNOTATIONS;
+ if (count != 0) {
+ complete = new AnnotationGen[visibleOnes.length + invisibleOnes.length];
+ System.arraycopy(visibleOnes, 0, complete, 0, visibleOnes.length);
+ System.arraycopy(invisibleOnes, 0, complete, visibleOnes.length, invisibleOnes.length);
+ foundSome = true;
+ }
+ annotationsForEachParameter.add(complete);
+ }
+ if (foundSome) {
+ unpackedParameterAnnotations = annotationsForEachParameter.toArray(new AnnotationGen[][] {});
+ return;
+ }
+ }
+ unpackedParameterAnnotations = NO_PARAMETER_ANNOTATIONS;
+ }
+
+ public AnnotationGen[] getAnnotationsOnParameter(int i) {
+ ensureParameterAnnotationsUnpacked();
+ if (unpackedParameterAnnotations == NO_PARAMETER_ANNOTATIONS) {
+ return AnnotationGen.NO_ANNOTATIONS;
+ }
+ return unpackedParameterAnnotations[i];
+ }
+
+ public AnnotationGen[][] getParameterAnnotations() {
+ ensureParameterAnnotationsUnpacked();
+ return unpackedParameterAnnotations;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java
new file mode 100644
index 000000000..547041584
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/MethodParameters.java
@@ -0,0 +1,112 @@
+/* *******************************************************************
+ * Copyright (c) 2013 VMware
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+// see http://cr.openjdk.java.net/~abuckley/8misc.pdf
+public class MethodParameters extends Attribute {
+
+ public final static int[] NO_PARAMETER_NAME_INDEXES = new int[0];
+ public final static int[] NO_PARAMETER_ACCESS_FLAGS = new int[0];
+
+ public final static int ACCESS_FLAGS_FINAL = 0x0010;
+ public final static int ACCESS_FLAGS_SYNTHETIC = 0x1000;
+ public final static int ACCESS_FLAGS_MANDATED = 0x8000;
+
+ // if 'isInPackedState' then this data needs unpacking
+ private boolean isInPackedState = false;
+ private byte[] data;
+ private int[] names;
+ private int[] accessFlags;
+
+ public MethodParameters(int index, int length, DataInputStream dis, ConstantPool cpool) throws IOException {
+ super(Constants.ATTR_METHOD_PARAMETERS,index,length,cpool);
+ data = new byte[length];
+ dis.readFully(data,0,length);
+ isInPackedState = true;
+ }
+
+ private void ensureInflated() {
+ if (names!=null) return;
+ try {
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
+ int parametersCount = dis.readUnsignedByte();
+ if (parametersCount == 0) {
+ names = NO_PARAMETER_NAME_INDEXES;
+ accessFlags = NO_PARAMETER_ACCESS_FLAGS;
+ } else {
+ names = new int[parametersCount];
+ accessFlags = new int[parametersCount];
+ for (int i=0;i<parametersCount;i++) {
+ names[i] = dis.readUnsignedShort();
+ accessFlags[i] = dis.readUnsignedShort();
+ }
+ }
+ isInPackedState = false;
+ } catch (IOException ioe) {
+ throw new RuntimeException("Unabled to inflate type annotation data, badly formed?");
+ }
+ }
+
+ public void dump(DataOutputStream dos) throws IOException {
+ super.dump(dos);
+ if (isInPackedState) {
+ dos.write(data);
+ } else {
+ dos.writeByte(names.length);
+ for (int i=0;i<names.length;i++) {
+ dos.writeShort(names[i]);
+ dos.writeShort(accessFlags[i]);
+ }
+ }
+ }
+
+ public int getParametersCount() {
+ ensureInflated();
+ return names.length;
+ }
+
+ public String getParameterName(int parameter) {
+ ensureInflated();
+ ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(names[parameter], Constants.CONSTANT_Utf8);
+ return c.getValue();
+ }
+
+ public int getAccessFlags(int parameter) {
+ ensureInflated();
+ return accessFlags[parameter];
+ }
+
+ public boolean isFinal(int parameter) {
+ return (getAccessFlags(parameter) & ACCESS_FLAGS_FINAL)!=0;
+ }
+
+ public boolean isSynthetic(int parameter) {
+ return (getAccessFlags(parameter) & ACCESS_FLAGS_SYNTHETIC)!=0;
+ }
+
+ public boolean isMandated(int parameter) {
+ return (getAccessFlags(parameter) & ACCESS_FLAGS_MANDATED)!=0;
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitMethodParameters(this);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Modifiers.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Modifiers.java
new file mode 100644
index 000000000..63719913d
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Modifiers.java
@@ -0,0 +1,140 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Super class for all objects that have modifiers like private, final, ... I.e.
+ * classes, fields, and methods.
+ * was AccessFlags
+ *
+ * @version $Id: Modifiers.java,v 1.2 2008/05/28 23:53:01 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public abstract class Modifiers {
+
+ protected int modifiers;
+
+ public Modifiers() { }
+
+ public Modifiers(int a) {
+ modifiers = a;
+ }
+
+ public final int getModifiers() {
+ return modifiers;
+ }
+
+ public final void setModifiers(int modifiers) {
+ this.modifiers = modifiers;
+ }
+
+ public final boolean isPublic() {
+ return (modifiers & Constants.ACC_PUBLIC) != 0;
+ }
+
+ public final boolean isPrivate() {
+ return (modifiers & Constants.ACC_PRIVATE) != 0;
+ }
+
+ public final boolean isProtected() {
+ return (modifiers & Constants.ACC_PROTECTED) != 0;
+ }
+
+ public final boolean isStatic() {
+ return (modifiers & Constants.ACC_STATIC) != 0;
+ }
+
+ public final boolean isFinal() {
+ return (modifiers & Constants.ACC_FINAL) != 0;
+ }
+
+ public final boolean isSynchronized() {
+ return (modifiers & Constants.ACC_SYNCHRONIZED) != 0;
+ }
+
+ public final boolean isVolatile() {
+ return (modifiers & Constants.ACC_VOLATILE) != 0;
+ }
+
+ public final boolean isTransient() {
+ return (modifiers & Constants.ACC_TRANSIENT) != 0;
+ }
+
+ public final boolean isNative() {
+ return (modifiers & Constants.ACC_NATIVE) != 0;
+ }
+
+ public final boolean isInterface() {
+ return (modifiers & Constants.ACC_INTERFACE) != 0;
+ }
+
+ public final boolean isAbstract() {
+ return (modifiers & Constants.ACC_ABSTRACT) != 0;
+ }
+
+ public final boolean isStrictfp() {
+ return (modifiers & Constants.ACC_STRICT) != 0;
+ }
+
+ public final boolean isVarargs() {
+ return (modifiers & Constants.ACC_VARARGS) != 0;
+ }
+
+ public final boolean isBridge() {
+ return (modifiers & Constants.ACC_BRIDGE) != 0;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java
new file mode 100644
index 000000000..5eef18cde
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Module.java
@@ -0,0 +1,664 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2016-17 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents the module
+ * information captured in a class file.
+ * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html
+ * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25
+ *
+ * @author Andy Clement
+ */
+public final class Module extends Attribute {
+
+ private static final String[] NO_MODULE_NAMES = {};
+
+ private int moduleNameIndex; // u2 module_name_index
+ private int moduleFlags; // u2 module_flags
+ private int moduleVersionIndex; // u2 module_version_index
+ private Require[] requires;
+ private Export[] exports;
+ private Open[] opens;
+ private Uses[] uses;
+ private Provide[] provides;
+
+ private byte[] moduleInfo;
+ private int ptr;
+ private boolean unpacked = false;
+
+ public Module(Module module) {
+ super(module.getTag(), module.getNameIndex(), module.getLength(), module.getConstantPool());
+ moduleInfo = module.getBytes();
+ }
+
+ public Module(int nameIndex, int length, byte[] data, ConstantPool cp) {
+ super(Constants.ATTR_MODULE, nameIndex, length, cp);
+ }
+
+ Module(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException {
+ this(nameIndex, length, (byte[])null, cp);
+ moduleInfo = new byte[length];
+ stream.read(moduleInfo);
+ unpacked = false;
+ }
+
+ public class Require {
+
+ private final int moduleIndex;
+ private final int flags;
+ private final int versionIndex;
+
+ public Require(int moduleIndex, int flags, int versionIndex) {
+ this.moduleIndex = moduleIndex;
+ this.flags = flags;
+ this.versionIndex = versionIndex;
+ }
+
+ public String getModuleName() {
+ return cpool.getModuleName(moduleIndex);
+ }
+
+ public int getFlags() {
+ return flags;
+ }
+
+ public int getVersionIndex() {
+ return versionIndex;
+ }
+
+ public String getVersionString() {
+ if (versionIndex == 0) {
+ return null;
+ } else {
+ return cpool.getConstantUtf8(versionIndex).getValue();
+ }
+ }
+
+ public String getFlagsAsString() {
+ StringBuilder s = new StringBuilder();
+ if ((flags & Constants.MODULE_ACC_TRANSITIVE)!=0) {
+ s.append(" transitive");
+ }
+ if ((flags & Constants.MODULE_ACC_STATIC_PHASE)!=0) {
+ s.append(" static");
+ }
+ if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) {
+ s.append(" synthetic");
+ }
+ if ((flags & Constants.MODULE_ACC_MANDATED)!=0) {
+ s.append(" mandated");
+ }
+ return s.toString();
+ }
+
+ public String toString() {
+ return "requires"+getFlagsAsString()+" "+getModuleName()+(versionIndex==0?"":" "+getVersionString());
+ }
+ }
+
+
+ public class Export {
+
+ private final int packageIndex;
+ private final int flags;
+ private final int[] toModuleIndices;
+
+ public Export(int packageIndex, int flags, int[] toModuleIndices) {
+ this.packageIndex = packageIndex;
+ this.flags = flags;
+ this.toModuleIndices = toModuleIndices;
+ }
+
+ public int getPackageIndex() {
+ return packageIndex;
+ }
+
+ public int getFlags() {
+ return flags;
+ }
+
+ public int[] getToModuleIndices() {
+ return toModuleIndices;
+ }
+
+ public String getPackage() {
+ return cpool.getPackageName(packageIndex);
+ }
+
+ public String getFlagsAsString() {
+ StringBuilder s = new StringBuilder();
+ if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) {
+ s.append(" synthetic");
+ }
+ if ((flags & Constants.MODULE_ACC_MANDATED)!=0) {
+ s.append(" synthetic");
+ }
+ return s.toString();
+ }
+
+ public String[] getToModuleNames() {
+ if (toModuleIndices==null) {
+ return NO_MODULE_NAMES;
+ }
+ String[] toModuleNames = new String[toModuleIndices.length];
+ for (int i=0;i<toModuleIndices.length;i++) {
+ toModuleNames[i] = cpool.getModuleName(toModuleIndices[i]);
+ }
+ return toModuleNames;
+ }
+
+ public String toString() {
+ StringBuilder s =new StringBuilder();
+ s.append("exports").append(getFlagsAsString()).append(" ").append(getPackage().replace('/', '.'));
+ String[] toModules = getToModuleNames();
+ if (toModules.length!=0) {
+ s.append(" to ");
+ for (int i=0;i<toModules.length;i++) {
+ if (i>0) {
+ s.append(", ");
+ }
+ s.append(toModules[i]);
+ }
+ }
+ return s.toString().trim();
+ }
+ }
+
+
+ public class Open {
+
+ private final int packageIndex;
+ private final int flags;
+ private final int[] toModuleIndices;
+
+ public Open(int packageIndex, int flags, int[] toModuleIndices) {
+ this.packageIndex = packageIndex;
+ this.flags = flags;
+ this.toModuleIndices = toModuleIndices;
+ }
+
+ public int getPackageIndex() {
+ return packageIndex;
+ }
+
+ public int getFlags() {
+ return flags;
+ }
+
+ public int[] getToModuleIndices() {
+ return toModuleIndices;
+ }
+
+ public String getPackage() {
+ return cpool.getPackageName(packageIndex);
+ }
+
+ public String getFlagsAsString() {
+ StringBuilder s = new StringBuilder();
+ if ((flags & Constants.MODULE_ACC_SYNTHETIC)!=0) {
+ s.append(" synthetic");
+ }
+ if ((flags & Constants.MODULE_ACC_MANDATED)!=0) {
+ s.append(" synthetic");
+ }
+ return s.toString();
+ }
+
+ public String[] getToModuleNames() {
+ if (toModuleIndices==null) {
+ return NO_MODULE_NAMES;
+ }
+ String[] toModuleNames = new String[toModuleIndices.length];
+ for (int i=0;i<toModuleIndices.length;i++) {
+ toModuleNames[i] = cpool.getModuleName(toModuleIndices[i]);
+ }
+ return toModuleNames;
+ }
+
+ public String toString() {
+ StringBuilder s =new StringBuilder();
+ s.append("opens").append(getFlagsAsString()).append(" ").append(getPackage().replace('/', '.'));
+ String[] toModules = getToModuleNames();
+ if (toModules.length!=0) {
+ s.append(" to ");
+ for (int i=0;i<toModules.length;i++) {
+ if (i>0) {
+ s.append(", ");
+ }
+ s.append(toModules[i]);
+ }
+ }
+ return s.toString().trim();
+ }
+ }
+
+ public class Provide {
+ private final int providedTypeIndex;
+ private final int[] withTypeIndices;
+
+ public Provide(int providedTypeIndex, int[] withTypeIndices) {
+ this.providedTypeIndex = providedTypeIndex;
+ this.withTypeIndices = withTypeIndices;
+ }
+
+ public String getProvidedType() {
+ return cpool.getConstantString_CONSTANTClass(providedTypeIndex);
+ }
+
+ public int getProvidedTypeIndex() {
+ return providedTypeIndex;
+ }
+
+ public String[] getWithTypeStrings() {
+ String[] result = new String[withTypeIndices.length];
+ for (int i=0;i<withTypeIndices.length;i++) {
+ result[i] = cpool.getConstantString_CONSTANTClass(withTypeIndices[i]);
+ }
+ return result;
+ }
+
+ public int[] getWithTypeIndices() {
+ return withTypeIndices;
+ }
+
+ public String toString() {
+ StringBuilder s =new StringBuilder();
+ s.append("provides ").append(getProvidedType().replace('/', '.'));
+ s.append(" with ");
+ String[] withtypes = getWithTypeStrings();
+ for (int i=0;i< withtypes.length;i++) {
+ if (i>0) s.append(",");
+ s.append(withtypes[i].replace('/','.'));
+ }
+ return s.toString();
+ }
+ }
+
+ public class Uses {
+ private final int typeNameIndex;
+
+ public Uses(int typeNameIndex) {
+ this.typeNameIndex = typeNameIndex;
+ }
+
+ public String getTypeName() {
+ return cpool.getConstantString_CONSTANTClass(typeNameIndex);
+ }
+
+ public int getTypeNameIndex() {
+ return typeNameIndex;
+ }
+
+ public String toString() {
+ StringBuilder s =new StringBuilder();
+ s.append("uses ").append(getTypeName().replace('/', '.'));
+ return s.toString().trim();
+ }
+ }
+
+ private final int readInt() {
+ return ((moduleInfo[ptr++] & 0xFF) << 24) + ((moduleInfo[ptr++] & 0xFF) << 16)
+ + ((moduleInfo[ptr++] & 0xFF) << 8) + (moduleInfo[ptr++] & 0xFF);
+ }
+
+ private final int readUnsignedShort() {
+ return ((moduleInfo[ptr++] & 0xff) << 8) + (moduleInfo[ptr++] & 0xff);
+ }
+
+ private final int readUnsignedShort(int offset) {
+ return ((moduleInfo[offset++] & 0xff) << 8) + (moduleInfo[offset] & 0xff);
+ }
+
+ // Format: http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.25
+ private void ensureUnpacked() {
+ if (!unpacked) {
+ ptr = 0;
+ moduleNameIndex = readUnsignedShort();
+ moduleFlags = readUnsignedShort();
+ moduleVersionIndex = readUnsignedShort();
+
+ int count = readUnsignedShort();
+ requires = new Require[count];
+ for (int i = 0; i < count; i++) {
+ requires[i] = new Require(readUnsignedShort(), readUnsignedShort(), readUnsignedShort());
+ }
+
+ count = readUnsignedShort();
+ exports = new Export[count];
+ for (int i = 0; i < count; i++) {
+ int index = readUnsignedShort();
+ int flags = readUnsignedShort();
+ int toCount = readUnsignedShort();
+ int[] to = new int[toCount];
+ for (int j = 0; j < toCount; j++) {
+ to[j] = readUnsignedShort();
+ }
+ exports[i] = new Export(index, flags, to);
+ }
+
+ count = readUnsignedShort();
+ opens = new Open[count];
+ for (int i = 0; i < count; i++) {
+ int index = readUnsignedShort();
+ int flags = readUnsignedShort();
+ int toCount = readUnsignedShort();
+ int[] to = new int[toCount];
+ for (int j = 0; j < toCount; j++) {
+ to[j] = readUnsignedShort();
+ }
+ opens[i] = new Open(index, flags, to);
+ }
+ count = readUnsignedShort();
+ uses = new Uses[count];
+ for (int i = 0; i < count; i++) {
+ uses[i] = new Uses(readUnsignedShort());
+ }
+ count = readUnsignedShort();
+ provides = new Provide[count];
+ for (int i = 0; i < count; i++) {
+ int index = readUnsignedShort();
+ int toCount = readUnsignedShort();
+ int[] to = new int[toCount];
+ for (int j = 0; j < toCount; j++) {
+ to[j] = readUnsignedShort();
+ }
+ provides[i] = new Provide(index, to);
+ }
+ unpacked = true;
+ }
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ super.dump(file);
+ if (!unpacked) {
+ file.write(moduleInfo);
+ } else {
+
+ file.writeShort(moduleNameIndex);
+ file.writeShort(moduleFlags);
+ file.writeShort(moduleVersionIndex);
+
+ file.writeShort(requires.length);
+ for (int i = 0; i < requires.length; i++) {
+ file.writeShort(requires[i].moduleIndex);
+ file.writeShort(requires[i].flags);
+ file.writeShort(requires[i].versionIndex);
+ }
+ file.writeShort(exports.length);
+ for (Export export : exports) {
+ file.writeShort(export.packageIndex);
+ int[] toIndices = export.toModuleIndices;
+ file.writeShort(toIndices.length);
+ for (int index : toIndices) {
+ file.writeShort(index);
+ }
+ }
+ file.writeShort(opens.length);
+ for (Open open : opens) {
+ file.writeShort(open.packageIndex);
+ int[] toIndices = open.toModuleIndices;
+ file.writeShort(toIndices.length);
+ for (int index : toIndices) {
+ file.writeShort(index);
+ }
+ }
+ file.writeShort(uses.length);
+ for (Uses use : uses) {
+ file.writeShort(use.getTypeNameIndex());
+ }
+ file.writeShort(provides.length);
+ for (Provide provide : provides) {
+ file.writeShort(provide.providedTypeIndex);
+ int[] toIndices = provide.withTypeIndices;
+ file.writeShort(toIndices.length);
+ for (int index : toIndices) {
+ file.writeShort(index);
+ }
+ }
+ }
+ }
+
+ public String toStringRequires() {
+ StringBuilder s = new StringBuilder();
+ s.append('#').append(requires.length);
+ if (requires.length > 0) {
+ for (Require require : requires) {
+ s.append(' ');
+ s.append(require.moduleIndex).append(':').append(require.flags);
+ }
+ }
+ return s.toString();
+ }
+
+ public String toStringExports() {
+ StringBuilder s = new StringBuilder();
+ s.append('#').append(exports.length);
+ if (exports.length > 0) {
+ for (Export export : exports) {
+ s.append(' ');
+ s.append(export.packageIndex).append(":[");
+ int[] toIndices = export.toModuleIndices;
+ for (int i = 0; i < toIndices.length; i++) {
+ if (i > 0)
+ s.append(',');
+ s.append(toIndices[i]);
+ }
+ s.append("]");
+ }
+ }
+ return s.toString();
+ }
+
+ public String toStringOpens() {
+ StringBuilder s = new StringBuilder();
+ s.append('#').append(opens.length);
+ if (opens.length > 0) {
+ for (Open open : opens) {
+ s.append(' ');
+ s.append(open.packageIndex).append(":[");
+ int[] toIndices = open.toModuleIndices;
+ for (int i = 0; i < toIndices.length; i++) {
+ if (i > 0)
+ s.append(',');
+ s.append(toIndices[i]);
+ }
+ s.append("]");
+ }
+ }
+ return s.toString();
+ }
+
+ public String toStringUses() {
+ StringBuilder s = new StringBuilder();
+ s.append('#').append(uses.length);
+ if (uses.length > 0) {
+ for (Uses use : uses) {
+ s.append(' ');
+ s.append(use.getTypeName());
+ }
+ }
+ return s.toString();
+ }
+
+ public String toStringProvides() {
+ StringBuilder s = new StringBuilder();
+ s.append('#').append(provides.length);
+ if (provides.length > 0) {
+ for (Provide provide : provides) {
+ s.append(' ');
+ s.append(provide.providedTypeIndex).append(":[");
+ int[] indices = provide.withTypeIndices;
+ for (int i = 0; i < indices.length; i++) {
+ if (i > 0)
+ s.append(',');
+ s.append(indices[i]);
+ }
+ s.append("]");
+ }
+ }
+ return s.toString();
+ }
+
+ @Override
+ public final String toString() {
+ StringBuilder s = new StringBuilder();
+ ensureUnpacked();
+ s.append("Module(");
+ if (requires.length != 0) {
+ s.append("requires=");
+ s.append(toStringRequires());
+ s.append(" ");
+ }
+ if (exports.length != 0) {
+ s.append("exports=");
+ s.append(toStringExports());
+ s.append(" ");
+ }
+ if (opens.length != 0) {
+ s.append("opens=");
+ s.append(toStringOpens());
+ s.append(" ");
+ }
+ if (uses.length != 0) {
+ s.append("uses=");
+ s.append(toStringUses());
+ s.append(" ");
+ }
+ if (provides.length != 0) {
+ s.append("provides=");
+ s.append(toStringProvides());
+ s.append(" ");
+ }
+ return s.toString().trim()+")";
+ }
+
+ /**
+ * @return deep copy of this attribute //
+ */
+// @Override
+// public Attribute copy(ConstantPool constant_pool) {
+// return (Module) clone();
+// }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitModule(this);
+ }
+
+ public Require[] getRequires() {
+ ensureUnpacked();
+ return requires;
+ }
+
+ public String[] getRequiredModuleNames() {
+ ensureUnpacked();
+ String[] results = new String[requires.length];
+ for (int i=0;i<requires.length;i++) {
+ results[i] = cpool.getModuleName(requires[i].moduleIndex);
+ }
+ return results;
+ }
+
+ public byte[] getBytes() {
+ return moduleInfo;
+ }
+
+ public Export[] getExports() {
+ ensureUnpacked();
+ return exports;
+ }
+
+ public Open[] getOpens() {
+ ensureUnpacked();
+ return opens;
+ }
+
+ public Uses[] getUses() {
+ ensureUnpacked();
+ return uses;
+ }
+
+ public Provide[] getProvides() {
+ ensureUnpacked();
+ return provides;
+ }
+
+ public String getModuleName() {
+ return ((ConstantModule)cpool.getConstant(moduleNameIndex)).getModuleName(cpool);
+ }
+
+ public int getModuleFlags() {
+ // 0x0020 (ACC_OPEN) - Indicates that this module is open.
+ // 0x1000 (ACC_SYNTHETIC) - Indicates that this module was not explicitly or implicitly declared.
+ // 0x8000 (ACC_MANDATED) - Indicates that this module was implicitly declared
+ return moduleFlags;
+ }
+
+ /** @return the module version or null if no version information specified */
+ public String getModuleVersion() {
+ if (moduleVersionIndex == 0) {
+ return null;
+ } else {
+ return cpool.getConstantUtf8(moduleVersionIndex).getValue();
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModuleMainClass.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModuleMainClass.java
new file mode 100644
index 000000000..3fa500a8e
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModuleMainClass.java
@@ -0,0 +1,106 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2017 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Indicates the main class of a module.
+ * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26
+ *
+ * @author Andy Clement
+ */
+public final class ModuleMainClass extends Attribute {
+
+ private int mainClassIndex;
+
+ public ModuleMainClass(ModuleMainClass c) {
+ this(c.getNameIndex(), c.getLength(), c.getMainClassIndex(), c.getConstantPool());
+ }
+
+ public ModuleMainClass(int nameIndex, int length, int mainClassIndex, ConstantPool cp) {
+ super(Constants.ATTR_MODULE_MAIN_CLASS, nameIndex, length, cp);
+ this.mainClassIndex = mainClassIndex;
+ }
+
+ ModuleMainClass(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException {
+ this(nameIndex, length, 0, cp);
+ this.mainClassIndex = stream.readUnsignedShort();
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitModuleMainClass(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream stream) throws IOException {
+ super.dump(stream);
+ stream.writeShort(mainClassIndex);
+ }
+
+ public final int getMainClassIndex() {
+ return mainClassIndex;
+ }
+
+ @Override
+ public final String toString() {
+ return cpool.getConstantString_CONSTANTClass(mainClassIndex);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java
new file mode 100644
index 000000000..37da4bc47
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/ModulePackages.java
@@ -0,0 +1,126 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2017 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Indicates all the packages of a module that are exported or opened by the module attribute.
+ * http://cr.openjdk.java.net/~mr/jigsaw/spec/java-se-9-jvms-diffs.pdf 4.7.26
+ *
+ * @author Andy Clement
+ */
+public final class ModulePackages extends Attribute {
+
+ private static int[] NO_PACKAGES = new int[0];
+ private int[] packageIndices;
+
+ public ModulePackages(ModulePackages c) {
+ this(c.getNameIndex(), c.getLength(), c.getPackageIndices(), c.getConstantPool());
+ }
+
+ public ModulePackages(int nameIndex, int length, int[] packageIndices, ConstantPool cp) {
+ super(Constants.ATTR_MODULE_PACKAGES, nameIndex, length, cp);
+ setPackageIndices(packageIndices);
+ }
+
+ ModulePackages(int nameIndex, int length, DataInputStream stream, ConstantPool cp) throws IOException {
+ this(nameIndex, length, (int[]) null, cp);
+ int packageIndicesCount = stream.readUnsignedShort();
+ packageIndices = new int[packageIndicesCount];
+ for (int i = 0; i < packageIndicesCount; i++) {
+ packageIndices[i] = stream.readUnsignedShort();
+ }
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitModulePackages(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream stream) throws IOException {
+ super.dump(stream);
+ stream.writeShort(packageIndices.length);
+ for (int i = 0; i < packageIndices.length; i++) {
+ stream.writeShort(packageIndices[i]);
+ }
+ }
+
+ public final int[] getPackageIndices() {
+ return packageIndices;
+ }
+
+ public final void setPackageIndices(int[] packageIndices) {
+ if (packageIndices == null) {
+ this.packageIndices = NO_PACKAGES;
+ } else {
+ this.packageIndices = packageIndices;
+ }
+ }
+
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < packageIndices.length; i++) {
+ buf.append(cpool.getPackageName(packageIndices[i]) + "\n");
+ }
+ return buf.toString();
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java
new file mode 100644
index 000000000..52d312659
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestHost.java
@@ -0,0 +1,118 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.28
+ *
+ * @see Attribute
+ */
+public final class NestHost extends Attribute {
+ private int hostClassIndex;
+
+ public NestHost(NestHost c) {
+ this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool());
+ }
+
+ public NestHost(int nameIndex, int length, int hostClassIndex, ConstantPool cp) {
+ super(Constants.ATTR_NEST_MEMBERS, nameIndex, length, cp);
+ this.hostClassIndex = hostClassIndex;
+ }
+
+ NestHost(int nameIndex, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
+ this(nameIndex, length, 0, constant_pool);
+ hostClassIndex = file.readUnsignedShort();
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitNestHost(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ super.dump(file);
+ file.writeShort(hostClassIndex);
+ }
+
+ public final int getHostClassIndex() {
+ return hostClassIndex;
+ }
+
+ public final void setHostClassIndex(int hostClassIndex) {
+ this.hostClassIndex = hostClassIndex;
+ }
+
+ public final String getHostClassName() {
+ ConstantClass constantClass = (ConstantClass)cpool.getConstant(hostClassIndex,Constants.CONSTANT_Class);
+ return constantClass.getClassname(cpool);
+ }
+
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("NestHost(");
+ ConstantClass constantClass = (ConstantClass)cpool.getConstant(hostClassIndex,Constants.CONSTANT_Class);
+ buf.append(constantClass.getClassname(cpool));
+ buf.append(")");
+ return buf.toString();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java
new file mode 100644
index 000000000..9d273966f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/NestMembers.java
@@ -0,0 +1,131 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.29
+ *
+ * @see Attribute
+ */
+public final class NestMembers extends Attribute {
+ private int numberOfClasses;
+ private int[] classes; // CONSTANT_Class_info references
+
+ public NestMembers(NestMembers c) {
+ this(c.getNameIndex(), c.getLength(), c.getClasses(), c.getConstantPool());
+ }
+
+ public NestMembers(int nameIndex, int length, int[] classes, ConstantPool cp) {
+ super(Constants.ATTR_NEST_MEMBERS, nameIndex, length, cp);
+ setClasses(classes);
+ }
+
+ NestMembers(int nameIndex, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
+ this(nameIndex, length, (int[]) null, constant_pool);
+ numberOfClasses = file.readUnsignedShort();
+ classes = new int[numberOfClasses];
+ for (int i = 0; i < numberOfClasses; i++) {
+ classes[i] = file.readUnsignedShort();
+ }
+ }
+
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitNestMembers(this);
+ }
+
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ super.dump(file);
+ file.writeShort(numberOfClasses);
+ for (int i = 0; i < numberOfClasses; i++) {
+ file.writeShort(classes[i]);
+ }
+ }
+
+ public final int[] getClasses() {
+ return classes;
+ }
+
+ public final void setClasses(int[] inner_classes) {
+ this.classes = inner_classes;
+ numberOfClasses = (inner_classes == null) ? 0 : inner_classes.length;
+ }
+
+ public final String[] getClassesNames() {
+ String[] result = new String[numberOfClasses];
+ for (int i = 0; i < numberOfClasses; i++) {
+ ConstantClass constantClass = (ConstantClass)cpool.getConstant(classes[i],Constants.CONSTANT_Class);
+ result[i] = constantClass.getClassname(cpool);
+ }
+ return result;
+ }
+
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < numberOfClasses; i++) {
+ ConstantClass constantClass = (ConstantClass)cpool.getConstant(classes[i],Constants.CONSTANT_Class);
+ buf.append(constantClass.getClassname(cpool)).append(" ");
+ }
+ return "NestMembers("+buf.toString().trim()+")";
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java
new file mode 100644
index 000000000..5bef82979
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Node.java
@@ -0,0 +1,65 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * Denote class to have an accept method();
+ *
+ * @version $Id: Node.java,v 1.3 2008/05/28 23:53:01 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public interface Node {
+ public void accept(ClassVisitor obj);
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java
new file mode 100644
index 000000000..b7488e9a4
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Signature.java
@@ -0,0 +1,310 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Extended by Adrian Colyer, June 2005 to support unpacking of Signature
+ * attribute
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents a reference to a <href="http://wwwipd.ira.uka.de/~pizza/gj/">GJ</a>
+ * attribute.
+ *
+ * @version $Id: Signature.java,v 1.11 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Attribute
+ */
+public final class Signature extends Attribute {
+ 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());
+ }
+
+ /**
+ * 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 constant_pool Array of constants
+ * @param Signature_index Index in constant pool to CONSTANT_Utf8
+ */
+ 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;
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @return Index in constant pool of source file name.
+ */
+ public final int getSignatureIndex() {
+ return signature_index;
+ }
+
+ /**
+ * @param Signature_index.
+ */
+ public final void setSignatureIndex(int signature_index) {
+ this.signature_index = signature_index;
+ }
+
+ /**
+ * @return GJ signature.
+ */
+ public final String getSignature() {
+ ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(signature_index, Constants.CONSTANT_Utf8);
+ return c.getValue();
+ }
+
+ /**
+ * Extends ByteArrayInputStream to make 'unreading' chars possible.
+ */
+ private static final class MyByteArrayInputStream extends ByteArrayInputStream {
+ MyByteArrayInputStream(String data) {
+ super(data.getBytes());
+ }
+
+ 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
+ */
+ @Override
+ public final String toString() {
+ String s = getSignature();
+
+ return "Signature(" + s + ")";
+ }
+
+ // /**
+ // * @return deep copy of this attribute
+ // */
+ // @Override
+ // public Attribute copy(ConstantPool constant_pool) {
+ // return (Signature) clone();
+ // }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java
new file mode 100644
index 000000000..84ff40cf9
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SimpleConstant.java
@@ -0,0 +1,58 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.classfile;
+
+public interface SimpleConstant {
+ public String getStringValue();
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java
new file mode 100644
index 000000000..9fd840fc0
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/SourceFile.java
@@ -0,0 +1,169 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> 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
+ * <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id: SourceFile.java,v 1.5 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Attribute
+ */
+public final class SourceFile extends Attribute {
+ 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());
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @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) cpool.getConstant(sourcefile_index, Constants.CONSTANT_Utf8);
+ return c.getValue();
+ }
+
+ /**
+ * @return String representation
+ */
+ @Override
+ public final String toString() {
+ return "SourceFile(" + getSourceFileName() + ")";
+ }
+
+ /**
+ * @return deep copy of this attribute //
+ */
+ // @Override
+ // public Attribute copy(ConstantPool constant_pool) {
+ // return (SourceFile) clone();
+ // }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java
new file mode 100644
index 000000000..29f9c1535
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMap.java
@@ -0,0 +1,190 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents a stack map attribute used for preverification of Java classes for the <a href="http://java.sun.com/j2me/">
+ * Java 2 Micro Edition</a> (J2ME). This attribute is used by the <a href="http://java.sun.com/products/cldc/">KVM</a> and contained
+ * within the Code attribute of a method. See CLDC specification 5.3.1.2
+ *
+ * @version $Id: StackMap.java,v 1.6 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Code
+ * @see StackMapEntry
+ * @see StackMapType
+ */
+public final class StackMap extends Attribute {
+ 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);
+ }
+
+ /**
+ * Construct object from file stream.
+ *
+ * @param name_index Index of name
+ * @param length Content length in bytes
+ * @param file Input stream
+ * @throws IOException
+ * @param constant_pool Array of constants
+ */
+ 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);
+ }
+
+ /**
+ * @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;
+ }
+
+ /**
+ * @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
+ // */
+ // 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.cpool = 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
+ */
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitStackMap(this);
+ }
+
+ public final int getMapLength() {
+ return map_length;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java
new file mode 100644
index 000000000..76bb2ab79
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapEntry.java
@@ -0,0 +1,210 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+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
+ *
+ * @version $Id: StackMapEntry.java,v 1.5 2008/05/28 23:53:02 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @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;
+
+ /**
+ * 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);
+ }
+
+ /**
+ * @return String representation.
+ */
+ public final String toString() {
+ StringBuffer buf = new StringBuffer("(offset=" + 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; }
+ public int getByteCodeOffset() { return byte_code_offset; }
+ public void setNumberOfLocals(int n) { number_of_locals = n; }
+ public int getNumberOfLocals() { return number_of_locals; }
+ 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(ClassVisitor 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;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java
new file mode 100644
index 000000000..b1116abbe
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/StackMapType.java
@@ -0,0 +1,172 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.apache.bcel.Constants;
+import java.io.*;
+
+/**
+ * This class represents the type of a local variable or item on stack
+ * used in the StackMap entries.
+ *
+ * @version $Id: StackMapType.java,v 1.3 2008/05/28 23:53:02 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @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;
+
+ /**
+ * 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;
+ }
+
+ public byte getType() { return type; }
+ public void setIndex(int t) { index = 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());
+ }
+
+ /** @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)
+ 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;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java
new file mode 100644
index 000000000..57fe97468
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Synthetic.java
@@ -0,0 +1,185 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> 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 <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id: Synthetic.java,v 1.5 2009/09/15 19:40:12 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Attribute
+ */
+public final class Synthetic extends Attribute {
+ 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());
+ }
+
+ //
+ // public Synthetic(ConstantPoolGen cpool) {
+ // super(Constants.ATTR_SYNTHETIC, cpool.addUtf8("Synthetic"), 0, cpool);
+ // ConstantPoolGen cpg = myGen.getConstantPool();
+ // int index = ;
+ // Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg.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");
+ }
+ }
+
+ /**
+ * 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(ClassVisitor 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);
+ }
+
+ /**
+ * @return data bytes.
+ */
+ public final byte[] getBytes() {
+ return bytes;
+ }
+
+ /**
+ * @param bytes.
+ */
+ public final void setBytes(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ /**
+ * @return String representation.
+ */
+ @Override
+ public final String toString() {
+ StringBuffer buf = new StringBuffer("Synthetic");
+
+ if (length > 0)
+ buf.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 = (byte[])bytes.clone();
+ //
+ // c.cpool = constant_pool;
+ // return c;
+ // }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java
new file mode 100644
index 000000000..416d105b1
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Unknown.java
@@ -0,0 +1,215 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class represents a reference to an unknown (i.e., application-specific) attribute of a class. It is instantiated from the
+ * <em>Attribute.readAttribute()</em> method. Applications that need to read in application-specific attributes should create an <a
+ * href="./AttributeReader.html">AttributeReader</a> implementation and attach it via <a
+ * href="./Attribute.html#addAttributeReader(java.lang.String,
+ * org.aspectj.apache.bcel.classfile.AttributeReader)">Attribute.addAttributeReader</a>.
+ *
+ *
+ * @version $Id: Unknown.java,v 1.6 2009/09/15 19:40:12 aclement Exp $
+ * @see org.aspectj.apache.bcel.classfile.Attribute
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class Unknown extends Attribute {
+ private byte[] bytes;
+ private String name;
+
+ // evil static - removed by Andy C - no apparent users (4 Mar 06)
+ // private static HashMap 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] = (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)).getValue();
+ // unknown_attributes.put(name, this);
+ }
+
+ /**
+ * 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(ClassVisitor v) {
+ v.visitUnknown(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;
+ }
+
+ /**
+ * @return name of attribute.
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param bytes.
+ */
+ public final void setBytes(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ /**
+ * @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 + ")";
+ }
+
+ /**
+ * @return deep copy of this attribute
+ */
+ // @Override
+ // public Attribute copy(ConstantPool constant_pool) {
+ // Unknown c = (Unknown) clone();
+ //
+ // if (bytes != null)
+ // c.bytes = bytes.clone();
+ //
+ // c.cpool = constant_pool;
+ // return c;
+ // }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java
new file mode 100644
index 000000000..98f5952ae
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/Utility.java
@@ -0,0 +1,1094 @@
+package org.aspectj.apache.bcel.classfile;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeParamAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos;
+import org.aspectj.apache.bcel.generic.Type;
+import org.aspectj.apache.bcel.util.ByteSequence;
+
+/**
+ * Utility functions that do not really belong to any class in particular.
+ *
+ * @version $Id: Utility.java,v 1.14 2009/09/28 16:39:46 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ *
+ * modified: Andy Clement 2-mar-05 Removed unnecessary static and optimized
+ */
+public abstract class Utility {
+
+ /*
+ * 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.
+ */
+ private static boolean wide = false;
+
+ /**
+ * 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: see comment at top of class...
+ 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 <EM>(number of opcodes, not bytes!)</EM>
+ * @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++) {
+ // Skip `index' lines of code
+ 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 + codeToString(stream, constant_pool, verbose) + '\n');
+ }
+ }
+ } catch (IOException e) {
+ System.out.println(buf.toString());
+ e.printStackTrace();
+ throw new ClassFormatException("Byte code error: " + e);
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Disassemble a stream of byte codes and return the string representation.
+ */
+ public static final String codeToString(byte[] code, ConstantPool constant_pool, int index, int length) {
+ return codeToString(code, constant_pool, index, length, true);
+ }
+
+ public static final String codeToString(ByteSequence bytes, ConstantPool constant_pool) throws IOException {
+ return codeToString(bytes, constant_pool, true);
+ }
+
+ /**
+ * Shorten long class names, <em>java/lang/String</em> becomes <em>String</em>.
+ *
+ * @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 <em>str</em>, i.e., chop off the <em>prefix</em>, if the class name starts with this string and the
+ * flag <em>chopit</em> is true. Slashes <em>/</em> are converted to dots <em>.</em>.
+ *
+ * @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) {
+ str = str.replace('/', '.');
+ if (chopit) {
+ int len = prefix.length();
+ // If string starts with 'prefix' and contains no further dots
+ if (str.startsWith(prefix)) {
+ String result = str.substring(len);
+ if (result.indexOf('.') == -1) {
+ str = result;
+ }
+ }
+ }
+ return str;
+ }
+
+ /**
+ * Shorten long class names, <em>java/lang/String</em> becomes <em>java.lang.String</em>, e.g.. If <em>chopit</em> is
+ * <em>true</em> the prefix <em>java.lang</em> 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);
+ }
+
+ 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);
+ }
+
+ /**
+ * 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.
+ */
+ 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) != ')') {
+ ResultHolder rh = signatureToStringInternal(signature.substring(index), chopit);
+ String param_type = rh.getResult();
+ buf.append(param_type);
+
+ if (vars != null) {
+ LocalVariable l = vars.getLocalVariable(var_index);
+
+ if (l != null) {
+ buf.append(" " + l.getName());
+ }
+ } else {
+ buf.append(" arg" + var_index);
+ }
+
+ if ("double".equals(param_type) || "long".equals(param_type)) {
+ var_index += 2;
+ } else {
+ var_index++;
+ }
+
+ buf.append(", ");
+ index += rh.getConsumedChars();
+ }
+
+ index++;
+
+ // 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();
+ }
+
+ /**
+ * Replace all occurences of <em>old</em> in <em>str</em> with <em>new</em>.
+ *
+ * @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 {
+ index = str.indexOf(old);
+ if (index != -1) {
+ old_index = 0;
+
+ // 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) {
+ 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);
+ }
+
+ public static final String signatureToString(String signature, boolean chopit) {
+ ResultHolder rh = signatureToStringInternal(signature, chopit);
+ return rh.getResult();
+ }
+
+ /**
+ * This method converts this string into a Java type declaration such as 'String[]' and throws a `ClassFormatException' when the
+ * parsed type is invalid.
+ */
+ public static final ResultHolder signatureToStringInternal(String signature, boolean chopit) {
+ int processedChars = 1; // This is the default, read just one char
+ try {
+ switch (signature.charAt(0)) {
+ case 'B':
+ return ResultHolder.BYTE;
+ case 'C':
+ return ResultHolder.CHAR;
+ case 'D':
+ return ResultHolder.DOUBLE;
+ case 'F':
+ return ResultHolder.FLOAT;
+ case 'I':
+ return ResultHolder.INT;
+ case 'J':
+ return ResultHolder.LONG;
+ case 'L': { // Full class name
+ int index = signature.indexOf(';'); // Look for closing ';'
+
+ if (index < 0) {
+ throw new ClassFormatException("Invalid signature: " + signature);
+ }
+
+ if (signature.length() > index + 1 && signature.charAt(index + 1) == '>') {
+ index = index + 2;
+ }
+
+ int genericStart = signature.indexOf('<');
+ if (genericStart != -1) {
+ int genericEnd = signature.indexOf('>');
+ // FIXME asc going to need a lot more work in here for generics
+ ResultHolder rh = signatureToStringInternal(signature.substring(genericStart + 1, genericEnd), chopit);
+ StringBuffer sb = new StringBuffer();
+ sb.append(signature.substring(1, genericStart));
+ sb.append("<").append(rh.getResult()).append(">");
+ ResultHolder retval = new ResultHolder(compactClassName(sb.toString(), chopit), genericEnd + 1);
+ return retval;
+ } else {
+ processedChars = index + 1; // "Lblabla;" `L' and `;' are removed
+ ResultHolder retval = new ResultHolder(compactClassName(signature.substring(1, index), chopit), processedChars);
+ return retval;
+ }
+ }
+
+ case 'S':
+ return ResultHolder.SHORT;
+ case 'Z':
+ return ResultHolder.BOOLEAN;
+
+ case '[': { // Array declaration
+ StringBuffer brackets;
+ int consumedChars, n;
+
+ brackets = new StringBuffer(); // Accumulate []'s
+ // Count opening brackets and look for optional size argument
+ for (n = 0; signature.charAt(n) == '['; n++) {
+ brackets.append("[]");
+ }
+ consumedChars = n;
+ ResultHolder restOfIt = signatureToStringInternal(signature.substring(n), chopit);
+ consumedChars += restOfIt.getConsumedChars();
+ brackets.insert(0, restOfIt.getResult());
+ return new ResultHolder(brackets.toString(), consumedChars);
+ }
+ case 'V':
+ return ResultHolder.VOID;
+
+ default:
+ throw new ClassFormatException("Invalid signature: `" + signature + "'");
+ }
+ } catch (StringIndexOutOfBoundsException e) { // Should never occur
+ throw new ClassFormatException("Invalid signature: " + e + ":" + signature);
+ }
+ }
+
+ /**
+ * Return type of method signature as a byte value as defined in <em>Constants</em>
+ *
+ * @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);
+ }
+ }
+
+ /**
+ * 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);
+
+ // Just one digit, so prepend 0
+ 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);
+ } else {
+ return new String(buf) + str;
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * Converts a list of AnnotationGen objects into a set of attributes that can be attached to the class file.
+ *
+ * @param cp The constant pool gen where we can create the necessary name refs
+ * @param annotations A list of AnnotationGen objects
+ */
+ public static Collection<RuntimeAnnos> getAnnotationAttributes(ConstantPool cp, List<AnnotationGen> annotations) {
+
+ if (annotations.size() == 0) {
+ return null;
+ }
+
+ try {
+ int countVisible = 0;
+ int countInvisible = 0;
+
+ // put the annotations in the right output stream
+ for (AnnotationGen a : annotations) {
+ if (a.isRuntimeVisible()) {
+ countVisible++;
+ } else {
+ countInvisible++;
+ }
+ }
+
+ ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream();
+ ByteArrayOutputStream riaBytes = new ByteArrayOutputStream();
+ DataOutputStream rvaDos = new DataOutputStream(rvaBytes);
+ DataOutputStream riaDos = new DataOutputStream(riaBytes);
+
+ rvaDos.writeShort(countVisible);
+ riaDos.writeShort(countInvisible);
+
+ // put the annotations in the right output stream
+ for (AnnotationGen a : annotations) {
+ if (a.isRuntimeVisible()) {
+ a.dump(rvaDos);
+ } else {
+ a.dump(riaDos);
+ }
+ }
+
+ rvaDos.close();
+ riaDos.close();
+
+ byte[] rvaData = rvaBytes.toByteArray();
+ byte[] riaData = riaBytes.toByteArray();
+
+ int rvaIndex = -1;
+ int riaIndex = -1;
+
+ if (rvaData.length > 2) {
+ rvaIndex = cp.addUtf8("RuntimeVisibleAnnotations");
+ }
+ if (riaData.length > 2) {
+ riaIndex = cp.addUtf8("RuntimeInvisibleAnnotations");
+ }
+
+ List<RuntimeAnnos> newAttributes = new ArrayList<RuntimeAnnos>();
+ if (rvaData.length > 2) {
+ newAttributes.add(new RuntimeVisAnnos(rvaIndex, rvaData.length, rvaData, cp));
+ }
+ if (riaData.length > 2) {
+ newAttributes.add(new RuntimeInvisAnnos(riaIndex, riaData.length, riaData, cp));
+ }
+
+ return newAttributes;
+ } catch (IOException e) {
+ System.err.println("IOException whilst processing annotations");
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Annotations against a class are stored in one of four attribute kinds: - RuntimeVisibleParameterAnnotations -
+ * RuntimeInvisibleParameterAnnotations
+ */
+ // OPTIMIZE looks heavyweight?
+ public static Attribute[] getParameterAnnotationAttributes(ConstantPool cp, List<AnnotationGen>[] vec) {
+
+ int visCount[] = new int[vec.length];
+ int totalVisCount = 0;
+ int invisCount[] = new int[vec.length];
+ int totalInvisCount = 0;
+ try {
+
+ for (int i = 0; i < vec.length; i++) {
+ List<AnnotationGen> l = vec[i];
+ if (l != null) {
+ for (AnnotationGen element : l) {
+ if (element.isRuntimeVisible()) {
+ visCount[i]++;
+ totalVisCount++;
+ } else {
+ invisCount[i]++;
+ totalInvisCount++;
+ }
+ }
+ }
+ }
+
+ // Lets do the visible ones
+ ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream();
+ DataOutputStream rvaDos = new DataOutputStream(rvaBytes);
+ rvaDos.writeByte(vec.length); // First goes number of parameters
+
+ for (int i = 0; i < vec.length; i++) {
+ rvaDos.writeShort(visCount[i]);
+ if (visCount[i] > 0) {
+ List<AnnotationGen> l = vec[i];
+ for (AnnotationGen element : l) {
+ if (element.isRuntimeVisible()) {
+ element.dump(rvaDos);
+ }
+ }
+ }
+ }
+ rvaDos.close();
+
+ // Lets do the invisible ones
+ ByteArrayOutputStream riaBytes = new ByteArrayOutputStream();
+ DataOutputStream riaDos = new DataOutputStream(riaBytes);
+ riaDos.writeByte(vec.length); // First goes number of parameters
+
+ for (int i = 0; i < vec.length; i++) {
+ riaDos.writeShort(invisCount[i]);
+ if (invisCount[i] > 0) {
+ List<AnnotationGen> l = vec[i];
+ for (AnnotationGen element : l) {
+ if (!element.isRuntimeVisible()) {
+ element.dump(riaDos);
+ }
+ }
+ }
+ }
+ riaDos.close();
+
+ byte[] rvaData = rvaBytes.toByteArray();
+ byte[] riaData = riaBytes.toByteArray();
+
+ int rvaIndex = -1;
+ int riaIndex = -1;
+
+ if (totalVisCount > 0) {
+ rvaIndex = cp.addUtf8("RuntimeVisibleParameterAnnotations");
+ }
+ if (totalInvisCount > 0) {
+ riaIndex = cp.addUtf8("RuntimeInvisibleParameterAnnotations");
+ }
+
+ List<RuntimeParamAnnos> newAttributes = new ArrayList<RuntimeParamAnnos>();
+
+ if (totalVisCount > 0) {
+ newAttributes.add(new RuntimeVisParamAnnos(rvaIndex, rvaData.length, rvaData, cp));
+ }
+
+ if (totalInvisCount > 0) {
+ newAttributes.add(new RuntimeInvisParamAnnos(riaIndex, riaData.length, riaData, cp));
+ }
+
+ return newAttributes.toArray(new Attribute[] {});
+ } catch (IOException e) {
+ System.err.println("IOException whilst processing parameter annotations");
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static class ResultHolder {
+ private String result;
+ private int consumed;
+
+ public static final ResultHolder BYTE = new ResultHolder("byte", 1);
+ public static final ResultHolder CHAR = new ResultHolder("char", 1);
+ public static final ResultHolder DOUBLE = new ResultHolder("double", 1);
+ public static final ResultHolder FLOAT = new ResultHolder("float", 1);
+ public static final ResultHolder INT = new ResultHolder("int", 1);
+ public static final ResultHolder LONG = new ResultHolder("long", 1);
+ public static final ResultHolder SHORT = new ResultHolder("short", 1);
+ public static final ResultHolder BOOLEAN = new ResultHolder("boolean", 1);
+ public static final ResultHolder VOID = new ResultHolder("void", 1);
+
+ public ResultHolder(String s, int c) {
+ result = s;
+ consumed = c;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public int getConsumedChars() {
+ return consumed;
+ }
+ }
+
+ /**
+ * Return type of signature as a byte value as defined in <em>Constants</em>
+ *
+ * @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);
+ }
+ }
+
+ public static final byte typeOfSignature(char c) throws ClassFormatException {
+ switch (c) {
+ 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 type of signature: " + c);
+ }
+ }
+
+ /**
+ * 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 = bytes.readByte();
+ if (b != 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 = " + default_offset + ", low = " + low + ", high = " + high + "(");
+
+ 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 = " + default_offset + ", npairs = " + npairs + " (");
+
+ for (int i = 0; i < npairs; i++) {
+ match[i] = bytes.readInt();
+ jump_table[i] = offset + bytes.readInt();
+ buf.append("(" + match[i] + ", " + jump_table[i] + ")");
+ 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#" + ((bytes.getIndex() - 1) + bytes.readShort()));
+ break;
+
+ // 32-bit wide jumps
+ case Constants.GOTO_W:
+ case Constants.JSR_W:
+ buf.append("\t\t#" + ((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%" + 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<" + Constants.TYPE_NAMES[bytes.readByte()] + ">");
+ break;
+
+ // Access object/class fields
+ case Constants.GETFIELD:
+ case Constants.GETSTATIC:
+ case Constants.PUTFIELD:
+ case Constants.PUTSTATIC:
+ index = bytes.readUnsignedShort();
+ buf.append("\t\t" + constant_pool.constantToString(index, Constants.CONSTANT_Fieldref)
+ + (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<" + constant_pool.constantToString(index) + ">" + (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" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : ""));
+ break;
+
+ case Constants.INVOKEINTERFACE:
+ index = bytes.readUnsignedShort();
+ int nargs = bytes.readUnsignedByte(); // historical, redundant
+ buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")\t" : "") + nargs + "\t"
+ + bytes.readUnsignedByte()); // Last byte is a reserved
+ // space
+ break;
+
+ case Constants.INVOKEDYNAMIC://http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokedynamic
+ index = bytes.readUnsignedShort();
+ bytes.readUnsignedShort(); // zeroes
+ buf.append("\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : ""));
+ break;
+
+ // Operands are references to items in constant pool
+ case Constants.LDC_W:
+ case Constants.LDC2_W:
+ index = bytes.readUnsignedShort();
+ buf.append("\t\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : ""));
+ break;
+
+ case Constants.LDC:
+ index = bytes.readUnsignedByte();
+ buf.append("\t\t" + constant_pool.constantToString(index) + (verbose ? " (" + index + ")" : ""));
+ break;
+
+ // Array of references
+ case Constants.ANEWARRAY:
+ index = bytes.readUnsignedShort();
+ buf.append("\t\t<" + compactClassName(constant_pool.getConstantString(index, Constants.CONSTANT_Class), false) + ">"
+ + (verbose ? " (" + index + ")" : ""));
+ break;
+
+ // Multidimensional array of references
+ case Constants.MULTIANEWARRAY: {
+ index = bytes.readUnsignedShort();
+ int dimensions = bytes.readUnsignedByte();
+
+ buf.append("\t<" + compactClassName(constant_pool.getConstantString(index, Constants.CONSTANT_Class), false) + ">\t"
+ + dimensions + (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%" + vindex + "\t" + constant);
+ break;
+
+ default:
+ if ((Constants.iLen[opcode] - 1) > 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();
+ }
+
+ // private helpers
+ private static final int pow2(int n) {
+ return 1 << n;
+ }
+
+ /**
+ * Convert type to Java method signature, e.g. int[] f(java.lang.String x) becomes (Ljava/lang/String;)[I
+ *
+ * @param returnType what the method returns
+ * @param argTypes what are the argument types
+ * @return method signature for given type(s).
+ */
+ public static String toMethodSignature(Type returnType, Type[] argTypes) {
+ StringBuffer buf = new StringBuffer("(");
+ int length = (argTypes == null) ? 0 : argTypes.length;
+ for (int i = 0; i < length; i++) {
+ buf.append(argTypes[i].getSignature());
+ }
+ buf.append(')');
+ buf.append(returnType.getSignature());
+ return buf.toString();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java
new file mode 100644
index 000000000..2e6024580
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationElementValue.java
@@ -0,0 +1,73 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+
+public class AnnotationElementValue extends ElementValue {
+
+ private AnnotationGen a;
+
+ public AnnotationElementValue(AnnotationGen a, ConstantPool cpool) {
+ super(ANNOTATION, cpool);
+ this.a = a;
+ }
+
+ public AnnotationElementValue(int type, AnnotationGen annotation, ConstantPool cpool) {
+ super(type, cpool);
+ assert type == ANNOTATION;
+ this.a = annotation;
+ }
+
+ public AnnotationElementValue(AnnotationElementValue value, ConstantPool cpool, boolean copyPoolEntries) {
+ super(ANNOTATION, cpool);
+ a = new AnnotationGen(value.getAnnotation(), cpool, copyPoolEntries);
+ }
+
+ @Override
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeByte(type); // u1 type of value (ANNOTATION == '@')
+ a.dump(dos);
+ }
+
+ @Override
+ public String stringifyValue() {
+ StringBuffer sb = new StringBuffer();
+ ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(a.getTypeIndex(), Constants.CONSTANT_Utf8);
+ sb.append(cu8.getValue());
+ // haven't really tested this values section:
+ List<NameValuePair> pairs = a.getValues();
+ if (pairs != null && pairs.size() > 0) {
+ sb.append("(");
+ for (int p = 0; p < pairs.size(); p++) {
+ if (p > 0) {
+ sb.append(",");
+ }
+ sb.append(pairs.get(p).getNameString()).append("=").append(pairs.get(p).getValue().stringifyValue());
+ }
+ sb.append(")");
+ }
+ return sb.toString();
+ }
+
+ public AnnotationGen getAnnotation() {
+ return a;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java
new file mode 100644
index 000000000..9a0a42909
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java
@@ -0,0 +1,176 @@
+/* *******************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+import org.aspectj.apache.bcel.classfile.Utility;
+import org.aspectj.apache.bcel.generic.ObjectType;
+
+public class AnnotationGen {
+ public static final AnnotationGen[] NO_ANNOTATIONS = new AnnotationGen[0];
+
+ private int typeIndex;
+ private List<NameValuePair> pairs = Collections.emptyList();
+ private ConstantPool cpool;
+ private boolean isRuntimeVisible = false;
+
+ public AnnotationGen(AnnotationGen a, ConstantPool cpool, boolean copyPoolEntries) {
+ this.cpool = cpool;
+ if (copyPoolEntries) {
+ typeIndex = cpool.addUtf8(a.getTypeSignature());
+ } else {
+ typeIndex = a.getTypeIndex();
+ }
+ isRuntimeVisible = a.isRuntimeVisible();
+ pairs = copyValues(a.getValues(), cpool, copyPoolEntries);
+ }
+
+ private List<NameValuePair> copyValues(List<NameValuePair> in, ConstantPool cpool, boolean copyPoolEntries) {
+ List<NameValuePair> out = new ArrayList<NameValuePair>();
+ for (NameValuePair nvp : in) {
+ out.add(new NameValuePair(nvp, cpool, copyPoolEntries));
+ }
+ return out;
+ }
+
+ private AnnotationGen(ConstantPool cpool) {
+ this.cpool = cpool;
+ }
+
+ /**
+ * Retrieve an immutable version of this AnnotationGen
+ */
+ public AnnotationGen(ObjectType type, List<NameValuePair> pairs, boolean runtimeVisible, ConstantPool cpool) {
+ this.cpool = cpool;
+ if (type != null) {
+ this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects
+ }
+ this.pairs = pairs;
+ isRuntimeVisible = runtimeVisible;
+ }
+
+ public static AnnotationGen read(DataInputStream dis, ConstantPool cpool, boolean b) throws IOException {
+ AnnotationGen a = new AnnotationGen(cpool);
+ a.typeIndex = dis.readUnsignedShort();
+ int elemValuePairCount = dis.readUnsignedShort();
+ for (int i = 0; i < elemValuePairCount; i++) {
+ int nidx = dis.readUnsignedShort();
+ a.addElementNameValuePair(new NameValuePair(nidx, ElementValue.readElementValue(dis, cpool), cpool));
+ }
+ a.isRuntimeVisible(b);
+ return a;
+ }
+
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeShort(typeIndex); // u2 index of type name in cpool
+ dos.writeShort(pairs.size()); // u2 element_value pair count
+ for (int i = 0; i < pairs.size(); i++) {
+ NameValuePair envp = pairs.get(i);
+ envp.dump(dos);
+ }
+ }
+
+ public void addElementNameValuePair(NameValuePair evp) {
+ if (pairs == Collections.EMPTY_LIST) {
+ pairs = new ArrayList<NameValuePair>();
+ }
+ pairs.add(evp);
+ }
+
+ public int getTypeIndex() {
+ return typeIndex;
+ }
+
+ public String getTypeSignature() {
+ ConstantUtf8 utf8 = (ConstantUtf8) cpool.getConstant(typeIndex);
+ return utf8.getValue();
+ }
+
+ public String getTypeName() {
+ return Utility.signatureToString(getTypeSignature());
+ }
+
+ public List<NameValuePair> getValues() {
+ return pairs;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer s = new StringBuffer();
+ s.append("AnnotationGen:[" + getTypeName() + " #" + pairs.size() + " {");
+ for (int i = 0; i < pairs.size(); i++) {
+ s.append(pairs.get(i));
+ if (i + 1 < pairs.size())
+ s.append(",");
+ }
+ s.append("}]");
+ return s.toString();
+ }
+
+ public String toShortString() {
+ StringBuffer s = new StringBuffer();
+ s.append("@").append(getTypeName());
+ if (pairs.size()!=0) {
+ s.append("(");
+ for (int i = 0; i < pairs.size(); i++) {
+ s.append(pairs.get(i));
+ if (i + 1 < pairs.size())
+ s.append(",");
+ }
+ s.append(")");
+ }
+ return s.toString();
+ }
+
+ private void isRuntimeVisible(boolean b) {
+ isRuntimeVisible = b;
+ }
+
+ public boolean isRuntimeVisible() {
+ return isRuntimeVisible;
+ }
+
+ /**
+ * @return true if the annotation has a value with the specified name and (toString'd) value
+ */
+ public boolean hasNameValuePair(String name, String value) {
+ for (NameValuePair pair : pairs) {
+ if (pair.getNameString().equals(name)) {
+ if (pair.getValue().stringifyValue().equals(value)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return true if the annotation has a value with the specified name
+ */
+ public boolean hasNamedValue(String name) {
+ for (NameValuePair pair : pairs) {
+ if (pair.getNameString().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java
new file mode 100644
index 000000000..3dd19af71
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ArrayElementValue.java
@@ -0,0 +1,84 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+public class ArrayElementValue extends ElementValue {
+ private static final ElementValue[] NO_VALUES = new ElementValue[0];
+
+ // J5TODO: Should we make this an array or a list? A list would be easier to modify ...
+ private ElementValue[] evalues = NO_VALUES;
+
+ public ElementValue[] getElementValuesArray() {
+ return evalues;
+ }
+
+ public int getElementValuesArraySize() {
+ return evalues.length;
+ }
+
+ public ArrayElementValue(ConstantPool cp) {
+ super(ARRAY, cp);
+ }
+
+ public ArrayElementValue(int type, ElementValue[] datums, ConstantPool cpool) {
+ super(type, cpool);
+ if (type != ARRAY)
+ throw new RuntimeException("Only element values of type array can be built with this ctor");
+ this.evalues = datums;
+ }
+
+ public ArrayElementValue(ArrayElementValue value, ConstantPool cpool, boolean copyPoolEntries) {
+ super(ARRAY, cpool);
+ evalues = new ElementValue[value.getElementValuesArraySize()];
+ ElementValue[] in = value.getElementValuesArray();
+ for (int i = 0; i < in.length; i++) {
+ evalues[i] = ElementValue.copy(in[i], cpool, copyPoolEntries);
+ }
+ }
+
+ @Override
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeByte(type); // u1 type of value (ARRAY == '[')
+ dos.writeShort(evalues.length);
+ for (int i = 0; i < evalues.length; i++) {
+ evalues[i].dump(dos);
+ }
+ }
+
+ @Override
+ public String stringifyValue() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ for (int i = 0; i < evalues.length; i++) {
+ ElementValue element = evalues[i];
+ sb.append(element.stringifyValue());
+ if ((i + 1) < evalues.length)
+ sb.append(",");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public void addElement(ElementValue gen) {
+ ElementValue[] old = evalues;
+ evalues = new ElementValue[evalues.length + 1];
+ System.arraycopy(old, 0, evalues, 0, old.length);
+ evalues[old.length] = gen;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java
new file mode 100644
index 000000000..a4e18b6d4
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ClassElementValue.java
@@ -0,0 +1,79 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+import org.aspectj.apache.bcel.generic.ObjectType;
+
+public class ClassElementValue extends ElementValue {
+
+ // For primitive types and string type, this points to the value entry in the cpool
+ // For 'class' this points to the class entry in the cpool
+ private int idx;
+
+ protected ClassElementValue(int typeIdx, ConstantPool cpool) {
+ super(ElementValue.CLASS, cpool);
+ this.idx = typeIdx;
+ }
+
+ public ClassElementValue(ObjectType t, ConstantPool cpool) {
+ super(ElementValue.CLASS, cpool);
+ // this.idx = cpool.addClass(t);
+ idx = cpool.addUtf8(t.getSignature());
+ }
+
+ /**
+ * Return immutable variant of this ClassElementValueGen
+ */
+ // public ElementValueGen getElementValue() {
+ // return new ClassElementValueGen(type,idx,cpGen);
+ // }
+ public ClassElementValue(ClassElementValue value, ConstantPool cpool, boolean copyPoolEntries) {
+ super(CLASS, cpool);
+ if (copyPoolEntries) {
+ // idx = cpool.addClass(value.getClassString());
+ idx = cpool.addUtf8(value.getClassString());
+ } else {
+ idx = value.getIndex();
+
+ }
+ }
+
+ public int getIndex() {
+ return idx;
+ }
+
+ public String getClassString() {
+ ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx);
+ return cu8.getValue();
+ // ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx);
+ // ConstantUtf8 utf8 = (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex());
+ // return utf8.getBytes();
+ }
+
+ @Override
+ public String stringifyValue() {
+ return getClassString();
+ }
+
+ @Override
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeByte(type); // u1 kind of value
+ dos.writeShort(idx);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java
new file mode 100644
index 000000000..06f7c7273
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java
@@ -0,0 +1,135 @@
+/* *******************************************************************
+ * Copyright (c) 2004, 2013 IBM, VMware
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+public abstract class ElementValue {
+
+ public static final int STRING = 's';
+ public static final int ENUM_CONSTANT = 'e';
+ public static final int CLASS = 'c';
+ public static final int ANNOTATION = '@';
+ public static final int ARRAY = '[';
+
+ public static final int PRIMITIVE_INT = 'I';
+ public static final int PRIMITIVE_BYTE = 'B';
+ public static final int PRIMITIVE_CHAR = 'C';
+ public static final int PRIMITIVE_DOUBLE = 'D';
+ public static final int PRIMITIVE_FLOAT = 'F';
+ public static final int PRIMITIVE_LONG = 'J';
+ public static final int PRIMITIVE_SHORT = 'S';
+ public static final int PRIMITIVE_BOOLEAN = 'Z';
+
+ protected int type;
+ protected ConstantPool cpool;
+
+ protected ElementValue(int type, ConstantPool cpool) {
+ this.type = type;
+ this.cpool = cpool;
+ }
+
+ public int getElementValueType() {
+ return type;
+ }
+
+ public abstract String stringifyValue();
+
+ public abstract void dump(DataOutputStream dos) throws IOException;
+
+ public static ElementValue readElementValue(DataInputStream dis, ConstantPool cpGen) throws IOException {
+ int type = dis.readUnsignedByte();
+ switch (type) {
+ case 'B': // byte
+ return new SimpleElementValue(PRIMITIVE_BYTE, dis.readUnsignedShort(), cpGen);
+ case 'C': // char
+ return new SimpleElementValue(PRIMITIVE_CHAR, dis.readUnsignedShort(), cpGen);
+ case 'D': // double
+ return new SimpleElementValue(PRIMITIVE_DOUBLE, dis.readUnsignedShort(), cpGen);
+ case 'F': // float
+ return new SimpleElementValue(PRIMITIVE_FLOAT, dis.readUnsignedShort(), cpGen);
+ case 'I': // int
+ return new SimpleElementValue(PRIMITIVE_INT, dis.readUnsignedShort(), cpGen);
+ case 'J': // long
+ return new SimpleElementValue(PRIMITIVE_LONG, dis.readUnsignedShort(), cpGen);
+ case 'S': // short
+ return new SimpleElementValue(PRIMITIVE_SHORT, dis.readUnsignedShort(), cpGen);
+ case 'Z': // boolean
+ return new SimpleElementValue(PRIMITIVE_BOOLEAN, dis.readUnsignedShort(), cpGen);
+ case 's': // String
+ return new SimpleElementValue(STRING, dis.readUnsignedShort(), cpGen);
+
+ case 'e': // Enum constant
+ return new EnumElementValue(dis.readUnsignedShort(), dis.readUnsignedShort(), cpGen);
+
+ case 'c': // Class
+ return new ClassElementValue(dis.readUnsignedShort(), cpGen);
+
+ // FIXME should this be true here? or should it be the value for the containing annotation?
+ case '@': // Annotation
+ return new AnnotationElementValue(ANNOTATION, AnnotationGen.read(dis, cpGen, true), cpGen);
+
+ case '[': // Array
+ int numArrayVals = dis.readUnsignedShort();
+ ElementValue[] evalues = new ElementValue[numArrayVals];
+ for (int j = 0; j < numArrayVals; j++) {
+ evalues[j] = ElementValue.readElementValue(dis, cpGen);
+ }
+ return new ArrayElementValue(ARRAY, evalues, cpGen);
+
+ default:
+ throw new RuntimeException("Unexpected element value kind in annotation: " + type);
+ }
+ }
+
+ protected ConstantPool getConstantPool() {
+ return cpool;
+ }
+
+ /**
+ * Creates an (modifiable) ElementValueGen copy of an (immutable) ElementValue - constant pool is assumed correct.
+ */
+ public static ElementValue copy(ElementValue value, ConstantPool cpool, boolean copyPoolEntries) {
+ switch (value.getElementValueType()) {
+ case 'B': // byte
+ case 'C': // char
+ case 'D': // double
+ case 'F': // float
+ case 'I': // int
+ case 'J': // long
+ case 'S': // short
+ case 'Z': // boolean
+ case 's': // String
+ return new SimpleElementValue((SimpleElementValue) value, cpool, copyPoolEntries);
+
+ case 'e': // Enum constant
+ return new EnumElementValue((EnumElementValue) value, cpool, copyPoolEntries);
+
+ case '@': // Annotation
+ return new AnnotationElementValue((AnnotationElementValue) value, cpool, copyPoolEntries);
+
+ case '[': // Array
+ return new ArrayElementValue((ArrayElementValue) value, cpool, copyPoolEntries);
+
+ case 'c': // Class
+ return new ClassElementValue((ClassElementValue) value, cpool, copyPoolEntries);
+
+ default:
+ throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")");
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java
new file mode 100644
index 000000000..a8b219774
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/EnumElementValue.java
@@ -0,0 +1,116 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+import org.aspectj.apache.bcel.generic.ObjectType;
+
+public class EnumElementValue extends ElementValue {
+
+ // For enum types, these two indices point to the type and value
+ private int typeIdx;
+ private int valueIdx;
+
+ /**
+ * This ctor assumes the constant pool already contains the right type and value - as indicated by typeIdx and valueIdx. This
+ * ctor is used for deserialization
+ */
+ protected EnumElementValue(int typeIdx, int valueIdx, ConstantPool cpool) {
+ super(ElementValue.ENUM_CONSTANT, cpool);
+ if (type != ENUM_CONSTANT) {
+ throw new RuntimeException("Only element values of type enum can be built with this ctor");
+ }
+ this.typeIdx = typeIdx;
+ this.valueIdx = valueIdx;
+ }
+
+ // /**
+ // * Return immutable variant of this EnumElementValue
+ // */
+ // public ElementValueGen getElementValue() {
+ // System.err.println("Duplicating value: "+getEnumTypeString()+":"+getEnumValueString());
+ // return new EnumElementValueGen(type,typeIdx,valueIdx,cpGen);
+ // }
+
+ public EnumElementValue(ObjectType t, String value, ConstantPool cpool) {
+ super(ElementValue.ENUM_CONSTANT, cpool);
+ typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t);
+ valueIdx = cpool.addUtf8(value);// was addString(value);
+ }
+
+ public EnumElementValue(EnumElementValue value, ConstantPool cpool, boolean copyPoolEntries) {
+ super(ENUM_CONSTANT, cpool);
+ if (copyPoolEntries) {
+ typeIdx = cpool.addUtf8(value.getEnumTypeString());// was addClass(value.getEnumTypeString());
+ valueIdx = cpool.addUtf8(value.getEnumValueString()); // was addString(value.getEnumValueString());
+ } else {
+ typeIdx = value.getTypeIndex();
+ valueIdx = value.getValueIndex();
+ }
+ }
+
+ @Override
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeByte(type); // u1 type of value (ENUM_CONSTANT == 'e')
+ dos.writeShort(typeIdx); // u2
+ dos.writeShort(valueIdx); // u2
+ }
+
+ /**
+ * return signature and value, something like Lp/Color;RED
+ */
+ @Override
+ public String stringifyValue() {
+ StringBuffer sb = new StringBuffer();
+ ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(typeIdx, Constants.CONSTANT_Utf8);
+ sb.append(cu8.getValue());
+ cu8 = (ConstantUtf8) cpool.getConstant(valueIdx, Constants.CONSTANT_Utf8);
+ sb.append(cu8.getValue());
+ return sb.toString();
+ }
+
+ public String toString() {
+ StringBuilder s = new StringBuilder("E(");
+ s.append(getEnumTypeString()).append(" ").append(getEnumValueString()).append(")");
+ return s.toString();
+ }
+
+ // BCELBUG: Should we need to call utility.signatureToString() on the output here?
+ public String getEnumTypeString() {
+ // Constant cc = getConstantPool().getConstant(typeIdx);
+ // ConstantClass cu8 = (ConstantClass)getConstantPool().getConstant(typeIdx);
+ // return ((ConstantUtf8)getConstantPool().getConstant(cu8.getNameIndex())).getBytes();
+ return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)).getValue();
+ // return Utility.signatureToString(cu8.getBytes());
+ }
+
+ public String getEnumValueString() {
+ return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getValue();
+ // ConstantString cu8 = (ConstantString)getConstantPool().getConstant(valueIdx);
+ // return ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes();
+ }
+
+ public int getValueIndex() {
+ return valueIdx;
+ }
+
+ public int getTypeIndex() {
+ return typeIdx;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java
new file mode 100644
index 000000000..99b4211ec
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/NameValuePair.java
@@ -0,0 +1,75 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+public class NameValuePair {
+ private int nameIdx;
+ private ElementValue value;
+ private ConstantPool cpool;
+
+ public NameValuePair(NameValuePair pair, ConstantPool cpool, boolean copyPoolEntries) {
+ this.cpool = cpool;
+ // J5ASSERT:
+ // Could assert nvp.getNameString() points to the same thing as cpool.getConstant(nvp.getNameIndex())
+ // if (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) {
+ // throw new RuntimeException("envp buggered");
+ // }
+ if (copyPoolEntries) {
+ nameIdx = cpool.addUtf8(pair.getNameString());
+ } else {
+ nameIdx = pair.getNameIndex();
+ }
+ value = ElementValue.copy(pair.getValue(), cpool, copyPoolEntries);
+ }
+
+ protected NameValuePair(int idx, ElementValue value, ConstantPool cpool) {
+ this.nameIdx = idx;
+ this.value = value;
+ this.cpool = cpool;
+ }
+
+ public NameValuePair(String name, ElementValue value, ConstantPool cpool) {
+ this.nameIdx = cpool.addUtf8(name);
+ this.value = value;
+ this.cpool = cpool;
+ }
+
+ protected void dump(DataOutputStream dos) throws IOException {
+ dos.writeShort(nameIdx); // u2 name of the element
+ value.dump(dos);
+ }
+
+ public int getNameIndex() {
+ return nameIdx;
+ }
+
+ public final String getNameString() {
+ return cpool.getConstantUtf8(nameIdx).getValue();
+ }
+
+ public final ElementValue getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getNameString()).append("=").append(value.stringifyValue());
+ return sb.toString();
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java
new file mode 100644
index 000000000..ac145087b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java
@@ -0,0 +1,98 @@
+/* *******************************************************************
+ * Copyright (c) 2004, 2013 IBM, VMware
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+public abstract class RuntimeAnnos extends Attribute {
+
+ private List<AnnotationGen> annotations;
+ private boolean visible;
+
+ // Keep just a byte stream of the data until someone actually asks for it
+ private boolean inflated = false;
+ private byte[] annotation_data;
+
+ public RuntimeAnnos(byte attrid, boolean visible, int nameIdx, int len, ConstantPool cpool) {
+ super(attrid, nameIdx, len, cpool);
+ this.visible = visible;
+ annotations = new ArrayList<AnnotationGen>();
+ }
+
+ public RuntimeAnnos(byte attrid, boolean visible, int nameIdx, int len, byte[] data, ConstantPool cpool) {
+ super(attrid, nameIdx, len, cpool);
+ this.visible = visible;
+ annotations = new ArrayList<AnnotationGen>();
+ annotation_data = data;
+ }
+
+ public List<AnnotationGen> getAnnotations() {
+ if (!inflated)
+ inflate();
+ return annotations;
+ }
+
+ public boolean areVisible() {
+ return visible;
+ }
+
+ protected void readAnnotations(DataInputStream dis, ConstantPool cpool) throws IOException {
+ annotation_data = new byte[length];
+ dis.readFully(annotation_data, 0, length);
+ }
+
+ protected void writeAnnotations(DataOutputStream dos) throws IOException {
+ if (!inflated) {
+ dos.write(annotation_data, 0, length);
+ } else {
+ dos.writeShort(annotations.size());
+ for (Iterator<AnnotationGen> i = annotations.iterator(); i.hasNext();) {
+ AnnotationGen ann = i.next();
+ ann.dump(dos);
+ }
+ }
+ }
+
+
+ private void inflate() {
+ try {
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data));
+ int numberOfAnnotations = dis.readUnsignedShort();
+ if (numberOfAnnotations > 0) {
+ List<AnnotationGen> inflatedAnnotations = new ArrayList<AnnotationGen>();
+ for (int i = 0; i < numberOfAnnotations; i++) {
+ inflatedAnnotations.add(AnnotationGen.read(dis, getConstantPool(), visible));
+ }
+ annotations = inflatedAnnotations;
+ }
+ dis.close();
+ inflated = true;
+ } catch (IOException ioe) {
+ throw new RuntimeException("Unabled to inflate annotation data, badly formed? ");
+ }
+ }
+
+ /** FOR TESTING ONLY: Tells you if the annotations have been inflated to an object graph */
+ public boolean isInflated() {
+ return inflated;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java
new file mode 100644
index 000000000..a6b2e529f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java
@@ -0,0 +1,51 @@
+/* *******************************************************************
+ * Copyright (c) 2004, 2013 IBM, VMware
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ClassVisitor;
+
+public class RuntimeInvisAnnos extends RuntimeAnnos {
+
+ public RuntimeInvisAnnos(int nameIdx, int len, ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS, false, nameIdx, len, cpool);
+ }
+
+ public RuntimeInvisAnnos(int nameIdx, int len,
+ DataInputStream dis,ConstantPool cpool) throws IOException {
+ this(nameIdx, len, cpool);
+ readAnnotations(dis,cpool);
+ }
+
+ public RuntimeInvisAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS,false,nameIndex,len,rvaData,cpool);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitRuntimeInvisibleAnnotations(this);
+ }
+
+ public final void dump(DataOutputStream dos) throws IOException {
+ super.dump(dos);
+ writeAnnotations(dos);
+ }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java
new file mode 100644
index 000000000..cb2eb8d7a
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java
@@ -0,0 +1,45 @@
+/* *******************************************************************
+ * Copyright (c) 2004, 2013 IBM, VMware
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ClassVisitor;
+
+public class RuntimeInvisParamAnnos extends RuntimeParamAnnos {
+
+ public RuntimeInvisParamAnnos(int nameIdx, int len, ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, false, nameIdx, len, cpool);
+ }
+
+ public RuntimeInvisParamAnnos(int nameIdx, int len,
+ DataInputStream dis,ConstantPool cpool) throws IOException {
+ this(nameIdx, len, cpool);
+ readParameterAnnotations(dis,cpool);
+ }
+
+ public RuntimeInvisParamAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,false,nameIndex,len,rvaData,cpool);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitRuntimeInvisibleParameterAnnotations(this);
+ }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java
new file mode 100644
index 000000000..333ccbddd
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisTypeAnnos.java
@@ -0,0 +1,36 @@
+/* *******************************************************************
+ * Copyright (c) 2013 VMware
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ClassVisitor;
+
+public class RuntimeInvisTypeAnnos extends RuntimeTypeAnnos {
+
+ public RuntimeInvisTypeAnnos(int nameIdx, int len, DataInputStream dis,
+ ConstantPool cpool) throws IOException {
+ this(nameIdx, len, cpool);
+ readTypeAnnotations(dis, cpool);
+ }
+
+ public RuntimeInvisTypeAnnos(int nameIdx, int len, ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, false, nameIdx, len, cpool);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitRuntimeInvisibleTypeAnnotations(this);
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java
new file mode 100644
index 000000000..517ebee62
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java
@@ -0,0 +1,137 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+public abstract class RuntimeParamAnnos extends Attribute {
+
+ private List<AnnotationGen[]> parameterAnnotations;
+ private boolean visible;
+
+
+ // Keep just a byte stream of the data until someone actually asks for it
+ private boolean inflated = false;
+ private byte[] annotation_data;
+
+
+ public RuntimeParamAnnos(byte attrid, boolean visible,
+ int nameIdx, int len, ConstantPool cpool) {
+ super(attrid,nameIdx,len,cpool);
+ this.visible = visible;
+ parameterAnnotations = new ArrayList<AnnotationGen[]>();
+ }
+
+ public RuntimeParamAnnos(byte attrid,boolean visible,int nameIdx,int len,byte[] data,ConstantPool cpool) {
+ super(attrid,nameIdx,len,cpool);
+ this.visible = visible;
+ parameterAnnotations = new ArrayList<AnnotationGen[]>();
+ annotation_data = data;
+ }
+
+ public final void dump(DataOutputStream dos) throws IOException {
+ super.dump(dos);
+ writeAnnotations(dos);
+ }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ }
+
+ /** Return a list of Annotation[] - each list entry contains the annotations for one parameter */
+ public List /*Annotation[]*/<AnnotationGen[]> getParameterAnnotations() {
+ if (!inflated) inflate();
+ return parameterAnnotations;
+ }
+
+ public AnnotationGen[] getAnnotationsOnParameter(int parameterIndex) {
+ if (!inflated) inflate();
+ // This may happen. In a ctor for a non static inner type the compiler
+ // may have added an extra parameter to the generated ctor (the parameter
+ // contains the instance of the outer class) - in this case
+ // it may appear that there are more parameters than there are entries
+ // in the parameter annotations array
+ if (parameterIndex>=parameterAnnotations.size()) {
+ return AnnotationGen.NO_ANNOTATIONS;
+ }
+ return parameterAnnotations.get(parameterIndex);
+ }
+
+ public boolean areVisible() {
+ return visible;
+ }
+
+ protected void readParameterAnnotations(DataInputStream dis,ConstantPool cpool) throws IOException {
+ annotation_data = new byte[length];
+ dis.readFully(annotation_data,0,length);
+ }
+
+ private void inflate() {
+ try {
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data));
+ int numParameters = dis.readUnsignedByte();
+ if (numParameters > 0) {
+ List<AnnotationGen[]> inflatedParameterAnnotations = new ArrayList<AnnotationGen[]>();
+ for (int i=0; i<numParameters; i++) {
+ int numAnnotations = dis.readUnsignedShort();
+ if (numAnnotations == 0 ) {
+ inflatedParameterAnnotations.add(AnnotationGen.NO_ANNOTATIONS);
+ } else {
+ AnnotationGen[] annotations = new AnnotationGen[numAnnotations];
+ for (int j=0; j<numAnnotations; j++) {
+ annotations[j] = AnnotationGen.read(dis,getConstantPool(),visible);
+ }
+ inflatedParameterAnnotations.add(annotations);
+ }
+ }
+ parameterAnnotations = inflatedParameterAnnotations;
+ }
+ inflated = true;
+ } catch (IOException ioe) {
+ throw new RuntimeException("Unabled to inflate annotation data, badly formed?");
+ }
+ }
+
+
+ protected void writeAnnotations(DataOutputStream dos) throws IOException {
+ if (!inflated) {
+ dos.write(annotation_data,0,length);
+ } else {
+ dos.writeByte(parameterAnnotations.size());
+ for (int i=0; i<parameterAnnotations.size(); i++) {
+ AnnotationGen[] annotations = parameterAnnotations.get(i);
+ dos.writeShort(annotations.length);
+ for (int j=0; j<annotations.length;j++) {
+ annotations[j].dump(dos);
+ }
+ }
+ }
+ }
+
+ /** FOR TESTING ONLY: Tells you if the annotations have been inflated to an object graph */
+ public boolean isInflated() {
+ return inflated;
+ }
+
+ public String toString() {
+ return "Runtime"+(visible?"Visible":"Invisible")+"ParameterAnnotations ["+(inflated?"inflated":"not yet inflated")+"]";
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeTypeAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeTypeAnnos.java
new file mode 100644
index 000000000..fb5c32ce1
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeTypeAnnos.java
@@ -0,0 +1,105 @@
+/* *******************************************************************
+ * Copyright (c) 2013 VMware
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+public abstract class RuntimeTypeAnnos extends Attribute {
+
+ private boolean visible;
+ private TypeAnnotationGen[] typeAnnotations; // null until inflated
+
+ // Keep just a byte stream of the data until someone actually asks for the information within
+ private byte[] annotation_data;
+
+ public RuntimeTypeAnnos(byte attrid, boolean visible, int nameIdx, int len, ConstantPool cpool) {
+ super(attrid,nameIdx,len,cpool);
+ this.visible = visible;
+ }
+
+ protected void readTypeAnnotations(DataInputStream dis,ConstantPool cpool) throws IOException {
+ annotation_data = new byte[length];
+ dis.readFully(annotation_data,0,length);
+ }
+
+ public final void dump(DataOutputStream dos) throws IOException {
+ super.dump(dos);
+ writeTypeAnnotations(dos);
+ }
+
+ protected void writeTypeAnnotations(DataOutputStream dos) throws IOException {
+ if (typeAnnotations == null) {
+ dos.write(annotation_data,0,length);
+ } else {
+ dos.writeShort(typeAnnotations.length);
+ for (int i=0; i<typeAnnotations.length; i++) {
+ typeAnnotations[i].dump(dos);
+ }
+ }
+ }
+
+// public RuntimeTypeAnnos(byte attrid,boolean visible,int nameIdx,int len,byte[] data,ConstantPool cpool) {
+// super(attrid,nameIdx,len,cpool);
+// this.visible = visible;
+// parameterAnnotations = new ArrayList<AnnotationGen[]>();
+// annotation_data = data;
+// }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ }
+
+ public TypeAnnotationGen[] getTypeAnnotations() {
+ ensureInflated();
+ return typeAnnotations;
+ }
+
+
+ public boolean areVisible() {
+ return visible;
+ }
+
+ private void ensureInflated() {
+ if (typeAnnotations !=null) {
+ return;
+ }
+ try {
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data));
+ int numTypeAnnotations = dis.readUnsignedShort();
+ if (numTypeAnnotations == 0) {
+ typeAnnotations = TypeAnnotationGen.NO_TYPE_ANNOTATIONS;
+ } else {
+ typeAnnotations = new TypeAnnotationGen[numTypeAnnotations];
+ for (int i=0; i<numTypeAnnotations; i++) {
+ typeAnnotations[i] = TypeAnnotationGen.read(dis,getConstantPool(),visible);
+ }
+ }
+ } catch (IOException ioe) {
+ throw new RuntimeException("Unabled to inflate type annotation data, badly formed?");
+ }
+ }
+
+ public String toString() {
+ return "Runtime"+(visible?"Visible":"Invisible")+"TypeAnnotations ["+(isInflated()?"inflated":"not yet inflated")+"]";
+ }
+
+ public boolean isInflated() {
+ return typeAnnotations != null;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java
new file mode 100644
index 000000000..3b07cccc7
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java
@@ -0,0 +1,51 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ClassVisitor;
+
+public class RuntimeVisAnnos extends RuntimeAnnos {
+
+ public RuntimeVisAnnos(int nameIdx, int len, ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS, true, nameIdx, len, cpool);
+ }
+
+ public RuntimeVisAnnos(int nameIdx, int len,
+ DataInputStream dis,ConstantPool cpool) throws IOException {
+ this(nameIdx, len, cpool);
+ readAnnotations(dis,cpool);
+ }
+
+ public RuntimeVisAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS,true,nameIndex,len,rvaData,cpool);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitRuntimeVisibleAnnotations(this);
+ }
+
+ public final void dump(DataOutputStream dos) throws IOException {
+ super.dump(dos);
+ writeAnnotations(dos);
+ }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java
new file mode 100644
index 000000000..b47d8aac1
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java
@@ -0,0 +1,45 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ClassVisitor;
+
+public class RuntimeVisParamAnnos extends RuntimeParamAnnos {
+
+ public RuntimeVisParamAnnos(int nameIdx, int len, ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, true, nameIdx, len, cpool);
+ }
+
+ public RuntimeVisParamAnnos(int nameIndex, int len, byte[] rvaData,ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,true,nameIndex,len,rvaData,cpool);
+ }
+
+ public RuntimeVisParamAnnos(int nameIdx, int len,
+ DataInputStream dis,ConstantPool cpool) throws IOException {
+ this(nameIdx, len, cpool);
+ readParameterAnnotations(dis,cpool);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitRuntimeVisibleParameterAnnotations(this);
+ }
+
+ public Attribute copy(ConstantPool constant_pool) {
+ throw new RuntimeException("Not implemented yet!");
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisTypeAnnos.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisTypeAnnos.java
new file mode 100644
index 000000000..59b77dabc
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisTypeAnnos.java
@@ -0,0 +1,36 @@
+/* *******************************************************************
+ * Copyright (c) 2013 VMware
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ClassVisitor;
+
+public class RuntimeVisTypeAnnos extends RuntimeTypeAnnos {
+
+ public RuntimeVisTypeAnnos(int nameIdx, int len, DataInputStream dis,ConstantPool cpool) throws IOException {
+ this(nameIdx, len, cpool);
+ readTypeAnnotations(dis,cpool);
+ }
+
+ public RuntimeVisTypeAnnos(int nameIdx, int len, ConstantPool cpool) {
+ super(Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS, true, nameIdx, len, cpool);
+ }
+
+ public void accept(ClassVisitor v) {
+ v.visitRuntimeVisibleTypeAnnotations(this);
+ }
+
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/SimpleElementValue.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/SimpleElementValue.java
new file mode 100644
index 000000000..2c795b136
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/SimpleElementValue.java
@@ -0,0 +1,330 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement - initial implementation {date}
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantDouble;
+import org.aspectj.apache.bcel.classfile.ConstantFloat;
+import org.aspectj.apache.bcel.classfile.ConstantInteger;
+import org.aspectj.apache.bcel.classfile.ConstantLong;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+
+public class SimpleElementValue extends ElementValue {
+
+ // For primitive types and string type, this points to the value entry in the cpGen
+ // For 'class' this points to the class entry in the cpGen
+ private int idx;
+
+ // ctors for each supported type... type could be inferred but for now lets
+ // force it to be passed
+
+ /**
+ * Protected ctor used for deserialization, doesn't *put* an entry in the constant pool, assumes the one at the supplied index
+ * is correct.
+ */
+ protected SimpleElementValue(int type, int idx, ConstantPool cpGen) {
+ super(type, cpGen);
+ this.idx = idx;
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, int value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, long value) {
+ super(type, cpGen);
+ idx = cpGen.addLong(value);
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, double value) {
+ super(type, cpGen);
+ idx = cpGen.addDouble(value);
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, float value) {
+ super(type, cpGen);
+ idx = cpGen.addFloat(value);
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, short value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, byte value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, char value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, boolean value) {
+ super(type, cpGen);
+ if (value) {
+ idx = cpGen.addInteger(1);
+ } else {
+ idx = cpGen.addInteger(0);
+ }
+ }
+
+ public SimpleElementValue(int type, ConstantPool cpGen, String value) {
+ super(type, cpGen);
+ idx = cpGen.addUtf8(value);
+ }
+
+ public byte getValueByte() {
+ if (type != PRIMITIVE_BYTE) {
+ throw new RuntimeException("Dont call getValueByte() on a non BYTE ElementValue");
+ }
+ ConstantInteger c = (ConstantInteger) cpool.getConstant(idx, Constants.CONSTANT_Integer);
+ return (byte) c.getIntValue();
+ }
+
+ public char getValueChar() {
+ if (type != PRIMITIVE_CHAR) {
+ throw new RuntimeException("Dont call getValueChar() on a non CHAR ElementValue");
+ }
+ ConstantInteger c = (ConstantInteger) cpool.getConstant(idx, Constants.CONSTANT_Integer);
+ return (char) c.getIntValue();
+ }
+
+ public long getValueLong() {
+ if (type != PRIMITIVE_LONG) {
+ throw new RuntimeException("Dont call getValueLong() on a non LONG ElementValue");
+ }
+ ConstantLong j = (ConstantLong) cpool.getConstant(idx);
+ return j.getValue();
+ }
+
+ public float getValueFloat() {
+ if (type != PRIMITIVE_FLOAT) {
+ throw new RuntimeException("Dont call getValueFloat() on a non FLOAT ElementValue");
+ }
+ ConstantFloat f = (ConstantFloat) cpool.getConstant(idx);
+ return f.getValue();
+ }
+
+ public double getValueDouble() {
+ if (type != PRIMITIVE_DOUBLE) {
+ throw new RuntimeException("Dont call getValueDouble() on a non DOUBLE ElementValue");
+ }
+ ConstantDouble d = (ConstantDouble) cpool.getConstant(idx);
+ return d.getValue();
+ }
+
+ public boolean getValueBoolean() {
+ if (type != PRIMITIVE_BOOLEAN) {
+ throw new RuntimeException("Dont call getValueBoolean() on a non BOOLEAN ElementValue");
+ }
+ ConstantInteger bo = (ConstantInteger) cpool.getConstant(idx);
+ return (bo.getValue() != 0);
+ }
+
+ public short getValueShort() {
+ if (type != PRIMITIVE_SHORT) {
+ throw new RuntimeException("Dont call getValueShort() on a non SHORT ElementValue");
+ }
+ ConstantInteger s = (ConstantInteger) cpool.getConstant(idx);
+ return (short) s.getIntValue();
+ }
+
+ /**
+ * The boolean controls whether we copy info from the 'old' constant pool to the 'new'. You need to use this ctor if the
+ * annotation is being copied from one file to another.
+ */
+ public SimpleElementValue(SimpleElementValue value, ConstantPool cpool, boolean copyPoolEntries) {
+ super(value.getElementValueType(), cpool);
+ if (!copyPoolEntries) {
+ // J5ASSERT: Could assert value.stringifyValue() is the same as
+ // cpool.getConstant(SimpleElementValuevalue.getIndex())
+ idx = value.getIndex();
+ } else {
+ switch (value.getElementValueType()) {
+ case STRING:
+ idx = cpool.addUtf8(value.getValueString());
+ break;
+ case PRIMITIVE_INT:
+ idx = cpool.addInteger(value.getValueInt());
+ break;
+ case PRIMITIVE_BYTE:
+ idx = cpool.addInteger(value.getValueByte());
+ break;
+ case PRIMITIVE_CHAR:
+ idx = cpool.addInteger(value.getValueChar());
+ break;
+ case PRIMITIVE_LONG:
+ idx = cpool.addLong(value.getValueLong());
+ break;
+ case PRIMITIVE_FLOAT:
+ idx = cpool.addFloat(value.getValueFloat());
+ break;
+ case PRIMITIVE_DOUBLE:
+ idx = cpool.addDouble(value.getValueDouble());
+ break;
+ case PRIMITIVE_BOOLEAN:
+ if (value.getValueBoolean()) {
+ idx = cpool.addInteger(1);
+ } else {
+ idx = cpool.addInteger(0);
+ }
+ break;
+ case PRIMITIVE_SHORT:
+ idx = cpool.addInteger(value.getValueShort());
+ break;
+ default:
+ throw new RuntimeException("SimpleElementValueGen class does not know how " + "to copy this type " + type);
+ }
+ }
+ }
+
+ public int getIndex() {
+ return idx;
+ }
+
+ public String getValueString() {
+ if (type != STRING) {
+ throw new RuntimeException("Dont call getValueString() on a non STRING ElementValue");
+ }
+ ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(idx);
+ return c.getValue();
+ }
+
+ public int getValueInt() {
+ if (type != PRIMITIVE_INT) {
+ throw new RuntimeException("Dont call getValueString() on a non STRING ElementValue");
+ }
+ ConstantInteger c = (ConstantInteger) cpool.getConstant(idx);
+ return c.getValue();
+ }
+
+ // Whatever kind of value it is, return it as a string
+ @Override
+ public String stringifyValue() {
+ switch (type) {
+ case PRIMITIVE_INT:
+ ConstantInteger c = (ConstantInteger) cpool.getConstant(idx);
+ return Integer.toString(c.getValue());
+ case PRIMITIVE_LONG:
+ ConstantLong j = (ConstantLong) cpool.getConstant(idx);
+ return Long.toString(j.getValue());
+ case PRIMITIVE_DOUBLE:
+ ConstantDouble d = (ConstantDouble) cpool.getConstant(idx);
+ return d.getValue().toString();
+ case PRIMITIVE_FLOAT:
+ ConstantFloat f = (ConstantFloat) cpool.getConstant(idx);
+ return Float.toString(f.getValue());
+ case PRIMITIVE_SHORT:
+ ConstantInteger s = (ConstantInteger) cpool.getConstant(idx);
+ return Integer.toString(s.getValue());
+ case PRIMITIVE_BYTE:
+ ConstantInteger b = (ConstantInteger) cpool.getConstant(idx);
+ return Integer.toString(b.getValue());
+ case PRIMITIVE_CHAR:
+ ConstantInteger ch = (ConstantInteger) cpool.getConstant(idx);
+ return new Character((char) ch.getIntValue()).toString();
+ case PRIMITIVE_BOOLEAN:
+ ConstantInteger bo = (ConstantInteger) cpool.getConstant(idx);
+ if (bo.getValue() == 0) {
+ return "false";
+ } else {
+ return "true";
+ }
+ case STRING:
+ ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(idx);
+ return cu8.getValue();
+
+ default:
+ throw new RuntimeException("SimpleElementValueGen class does not know how to stringify type " + type);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ switch (type) {
+ case PRIMITIVE_INT:
+ ConstantInteger c = (ConstantInteger) cpool.getConstant(idx);
+ s.append("(int)").append(Integer.toString(c.getValue()));
+ break;
+ case PRIMITIVE_LONG:
+ ConstantLong j = (ConstantLong) cpool.getConstant(idx);
+ s.append("(long)").append(Long.toString(j.getValue()));
+ break;
+ case PRIMITIVE_DOUBLE:
+ ConstantDouble d = (ConstantDouble) cpool.getConstant(idx);
+ s.append("(double)").append(d.getValue().toString());
+ break;
+ case PRIMITIVE_FLOAT:
+ ConstantFloat f = (ConstantFloat) cpool.getConstant(idx);
+ s.append("(float)").append(Float.toString(f.getValue()));
+ break;
+ case PRIMITIVE_SHORT:
+ ConstantInteger ci = (ConstantInteger) cpool.getConstant(idx);
+ s.append("(short)").append(Integer.toString(ci.getValue()));
+ break;
+ case PRIMITIVE_BYTE:
+ ConstantInteger b = (ConstantInteger) cpool.getConstant(idx);
+ s.append("(byte)").append(Integer.toString(b.getValue()));
+ break;
+ case PRIMITIVE_CHAR:
+ ConstantInteger ch = (ConstantInteger) cpool.getConstant(idx);
+ s.append("(char)").append(new Character((char) ch.getIntValue()).toString());
+ break;
+ case PRIMITIVE_BOOLEAN:
+ ConstantInteger bo = (ConstantInteger) cpool.getConstant(idx);
+ s.append("(boolean)");
+ if (bo.getValue() == 0) {
+ s.append("false");
+ } else {
+ s.append("true");
+ }
+ break;
+ case STRING:
+ ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(idx);
+ s.append("(string)").append(cu8.getValue());
+ break;
+ default:
+ throw new RuntimeException("SimpleElementValueGen class does not know how to stringify type " + type);
+ }
+ return s.toString();
+ }
+
+ @Override
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeByte(type); // u1 kind of value
+ switch (type) {
+ case PRIMITIVE_INT:
+ case PRIMITIVE_BYTE:
+ case PRIMITIVE_CHAR:
+ case PRIMITIVE_FLOAT:
+ case PRIMITIVE_LONG:
+ case PRIMITIVE_BOOLEAN:
+ case PRIMITIVE_SHORT:
+ case PRIMITIVE_DOUBLE:
+ case STRING:
+ dos.writeShort(idx);
+ break;
+ default:
+ throw new RuntimeException("SimpleElementValueGen doesnt know how to write out type " + type);
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/TypeAnnotationGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/TypeAnnotationGen.java
new file mode 100644
index 000000000..45e5928a3
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/classfile/annotation/TypeAnnotationGen.java
@@ -0,0 +1,405 @@
+/* *******************************************************************
+ * Copyright (c) 2013 VMware
+ *
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Andy Clement initial implementation
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.annotation;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+public class TypeAnnotationGen {
+ public static final TypeAnnotationGen[] NO_TYPE_ANNOTATIONS = new TypeAnnotationGen[0];
+ public static final int[] NO_TYPE_PATH = new int[0];
+
+ private ConstantPool cpool;
+
+ private TypeAnnotationGen(ConstantPool cpool) {
+ this.cpool = cpool;
+ }
+
+ private int targetType;
+ private int[] typePath;
+ private AnnotationGen annotation;
+ private int info; // meaning varies depending on target type
+ private int info2; // meaning varies depending on target type
+ private int[] localVarTarget;
+
+ // target type constants
+ public final static int CLASS_TYPE_PARAMETER = 0x00;
+ public final static int METHOD_TYPE_PARAMETER = 0x01;
+
+ public final static int CLASS_EXTENDS = 0x10;
+ public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
+ public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
+ public final static int FIELD = 0x13;
+ public final static int METHOD_RETURN = 0x14;
+ public final static int METHOD_RECEIVER = 0x15;
+ public final static int METHOD_FORMAL_PARAMETER = 0x16;
+ public final static int THROWS = 0x17;
+
+ public final static int LOCAL_VARIABLE = 0x40;
+ public final static int RESOURCE_VARIABLE = 0x41;
+ public final static int EXCEPTION_PARAMETER = 0x42;
+ public final static int INSTANCEOF = 0x43;
+ public final static int NEW = 0x44;
+ public final static int CONSTRUCTOR_REFERENCE = 0x45;
+ public final static int METHOD_REFERENCE = 0x46;
+ public final static int CAST = 0x47;
+ public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
+ public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
+ public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
+ public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
+
+ // type path entry kinds
+ public final static int TYPE_PATH_ENTRY_KIND_ARRAY = 0;
+ public final static int TYPE_PATH_ENTRY_KIND_INNER_TYPE = 1;
+ public final static int TYPE_PATH_ENTRY_KIND_WILDCARD = 2;
+ public final static int TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT = 3;
+
+
+ public static TypeAnnotationGen read(DataInputStream dis, ConstantPool cpool, boolean isVisible) throws IOException {
+ TypeAnnotationGen typeAnno = new TypeAnnotationGen(cpool);
+ typeAnno.targetType = dis.readUnsignedByte();
+ // read target_info
+ switch (typeAnno.targetType) {
+ case CLASS_TYPE_PARAMETER:
+ typeAnno.info = dis.readUnsignedByte();// type_parameter_index
+ break;
+ case METHOD_TYPE_PARAMETER:
+ typeAnno.info = dis.readUnsignedByte(); // type_parameter_index
+ break;
+ case CLASS_EXTENDS:
+ int superTypeIndex = dis.readUnsignedShort();
+ if (superTypeIndex == 65535) {
+ typeAnno.info = -1;
+ } else {
+ typeAnno.info = superTypeIndex;
+ }
+ break;
+ case CLASS_TYPE_PARAMETER_BOUND:
+ case METHOD_TYPE_PARAMETER_BOUND:
+ typeAnno.info = dis.readUnsignedByte(); // type_parameter_index
+ typeAnno.info2 = dis.readUnsignedByte(); // bound_index;
+ break;
+ case FIELD:
+ case METHOD_RETURN:
+ case METHOD_RECEIVER:
+ break;
+ case METHOD_FORMAL_PARAMETER:
+ typeAnno.info = dis.readUnsignedByte(); // method_formal_parameter_index
+ break;
+ case THROWS:
+ typeAnno.info = dis.readUnsignedShort(); // throws_type_index
+ break;
+ case LOCAL_VARIABLE:
+ case RESOURCE_VARIABLE:
+ typeAnno.localVarTarget = readLocalVarTarget(dis);
+ break;
+ case EXCEPTION_PARAMETER:
+ // TODO should be a SHORT according to the spec but byte for now because of javac (b90)
+ typeAnno.info = dis.readUnsignedByte(); // exception_table_index
+ break;
+ case INSTANCEOF:
+ case NEW:
+ case CONSTRUCTOR_REFERENCE:
+ case METHOD_REFERENCE:
+ typeAnno.info = dis.readUnsignedShort(); // offset
+ break;
+ case CAST:
+ case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ case METHOD_INVOCATION_TYPE_ARGUMENT:
+ case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ case METHOD_REFERENCE_TYPE_ARGUMENT:
+ typeAnno.info = dis.readUnsignedShort(); // offset
+ typeAnno.info2 = dis.readUnsignedByte(); // type_argument_index
+ break;
+ default:
+ throw new IllegalStateException("nyi "+typeAnno.targetType);
+ }
+ int typepathlength = dis.readUnsignedByte();
+ if (typepathlength==0) {
+ typeAnno.typePath = NO_TYPE_PATH;
+ } else {
+ typeAnno.typePath = new int[typepathlength*2];
+ for (int i=0, max = typepathlength*2; i<max; i++) {
+ typeAnno.typePath[i] = dis.readUnsignedByte();
+ }
+ }
+ typeAnno.annotation = AnnotationGen.read(dis, cpool, isVisible);
+ return typeAnno;
+ }
+
+ public static int[] readLocalVarTarget(DataInputStream dis) throws IOException {
+ int tableLength = dis.readUnsignedShort();
+ int[] table = new int[tableLength*3];
+ int count = 0;
+ for (int i=0;i<tableLength;i++) {
+ table[count++]=dis.readUnsignedShort(); // start_pc
+ table[count++]=dis.readUnsignedShort(); // length
+ table[count++]=dis.readUnsignedShort(); // index
+ }
+ return table;
+ }
+
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeByte(targetType);
+ switch (targetType) {
+ case CLASS_TYPE_PARAMETER:
+ dos.writeByte(this.info); // type_parameter_index
+ break;
+ case METHOD_TYPE_PARAMETER:
+ dos.writeByte(info); // type_parameter_index
+ break;
+ case CLASS_EXTENDS:
+ dos.writeShort(info); // supertype_index
+ break;
+ case CLASS_TYPE_PARAMETER_BOUND:
+ case METHOD_TYPE_PARAMETER_BOUND:
+ dos.writeByte(info); // type_parameter_index
+ dos.writeByte(info2); // bound_index;
+ break;
+ case FIELD:
+ case METHOD_RETURN:
+ case METHOD_RECEIVER:
+ break;
+ case METHOD_FORMAL_PARAMETER:
+ dos.writeByte(info); // method_formal_parameter_index
+ break;
+ case THROWS:
+ dos.writeShort(info); // throws_type_index
+ break;
+ case LOCAL_VARIABLE:
+ case RESOURCE_VARIABLE:
+ dos.writeShort(localVarTarget.length/3);
+ for (int i=0;i<localVarTarget.length;i++) {
+ dos.writeShort(localVarTarget[i]);
+ }
+ break;
+ case EXCEPTION_PARAMETER:
+ // TODO should be a SHORT according to the spec but byte for now because of javac (b90)
+ dos.writeByte(info); // exception_table_index
+ break;
+ case INSTANCEOF:
+ case NEW:
+ case CONSTRUCTOR_REFERENCE:
+ case METHOD_REFERENCE:
+ dos.writeShort(info); // offset
+ break;
+ case CAST:
+ case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+ case METHOD_INVOCATION_TYPE_ARGUMENT:
+ case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
+ case METHOD_REFERENCE_TYPE_ARGUMENT:
+ dos.writeShort(info); // offset
+ dos.writeByte(info); // type_argument_index
+ break;
+ default:
+ throw new IllegalStateException("nyi "+targetType);
+ }
+ dos.writeByte(typePath.length);
+ for (int i=0;i<typePath.length;i++) {
+ dos.writeByte(typePath[i]);
+ }
+ annotation.dump(dos);
+ }
+
+ public int getSupertypeIndex() {
+ assert (targetType==CLASS_EXTENDS);
+ return info;
+ }
+
+ public int getOffset() {
+ assert (targetType==INSTANCEOF || targetType==NEW || targetType==CONSTRUCTOR_REFERENCE || targetType==METHOD_REFERENCE ||
+ targetType==CAST || targetType==CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT ||
+ targetType==METHOD_INVOCATION_TYPE_ARGUMENT || targetType==CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT ||
+ targetType==METHOD_REFERENCE_TYPE_ARGUMENT);
+ return info;
+ }
+
+ public int getTypeParameterIndex() {
+ assert (targetType==CLASS_TYPE_PARAMETER || targetType==METHOD_TYPE_PARAMETER ||
+ targetType==CLASS_TYPE_PARAMETER_BOUND || targetType==METHOD_TYPE_PARAMETER_BOUND);
+ return info;
+ }
+
+ public int getTypeArgumentIndex() {
+ assert (targetType==CAST || targetType==CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT ||
+ targetType==METHOD_INVOCATION_TYPE_ARGUMENT || targetType==CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT || targetType==METHOD_REFERENCE_TYPE_ARGUMENT);
+ return info2;
+ }
+
+ public int getBoundIndex() {
+ assert (targetType==CLASS_TYPE_PARAMETER_BOUND || targetType==METHOD_TYPE_PARAMETER_BOUND);
+ return info2;
+ }
+
+ public int getMethodFormalParameterIndex() {
+ assert (targetType==METHOD_FORMAL_PARAMETER);
+ return info;
+ }
+
+ public int getThrowsTypeIndex() {
+ assert (targetType==THROWS);
+ return info;
+ }
+
+ public int[] getLocalVarTarget() {
+ assert (targetType==LOCAL_VARIABLE||targetType==RESOURCE_VARIABLE);
+ return localVarTarget;
+ }
+
+ public int getExceptionTableIndex() {
+ assert (targetType==EXCEPTION_PARAMETER);
+ return info;
+ }
+
+
+
+ public int getTargetType() {
+ return targetType;
+ }
+
+ public AnnotationGen getAnnotation() {
+ return annotation;
+ }
+
+// @Override
+// public String toString() {
+// StringBuffer s = new StringBuffer();
+// s.append("AnnotationGen:[" + getTypeName() + " #" + pairs.size() + " {");
+// for (int i = 0; i < pairs.size(); i++) {
+// s.append(pairs.get(i));
+// if (i + 1 < pairs.size())
+// s.append(",");
+// }
+// s.append("}]");
+// return s.toString();
+// }
+//
+// public String toShortString() {
+// StringBuffer s = new StringBuffer();
+// s.append("@" + getTypeName() + "(");
+// for (int i = 0; i < pairs.size(); i++) {
+// s.append(pairs.get(i));
+// if (i + 1 < pairs.size())
+// s.append(",");
+// }
+// s.append(")");
+// return s.toString();
+// }
+//
+// private void isRuntimeVisible(boolean b) {
+// isRuntimeVisible = b;
+// }
+//
+// public boolean isRuntimeVisible() {
+// return isRuntimeVisible;
+// }
+//
+// /**
+// * @return true if the annotation has a value with the specified name and (toString'd) value
+// */
+// public boolean hasNameValuePair(String name, String value) {
+// for (NameValuePair pair : pairs) {
+// if (pair.getNameString().equals(name)) {
+// if (pair.getValue().stringifyValue().equals(value)) {
+// return true;
+// }
+// }
+// }
+// return false;
+// }
+//
+// /**
+// * @return true if the annotation has a value with the specified name
+// */
+// public boolean hasNamedValue(String name) {
+// for (NameValuePair pair : pairs) {
+// if (pair.getNameString().equals(name)) {
+// return true;
+// }
+// }
+// return false;
+// }
+
+// public TypeAnnotationGen(TypeAnnotationGen a, ConstantPool cpool, boolean copyPoolEntries) {
+// this.cpool = cpool;
+// if (copyPoolEntries) {
+// typeIndex = cpool.addUtf8(a.getTypeSignature());
+// } else {
+// typeIndex = a.getTypeIndex();
+// }
+// isRuntimeVisible = a.isRuntimeVisible();
+// pairs = copyValues(a.getValues(), cpool, copyPoolEntries);
+// }
+//
+// private List<NameValuePair> copyValues(List<NameValuePair> in, ConstantPool cpool, boolean copyPoolEntries) {
+// List<NameValuePair> out = new ArrayList<NameValuePair>();
+// for (NameValuePair nvp : in) {
+// out.add(new NameValuePair(nvp, cpool, copyPoolEntries));
+// }
+// return out;
+// }
+//
+//
+// /**
+// * Retrieve an immutable version of this AnnotationGen
+// */
+// public TypeAnnotationGen(ObjectType type, List<NameValuePair> pairs, boolean runtimeVisible, ConstantPool cpool) {
+// this.cpool = cpool;
+// if (type != null) {
+// this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects
+// }
+// this.pairs = pairs;
+// isRuntimeVisible = runtimeVisible;
+// }
+//
+
+ public int[] getTypePath() {
+ return typePath;
+ }
+
+ public String getTypePathString() {
+ return toTypePathString(typePath);
+ }
+
+ public static String toTypePathString(int[] typepath) {
+ StringBuilder sb = new StringBuilder();
+ int count = 0;
+ sb.append("[");
+ while (count < typepath.length) {
+ if (count>0) sb.append(",");
+ switch (typepath[count++]) {
+ case TYPE_PATH_ENTRY_KIND_ARRAY:
+ sb.append("ARRAY");
+ count++;
+ break;
+ case TYPE_PATH_ENTRY_KIND_INNER_TYPE:
+ sb.append("INNER_TYPE");
+ count++;
+ break;
+ case TYPE_PATH_ENTRY_KIND_WILDCARD:
+ sb.append("WILDCARD");
+ count++;
+ break;
+ case TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT:
+ sb.append("TYPE_ARGUMENT(").append(typepath[count++]).append(")");
+ break;
+ }
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java
new file mode 100644
index 000000000..d9599289b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ArrayType.java
@@ -0,0 +1,156 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Denotes array type, such as int[][]
+ *
+ * @version $Id: ArrayType.java,v 1.4 2008/08/26 15:02:04 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class ArrayType extends ReferenceType {
+ 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 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, "<dummy>");
+
+ 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 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;
+ else
+ 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);
+ } else
+ return false;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java
new file mode 100644
index 000000000..477fb1dff
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BasicType.java
@@ -0,0 +1,111 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Denotes basic type such as int.
+ *
+ * @version $Id: BasicType.java,v 1.4 2008/08/28 00:05:57 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+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.aspectj.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);
+ }
+ }
+
+ /**
+ * @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;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java
new file mode 100644
index 000000000..35d9528b8
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/BranchHandle.java
@@ -0,0 +1,134 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * 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().
+ *
+ * @see InstructionHandle
+ * @see Instruction
+ * @see InstructionList
+ * @version $Id: BranchHandle.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class BranchHandle extends InstructionHandle {
+ private InstructionBranch bi; // An alias in fact, but saves lots of casts
+
+ private BranchHandle(InstructionBranch i) {
+ super(i);
+ bi = i;
+ }
+
+ static final BranchHandle getBranchHandle(InstructionBranch i) {
+ return new BranchHandle(i);
+ }
+
+ /*
+ * 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.positionOfThisInstruction;
+ }
+
+ void setPosition(int pos) {
+ this.pos = bi.positionOfThisInstruction = pos;
+ }
+
+ /**
+ * 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) {
+ int x = bi.updatePosition(offset, max_offset);
+ pos = bi.positionOfThisInstruction;
+ 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);
+ bi = (InstructionBranch) i;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java
new file mode 100644
index 000000000..4ba767d97
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGen.java
@@ -0,0 +1,637 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.lang.reflect.Modifier;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.Field;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.classfile.Modifiers;
+import org.aspectj.apache.bcel.classfile.SourceFile;
+import org.aspectj.apache.bcel.classfile.Utility;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos;
+
+/**
+ * Template class for building up a java class. May be initialized with an existing java class.
+ *
+ * @see JavaClass
+ * @version $Id: ClassGen.java,v 1.15 2009/09/15 19:40:14 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ *
+ * Upgraded, Andy Clement 9th Mar 06 - calculates SUID
+ */
+public class ClassGen extends Modifiers implements Cloneable {
+
+ private String classname;
+ private String superclassname;
+ private String filename;
+ private int classnameIndex = -1;
+ private int superclassnameIndex = -1;
+ private int major = Constants.MAJOR_1_1;
+ private int minor = Constants.MINOR_1_1;
+ private ConstantPool cpool;
+ private List<Field> fieldsList = new ArrayList<Field>();
+ private List<Method> methodsList = new ArrayList<Method>();
+ private List<Attribute> attributesList = new ArrayList<Attribute>();
+ private List<String> interfaceList = new ArrayList<String>();
+ private List<AnnotationGen> annotationsList = new ArrayList<AnnotationGen>();
+
+ public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames,
+ ConstantPool cpool) {
+ this.classname = classname;
+ this.superclassname = superclassname;
+ this.filename = filename;
+ this.modifiers = modifiers;
+ this.cpool = cpool;
+ if (filename != null) {
+ addAttribute(new SourceFile(cpool.addUtf8("SourceFile"), 2, cpool.addUtf8(filename), cpool));
+ }
+ this.classnameIndex = cpool.addClass(classname);
+ this.superclassnameIndex = cpool.addClass(superclassname);
+ if (interfacenames != null) {
+ for (String interfacename : interfacenames) {
+ addInterface(interfacename);
+ }
+ }
+ }
+
+ public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames) {
+ this(classname, superclassname, filename, modifiers, interfacenames, new ConstantPool());
+ }
+
+ public ClassGen(JavaClass clazz) {
+ classnameIndex = clazz.getClassNameIndex();
+ superclassnameIndex = clazz.getSuperclassNameIndex();
+ classname = clazz.getClassName();
+ superclassname = clazz.getSuperclassName();
+ filename = clazz.getSourceFileName();
+ modifiers = clazz.getModifiers();
+ cpool = clazz.getConstantPool().copy();
+ major = clazz.getMajor();
+ minor = clazz.getMinor();
+
+ Method[] methods = clazz.getMethods();
+ Field[] fields = clazz.getFields();
+ String[] interfaces = clazz.getInterfaceNames();
+
+ for (int i = 0; i < interfaces.length; i++) {
+ addInterface(interfaces[i]);
+ }
+
+ // OPTIMIZE Could make unpacking lazy, done on first reference
+ Attribute[] attributes = clazz.getAttributes();
+ for (Attribute attr : attributes) {
+ if (attr instanceof RuntimeVisAnnos) {
+ RuntimeVisAnnos rva = (RuntimeVisAnnos) attr;
+ List<AnnotationGen> annos = rva.getAnnotations();
+ for (AnnotationGen a : annos) {
+ annotationsList.add(new AnnotationGen(a, cpool, false));
+ }
+ } else if (attr instanceof RuntimeInvisAnnos) {
+ RuntimeInvisAnnos ria = (RuntimeInvisAnnos) attr;
+ List<AnnotationGen> annos = ria.getAnnotations();
+ for (AnnotationGen anno : annos) {
+ annotationsList.add(new AnnotationGen(anno, cpool, false));
+ }
+ } else {
+ attributesList.add(attr);
+ }
+ }
+
+ for (int i = 0; i < methods.length; i++) {
+ addMethod(methods[i]);
+ }
+
+ for (int i = 0; i < fields.length; i++) {
+ addField(fields[i]);
+ }
+ }
+
+ /**
+ * @return build and return a JavaClass
+ */
+ public JavaClass getJavaClass() {
+ int[] interfaces = getInterfaces();
+ Field[] fields = getFields();
+ Method[] methods = getMethods();
+
+ Collection<Attribute> attributes = null;
+ if (annotationsList.size() == 0) {
+ attributes = attributesList;
+ } else {
+ // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations'
+ attributes = new ArrayList<Attribute>();
+ attributes.addAll(Utility.getAnnotationAttributes(cpool, annotationsList));
+ attributes.addAll(attributesList);
+ }
+
+ // Must be last since the above calls may still add something to it
+ ConstantPool cp = this.cpool.getFinalConstantPool();
+
+ return new JavaClass(classnameIndex, superclassnameIndex, filename, major, minor, modifiers, cp, interfaces, fields,
+ methods, attributes.toArray(new Attribute[attributes.size()]));// OPTIMIZE avoid toArray()?
+ }
+
+ public void addInterface(String name) {
+ interfaceList.add(name);
+ }
+
+ public void removeInterface(String name) {
+ interfaceList.remove(name);
+ }
+
+ public int getMajor() {
+ return major;
+ }
+
+ public void setMajor(int major) {
+ this.major = major;
+ }
+
+ public void setMinor(int minor) {
+ this.minor = minor;
+ }
+
+ public int getMinor() {
+ return minor;
+ }
+
+ public void addAttribute(Attribute a) {
+ attributesList.add(a);
+ }
+
+ public void addAnnotation(AnnotationGen a) {
+ annotationsList.add(a);
+ }
+
+ public void addMethod(Method m) {
+ methodsList.add(m);
+ }
+
+ /**
+ * Convenience method.
+ *
+ * Add an empty constructor to this class that does nothing but calling super().
+ *
+ * @param access rights for constructor
+ */
+ public void addEmptyConstructor(int access_flags) {
+ InstructionList il = new InstructionList();
+ il.append(InstructionConstants.THIS); // Push `this'
+ il.append(new InvokeInstruction(Constants.INVOKESPECIAL, cpool.addMethodref(superclassname, "<init>", "()V")));
+ il.append(InstructionConstants.RETURN);
+
+ MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>", classname, il, cpool);
+ mg.setMaxStack(1);
+ mg.setMaxLocals();
+ addMethod(mg.getMethod());
+ }
+
+ /**
+ * Add a field to this class.
+ *
+ * @param f field to add
+ */
+ public void addField(Field f) {
+ fieldsList.add(f);
+ }
+
+ public boolean containsField(Field f) {
+ return fieldsList.contains(f);
+ }
+
+ /**
+ * @return field object with given name, or null if not found
+ */
+ public Field findsField(String name) {
+ for (Field field : fieldsList) {
+ if (field.getName().equals(name)) {
+ return field;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return method object with given name and signature, or null if not found
+ */
+ public Method containsMethod(String name, String signature) {
+ for (Method method : methodsList) {
+ if (method.getName().equals(name) && method.getSignature().equals(signature)) {
+ return method;
+ }
+ }
+ return null;
+ }
+
+ public void removeAttribute(Attribute a) {
+ attributesList.remove(a);
+ }
+
+ public void removeAnnotation(AnnotationGen a) {
+ annotationsList.remove(a);
+ }
+
+ public void removeMethod(Method m) {
+ methodsList.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 = methodsList.indexOf(old);
+
+ if (i < 0)
+ methodsList.add(new_);
+ else
+ methodsList.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 = fieldsList.indexOf(old);
+
+ if (i < 0)
+ fieldsList.add(new_);
+ else
+ fieldsList.set(i, new_);
+ }
+
+ public void removeField(Field f) {
+ fieldsList.remove(f);
+ }
+
+ public String getClassName() {
+ return classname;
+ }
+
+ public String getSuperclassName() {
+ return superclassname;
+ }
+
+ public String getFileName() {
+ return filename;
+ }
+
+ public void setClassName(String name) {
+ classname = name.replace('/', '.');
+ classnameIndex = cpool.addClass(name);
+ }
+
+ public void setSuperclassName(String name) {
+ superclassname = name.replace('/', '.');
+ superclassnameIndex = cpool.addClass(name);
+ }
+
+ public Method[] getMethods() {
+ Method[] methods = new Method[methodsList.size()];
+ methodsList.toArray(methods);
+ return methods;
+ }
+
+ public void setMethods(Method[] methods) {
+ methodsList.clear();
+ for (int m = 0; m < methods.length; m++)
+ addMethod(methods[m]);
+ }
+
+ public void setFields(Field[] fs) {
+ fieldsList.clear();
+ for (int m = 0; m < fs.length; m++)
+ addField(fs[m]);
+ }
+
+ public void setMethodAt(Method method, int pos) {
+ methodsList.set(pos, method);
+ }
+
+ public Method getMethodAt(int pos) {
+ return methodsList.get(pos);
+ }
+
+ public String[] getInterfaceNames() {
+ int size = interfaceList.size();
+ String[] interfaces = new String[size];
+
+ interfaceList.toArray(interfaces);
+ return interfaces;
+ }
+
+ public int[] getInterfaces() {
+ int size = interfaceList.size();
+ int[] interfaces = new int[size];
+
+ for (int i = 0; i < size; i++)
+ interfaces[i] = cpool.addClass(interfaceList.get(i));
+
+ return interfaces;
+ }
+
+ public Field[] getFields() {
+ Field[] fields = new Field[fieldsList.size()];
+ fieldsList.toArray(fields);
+ return fields;
+ }
+
+ public Collection<Attribute> getAttributes() {
+ return attributesList;
+ }
+
+ // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here?
+ public AnnotationGen[] getAnnotations() {
+ AnnotationGen[] annotations = new AnnotationGen[annotationsList.size()];
+ annotationsList.toArray(annotations);
+ return annotations;
+ }
+
+ public ConstantPool getConstantPool() {
+ return cpool;
+ }
+
+ public void setConstantPool(ConstantPool constant_pool) {
+ cpool = constant_pool;
+ }
+
+ public void setClassNameIndex(int class_name_index) {
+ this.classnameIndex = class_name_index;
+ classname = cpool.getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
+ }
+
+ public void setSuperclassNameIndex(int superclass_name_index) {
+ this.superclassnameIndex = superclass_name_index;
+ superclassname = cpool.getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
+ }
+
+ public int getSuperclassNameIndex() {
+ return superclassnameIndex;
+ }
+
+ public int getClassNameIndex() {
+ return classnameIndex;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ System.err.println(e);
+ return null;
+ }
+ }
+
+ public final boolean isAnnotation() {
+ return (modifiers & Constants.ACC_ANNOTATION) != 0;
+ }
+
+ public final boolean isEnum() {
+ return (modifiers & Constants.ACC_ENUM) != 0;
+ }
+
+ /**
+ * Calculate the SerialVersionUID for a class.
+ */
+ public long getSUID() {
+ try {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(baos);
+
+ // 1. classname
+ dos.writeUTF(getClassName());
+
+ // 2. classmodifiers: ACC_PUBLIC, ACC_FINAL, ACC_INTERFACE, and ACC_ABSTRACT
+ int classmods = 0;
+ classmods |= (isPublic() ? Constants.ACC_PUBLIC : 0);
+ classmods |= (isFinal() ? Constants.ACC_FINAL : 0);
+ classmods |= (isInterface() ? Constants.ACC_INTERFACE : 0);
+
+ if (isAbstract()) {
+ // if an interface then abstract is only set if it has methods
+ if (isInterface()) {
+ if (methodsList.size() > 0)
+ classmods |= Constants.ACC_ABSTRACT;
+ } else {
+ classmods |= Constants.ACC_ABSTRACT;
+ }
+ }
+
+ dos.writeInt(classmods);
+
+ // 3. ordered list of interfaces
+ String[] names = getInterfaceNames();
+ if (names != null) {
+ Arrays.sort(names);
+ for (int i = 0; i < names.length; i++)
+ dos.writeUTF(names[i]);
+ }
+
+ // 4. ordered list of fields (ignoring private static and private transient fields):
+ // (relevant modifiers are ACC_PUBLIC, ACC_PRIVATE,
+ // ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE,
+ // ACC_TRANSIENT)
+ List<Field> relevantFields = new ArrayList<Field>();
+ for (Field field : fieldsList) {
+ if (!(field.isPrivate() && field.isStatic()) && !(field.isPrivate() && field.isTransient())) {
+ relevantFields.add(field);
+ }
+ }
+ Collections.sort(relevantFields, new FieldComparator());
+ int relevantFlags = Constants.ACC_PUBLIC | Constants.ACC_PRIVATE | Constants.ACC_PROTECTED | Constants.ACC_STATIC
+ | Constants.ACC_FINAL | Constants.ACC_VOLATILE | Constants.ACC_TRANSIENT;
+ for (Field f : relevantFields) {
+ dos.writeUTF(f.getName());
+ dos.writeInt(relevantFlags & f.getModifiers());
+ dos.writeUTF(f.getType().getSignature());
+ }
+
+ // some up front method processing: discover clinit, init and ordinary methods of interest:
+ List<Method> relevantMethods = new ArrayList<Method>();
+ List<Method> relevantCtors = new ArrayList<Method>();
+ boolean hasClinit = false;
+ for (Method m : methodsList) {
+ boolean couldBeInitializer = m.getName().charAt(0) == '<';
+ if (couldBeInitializer && m.getName().equals("<clinit>")) {
+ hasClinit = true;
+ } else if (couldBeInitializer && m.getName().equals("<init>")) {
+ if (!m.isPrivate())
+ relevantCtors.add(m);
+ } else {
+ if (!m.isPrivate())
+ relevantMethods.add(m);
+ }
+ }
+ Collections.sort(relevantCtors, new ConstructorComparator());
+ Collections.sort(relevantMethods, new MethodComparator());
+
+ // 5. If a class initializer exists, write out the following:
+ // 1. The name of the method, <clinit>.
+ // 2. The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
+ // 3. The descriptor of the method, ()V.
+ if (hasClinit) {
+ dos.writeUTF("<clinit>");
+ dos.writeInt(Modifier.STATIC);
+ dos.writeUTF("()V");
+ }
+
+ // for methods and constructors:
+ // ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED,
+ // ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT
+ relevantFlags = Constants.ACC_PUBLIC | Constants.ACC_PRIVATE | Constants.ACC_PROTECTED | Constants.ACC_STATIC
+ | Constants.ACC_FINAL | Constants.ACC_SYNCHRONIZED | Constants.ACC_NATIVE | Constants.ACC_ABSTRACT
+ | Constants.ACC_STRICT;
+
+ // 6. sorted non-private constructors
+ for (Method ctor : relevantCtors) {
+ dos.writeUTF(ctor.getName()); // <init>
+ dos.writeInt(relevantFlags & ctor.getModifiers());
+ dos.writeUTF(ctor.getSignature().replace('/', '.'));
+ }
+
+ // 7. sorted non-private methods
+ for (Method m : relevantMethods) {
+ dos.writeUTF(m.getName());
+ dos.writeInt(relevantFlags & m.getModifiers());
+ dos.writeUTF(m.getSignature().replace('/', '.'));
+ }
+ dos.flush();
+ dos.close();
+ byte[] bs = baos.toByteArray();
+ MessageDigest md = MessageDigest.getInstance("SHA");
+ byte[] result = md.digest(bs);
+
+ long suid = 0L;
+ int pos = result.length > 8 ? 7 : result.length - 1; // use the bytes we have
+ while (pos >= 0) {
+ suid = suid << 8 | ((long) result[pos--] & 0xff);
+ }
+
+ // if it was definetly 8 everytime...
+ // long suid = ((long)(sha[0]&0xff) | (long)(sha[1]&0xff) << 8 |
+ // (long)(sha[2]&0xff) << 16 | (long)(sha[3]&0xff) << 24 |
+ // (long)(sha[4]&0xff) << 32 | (long)(sha[5]&0xff) << 40 |
+ // (long)(sha[6]&0xff) << 48 | (long)(sha[7]&0xff) << 56);
+ return suid;
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("Unable to calculate suid for " + getClassName() + ": " + e.toString());
+ }
+ }
+
+ private static class FieldComparator implements Comparator<Field> {
+ public int compare(Field f0, Field f1) {
+ return f0.getName().compareTo(f1.getName());
+ }
+ }
+
+ private static class ConstructorComparator implements Comparator<Method> {
+ public int compare(Method m0, Method m1) {
+ // can ignore the name...
+ return (m0).getSignature().compareTo(m1.getSignature());
+ }
+ }
+
+ private static class MethodComparator implements Comparator<Method> {
+ public int compare(Method m0, Method m1) {
+ int result = m0.getName().compareTo(m1.getName());
+ if (result == 0) {
+ result = m0.getSignature().compareTo(m1.getSignature());
+ }
+ return result;
+ }
+ }
+
+ public boolean hasAttribute(String attributeName) {
+ for (Attribute attr : attributesList) {
+ if (attr.getName().equals(attributeName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Attribute getAttribute(String attributeName) {
+ for (Attribute attr : attributesList) {
+ if (attr.getName().equals(attributeName)) {
+ return attr;
+ }
+ }
+ return null;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java
new file mode 100644
index 000000000..b981dc8dc
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ClassGenException.java
@@ -0,0 +1,68 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared
+ * in the throws clause every time.
+ *
+ * @version $Id: ClassGenException.java,v 1.3 2008/05/28 23:52:57 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class ClassGenException extends RuntimeException {
+ public ClassGenException() { super(); }
+ public ClassGenException(String s) { super(s); }
+}
+
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java
new file mode 100644
index 000000000..01b839207
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/CodeExceptionGen.java
@@ -0,0 +1,202 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.apache.bcel.classfile.CodeException;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * 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,v 1.5 2008/05/28 23:52:56 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see MethodGen
+ * @see CodeException
+ * @see InstructionHandle
+ */
+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;
+
+ /**
+ * 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.<BR>
+ *
+ * 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(ConstantPool 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) {
+ InstructionBranch.notifyTarget(this.start_pc, start_pc, this);
+ this.start_pc = start_pc;
+ }
+
+ /* Set end of handler
+ * @param end_pc End of handled region (inclusive)
+ */
+ public void setEndPC(InstructionHandle end_pc) {
+ InstructionBranch.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) {
+ InstructionBranch.notifyTarget(this.handler_pc, handler_pc, this);
+ this.handler_pc = handler_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 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;
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java
new file mode 100644
index 000000000..6a12a8c80
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGen.java
@@ -0,0 +1,245 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.Constant;
+import org.aspectj.apache.bcel.classfile.ConstantDouble;
+import org.aspectj.apache.bcel.classfile.ConstantFloat;
+import org.aspectj.apache.bcel.classfile.ConstantInteger;
+import org.aspectj.apache.bcel.classfile.ConstantLong;
+import org.aspectj.apache.bcel.classfile.ConstantObject;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantString;
+import org.aspectj.apache.bcel.classfile.ConstantValue;
+import org.aspectj.apache.bcel.classfile.Field;
+import org.aspectj.apache.bcel.classfile.Utility;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos;
+
+/**
+ * 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 the declared type).
+ *
+ * @version $Id: FieldGen.java,v 1.11 2011/10/03 22:41:24 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Field
+ */
+public class FieldGen extends FieldGenOrMethodGen {
+ private Object value = null;
+
+ /**
+ * 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 modifiers access qualifiers
+ * @param type field type
+ * @param name field name
+ * @param cpool constant pool
+ */
+ public FieldGen(int modifiers, Type type, String name, ConstantPool cpool) {
+ setModifiers(modifiers);
+ setType(type);
+ setName(name);
+ setConstantPool(cpool);
+ }
+
+ /**
+ * 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, ConstantPool cp) {
+ this(field.getModifiers(), 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 if (attrs[i] instanceof RuntimeAnnos) {
+ RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) attrs[i];
+ List<AnnotationGen> l = runtimeAnnotations.getAnnotations();
+ for (Iterator<AnnotationGen> it = l.iterator(); it.hasNext();) {
+ AnnotationGen element = it.next();
+ addAnnotation(new AnnotationGen(element, cp, false));
+ }
+ } else {
+ addAttribute(attrs[i]);
+ }
+ }
+ }
+
+ public void setValue(int index) {
+ ConstantPool cp = this.cp;
+ Constant c = cp.getConstant(index);
+ if (c instanceof ConstantInteger) {
+ value = ((ConstantInteger) c).getIntValue();
+ } else if (c instanceof ConstantFloat) {
+ value = ((ConstantFloat) c).getValue();
+ } else if (c instanceof ConstantDouble) {
+ value = ((ConstantDouble) c).getValue();
+ } else if (c instanceof ConstantLong) {
+ value = ((ConstantLong) c).getValue();
+ } else if (c instanceof ConstantString) {
+ value = ((ConstantString)c).getString(cp);
+ } else {
+ value = ((ConstantObject) c).getConstantValue(cp);
+ }
+ }
+
+ public void setValue(String constantString) {
+ value = constantString;
+ }
+
+ public void wipeValue() {
+ 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);
+ }
+
+ /**
+ * Get field object after having set up all necessary values.
+ */
+ public Field getField() {
+ String signature = getSignature();
+ int nameIndex = cp.addUtf8(name);
+ int signatureIndex = cp.addUtf8(signature);
+
+ if (value != null) {
+ checkType(type);
+ int index = addConstant();
+ addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, index, cp));
+ }
+
+ addAnnotationsAsAttribute(cp);
+
+ return new Field(modifiers, nameIndex, signatureIndex, getAttributesImmutable(), cp);
+ }
+
+ 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());
+ }
+ }
+
+ @Override
+ public String getSignature() {
+ return type.getSignature();
+ }
+
+ public String getInitialValue() {
+ return (value == null ? null : value.toString());
+ }
+
+ public void setInitialStringValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Return string representation close to declaration format, `public static final short MAX = 100', e.g..
+ */
+ @Override
+ public final String toString() {
+ String access = Utility.accessToString(modifiers);
+ access = access.equals("") ? "" : (access + " ");
+ String signature = type.toString();
+ String name = getName();
+
+ StringBuffer buf = new StringBuffer(access).append(signature).append(" ").append(name);
+ String value = getInitialValue();
+
+ if (value != null) {
+ buf.append(" = ").append(value);
+ }
+ // TODO: Add attributes and annotations to the string
+ return buf.toString();
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java
new file mode 100644
index 000000000..ff8b6f42c
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldGenOrMethodGen.java
@@ -0,0 +1,158 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.Modifiers;
+import org.aspectj.apache.bcel.classfile.Utility;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos;
+
+/**
+ * Super class for FieldGen and MethodGen objects, since they have some methods in common!
+ *
+ * @version $Id: FieldGenOrMethodGen.java,v 1.8 2009/09/15 19:40:14 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public abstract class FieldGenOrMethodGen extends Modifiers {
+
+ protected String name;
+ protected Type type;
+ protected ConstantPool cp;
+ private ArrayList<Attribute> attributeList = new ArrayList<Attribute>();
+ protected ArrayList<AnnotationGen> annotationList = new ArrayList<AnnotationGen>();
+
+ protected FieldGenOrMethodGen() {
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public ConstantPool getConstantPool() {
+ return cp;
+ }
+
+ public void setConstantPool(ConstantPool cp) {
+ this.cp = cp;
+ }
+
+ public void addAttribute(Attribute a) {
+ attributeList.add(a);
+ }
+
+ public void removeAttribute(Attribute a) {
+ attributeList.remove(a);
+ }
+
+ public void removeAttributes() {
+ attributeList.clear();
+ }
+
+ public List<AnnotationGen> getAnnotations() {
+ return annotationList;
+ }
+
+ public void addAnnotation(AnnotationGen ag) {
+ annotationList.add(ag);
+ }
+
+ public void removeAnnotation(AnnotationGen ag) {
+ annotationList.remove(ag);
+ }
+
+ public void removeAnnotations() {
+ annotationList.clear();
+ }
+
+ public List<Attribute> getAttributes() {
+ return attributeList;
+ }
+
+ public Attribute[] getAttributesImmutable() {
+ Attribute[] attributes = new Attribute[attributeList.size()];
+ attributeList.toArray(attributes);
+ return attributes;
+ }
+
+ protected void addAnnotationsAsAttribute(ConstantPool cp) {
+ Collection<RuntimeAnnos> attrs = Utility.getAnnotationAttributes(cp, annotationList);
+ if (attrs != null) {
+ for (Attribute attr : attrs) {
+ addAttribute(attr);
+ }
+ }
+ }
+
+ public abstract String getSignature();
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java
new file mode 100644
index 000000000..54983e7c9
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldInstruction.java
@@ -0,0 +1,112 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * Super class for the GET/PUTxxx family of instructions.
+ *
+ * @version $Id: FieldInstruction.java,v 1.7 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class FieldInstruction extends FieldOrMethod {
+
+ public FieldInstruction(short opcode, int index) {
+ super(opcode, index);
+ }
+
+ public String toString(ConstantPool cp) {
+ return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " "
+ + cp.constantToString(index, org.aspectj.apache.bcel.Constants.CONSTANT_Fieldref);
+ }
+
+ /**
+ * @return size of field (1 or 2)
+ */
+ protected int getFieldSize(ConstantPool cpg) {
+ return Type.getTypeSize(getSignature(cpg));
+ }
+
+ public Type getType(ConstantPool cpg) {
+ return getFieldType(cpg);
+ }
+
+ public Type getFieldType(ConstantPool cpg) {
+ return Type.getType(getSignature(cpg));
+ }
+
+ public String getFieldName(ConstantPool cpg) {
+ return getName(cpg);
+ }
+
+ public int produceStack(ConstantPool cpg) {
+ if (!isStackProducer()) {
+ return 0;
+ }
+
+ return getFieldSize(cpg); // SAME FOR GETFIELD/GETSTATIC
+ }
+
+ public int consumeStack(ConstantPool cpg) {
+ if (!isStackConsumer()) {
+ return 0;
+ }
+ if (opcode == GETFIELD) {
+ return 1;
+ }
+ return getFieldSize(cpg) + (opcode == PUTFIELD ? 1 : 0);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java
new file mode 100644
index 000000000..44b263ffb
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/FieldOrMethod.java
@@ -0,0 +1,133 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import org.aspectj.apache.bcel.classfile.Constant;
+import org.aspectj.apache.bcel.classfile.ConstantCP;
+import org.aspectj.apache.bcel.classfile.ConstantNameAndType;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+
+/**
+ * Super class for InvokeInstruction and FieldInstruction, since they have some methods in common!
+ *
+ * @version $Id: FieldOrMethod.java,v 1.8 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public abstract class FieldOrMethod extends InstructionCP {
+
+ protected String signature;
+ protected String name;
+ private String classname;
+
+ protected FieldOrMethod(short opcode, int index) {
+ super(opcode, index);
+ }
+
+ /**
+ * @return signature of referenced method/field.
+ */
+ public String getSignature(ConstantPool cp) {
+ if (signature == null) {
+ Constant c = cp.getConstant(index);
+ ConstantCP cmr = (ConstantCP) c;
+ ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
+ signature = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getValue();
+ }
+ return signature;
+ }
+
+ /**
+ * @return name of referenced method/field.
+ */
+ public String getName(ConstantPool cp) {
+ if (name == null) {
+ ConstantCP cmr = (ConstantCP) cp.getConstant(index);
+ ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
+ name = ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getValue();
+ }
+ return name;
+ }
+
+ /**
+ * @return name of the referenced class/interface
+ */
+ public String getClassName(ConstantPool cp) {
+ if (classname == null) {
+ ConstantCP cmr = (ConstantCP) cp.getConstant(index);
+ String str = cp.getConstantString(cmr.getClassIndex(), CONSTANT_Class);
+ if (str.charAt(0) == '[') {
+ classname = str;
+ } else {
+ classname = str.replace('/', '.');
+ }
+ }
+ return classname;
+ }
+
+ /**
+ * @return type of the referenced class/interface
+ */
+ public ObjectType getClassType(ConstantPool cpg) {
+ return new ObjectType(getClassName(cpg));
+ }
+
+ /**
+ * @return type of the referenced class/interface
+ */
+ @Override
+ public ObjectType getLoadClassType(ConstantPool cpg) {
+ return getClassType(cpg);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java
new file mode 100644
index 000000000..d70e20308
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/IINC.java
@@ -0,0 +1,121 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * IINC - Increment local variable by constant
+ *
+ * @version $Id: IINC.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class IINC extends InstructionLV {
+ private int c;
+
+ public IINC(int n, int c, boolean w) {
+ super(Constants.IINC, n);
+ this.c = c;
+ // this.wide = w;//((n > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE));
+ }
+
+ private boolean wide() {
+ return ((lvar > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE));
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ if (wide()) {
+ out.writeByte(WIDE);
+ out.writeByte(opcode);
+ out.writeShort(lvar);
+ out.writeShort(c);
+ } else {
+ out.writeByte(opcode);
+ out.writeByte(lvar);
+ out.writeByte(c);
+ }
+ }
+
+ public int getLength() {
+ if (wide()) {
+ return 6;
+ } else {
+ return 3; // includes wide byte
+ }
+ }
+
+ public String toString(boolean verbose) {
+ return super.toString(verbose) + " " + c;
+ }
+
+ public final int getIncrement() {
+ return c;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof IINC)) {
+ return false;
+ }
+ IINC o = (IINC) other;
+ return /* o.opcode == opcode && */o.lvar == lvar && o.c == c;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + lvar * (c + 17);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java
new file mode 100644
index 000000000..b545f4d37
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java
@@ -0,0 +1,127 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * INVOKEINTERFACE - Invoke interface method
+ *
+ * <PRE>
+ * Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...
+ * </PRE>
+ *
+ * @version $Id: INVOKEINTERFACE.java,v 1.4 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class INVOKEINTERFACE extends InvokeInstruction {
+ private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2
+
+ public INVOKEINTERFACE(int index, int nargs, int zerobyte) {
+ super(Constants.INVOKEINTERFACE, index);
+
+ 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
+ */
+ public void dump(DataOutputStream out) throws IOException {
+ out.writeByte(opcode);
+ out.writeShort(index);
+ out.writeByte(nargs);
+ out.writeByte(0);
+ }
+
+ /**
+ * The <B>count</B> argument according to the Java Language Specification, Second Edition.
+ */
+ public int getCount() {
+ return nargs;
+ }
+
+ /**
+ * @return mnemonic for instruction with symbolic references resolved
+ */
+ public String toString(ConstantPool cp) {
+ return super.toString(cp) + " " + nargs;
+ }
+
+ public int consumeStack(ConstantPool cpg) { // nargs is given in byte-code
+ return nargs; // nargs includes this reference
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof INVOKEINTERFACE)) {
+ return false;
+ }
+ INVOKEINTERFACE o = (INVOKEINTERFACE) other;
+ return o.opcode == opcode && o.index == index && o.nargs == nargs;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + index * (nargs + 17);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java
new file mode 100644
index 000000000..424ff4a66
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstVisitor.java
@@ -0,0 +1,247 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * 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: InstVisitor.java,v 1.2 2008/05/28 23:52:59 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public interface InstVisitor {
+ public void visitStackInstruction(Instruction obj);
+ public void visitLocalVariableInstruction(InstructionLV obj);
+ public void visitBranchInstruction(InstructionBranch obj);
+ public void visitLoadClass(Instruction obj);
+ public void visitFieldInstruction(Instruction obj);
+ public void visitIfInstruction(Instruction obj);
+ public void visitConversionInstruction(Instruction obj);
+ public void visitPopInstruction(Instruction obj);
+ public void visitStoreInstruction(Instruction obj);
+ public void visitTypedInstruction(Instruction obj);
+ public void visitSelect(InstructionSelect obj);
+ public void visitJsrInstruction(InstructionBranch obj);
+ public void visitGotoInstruction(Instruction obj);
+ public void visitUnconditionalBranch(Instruction obj);
+ public void visitPushInstruction(Instruction obj);
+ public void visitArithmeticInstruction(Instruction obj);
+ public void visitCPInstruction(Instruction obj);
+ public void visitInvokeInstruction(InvokeInstruction obj);
+ public void visitArrayInstruction(Instruction obj);
+ public void visitAllocationInstruction(Instruction obj);
+ public void visitReturnInstruction(Instruction obj);
+ public void visitFieldOrMethod(Instruction obj);
+ public void visitConstantPushInstruction(Instruction obj);
+ public void visitExceptionThrower(Instruction obj);
+ public void visitLoadInstruction(Instruction obj);
+ public void visitVariableLengthInstruction(Instruction obj);
+ public void visitStackProducer(Instruction obj);
+ public void visitStackConsumer(Instruction obj);
+ public void visitACONST_NULL(Instruction obj);
+ public void visitGETSTATIC(FieldInstruction obj);
+ public void visitIF_ICMPLT(Instruction obj);
+ public void visitMONITOREXIT(Instruction obj);
+ public void visitIFLT(Instruction obj);
+ public void visitLSTORE(Instruction obj);
+ public void visitPOP2(Instruction obj);
+ public void visitBASTORE(Instruction obj);
+ public void visitISTORE(Instruction obj);
+ public void visitCHECKCAST(Instruction obj);
+ public void visitFCMPG(Instruction obj);
+ public void visitI2F(Instruction obj);
+ public void visitATHROW(Instruction obj);
+ public void visitDCMPL(Instruction obj);
+ public void visitARRAYLENGTH(Instruction obj);
+ public void visitDUP(Instruction obj);
+ public void visitINVOKESTATIC(InvokeInstruction obj);
+ public void visitLCONST(Instruction obj);
+ public void visitDREM(Instruction obj);
+ public void visitIFGE(Instruction obj);
+ public void visitCALOAD(Instruction obj);
+ public void visitLASTORE(Instruction obj);
+ public void visitI2D(Instruction obj);
+ public void visitDADD(Instruction obj);
+ public void visitINVOKESPECIAL(InvokeInstruction obj);
+ public void visitIAND(Instruction obj);
+ public void visitPUTFIELD(FieldInstruction obj);
+ public void visitILOAD(Instruction obj);
+ public void visitDLOAD(Instruction obj);
+ public void visitDCONST(Instruction obj);
+ public void visitNEW(Instruction obj);
+ public void visitIFNULL(Instruction obj);
+ public void visitLSUB(Instruction obj);
+ public void visitL2I(Instruction obj);
+ public void visitISHR(Instruction obj);
+ public void visitTABLESWITCH(TABLESWITCH obj);
+ public void visitIINC(IINC obj);
+ public void visitDRETURN(Instruction obj);
+ public void visitFSTORE(Instruction obj);
+ public void visitDASTORE(Instruction obj);
+ public void visitIALOAD(Instruction obj);
+ public void visitDDIV(Instruction obj);
+ public void visitIF_ICMPGE(Instruction obj);
+ public void visitLAND(Instruction obj);
+ public void visitIDIV(Instruction obj);
+ public void visitLOR(Instruction obj);
+ public void visitCASTORE(Instruction obj);
+ public void visitFREM(Instruction obj);
+ public void visitLDC(Instruction obj);
+ public void visitBIPUSH(Instruction obj);
+ public void visitDSTORE(Instruction obj);
+ public void visitF2L(Instruction obj);
+ public void visitFMUL(Instruction obj);
+ public void visitLLOAD(Instruction obj);
+ public void visitJSR(InstructionBranch obj);
+ public void visitFSUB(Instruction obj);
+ public void visitSASTORE(Instruction obj);
+ public void visitALOAD(Instruction obj);
+ public void visitDUP2_X2(Instruction obj);
+ public void visitRETURN(Instruction obj);
+ public void visitDALOAD(Instruction obj);
+ public void visitSIPUSH(Instruction obj);
+ public void visitDSUB(Instruction obj);
+ public void visitL2F(Instruction obj);
+ public void visitIF_ICMPGT(Instruction obj);
+ public void visitF2D(Instruction obj);
+ public void visitI2L(Instruction obj);
+ public void visitIF_ACMPNE(Instruction obj);
+ public void visitPOP(Instruction obj);
+ public void visitI2S(Instruction obj);
+ public void visitIFEQ(Instruction obj);
+ public void visitSWAP(Instruction obj);
+ public void visitIOR(Instruction obj);
+ public void visitIREM(Instruction obj);
+ public void visitIASTORE(Instruction obj);
+ public void visitNEWARRAY(Instruction obj);
+ public void visitINVOKEINTERFACE(INVOKEINTERFACE obj);
+ public void visitINEG(Instruction obj);
+ public void visitLCMP(Instruction obj);
+ public void visitJSR_W(InstructionBranch obj);
+ public void visitMULTIANEWARRAY(MULTIANEWARRAY obj);
+ public void visitDUP_X2(Instruction obj);
+ public void visitSALOAD(Instruction obj);
+ public void visitIFNONNULL(Instruction obj);
+ public void visitDMUL(Instruction obj);
+ public void visitIFNE(Instruction obj);
+ public void visitIF_ICMPLE(Instruction obj);
+ public void visitLDC2_W(Instruction obj);
+ public void visitGETFIELD(FieldInstruction obj);
+ public void visitLADD(Instruction obj);
+ public void visitNOP(Instruction obj);
+ public void visitFALOAD(Instruction obj);
+ public void visitINSTANCEOF(Instruction obj);
+ public void visitIFLE(Instruction obj);
+ public void visitLXOR(Instruction obj);
+ public void visitLRETURN(Instruction obj);
+ public void visitFCONST(Instruction obj);
+ public void visitIUSHR(Instruction obj);
+ public void visitBALOAD(Instruction obj);
+ public void visitDUP2(Instruction obj);
+ public void visitIF_ACMPEQ(Instruction obj);
+ public void visitIMPDEP1(Instruction obj);
+ public void visitMONITORENTER(Instruction obj);
+ public void visitLSHL(Instruction obj);
+ public void visitDCMPG(Instruction obj);
+ public void visitD2L(Instruction obj);
+ public void visitIMPDEP2(Instruction obj);
+ public void visitL2D(Instruction obj);
+ public void visitRET(RET obj);
+ public void visitIFGT(Instruction obj);
+ public void visitIXOR(Instruction obj);
+ public void visitINVOKEVIRTUAL(InvokeInstruction obj);
+ public void visitFASTORE(Instruction obj);
+ public void visitIRETURN(Instruction obj);
+ public void visitIF_ICMPNE(Instruction obj);
+ public void visitFLOAD(Instruction obj);
+ public void visitLDIV(Instruction obj);
+ public void visitPUTSTATIC(FieldInstruction obj);
+ public void visitAALOAD(Instruction obj);
+ public void visitD2I(Instruction obj);
+ public void visitIF_ICMPEQ(Instruction obj);
+ public void visitAASTORE(Instruction obj);
+ public void visitARETURN(Instruction obj);
+ public void visitDUP2_X1(Instruction obj);
+ public void visitFNEG(Instruction obj);
+ public void visitGOTO_W(Instruction obj);
+ public void visitD2F(Instruction obj);
+ public void visitGOTO(Instruction obj);
+ public void visitISUB(Instruction obj);
+ public void visitF2I(Instruction obj);
+ public void visitDNEG(Instruction obj);
+ public void visitICONST(Instruction obj);
+ public void visitFDIV(Instruction obj);
+ public void visitI2B(Instruction obj);
+ public void visitLNEG(Instruction obj);
+ public void visitLREM(Instruction obj);
+ public void visitIMUL(Instruction obj);
+ public void visitIADD(Instruction obj);
+ public void visitLSHR(Instruction obj);
+ public void visitLOOKUPSWITCH(LOOKUPSWITCH obj);
+ public void visitDUP_X1(Instruction obj);
+ public void visitFCMPL(Instruction obj);
+ public void visitI2C(Instruction obj);
+ public void visitLMUL(Instruction obj);
+ public void visitLUSHR(Instruction obj);
+ public void visitISHL(Instruction obj);
+ public void visitLALOAD(Instruction obj);
+ public void visitASTORE(Instruction obj);
+ public void visitANEWARRAY(Instruction obj);
+ public void visitFRETURN(Instruction obj);
+ public void visitFADD(Instruction obj);
+ public void visitBREAKPOINT(Instruction obj);
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java
new file mode 100644
index 000000000..113be06ee
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Instruction.java
@@ -0,0 +1,454 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.util.ByteSequence;
+
+/**
+ * Abstract super class for all Java byte codes.
+ *
+ * @version $Id: Instruction.java,v 1.10 2011/04/05 15:15:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class Instruction implements Cloneable, Serializable, Constants {
+ public short opcode = -1;
+
+ public Instruction(short opcode) {
+ this.opcode = opcode;
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ out.writeByte(opcode);
+ }
+
+ 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.
+ *
+ * @return (shallow) copy of an instruction
+ */
+ // GET RID OF THIS - make it throw an exception and track the callers
+ final public Instruction copy() {
+ // if overridden correctly can just return 'this' here
+ if (InstructionConstants.INSTRUCTIONS[opcode] != null) { // immutable instructions do not need copying
+ return this;
+ } else {
+ Instruction i = null;
+ try {// OPTIMIZE is clone the right thing to do here? it is horrible
+ i = (Instruction) clone();
+ } catch (CloneNotSupportedException e) {
+ System.err.println(e);
+ }
+ return i;
+ }
+ }
+
+ /**
+ * Read an instruction bytecode from an input stream and return the appropriate object.
+ *
+ * @param file file to read from
+ * @return instruction object being read
+ */
+ public static final Instruction readInstruction(ByteSequence bytes) throws IOException {
+ boolean wide = false;
+ short opcode = (short) bytes.readUnsignedByte();
+
+ if (opcode == Constants.WIDE) {
+ wide = true;
+ opcode = (short) bytes.readUnsignedByte();
+ }
+
+ Instruction constantInstruction = InstructionConstants.INSTRUCTIONS[opcode];
+
+ if (constantInstruction != null) {
+ return constantInstruction;
+ }
+
+ Instruction obj = null;
+ try {
+ switch (opcode) {
+ case Constants.BIPUSH:
+ obj = new InstructionByte(Constants.BIPUSH, bytes.readByte());
+ break;
+ case Constants.SIPUSH:
+ obj = new InstructionShort(Constants.SIPUSH, bytes.readShort());
+ break;
+ case Constants.LDC:
+ obj = new InstructionCP(Constants.LDC, bytes.readUnsignedByte());
+ break;
+ case Constants.LDC_W:
+ case Constants.LDC2_W:
+ obj = new InstructionCP(opcode, bytes.readUnsignedShort());
+ break;
+ case Constants.ILOAD:
+ case Constants.LLOAD:
+ case Constants.FLOAD:
+ case Constants.DLOAD:
+ case Constants.ALOAD:
+ case Constants.ISTORE:
+ case Constants.LSTORE:
+ case Constants.FSTORE:
+ case Constants.DSTORE:
+ case Constants.ASTORE:
+ obj = new InstructionLV(opcode, wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte());
+ break;
+ case Constants.IINC:
+ obj = new IINC(wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte(), wide ? bytes.readShort()
+ : bytes.readByte(), wide);
+ break;
+ case Constants.IFNULL:
+ case Constants.IFNONNULL:
+ case Constants.IFEQ:
+ case Constants.IFNE:
+ case Constants.IFLT:
+ case Constants.IFGE:
+ case Constants.IFGT:
+ case Constants.IFLE:
+ case Constants.IF_ICMPEQ:
+ case Constants.IF_ICMPNE:
+ case Constants.IF_ICMPLT:
+ case Constants.IF_ICMPGE:
+ case Constants.IF_ICMPGT:
+ case Constants.IF_ICMPLE:
+ case Constants.IF_ACMPEQ:
+ case Constants.IF_ACMPNE:
+ case Constants.GOTO:
+ case Constants.JSR:
+ obj = new InstructionBranch(opcode, bytes.readShort());
+ break;
+ case Constants.GOTO_W:
+ case Constants.JSR_W:
+ obj = new InstructionBranch(opcode, bytes.readInt());
+ break;
+ case Constants.TABLESWITCH:
+ obj = new TABLESWITCH(bytes);
+ break;
+ case Constants.LOOKUPSWITCH:
+ obj = new LOOKUPSWITCH(bytes);
+ break;
+ case Constants.RET:
+ obj = new RET(wide ? bytes.readUnsignedShort() : bytes.readUnsignedByte(), wide);
+ break;
+ case Constants.NEW:
+ obj = new InstructionCP(Constants.NEW, bytes.readUnsignedShort());
+ break;
+ case Constants.GETSTATIC:
+ case Constants.PUTSTATIC:
+ case Constants.GETFIELD:
+ case Constants.PUTFIELD:
+ obj = new FieldInstruction(opcode, bytes.readUnsignedShort());
+ break;
+ case Constants.INVOKEVIRTUAL:
+ case Constants.INVOKESPECIAL:
+ case Constants.INVOKESTATIC:
+ obj = new InvokeInstruction(opcode, bytes.readUnsignedShort());
+ break;
+ case Constants.INVOKEINTERFACE:
+ obj = new INVOKEINTERFACE(bytes.readUnsignedShort(), bytes.readUnsignedByte(), bytes.readByte());
+ break;
+ case Constants.INVOKEDYNAMIC:
+ obj = new InvokeDynamic(bytes.readUnsignedShort(),bytes.readUnsignedShort());
+ break;
+ case Constants.NEWARRAY:
+ obj = new InstructionByte(Constants.NEWARRAY, bytes.readByte());
+ break;
+ case Constants.ANEWARRAY:
+ case Constants.CHECKCAST:
+ obj = new InstructionCP(opcode, bytes.readUnsignedShort());
+ break;
+ case Constants.INSTANCEOF:
+ obj = new InstructionCP(Constants.INSTANCEOF, bytes.readUnsignedShort());
+ break;
+ case Constants.MULTIANEWARRAY:
+ obj = new MULTIANEWARRAY(bytes.readUnsignedShort(), bytes.readByte());
+ break;
+ default:
+ throw new ClassGenException("Illegal opcode detected");
+ }
+ } catch (ClassGenException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ClassGenException(e.toString());
+ }
+
+ return obj;
+ }
+
+ /**
+ * @return Number of words consumed from stack by this instruction, or Constants.UNPREDICTABLE, if this can not be computed
+ * statically
+ */
+ public int consumeStack(ConstantPool cpg) {
+ return Constants.CONSUME_STACK[opcode];
+ }
+
+ /**
+ * @return Number of words produced onto stack by this instruction, or Constants.UNPREDICTABLE, if this can not be computed
+ * statically
+ */
+ public int produceStack(ConstantPool cpg) {
+ return Constants.stackEntriesProduced[opcode];
+ }
+
+ public short getOpcode() {
+ return opcode;
+ }
+
+ public int getLength() {
+ // if it is zero, it should have been provided by an overriding implementation of getLength()
+ int len = Constants.iLen[opcode];
+ assert len != 0;
+ // if (len == 0) {
+ // throw new IllegalStateException("Length not right for " + getName().toUpperCase());
+ // }
+ return len;
+ }
+
+ /** Some instructions may be reused, so don't do anything by default */
+ void dispose() {
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this.getClass() != Instruction.class) {
+ throw new RuntimeException("NO WAY " + this.getClass());
+ }
+ if (!(other instanceof Instruction)) {
+ return false;
+ }
+ return ((Instruction) other).opcode == opcode;
+
+ // IMPLEMENT EQUALS AND HASHCODE IN THE SUBTYPES!
+
+ // Instruction i1 = this;
+ // Instruction i2 = (Instruction) that;
+ // if (i1.opcode == i2.opcode) {
+ // if (i1.isConstantInstruction()) {
+ // return i1.getValue().equals(i2.getValue());
+ // } else if (i1.isIndexedInstruction()) {
+ // return i1.getIndex() == i2.getIndex();
+ // } else if (i1.opcode == Constants.NEWARRAY) {
+ // return ((InstructionByte) i1).getTypecode() == ((InstructionByte) i2).getTypecode();
+ // } else {
+ // return true;
+ // }
+ // }
+ //
+ // return false;
+ }
+
+ @Override
+ public int hashCode() {
+ if (this.getClass() != Instruction.class) {
+ throw new RuntimeException("NO WAY " + this.getClass());
+ }
+ return opcode * 37;
+ // int result = 17 + opcode * 37;
+ // if (isConstantInstruction()) {
+ // result = 37 * getValue().hashCode() + result;
+ // } else if (isIndexedInstruction()) {
+ // result = 37 * getIndex() + result;
+ // } else if (opcode == Constants.NEWARRAY) {
+ // result = 37 * ((InstructionByte) this).getTypecode() + result;
+ // }
+ // return result;
+ }
+
+ public Type getType() {
+ return getType(null);
+ }
+
+ public Type getType(ConstantPool cp) {
+ // if (types[opcode]==null) throw new RuntimeException(getName()+" is not a typed instruction");
+ Type t = Constants.types[opcode];
+ if (t != null) {
+ return t;
+ }
+ throw new RuntimeException("Do not know type for instruction " + getName() + "(" + opcode + ")");
+ }
+
+ public Number getValue() {
+ assert (instFlags[opcode] & CONSTANT_INST) == 0;
+ // if ((instFlags[opcode] & CONSTANT_INST) == 0) {
+ // throw new RuntimeException(getName() + " is not a constant instruction");
+ // }
+ switch (opcode) {
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ return new Integer(opcode - ICONST_0);
+ default:
+ throw new IllegalStateException("Not implemented yet for " + getName());
+ }
+ }
+
+ public int getIndex() {
+ return -1;
+ }
+
+ public void setIndex(int i) {
+ throw new IllegalStateException("Shouldnt be asking " + getName().toUpperCase());
+ }
+
+ public Object getValue(ConstantPool cpg) {
+ throw new IllegalStateException("Shouldnt be asking " + getName().toUpperCase());
+ }
+
+ public boolean isLoadInstruction() {
+ return (Constants.instFlags[opcode] & LOAD_INST) != 0;
+ }
+
+ // remove these from here, leave them in the InstructionLV
+ public boolean isASTORE() {
+ return false;
+ }
+
+ public boolean isALOAD() {
+ return false;
+ }
+
+ public boolean isStoreInstruction() {
+ return (Constants.instFlags[opcode] & STORE_INST) != 0;
+ }
+
+ // public boolean containsTarget(InstructionHandle ih) {
+ // throw new IllegalStateException("Dont ask!!");
+ // }
+
+ public boolean isJsrInstruction() {
+ return (Constants.instFlags[opcode] & JSR_INSTRUCTION) != 0;
+ }
+
+ public boolean isConstantInstruction() {
+ return (Constants.instFlags[opcode] & CONSTANT_INST) != 0;
+ }
+
+ public boolean isConstantPoolInstruction() {
+ return (Constants.instFlags[opcode] & CP_INST) != 0;
+ }
+
+ public boolean isStackProducer() {
+ return Constants.stackEntriesProduced[opcode] != 0;
+ }
+
+ public boolean isStackConsumer() {
+ return Constants.CONSUME_STACK[opcode] != 0;
+ }
+
+ public boolean isIndexedInstruction() {
+ return (Constants.instFlags[opcode] & INDEXED) != 0;
+ }
+
+ public boolean isArrayCreationInstruction() {
+ return opcode == NEWARRAY || opcode == ANEWARRAY || opcode == MULTIANEWARRAY;
+ }
+
+ public ObjectType getLoadClassType(ConstantPool cpg) {
+ assert (Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0;
+ // if ((Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0) {
+ // throw new IllegalStateException("This opcode " + opcode + " does not have the property "
+ // + Long.toHexString(Constants.LOADCLASS_INST));
+ // }
+ Type t = getType(cpg);
+ if (t instanceof ArrayType) {
+ t = ((ArrayType) t).getBasicType();
+ }
+ return t instanceof ObjectType ? (ObjectType) t : null;
+ }
+
+ public boolean isReturnInstruction() {
+ return (Constants.instFlags[opcode] & RET_INST) != 0;
+ }
+
+ // public boolean isGoto() {
+ // return opcode == GOTO || opcode == GOTO_W;
+ // }
+
+ public boolean isLocalVariableInstruction() {
+ return (Constants.instFlags[opcode] & LV_INST) != 0;
+ }
+
+ /**
+ * Long output format: 'name of opcode' "[" 'opcode number' "]" "(" 'length of instruction' ")"
+ */
+ public String toString(boolean verbose) {
+ if (verbose) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getName()).append("[").append(opcode).append("](size").append(Constants.iLen[opcode]).append(")");
+ return sb.toString();
+ } else {
+ return getName();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return toString(true);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java
new file mode 100644
index 000000000..53fed8e52
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionBranch.java
@@ -0,0 +1,338 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch instructions may have a variable length, namely
+ * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH. A branch instruction may be talking in terms of absolute destination (targetIndex) or
+ * about an instruction it doesnt yet know the position if (targetInstruction). targetInstruction (if set) overrides targetIndex
+ *
+ * @see InstructionList
+ * @version $Id: InstructionBranch.java,v 1.6 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class InstructionBranch extends Instruction implements InstructionTargeter {
+ private static final int UNSET = -1;
+
+ protected int targetIndex = UNSET; // Branch target relative to this
+ // instruction
+ protected InstructionHandle targetInstruction; // Target object in
+ // instruction list
+ protected int positionOfThisInstruction; // for calculating relative branch
+
+ // destinations!
+
+ public InstructionBranch(short opcode, InstructionHandle target) {
+ super(opcode);
+ setTarget(target);
+ }
+
+ public InstructionBranch(short opcode, int index) {
+ super(opcode);
+ this.targetIndex = index;
+ }
+
+ public InstructionBranch(short opcode) {
+ super(opcode);
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ int target = getTargetOffset();
+
+ if (Math.abs(target) >= 32767 && opcode != GOTO_W && opcode != JSR_W) {
+ throw new ClassGenException("Branch target offset too large for short. Instruction: " + getName().toUpperCase() + "("
+ + opcode + ")");
+ }
+
+ out.writeByte(opcode);
+
+ switch (opcode) {
+
+ case GOTO_W:
+ case JSR_W:
+ out.writeInt(target);
+ break;
+
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ case IF_ICMPEQ:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ICMPLT:
+ case IF_ICMPNE:
+ case IFEQ:
+ case IFLE:
+ case IFLT:
+ case IFGT:
+ case IFNE:
+ case IFGE:
+ case IFNULL:
+ case IFNONNULL:
+ case GOTO:
+ case JSR:
+ out.writeShort(target);
+ break;
+
+ default:
+ throw new IllegalStateException("Don't know how to write out " + getName().toUpperCase());
+ }
+
+ }
+
+ protected int getTargetOffset() {
+ if (targetInstruction == null && targetIndex == UNSET) {
+ throw new ClassGenException("Target of " + super.toString(true) + " is unknown");
+ }
+
+ if (targetInstruction == null) {
+ return targetIndex;
+ } else {
+ return targetInstruction.getPosition() - positionOfThisInstruction;
+ }
+ }
+
+ /**
+ * 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) {
+ int i = getTargetOffset();
+
+ positionOfThisInstruction += offset;
+
+ if (Math.abs(i) >= 32767 - max_offset && opcode != JSR_W && opcode != GOTO_W) {
+ // Try and promote it to wide if we can
+ if (opcode == JSR || opcode == GOTO) {
+ if (opcode == JSR) {
+ opcode = JSR_W;
+ } else {
+ opcode = GOTO_W;
+ }
+ return 2; // instruction jump destination grows from a short to a long
+ } else {
+ throw new IllegalStateException("Unable to pack method, jump (with opcode=" + opcode + ") is too far: "
+ + Math.abs(i));
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Long output format:
+ *
+ * @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 (targetInstruction != null) {
+ if (targetInstruction.getInstruction() == this) {
+ t = "<points to itself>";
+ } else if (targetInstruction.getInstruction() == null) {
+ t = "<null destination>";
+ } else {
+ t = targetInstruction.getInstruction().toString(false);
+ }
+ }
+ } else {
+ if (targetInstruction != null) {
+ targetIndex = getTargetOffset();
+ t = "" + (targetIndex + positionOfThisInstruction);
+ }
+ }
+
+ return s + " -> " + t;
+ }
+
+ /**
+ * @return target offset in byte code
+ */
+ public final int getIndex() {
+ return targetIndex;
+ }
+
+ /**
+ * @return target of branch instruction
+ */
+ public InstructionHandle getTarget() {
+ return targetInstruction;
+ }
+
+ /**
+ * Set branch target
+ *
+ * @param target branch target
+ */
+ public void setTarget(InstructionHandle target) {
+ notifyTarget(this.targetInstruction, target, this);
+ this.targetInstruction = target;
+ }
+
+ /**
+ * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen
+ */
+ static final void notifyTarget(InstructionHandle oldHandle, InstructionHandle newHandle, InstructionTargeter t) {
+ if (oldHandle != null) {
+ oldHandle.removeTargeter(t);
+ }
+ if (newHandle != null) {
+ newHandle.addTargeter(t);
+ }
+ }
+
+ /**
+ * Update the target destination for this instruction. If an oldHandle is provided it is checked to verify that is where the
+ * target currently points to before changing it.
+ *
+ * @param oldHandle old target
+ * @param newHandle new target
+ */
+ public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) {
+ if (targetInstruction == oldHandle) {
+ setTarget(newHandle);
+ } else {
+ throw new ClassGenException("Not targeting " + oldHandle + ", but " + targetInstruction);
+ }
+ }
+
+ /**
+ * @return true, if ih is target of this instruction
+ */
+ public boolean containsTarget(InstructionHandle ih) {
+ return targetInstruction == ih;
+ }
+
+ /**
+ * Inform target that it's not targeted anymore.
+ */
+ void dispose() {
+ setTarget(null);
+ targetIndex = -1;
+ positionOfThisInstruction = -1;
+ }
+
+ public Type getType(ConstantPool cp) {
+ if ((Constants.instFlags[opcode] & Constants.JSR_INSTRUCTION) != 0) {
+ return new ReturnaddressType(physicalSuccessor());
+ }
+ return super.getType(cp);
+ }
+
+ /**
+ * Returns an InstructionHandle to the physical successor of this JsrInstruction. <B>For this method to work, this
+ * JsrInstruction object must not be shared between multiple InstructionHandle objects!</B> 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.targetInstruction;
+
+ // 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();
+ }
+
+ public boolean isIfInstruction() {
+ return (Constants.instFlags[opcode] & Constants.IF_INST) != 0;
+ }
+
+ /**
+ * Only equal if they are the same branch instruction - otherwise too risky as the targets may only temporarily be pointing at
+ * the same destination.
+ */
+ public boolean equals(Object other) {
+ return this == other;
+ }
+
+ public int hashCode() {
+ int result = 17;
+ result = opcode * 37 + result;
+ return result;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java
new file mode 100644
index 000000000..5ba8a9abe
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionByte.java
@@ -0,0 +1,108 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Instruction that needs one byte
+ */
+public class InstructionByte extends Instruction {
+ private final byte theByte;
+
+ public InstructionByte(short opcode, byte b) {
+ super(opcode);
+ this.theByte = b;
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ out.writeByte(opcode);
+ out.writeByte(theByte);
+ }
+
+ public String toString(boolean verbose) {
+ return super.toString(verbose) + " " + theByte;
+ }
+
+ /**
+ * For supporting NEWARRAY
+ *
+ * @return typecode of the array
+ */
+ public final byte getTypecode() {
+ return theByte;
+ }
+
+ /**
+ * For supporting NEWARRAY
+ *
+ * @return type of the array
+ */
+ public final Type getType() {
+ return new ArrayType(BasicType.getType(theByte), 1);
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof InstructionByte)) {
+ return false;
+ }
+ InstructionByte o = (InstructionByte) other;
+ return o.opcode == opcode && o.theByte == theByte;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + theByte;
+ }
+} \ No newline at end of file
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java
new file mode 100644
index 000000000..85ae588e5
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCLV.java
@@ -0,0 +1,27 @@
+package org.aspectj.apache.bcel.generic;
+
+/**
+ * A small subclass of the local variable accessing instruction class InstructionLV - this subclass does
+ * not allow the index to be altered.
+ */
+public class InstructionCLV extends InstructionLV {
+
+ public InstructionCLV(short opcode) {
+ super(opcode);
+ }
+
+ public InstructionCLV(short opcode,int localVariableIndex) {
+ super(opcode,localVariableIndex);
+ }
+
+ public void setIndex(int localVariableIndex) {
+ if (localVariableIndex!=getIndex()) {
+ throw new ClassGenException("Do not attempt to modify the index to '"+localVariableIndex+"' for this constant instruction: "+this);
+ }
+ }
+
+ public boolean canSetIndex() {
+ return false;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java
new file mode 100644
index 000000000..09222d6a4
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionCP.java
@@ -0,0 +1,224 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Constant;
+import org.aspectj.apache.bcel.classfile.ConstantClass;
+import org.aspectj.apache.bcel.classfile.ConstantDouble;
+import org.aspectj.apache.bcel.classfile.ConstantFloat;
+import org.aspectj.apache.bcel.classfile.ConstantInteger;
+import org.aspectj.apache.bcel.classfile.ConstantLong;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ConstantString;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+
+/**
+ * Class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc.
+ *
+ * @version $Id: InstructionCP.java,v 1.6 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class InstructionCP extends Instruction {
+ protected int index;
+
+ public InstructionCP(short opcode, int index) {
+ super(opcode);
+ this.index = index;
+ }
+
+ @Override
+ public void dump(DataOutputStream out) throws IOException {
+ if (opcode == LDC_W && index < 256) {
+ out.writeByte(LDC);
+ out.writeByte(index);
+ } else {
+ out.writeByte(opcode);
+ if (Constants.iLen[opcode] == 2) {
+ if (index > 255) {
+ throw new IllegalStateException();
+ }
+ out.writeByte(index);
+ } else {
+ out.writeShort(index);
+ }
+ }
+ }
+
+ @Override
+ public int getLength() {
+ if (opcode == LDC_W && index < 256) {
+ return 2;
+ } else {
+ return super.getLength();
+ }
+ }
+
+ /**
+ * Long output format:
+ *
+ * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" "("&lt;length of instruction&gt;")" "&lt;"&lt; constant pool
+ * index&gt;"&gt;"
+ *
+ * @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
+ */
+ public String toString(ConstantPool cp) {
+ Constant c = cp.getConstant(index);
+ String str = cp.constantToString(c);
+
+ if (c instanceof ConstantClass) {
+ str = str.replace('.', '/');
+ }
+
+ return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str;
+ }
+
+ /**
+ * @return index in constant pool referred by this instruction.
+ */
+ @Override
+ public final int getIndex() {
+ return index;
+ }
+
+ @Override
+ public void setIndex(int index) {
+ this.index = index;
+ if (this.index > 255 && opcode == LDC) {
+ // promote it
+ opcode = LDC_W;
+ }
+ }
+
+ @Override
+ public Type getType(ConstantPool cpg) {
+ switch (cpg.getConstant(index).getTag()) {
+ case CONSTANT_String:
+ return Type.STRING;
+ case CONSTANT_Float:
+ return Type.FLOAT;
+ case CONSTANT_Integer:
+ return Type.INT;
+ case CONSTANT_Long:
+ return Type.LONG;
+ case CONSTANT_Double:
+ return Type.DOUBLE;
+ case CONSTANT_Class:
+ String name = cpg.getConstantString_CONSTANTClass(index);
+ // ConstantPool cp = cpg.getConstantPool();
+ // String name = cp.getConstantString(index, CONSTANT_Class);
+ if (!name.startsWith("[")) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("L").append(name).append(";");
+ return Type.getType(sb.toString());
+ } else {
+ return Type.getType(name);
+ }
+ default:
+ throw new RuntimeException("Unknown or invalid constant type at " + index);
+ }
+ }
+
+ @Override
+ public Object getValue(ConstantPool constantPool) {
+ Constant constant = constantPool.getConstant(index);
+
+ switch (constant.getTag()) {
+ case Constants.CONSTANT_String:
+ int i = ((ConstantString) constant).getStringIndex();
+ constant = constantPool.getConstant(i);
+ return ((ConstantUtf8) constant).getValue();
+
+ case Constants.CONSTANT_Float:
+ return ((ConstantFloat) constant).getValue();
+
+ case Constants.CONSTANT_Integer:
+ return ((ConstantInteger) constant).getValue();
+
+ case Constants.CONSTANT_Long:
+ return ((ConstantLong) constant).getValue();
+
+ case Constants.CONSTANT_Double:
+ return ((ConstantDouble) constant).getValue();
+ default:
+ throw new RuntimeException("Unknown or invalid constant type at " + index);
+ }
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof InstructionCP)) {
+ return false;
+ }
+ InstructionCP o = (InstructionCP) other;
+ return o.opcode == opcode && o.index == index;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + index;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java
new file mode 100644
index 000000000..e6f884793
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionConstants.java
@@ -0,0 +1,379 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.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
+ * 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);
+ *
+ * @version $Id: InstructionConstants.java,v 1.4 2008/08/13 18:18:22 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public interface InstructionConstants {
+ /** Predefined instruction objects
+ */
+ public static final Instruction NOP = new Instruction(Constants.NOP);
+ public static final Instruction ACONST_NULL = new Instruction(Constants.ACONST_NULL);
+ public static final Instruction ICONST_M1 = new Instruction(Constants.ICONST_M1);
+ public static final Instruction ICONST_0 = new Instruction(Constants.ICONST_0);
+ public static final Instruction ICONST_1 = new Instruction(Constants.ICONST_1);
+ public static final Instruction ICONST_2 = new Instruction(Constants.ICONST_2);
+ public static final Instruction ICONST_3 = new Instruction(Constants.ICONST_3);
+ public static final Instruction ICONST_4 = new Instruction(Constants.ICONST_4);
+ public static final Instruction ICONST_5 = new Instruction(Constants.ICONST_5);
+ public static final Instruction LCONST_0 = new Instruction(Constants.LCONST_0);
+ public static final Instruction LCONST_1 = new Instruction(Constants.LCONST_1);
+ public static final Instruction FCONST_0 = new Instruction(Constants.FCONST_0);
+ public static final Instruction FCONST_1 = new Instruction(Constants.FCONST_1);
+ public static final Instruction FCONST_2 = new Instruction(Constants.FCONST_2);
+ public static final Instruction DCONST_0 = new Instruction(Constants.DCONST_0);
+ public static final Instruction DCONST_1 = new Instruction(Constants.DCONST_1);
+ public static final Instruction IALOAD = new Instruction(Constants.IALOAD);
+ public static final Instruction LALOAD = new Instruction(Constants.LALOAD);
+ public static final Instruction FALOAD = new Instruction(Constants.FALOAD);
+ public static final Instruction DALOAD = new Instruction(Constants.DALOAD);
+ public static final Instruction AALOAD = new Instruction(Constants.AALOAD);
+ public static final Instruction BALOAD = new Instruction(Constants.BALOAD);
+ public static final Instruction CALOAD = new Instruction(Constants.CALOAD);
+ public static final Instruction SALOAD = new Instruction(Constants.SALOAD);
+ public static final Instruction IASTORE = new Instruction(Constants.IASTORE);
+ public static final Instruction LASTORE = new Instruction(Constants.LASTORE);
+ public static final Instruction FASTORE = new Instruction(Constants.FASTORE);
+ public static final Instruction DASTORE = new Instruction(Constants.DASTORE);
+ public static final Instruction AASTORE = new Instruction(Constants.AASTORE);
+ public static final Instruction BASTORE = new Instruction(Constants.BASTORE);
+ public static final Instruction CASTORE = new Instruction(Constants.CASTORE);
+ public static final Instruction SASTORE = new Instruction(Constants.SASTORE);
+ public static final Instruction POP = new Instruction(Constants.POP);
+ public static final Instruction POP2 = new Instruction(Constants.POP2);
+ public static final Instruction DUP = new Instruction(Constants.DUP);
+ public static final Instruction DUP_X1 = new Instruction(Constants.DUP_X1);
+ public static final Instruction DUP_X2 = new Instruction(Constants.DUP_X2);
+ public static final Instruction DUP2 = new Instruction(Constants.DUP2);
+ public static final Instruction DUP2_X1 = new Instruction(Constants.DUP2_X1);
+ public static final Instruction DUP2_X2 = new Instruction(Constants.DUP2_X2);
+ public static final Instruction SWAP = new Instruction(Constants.SWAP);
+ public static final Instruction IADD = new Instruction(Constants.IADD);
+ public static final Instruction LADD = new Instruction(Constants.LADD);
+ public static final Instruction FADD = new Instruction(Constants.FADD);
+ public static final Instruction DADD = new Instruction(Constants.DADD);
+ public static final Instruction ISUB = new Instruction(Constants.ISUB);
+ public static final Instruction LSUB = new Instruction(Constants.LSUB);
+ public static final Instruction FSUB = new Instruction(Constants.FSUB);
+ public static final Instruction DSUB = new Instruction(Constants.DSUB);
+ public static final Instruction IMUL = new Instruction(Constants.IMUL);
+ public static final Instruction LMUL = new Instruction(Constants.LMUL);
+ public static final Instruction FMUL = new Instruction(Constants.FMUL);
+ public static final Instruction DMUL = new Instruction(Constants.DMUL);
+ public static final Instruction IDIV = new Instruction(Constants.IDIV);
+ public static final Instruction LDIV = new Instruction(Constants.LDIV);
+ public static final Instruction FDIV = new Instruction(Constants.FDIV);
+ public static final Instruction DDIV = new Instruction(Constants.DDIV);
+ public static final Instruction IREM = new Instruction(Constants.IREM);
+ public static final Instruction LREM = new Instruction(Constants.LREM);
+ public static final Instruction FREM = new Instruction(Constants.FREM);
+ public static final Instruction DREM = new Instruction(Constants.DREM);
+ public static final Instruction INEG = new Instruction(Constants.INEG);
+ public static final Instruction LNEG = new Instruction(Constants.LNEG);
+ public static final Instruction FNEG = new Instruction(Constants.FNEG);
+ public static final Instruction DNEG = new Instruction(Constants.DNEG);
+ public static final Instruction ISHL = new Instruction(Constants.ISHL);
+ public static final Instruction LSHL = new Instruction(Constants.LSHL);
+ public static final Instruction ISHR = new Instruction(Constants.ISHR);
+ public static final Instruction LSHR = new Instruction(Constants.LSHR);
+ public static final Instruction IUSHR = new Instruction(Constants.IUSHR);
+ public static final Instruction LUSHR = new Instruction(Constants.LUSHR);
+ public static final Instruction IAND = new Instruction(Constants.IAND);
+ public static final Instruction LAND = new Instruction(Constants.LAND);
+ public static final Instruction IOR = new Instruction(Constants.IOR);
+ public static final Instruction LOR = new Instruction(Constants.LOR);
+ public static final Instruction IXOR = new Instruction(Constants.IXOR);
+ public static final Instruction LXOR = new Instruction(Constants.LXOR);
+ public static final Instruction I2L = new Instruction(Constants.I2L);
+ public static final Instruction I2F = new Instruction(Constants.I2F);
+ public static final Instruction I2D = new Instruction(Constants.I2D);
+ public static final Instruction L2I = new Instruction(Constants.L2I);
+ public static final Instruction L2F = new Instruction(Constants.L2F);
+ public static final Instruction L2D = new Instruction(Constants.L2D);
+ public static final Instruction F2I = new Instruction(Constants.F2I);
+ public static final Instruction F2L = new Instruction(Constants.F2L);
+ public static final Instruction F2D = new Instruction(Constants.F2D);
+ public static final Instruction D2I = new Instruction(Constants.D2I);
+ public static final Instruction D2L = new Instruction(Constants.D2L);
+ public static final Instruction D2F = new Instruction(Constants.D2F);
+ public static final Instruction I2B = new Instruction(Constants.I2B);
+ public static final Instruction I2C = new Instruction(Constants.I2C);
+ public static final Instruction I2S = new Instruction(Constants.I2S);
+ public static final Instruction LCMP = new Instruction(Constants.LCMP);
+ public static final Instruction FCMPL = new Instruction(Constants.FCMPL);
+ public static final Instruction FCMPG = new Instruction(Constants.FCMPG);
+ public static final Instruction DCMPL = new Instruction(Constants.DCMPL);
+ public static final Instruction DCMPG = new Instruction(Constants.DCMPG);
+ public static final Instruction IRETURN = new Instruction(Constants.IRETURN);
+ public static final Instruction LRETURN = new Instruction(Constants.LRETURN);
+ public static final Instruction FRETURN = new Instruction(Constants.FRETURN);
+ public static final Instruction DRETURN = new Instruction(Constants.DRETURN);
+ public static final Instruction ARETURN = new Instruction(Constants.ARETURN);
+ public static final Instruction RETURN = new Instruction(Constants.RETURN);
+ public static final Instruction ARRAYLENGTH = new Instruction(Constants.ARRAYLENGTH);
+ public static final Instruction ATHROW = new Instruction(Constants.ATHROW);
+ public static final Instruction MONITORENTER = new Instruction(Constants.MONITORENTER);
+ public static final Instruction MONITOREXIT = new Instruction(Constants.MONITOREXIT);
+ public static final Instruction IMPDEP1 = new Instruction(Constants.IMPDEP1);
+ public static final Instruction IMPDEP2 = new Instruction(Constants.IMPDEP2);
+
+ // You can use these constants in multiple places safely, any attempt to change the index
+ // for these constants will cause an exception
+ public static final InstructionLV THIS = new InstructionCLV(Constants.ALOAD,0);
+ public static final InstructionLV ALOAD_0 = new InstructionCLV(Constants.ALOAD_0);
+ public static final InstructionLV ALOAD_1 = new InstructionCLV(Constants.ALOAD_1);
+ public static final InstructionLV ALOAD_2 = new InstructionCLV(Constants.ALOAD_2);
+ public static final InstructionLV ALOAD_3 = new InstructionCLV(Constants.ALOAD_3);
+ public static final InstructionLV ILOAD_0 = new InstructionCLV(Constants.ILOAD_0);
+ public static final InstructionLV ILOAD_1 = new InstructionCLV(Constants.ILOAD_1);
+ public static final InstructionLV ILOAD_2 = new InstructionCLV(Constants.ILOAD_2);
+ public static final InstructionLV ILOAD_3 = new InstructionCLV(Constants.ILOAD_3);
+ public static final InstructionLV DLOAD_0 = new InstructionCLV(Constants.DLOAD_0);
+ public static final InstructionLV DLOAD_1 = new InstructionCLV(Constants.DLOAD_1);
+ public static final InstructionLV DLOAD_2 = new InstructionCLV(Constants.DLOAD_2);
+ public static final InstructionLV DLOAD_3 = new InstructionCLV(Constants.DLOAD_3);
+ public static final InstructionLV FLOAD_0 = new InstructionCLV(Constants.FLOAD_0);
+ public static final InstructionLV FLOAD_1 = new InstructionCLV(Constants.FLOAD_1);
+ public static final InstructionLV FLOAD_2 = new InstructionCLV(Constants.FLOAD_2);
+ public static final InstructionLV FLOAD_3 = new InstructionCLV(Constants.FLOAD_3);
+ public static final InstructionLV LLOAD_0 = new InstructionCLV(Constants.LLOAD_0);
+ public static final InstructionLV LLOAD_1 = new InstructionCLV(Constants.LLOAD_1);
+ public static final InstructionLV LLOAD_2 = new InstructionCLV(Constants.LLOAD_2);
+ public static final InstructionLV LLOAD_3 = new InstructionCLV(Constants.LLOAD_3);
+ public static final InstructionLV ASTORE_0 = new InstructionCLV(Constants.ASTORE_0);
+ public static final InstructionLV ASTORE_1 = new InstructionCLV(Constants.ASTORE_1);
+ public static final InstructionLV ASTORE_2 = new InstructionCLV(Constants.ASTORE_2);
+ public static final InstructionLV ASTORE_3 = new InstructionCLV(Constants.ASTORE_3);
+ public static final InstructionLV ISTORE_0 = new InstructionCLV(Constants.ISTORE_0);
+ public static final InstructionLV ISTORE_1 = new InstructionCLV(Constants.ISTORE_1);
+ public static final InstructionLV ISTORE_2 = new InstructionCLV(Constants.ISTORE_2);
+ public static final InstructionLV ISTORE_3 = new InstructionCLV(Constants.ISTORE_3);
+ public static final InstructionLV LSTORE_0 = new InstructionCLV(Constants.LSTORE_0);
+ public static final InstructionLV LSTORE_1 = new InstructionCLV(Constants.LSTORE_1);
+ public static final InstructionLV LSTORE_2 = new InstructionCLV(Constants.LSTORE_2);
+ public static final InstructionLV LSTORE_3 = new InstructionCLV(Constants.LSTORE_3);
+ public static final InstructionLV FSTORE_0 = new InstructionCLV(Constants.FSTORE_0);
+ public static final InstructionLV FSTORE_1 = new InstructionCLV(Constants.FSTORE_1);
+ public static final InstructionLV FSTORE_2 = new InstructionCLV(Constants.FSTORE_2);
+ public static final InstructionLV FSTORE_3 = new InstructionCLV(Constants.FSTORE_3);
+ public static final InstructionLV DSTORE_0 = new InstructionCLV(Constants.DSTORE_0);
+ public static final InstructionLV DSTORE_1 = new InstructionCLV(Constants.DSTORE_1);
+ public static final InstructionLV DSTORE_2 = new InstructionCLV(Constants.DSTORE_2);
+ public static final InstructionLV DSTORE_3 = new InstructionCLV(Constants.DSTORE_3);
+
+
+ /** 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 {
+ 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;
+ INSTRUCTIONS[Constants.IMPDEP1] = IMPDEP1;
+ INSTRUCTIONS[Constants.IMPDEP2] = IMPDEP2;
+
+ INSTRUCTIONS[Constants.ALOAD_0] = ALOAD_0;INSTRUCTIONS[Constants.ALOAD_1] = ALOAD_1;
+ INSTRUCTIONS[Constants.ALOAD_2] = ALOAD_2;INSTRUCTIONS[Constants.ALOAD_3] = ALOAD_3;
+ INSTRUCTIONS[Constants.LLOAD_0] = LLOAD_0;INSTRUCTIONS[Constants.LLOAD_1] = LLOAD_1;
+ INSTRUCTIONS[Constants.LLOAD_2] = LLOAD_2;INSTRUCTIONS[Constants.LLOAD_3] = LLOAD_3;
+ INSTRUCTIONS[Constants.DLOAD_0] = DLOAD_0;INSTRUCTIONS[Constants.DLOAD_1] = DLOAD_1;
+ INSTRUCTIONS[Constants.DLOAD_2] = DLOAD_2;INSTRUCTIONS[Constants.DLOAD_3] = DLOAD_3;
+ INSTRUCTIONS[Constants.FLOAD_0] = FLOAD_0;INSTRUCTIONS[Constants.FLOAD_1] = FLOAD_1;
+ INSTRUCTIONS[Constants.FLOAD_2] = FLOAD_2;INSTRUCTIONS[Constants.FLOAD_3] = FLOAD_3;
+ INSTRUCTIONS[Constants.ILOAD_0] = ILOAD_0;INSTRUCTIONS[Constants.ILOAD_1] = ILOAD_1;
+ INSTRUCTIONS[Constants.ILOAD_2] = ILOAD_2;INSTRUCTIONS[Constants.ILOAD_3] = ILOAD_3;
+
+ INSTRUCTIONS[Constants.ASTORE_0] = ASTORE_0;INSTRUCTIONS[Constants.ASTORE_1] = ASTORE_1;
+ INSTRUCTIONS[Constants.ASTORE_2] = ASTORE_2;INSTRUCTIONS[Constants.ASTORE_3] = ASTORE_3;
+ INSTRUCTIONS[Constants.LSTORE_0] = LSTORE_0;INSTRUCTIONS[Constants.LSTORE_1] = LSTORE_1;
+ INSTRUCTIONS[Constants.LSTORE_2] = LSTORE_2;INSTRUCTIONS[Constants.LSTORE_3] = LSTORE_3;
+ INSTRUCTIONS[Constants.DSTORE_0] = DSTORE_0;INSTRUCTIONS[Constants.DSTORE_1] = DSTORE_1;
+ INSTRUCTIONS[Constants.DSTORE_2] = DSTORE_2;INSTRUCTIONS[Constants.DSTORE_3] = DSTORE_3;
+ INSTRUCTIONS[Constants.FSTORE_0] = FSTORE_0;INSTRUCTIONS[Constants.FSTORE_1] = FSTORE_1;
+ INSTRUCTIONS[Constants.FSTORE_2] = FSTORE_2;INSTRUCTIONS[Constants.FSTORE_3] = FSTORE_3;
+ INSTRUCTIONS[Constants.ISTORE_0] = ISTORE_0;INSTRUCTIONS[Constants.ISTORE_1] = ISTORE_1;
+ INSTRUCTIONS[Constants.ISTORE_2] = ISTORE_2;INSTRUCTIONS[Constants.ISTORE_3] = ISTORE_3;
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java
new file mode 100644
index 000000000..4e1e6c8a8
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionFactory.java
@@ -0,0 +1,771 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.Utility;
+
+/**
+ * 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,v 1.7 2010/08/23 20:44:10 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constants
+ */
+public class InstructionFactory implements InstructionConstants {
+ protected ClassGen cg;
+ protected ConstantPool cp;
+
+ public InstructionFactory(ClassGen cg, ConstantPool cp) {
+ this.cg = cg;
+ this.cp = cp;
+ }
+
+ public InstructionFactory(ClassGen cg) {
+ this(cg, cg.getConstantPool());
+ }
+
+ public InstructionFactory(ConstantPool cp) {
+ this(null, cp);
+ }
+
+ public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind) {
+ return createInvoke(class_name, name, ret_type, arg_types, kind, false);
+ }
+
+ /**
+ * 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
+ * @param isInterface for an invokestatic on an interface allows us to tell this method the target is an interface
+ * @see Constants
+ */
+ public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, Type[] arg_types, short kind, boolean isInterface) {
+
+ String signature = Utility.toMethodSignature(ret_type, arg_types);
+
+ int index;
+ if (kind == Constants.INVOKEINTERFACE || isInterface) {
+ index = cp.addInterfaceMethodref(class_name, name, signature);
+ } else if (kind == Constants.INVOKEDYNAMIC){
+ throw new IllegalStateException("NYI");
+ } else {
+ index = cp.addMethodref(class_name, name, signature);
+ }
+
+ switch (kind) {
+ case Constants.INVOKESPECIAL:
+ return new InvokeInstruction(Constants.INVOKESPECIAL, index);
+ case Constants.INVOKEVIRTUAL:
+ return new InvokeInstruction(Constants.INVOKEVIRTUAL, index);
+ case Constants.INVOKESTATIC:
+ return new InvokeInstruction(Constants.INVOKESTATIC, index);
+ case Constants.INVOKEINTERFACE:
+ int nargs = 0;
+ for (int i = 0; i < arg_types.length; i++) {
+ nargs += arg_types[i].getSize();
+ }
+ return new INVOKEINTERFACE(index, nargs + 1, 0);
+ default:
+ throw new RuntimeException("Oops: Unknown invoke kind:" + kind);
+ }
+ }
+
+ public InvokeInstruction createInvoke(String class_name, String name, String signature, short kind) {
+ int index;
+ if (kind == Constants.INVOKEINTERFACE) {
+ index = cp.addInterfaceMethodref(class_name, name, signature);
+ } else if (kind == Constants.INVOKEDYNAMIC){
+ throw new IllegalStateException("NYI");
+ } else {
+ index = cp.addMethodref(class_name, name, signature);
+ }
+
+ switch (kind) {
+ case Constants.INVOKESPECIAL:
+ return new InvokeInstruction(Constants.INVOKESPECIAL, index);
+ case Constants.INVOKEVIRTUAL:
+ return new InvokeInstruction(Constants.INVOKEVIRTUAL, index);
+ case Constants.INVOKESTATIC:
+ return new InvokeInstruction(Constants.INVOKESTATIC, index);
+ case Constants.INVOKEINTERFACE:
+ Type[] argumentTypes = Type.getArgumentTypes(signature);
+ int nargs = 0;
+ for (int i = 0; i < argumentTypes.length; i++) {// Count size of arguments
+ nargs += argumentTypes[i].getSize();
+ }
+ return new INVOKEINTERFACE(index, nargs + 1, 0);
+ default:
+ throw new RuntimeException("Oops: Unknown invoke kind:" + kind);
+ }
+ }
+
+ public static Instruction createALOAD(int n) {
+ if (n < 4) {
+ return new InstructionLV((short) (Constants.ALOAD_0 + n));
+ }
+ return new InstructionLV(Constants.ALOAD, n);
+ }
+
+ public static Instruction createASTORE(int n) {
+ if (n < 4) {
+ return new InstructionLV((short) (Constants.ASTORE_0 + n));
+ }
+ return new InstructionLV(Constants.ASTORE, n);
+ }
+
+ /**
+ * Uses PUSH to push a constant value onto the stack.
+ *
+ * @param value must be of type Number, Boolean, Character or String
+ */
+ // OPTIMIZE callers should use the PUSH methods where possible if they know the types
+ public Instruction createConstant(Object value) {
+ Instruction instruction;
+
+ if (value instanceof Number) {
+ instruction = InstructionFactory.PUSH(cp, (Number) value);
+ } else if (value instanceof String) {
+ instruction = InstructionFactory.PUSH(cp, (String) value);
+ } else if (value instanceof Boolean) {
+ instruction = InstructionFactory.PUSH(cp, (Boolean) value);
+ } else if (value instanceof Character) {
+ instruction = InstructionFactory.PUSH(cp, (Character) value);
+ } else if (value instanceof ObjectType) {
+ instruction = InstructionFactory.PUSH(cp, (ObjectType) value);
+ } else {
+ throw new ClassGenException("Illegal type: " + value.getClass());
+ }
+
+ return instruction;
+ }
+
+ /**
+ * 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 FieldInstruction(Constants.GETFIELD, index);
+ case Constants.PUTFIELD:
+ return new FieldInstruction(Constants.PUTFIELD, index);
+ case Constants.GETSTATIC:
+ return new FieldInstruction(Constants.GETSTATIC, index);
+ case Constants.PUTSTATIC:
+ return new FieldInstruction(Constants.PUTSTATIC, index);
+
+ default:
+ throw new RuntimeException("Oops: Unknown getfield kind:" + kind);
+ }
+ }
+
+ /**
+ * Create reference to `this'
+ */
+ public static Instruction createThis() {
+ return new InstructionLV(Constants.ALOAD, 0);
+ }
+
+ /**
+ * Create typed return
+ */
+ public static Instruction 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);
+ }
+ }
+
+ /**
+ * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+ */
+ public static Instruction createPop(int size) {
+ return (size == 2) ? POP2 : POP;
+ }
+
+ /**
+ * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+ */
+ public static Instruction createDup(int size) {
+ return (size == 2) ? DUP2 : DUP;
+ }
+
+ /**
+ * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+ */
+ public static Instruction createDup_2(int size) {
+ return (size == 2) ? DUP2_X2 : DUP_X2;
+ }
+
+ /**
+ * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+ */
+ public static Instruction createDup_1(int size) {
+ return (size == 2) ? DUP2_X1 : DUP_X1;
+ }
+
+ /**
+ * @param index index of local variable
+ */
+ public static InstructionLV 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 InstructionLV(Constants.ISTORE, index);
+ case Constants.T_FLOAT:
+ return new InstructionLV(Constants.FSTORE, index);
+ case Constants.T_DOUBLE:
+ return new InstructionLV(Constants.DSTORE, index);
+ case Constants.T_LONG:
+ return new InstructionLV(Constants.LSTORE, index);
+ case Constants.T_ARRAY:
+ case Constants.T_OBJECT:
+ return new InstructionLV(Constants.ASTORE, index);
+ default:
+ throw new RuntimeException("Invalid type " + type);
+ }
+ }
+
+ /**
+ * @param index index of local variable
+ */
+ public static InstructionLV 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 InstructionLV(Constants.ILOAD, index);
+ case Constants.T_FLOAT:
+ return new InstructionLV(Constants.FLOAD, index);
+ case Constants.T_DOUBLE:
+ return new InstructionLV(Constants.DLOAD, index);
+ case Constants.T_LONG:
+ return new InstructionLV(Constants.LLOAD, index);
+ case Constants.T_ARRAY:
+ case Constants.T_OBJECT:
+ return new InstructionLV(Constants.ALOAD, index);
+ default:
+ throw new RuntimeException("Invalid type " + type);
+ }
+ }
+
+ /**
+ * @param type type of elements of array, i.e., array.getElementType()
+ */
+ public static Instruction 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 type type of elements of array, i.e., array.getElementType()
+ */
+ public static Instruction 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);
+ }
+ }
+
+ private static final char[] shortNames = { 'C', 'F', 'D', 'B', 'S', 'I', 'L' };
+
+ /**
+ * 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;
+ }
+
+ if (src == Constants.T_DOUBLE) {
+ switch (dest) {
+ case Constants.T_FLOAT:
+ return InstructionConstants.D2F;
+ case Constants.T_INT:
+ return InstructionConstants.D2I;
+ case Constants.T_LONG:
+ return InstructionConstants.D2L;
+ }
+ } else if (src == Constants.T_FLOAT) {
+ switch (dest) {
+ case Constants.T_DOUBLE:
+ return InstructionConstants.F2D;
+ case Constants.T_INT:
+ return InstructionConstants.F2I;
+ case Constants.T_LONG:
+ return InstructionConstants.F2L;
+ }
+ } else if (src == Constants.T_INT) {
+ switch (dest) {
+ case Constants.T_BYTE:
+ return InstructionConstants.I2B;
+ case Constants.T_CHAR:
+ return InstructionConstants.I2C;
+ case Constants.T_DOUBLE:
+ return InstructionConstants.I2D;
+ case Constants.T_FLOAT:
+ return InstructionConstants.I2F;
+ case Constants.T_LONG:
+ return InstructionConstants.I2L;
+ case Constants.T_SHORT:
+ return InstructionConstants.I2S;
+ }
+ } else if (src == Constants.T_LONG) {
+ switch (dest) {
+ case Constants.T_DOUBLE:
+ return InstructionConstants.L2D;
+ case Constants.T_FLOAT:
+ return InstructionConstants.L2F;
+ case Constants.T_INT:
+ return InstructionConstants.L2I;
+ }
+ }
+
+ // String name = "org.aspectj.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 null;
+ // return i;
+ } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) {
+ if (dest_type instanceof ArrayType) {
+ return new InstructionCP(Constants.CHECKCAST, cp.addArrayClass((ArrayType) dest_type));
+ } else {
+ return new InstructionCP(Constants.CHECKCAST, cp.addClass(((ObjectType) dest_type).getClassName()));
+ }
+ } else {
+ throw new RuntimeException("Can not cast " + src_type + " to " + dest_type);
+ }
+ }
+
+ public FieldInstruction createGetField(String class_name, String name, Type t) {
+ return new FieldInstruction(Constants.GETFIELD, cp.addFieldref(class_name, name, t.getSignature()));
+ }
+
+ public FieldInstruction createGetStatic(String class_name, String name, Type t) {
+ return new FieldInstruction(Constants.GETSTATIC, cp.addFieldref(class_name, name, t.getSignature()));
+ }
+
+ public FieldInstruction createPutField(String class_name, String name, Type t) {
+ return new FieldInstruction(Constants.PUTFIELD, cp.addFieldref(class_name, name, t.getSignature()));
+ }
+
+ public FieldInstruction createPutStatic(String class_name, String name, Type t) {
+ return new FieldInstruction(Constants.PUTSTATIC, cp.addFieldref(class_name, name, t.getSignature()));
+ }
+
+ public Instruction createCheckCast(ReferenceType t) {
+ if (t instanceof ArrayType) {
+ return new InstructionCP(Constants.CHECKCAST, cp.addArrayClass((ArrayType) t));
+ } else {
+ return new InstructionCP(Constants.CHECKCAST, cp.addClass((ObjectType) t));
+ }
+ }
+
+ public Instruction createInstanceOf(ReferenceType t) {
+ if (t instanceof ArrayType) {
+ return new InstructionCP(Constants.INSTANCEOF, cp.addArrayClass((ArrayType) t));
+ } else {
+ return new InstructionCP(Constants.INSTANCEOF, cp.addClass((ObjectType) t));
+ }
+ }
+
+ public Instruction createNew(ObjectType t) {
+ return new InstructionCP(Constants.NEW, cp.addClass(t));
+ }
+
+ public Instruction 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 InstructionCP(Constants.ANEWARRAY, cp.addClass((ObjectType) t));
+ } else if (t instanceof ArrayType) {
+ return new InstructionCP(Constants.ANEWARRAY, cp.addArrayClass((ArrayType) t));
+ } else {
+ return new InstructionByte(Constants.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 InstructionBranch createBranchInstruction(short opcode, InstructionHandle target) {
+ switch (opcode) {
+ case Constants.IFEQ:
+ return new InstructionBranch(Constants.IFEQ, target);
+ case Constants.IFNE:
+ return new InstructionBranch(Constants.IFNE, target);
+ case Constants.IFLT:
+ return new InstructionBranch(Constants.IFLT, target);
+ case Constants.IFGE:
+ return new InstructionBranch(Constants.IFGE, target);
+ case Constants.IFGT:
+ return new InstructionBranch(Constants.IFGT, target);
+ case Constants.IFLE:
+ return new InstructionBranch(Constants.IFLE, target);
+ case Constants.IF_ICMPEQ:
+ return new InstructionBranch(Constants.IF_ICMPEQ, target);
+ case Constants.IF_ICMPNE:
+ return new InstructionBranch(Constants.IF_ICMPNE, target);
+ case Constants.IF_ICMPLT:
+ return new InstructionBranch(Constants.IF_ICMPLT, target);
+ case Constants.IF_ICMPGE:
+ return new InstructionBranch(Constants.IF_ICMPGE, target);
+ case Constants.IF_ICMPGT:
+ return new InstructionBranch(Constants.IF_ICMPGT, target);
+ case Constants.IF_ICMPLE:
+ return new InstructionBranch(Constants.IF_ICMPLE, target);
+ case Constants.IF_ACMPEQ:
+ return new InstructionBranch(Constants.IF_ACMPEQ, target);
+ case Constants.IF_ACMPNE:
+ return new InstructionBranch(Constants.IF_ACMPNE, target);
+ case Constants.GOTO:
+ return new InstructionBranch(Constants.GOTO, target);
+ case Constants.JSR:
+ return new InstructionBranch(Constants.JSR, target);
+ case Constants.IFNULL:
+ return new InstructionBranch(Constants.IFNULL, target);
+ case Constants.IFNONNULL:
+ return new InstructionBranch(Constants.IFNONNULL, target);
+ case Constants.GOTO_W:
+ return new InstructionBranch(Constants.GOTO_W, target);
+ case Constants.JSR_W:
+ return new InstructionBranch(Constants.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(ConstantPool c) {
+ cp = c;
+ }
+
+ public ConstantPool getConstantPool() {
+ return cp;
+ }
+
+ /**
+ * Returns the right instruction for putting whatever you want onto the stack
+ */
+ public static Instruction PUSH(ConstantPool cp, int value) {
+ Instruction instruction = null;
+ if ((value >= -1) && (value <= 5)) {
+ return INSTRUCTIONS[Constants.ICONST_0 + value];
+ } else if ((value >= -128) && (value <= 127)) {
+ instruction = new InstructionByte(Constants.BIPUSH, (byte) value);
+ } else if ((value >= -32768) && (value <= 32767)) {
+ instruction = new InstructionShort(Constants.SIPUSH, (short) value);
+ } else // If everything fails create a Constant pool entry
+ {
+ int pos = cp.addInteger(value);
+ if (pos <= Constants.MAX_BYTE) {
+ instruction = new InstructionCP(Constants.LDC, pos);
+ } else {
+ instruction = new InstructionCP(Constants.LDC_W, pos);
+ }
+ }
+ return instruction;
+ }
+
+ public static Instruction PUSH(ConstantPool cp, ObjectType t) {
+ return new InstructionCP(Constants.LDC_W, cp.addClass(t));
+ }
+
+ public static Instruction PUSH(ConstantPool cp, boolean value) {
+ return INSTRUCTIONS[Constants.ICONST_0 + (value ? 1 : 0)];
+ }
+
+ public static Instruction PUSH(ConstantPool cp, float value) {
+ Instruction instruction = null;
+ if (value == 0.0) {
+ instruction = FCONST_0;
+ } else if (value == 1.0) {
+ instruction = FCONST_1;
+ } else if (value == 2.0) {
+ instruction = FCONST_2;
+ } else {
+ // Create a Constant pool entry
+ int i = cp.addFloat(value);
+ instruction = new InstructionCP(i <= Constants.MAX_BYTE ? Constants.LDC : Constants.LDC_W, i);
+ }
+ return instruction;
+ }
+
+ public static Instruction PUSH(ConstantPool cp, long value) {
+ Instruction instruction = null;
+ if (value == 0) {
+ instruction = LCONST_0;
+ } else if (value == 1) {
+ instruction = LCONST_1;
+ } else {
+ instruction = new InstructionCP(Constants.LDC2_W, cp.addLong(value));
+ }
+ return instruction;
+ }
+
+ public static Instruction PUSH(ConstantPool cp, double value) {
+ Instruction instruction = null;
+ if (value == 0.0) {
+ instruction = DCONST_0;
+ } else if (value == 1.0) {
+ instruction = DCONST_1;
+ } else {
+ // Create a Constant pool entry
+ instruction = new InstructionCP(Constants.LDC2_W, cp.addDouble(value));
+ }
+ return instruction;
+ }
+
+ public static Instruction PUSH(ConstantPool cp, String value) {
+ Instruction instruction = null;
+ if (value == null) {
+ instruction = ACONST_NULL;
+ } else {
+ int i = cp.addString(value);
+ instruction = new InstructionCP(i <= Constants.MAX_BYTE ? Constants.LDC : Constants.LDC_W, i);
+ }
+ return instruction;
+ }
+
+ public static Instruction PUSH(ConstantPool cp, Number value) {
+ Instruction instruction = null;
+ if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) {
+ instruction = PUSH(cp, value.intValue());
+ } else if (value instanceof Double) {
+ instruction = PUSH(cp, value.doubleValue());
+ } else if (value instanceof Float) {
+ instruction = PUSH(cp, value.floatValue());
+ } else if (value instanceof Long) {
+ instruction = PUSH(cp, value.longValue());
+ } else {
+ throw new ClassGenException("What's this: " + value);
+ }
+ return instruction;
+ }
+
+ public static Instruction PUSH(ConstantPool cp, Character value) {
+ return PUSH(cp, value.charValue());
+ }
+
+ public static Instruction PUSH(ConstantPool cp, Boolean value) {
+ return PUSH(cp, value.booleanValue());
+ }
+
+ /**
+ * Return a list that will load the Class object - on 1.5 or later use the class variant of ldc, whilst on earlier JVMs use the
+ * regular Class.forName.
+ */
+ public InstructionList PUSHCLASS(ConstantPool cp, String className) {
+ InstructionList iList = new InstructionList();
+ int classIndex = cp.addClass(className);
+ if (cg != null && cg.getMajor() >= Constants.MAJOR_1_5) {
+ if (classIndex <= Constants.MAX_BYTE) {
+ iList.append(new InstructionCP(Instruction.LDC, classIndex));
+ } else {
+ iList.append(new InstructionCP(Instruction.LDC_W, classIndex));
+ }
+ } else {
+ className = className.replace('/', '.');
+ iList.append(InstructionFactory.PUSH(cp, className));
+ iList.append(this.createInvoke("java.lang.Class", "forName", ObjectType.CLASS, Type.STRINGARRAY1,
+ Constants.INVOKESTATIC));
+ }
+ return iList;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java
new file mode 100644
index 000000000..2f2691df1
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionHandle.java
@@ -0,0 +1,189 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.aspectj.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 InstructionList.elements().
+ *
+ * @version $Id: InstructionHandle.java,v 1.9 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Instruction
+ * @see BranchHandle
+ * @see InstructionList
+ */
+public class InstructionHandle implements java.io.Serializable {
+ InstructionHandle next, prev; // Will be set from the outside
+ Instruction instruction;
+ protected int pos = -1; // byte code offset of instruction
+ private Set<InstructionTargeter> targeters = Collections.emptySet();
+
+ protected InstructionHandle(Instruction i) {
+ setInstruction(i);
+ }
+
+ static final InstructionHandle getInstructionHandle(Instruction i) {
+ return new InstructionHandle(i);
+ }
+
+ public final InstructionHandle getNext() {
+ return next;
+ }
+
+ public final InstructionHandle getPrev() {
+ return prev;
+ }
+
+ public final Instruction getInstruction() {
+ return instruction;
+ }
+
+ /**
+ * Replace current instruction contained in this handle. Old instruction is disposed using Instruction.dispose().
+ */
+ public void setInstruction(Instruction i) { // Overridden in BranchHandle
+ if (instruction != null) {
+ instruction.dispose();
+ }
+ instruction = i;
+ }
+
+ /**
+ * @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 pos;
+ }
+
+ /**
+ * Set the position, i.e., the byte code offset of the contained instruction.
+ */
+ void setPosition(int pos) {
+ this.pos = pos;
+ }
+
+ /**
+ * Delete contents, i.e., remove user access and make handle reusable.
+ */
+ // OPTIMIZE get rid of this? why do we need it
+ void dispose() {
+ next = prev = null;
+ instruction.dispose();
+ instruction = null;
+ pos = -1;
+ removeAllTargeters();
+ }
+
+ /**
+ * Remove all targeters, if any.
+ */
+ public void removeAllTargeters() {
+ targeters.clear();
+ }
+
+ /**
+ * Denote this handle isn't referenced anymore by t.
+ */
+ public void removeTargeter(InstructionTargeter t) {
+ targeters.remove(t);
+ }
+
+ /**
+ * Denote this handle is being referenced by t.
+ */
+ public void addTargeter(InstructionTargeter t) {
+ if (targeters == Collections.EMPTY_SET) {
+ targeters = new HashSet<InstructionTargeter>();
+ }
+ targeters.add(t);
+ }
+
+ public boolean hasTargeters() {
+ return !targeters.isEmpty();
+ }
+
+ public Set<InstructionTargeter> getTargeters() {
+ return targeters;
+ }
+
+ public Set<InstructionTargeter> getTargetersCopy() {
+ Set<InstructionTargeter> copy = new HashSet<InstructionTargeter>();
+ copy.addAll(targeters);
+ return copy;
+ }
+
+ /**
+ * @return a (verbose) string representation of the contained instruction.
+ */
+ public String toString(boolean verbose) {
+ return Utility.format(pos, 4, false, ' ') + ": " + instruction.toString(verbose);
+ }
+
+ public String toString() {
+ return toString(true);
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java
new file mode 100644
index 000000000..73c278016
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionLV.java
@@ -0,0 +1,278 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * Abstract super class for instructions dealing with local variables.
+ *
+ * @version $Id: InstructionLV.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class InstructionLV extends Instruction {
+ protected int lvar = -1;
+
+ public InstructionLV(short opcode, int lvar) {
+ super(opcode);
+ this.lvar = lvar;
+ }
+
+ public InstructionLV(short opcode) {
+ super(opcode);
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ if (lvar == -1) {
+ out.writeByte(opcode);
+ } else {
+ if (lvar < 4) {
+ if (opcode == ALOAD) {
+ out.writeByte(ALOAD_0 + lvar);
+ } else if (opcode == ASTORE) {
+ out.writeByte(ASTORE_0 + lvar);
+ } else if (opcode == ILOAD) {
+ out.writeByte(ILOAD_0 + lvar);
+ } else if (opcode == ISTORE) {
+ out.writeByte(ISTORE_0 + lvar);
+ } else if (opcode == DLOAD) {
+ out.writeByte(DLOAD_0 + lvar);
+ } else if (opcode == DSTORE) {
+ out.writeByte(DSTORE_0 + lvar);
+ } else if (opcode == FLOAD) {
+ out.writeByte(FLOAD_0 + lvar);
+ } else if (opcode == FSTORE) {
+ out.writeByte(FSTORE_0 + lvar);
+ } else if (opcode == LLOAD) {
+ out.writeByte(LLOAD_0 + lvar);
+ } else if (opcode == LSTORE) {
+ out.writeByte(LSTORE_0 + lvar);
+ } else {
+ if (wide()) {
+ out.writeByte(Constants.WIDE);
+ }
+ out.writeByte(opcode);
+ if (wide()) {
+ out.writeShort(lvar);
+ } else {
+ out.writeByte(lvar);
+ }
+ }
+ } else {
+ if (wide()) {
+ out.writeByte(Constants.WIDE);
+ }
+ out.writeByte(opcode);
+ if (wide()) {
+ out.writeShort(lvar);
+ } else {
+ out.writeByte(lvar);
+ }
+ }
+ }
+ }
+
+ /**
+ * Long output format:
+ *
+ * 'name of opcode' "[" 'opcode number' "]" "(" 'length of instruction' ")" "<" 'local variable index' ">"
+ */
+ 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) + (lvar != -1 && lvar < 4 ? "_" : " ") + lvar;
+ }
+ }
+
+ public boolean isALOAD() {
+ return opcode == ALOAD || opcode >= ALOAD_0 && opcode <= ALOAD_3;
+ }
+
+ public boolean isASTORE() {
+ return opcode == ASTORE || opcode >= ASTORE_0 && opcode <= ASTORE_3;
+ }
+
+ public int getBaseOpcode() {
+ if (opcode >= ILOAD && opcode <= ALOAD || opcode >= ISTORE && opcode <= ASTORE) {
+ // not an optimized instruction
+ return opcode;
+ }
+ if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) {
+ int ret = opcode - ILOAD_0;
+ ret = ret - ret % 4;
+ ret = ret / 4;
+ return ret + ILOAD;
+ }
+ int ret = opcode - ISTORE_0;
+ ret = ret - ret % 4;
+ ret = ret / 4;
+ return ret + ISTORE;
+ }
+
+ /**
+ * @return local variable index referred by this instruction.
+ */
+ // optimize!
+ public final int getIndex() {
+ if (lvar != -1) {
+ return lvar;
+ }
+ if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) {
+ return (opcode - Constants.ILOAD_0) % 4;
+ } else if (opcode >= Constants.ISTORE_0 && opcode <= Constants.ASTORE_3) {
+ return (opcode - Constants.ISTORE_0) % 4;
+ }
+ return -1;
+ }
+
+ public void setIndex(int i) {
+ // Switching the index for a load/store without a current index specified (ie. an aload_1 or istore_2)
+ // means we need to should adjust to a normal aload/istore opcode
+ if (getIndex() != i) {
+ if (opcode >= Constants.ILOAD_0 && opcode <= Constants.ALOAD_3) {
+ opcode = (short) (ILOAD + (opcode - ILOAD_0) / 4);
+ } else if (opcode >= Constants.ISTORE_0 && opcode <= Constants.ASTORE_3) {
+ opcode = (short) (ISTORE + (opcode - ISTORE_0) / 4);
+ }
+ this.lvar = i;
+ }
+ }
+
+ public boolean canSetIndex() {
+ return true;
+ }
+
+ public InstructionLV setIndexAndCopyIfNecessary(int newIndex) {
+ if (canSetIndex()) {
+ setIndex(newIndex);
+ return this;
+ } else {
+ if (getIndex() == newIndex) {
+ return this;
+ }
+ InstructionLV newInstruction = null;
+ int baseOpCode = getBaseOpcode();
+ if (newIndex < 4) {
+ if (isStoreInstruction()) {
+ newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode - Constants.ISTORE) * 4
+ + Constants.ISTORE_0 + newIndex];
+ } else {
+ newInstruction = (InstructionLV) InstructionConstants.INSTRUCTIONS[(baseOpCode - Constants.ILOAD) * 4
+ + Constants.ILOAD_0 + newIndex];
+ }
+ } else {
+ newInstruction = new InstructionLV((short) baseOpCode, newIndex);
+ }
+ // if (getBaseOpcode()!=newInstruction.getBaseOpcode() || newInstruction.getIndex()!=newIndex) {
+ // throw new
+ // RuntimeException("New Instruction created does not appear to be valid: originalBaseOpcode="+getBaseOpcode()+
+ // " newBaseOpcode="+newInstruction.getBaseOpcode());
+ // }
+ return newInstruction;
+ }
+ }
+
+ public int getLength() {
+ int size = Constants.iLen[opcode];
+ if (lvar == -1) {
+ return size;
+ } else {
+ if (lvar < 4) {
+ if (opcode == ALOAD || opcode == ASTORE) {
+ return 1;
+ } else if (opcode == ILOAD || opcode == ISTORE) {
+ return 1;
+ } else if (opcode == DLOAD || opcode == DSTORE) {
+ return 1;
+ } else if (opcode == FLOAD || opcode == FSTORE) {
+ return 1;
+ } else if (opcode == LLOAD || opcode == LSTORE) {
+ return 1;
+ } else {
+ if (wide()) {
+ return size + 2;
+ }
+ return size;
+ }
+ } else {
+ if (wide()) {
+ return size + 2;
+ }
+ return size;
+ }
+ }
+ }
+
+ private final boolean wide() {
+ return lvar > Constants.MAX_BYTE;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof InstructionLV)) {
+ return false;
+ }
+ InstructionLV o = (InstructionLV) other;
+ return o.opcode == opcode && o.lvar == lvar;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + lvar;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java
new file mode 100644
index 000000000..b08a2b77c
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionList.java
@@ -0,0 +1,1287 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Constant;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.util.ByteSequence;
+
+/**
+ * This class is a container for a list of <a href="Instruction.html">Instruction</a> objects. Instructions can be appended,
+ * inserted, moved, deleted, etc.. Instructions are being wrapped into <a href="InstructionHandle.html">InstructionHandles</a>
+ * 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 <a href="#getByteCode()">getByteCode</a>.
+ *
+ * @version $Id: InstructionList.java,v 1.12 2011/09/02 22:33:04 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Abraham Nevado
+ * @see Instruction
+ * @see InstructionHandle
+ * @see BranchHandle
+ */
+public class InstructionList implements Serializable {
+ private InstructionHandle start = null, end = null;
+ private int length = 0;
+ private int[] positions; // byte code offsets corresponding to instructions
+
+ public InstructionList() {
+ }
+
+ public InstructionList(Instruction i) {
+ append(i);
+ }
+
+ public boolean isEmpty() {
+ return start == null;
+ } // && end == null
+
+ public static InstructionHandle findHandle(InstructionHandle[] ihs, int[] pos, int count, int target) {
+ return findHandle(ihs, pos, count, target, false);
+ }
+
+ /**
+ * 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,
+ boolean returnClosestIfNoExactMatch) {
+ int l = 0, r = count - 1;
+ // Do a binary search since the pos array is ordered
+ int i, j;
+ do {
+ i = (l + r) / 2;
+ j = pos[i];
+ if (j == target) {
+ return ihs[i]; // found it
+ } else if (target < j) {
+ r = i - 1; // else constrain search area
+ } else {
+ l = i + 1; // target > j
+ }
+ } while (l <= r);
+
+ if (returnClosestIfNoExactMatch) {
+ i = (l + r) / 2;
+ if (i < 0) {
+ i = 0;
+ }
+ return ihs[i];
+ }
+ 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, positions, length, pos);
+ }
+
+ public InstructionHandle[] getInstructionsAsArray() {
+ return getInstructionHandles();
+ }
+
+ public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray) {
+ return findHandle(instructionArray, positions, length, pos);
+ }
+
+ public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray, boolean useClosestApproximationIfNoExactFound) {
+ return findHandle(instructionArray, positions, length, pos, useClosestApproximationIfNoExactFound);
+ }
+
+ /**
+ * 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 InstructionBranch) {
+ ih = append((InstructionBranch) i);
+ } else {
+ ih = append(i);
+ }
+
+ ih.setPosition(off);
+ ihs[count] = ih;
+
+ count++;
+ }
+ } catch (IOException e) {
+ throw new ClassGenException(e.toString());
+ }
+
+ positions = new int[count]; // Trim to proper size
+ System.arraycopy(pos, 0, positions, 0, count);
+
+ /*
+ * Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles.
+ */
+ // OPTIMIZE better way of doing this? keep little map from earlier from pos -> instruction handle?
+ for (int i = 0; i < count; i++) {
+ if (ihs[i] instanceof BranchHandle) {
+ InstructionBranch bi = (InstructionBranch) ihs[i].instruction;
+ int target = bi.positionOfThisInstruction + 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 InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH
+ InstructionSelect s = (InstructionSelect) bi;
+ int[] indices = s.getIndices();
+
+ for (int j = 0; j < indices.length; j++) {
+ target = bi.positionOfThisInstruction + 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 appendTo where to append the instruction list
+ * @param appendee Instruction list to append to this one
+ * @return instruction handle pointing to the <B>first</B> appended instruction
+ */
+ public InstructionHandle append(InstructionHandle appendTo, InstructionList appendee) {
+ assert appendee != null;
+
+ if (appendee.isEmpty()) {
+ return appendTo;
+ }
+
+ InstructionHandle next = appendTo.next;
+ InstructionHandle ret = appendee.start;
+
+ appendTo.next = appendee.start;
+ appendee.start.prev = appendTo;
+
+ appendee.end.next = next;
+
+ if (next != null) {
+ next.prev = appendee.end;
+ } else {
+ end = appendee.end; // Update end ...
+ }
+
+ length += appendee.length; // Update length
+
+ appendee.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 <B>first</B> 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 <B>first</B> appended instruction
+ */
+ public InstructionHandle append(InstructionList il) {
+ assert il != null;
+
+ 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;
+ }
+
+ public InstructionHandle appendDUP() {
+ InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.DUP);
+ append(ih);
+ return ih;
+ }
+
+ public InstructionHandle appendNOP() {
+ InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.NOP);
+ append(ih);
+ return ih;
+ }
+
+ public InstructionHandle appendPOP() {
+ InstructionHandle ih = InstructionHandle.getInstructionHandle(InstructionConstants.POP);
+ 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(InstructionBranch 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 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 <B>first</B> 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 <B>first</B> appended instruction
+ */
+ public BranchHandle append(InstructionHandle ih, InstructionBranch 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 i 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(InstructionBranch 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 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 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, InstructionBranch 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.<br>
+ * 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
+ 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;
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * If careAboutLostTargeters is true then this method will throw a 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, boolean careAboutLostTargeters) 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;
+
+ if (!careAboutLostTargeters) {
+ return;
+ }
+
+ ArrayList<InstructionHandle> target_vec = new ArrayList<InstructionHandle>();
+
+ 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--;
+
+ Set<InstructionTargeter> targeters = ih.getTargeters();
+ boolean isOK = false;
+ Iterator<InstructionTargeter> tIter = targeters.iterator();
+ while (tIter.hasNext()) {
+ InstructionTargeter instructionTargeter = tIter.next();
+ if (instructionTargeter.getClass().getName().endsWith("ShadowRange")
+ || instructionTargeter.getClass().getName().endsWith("ExceptionRange")
+ || instructionTargeter.getClass().getName().endsWith("LineNumberTag")) {
+ isOK = true;
+ } else {
+ System.out.println(instructionTargeter.getClass());
+ }
+ }
+ if (!isOK) {
+ target_vec.add(ih);
+ buf.append(ih.toString(true) + " ");
+ ih.next = ih.prev = null;
+ } else {
+ ih.dispose();
+ }
+
+ // if (ih.hasTargeters()) { // Still got targeters?
+ // InstructionTargeter[] targeters = ih.getTargeters();
+ // boolean isOK = false;
+ // for (int i = 0; i < targeters.length; i++) {
+ // InstructionTargeter instructionTargeter = targeters[i];
+ // if (instructionTargeter.getClass().getName().endsWith("ShadowRange")
+ // || instructionTargeter.getClass().getName().endsWith("ExceptionRange")
+ // || instructionTargeter.getClass().getName().endsWith("LineNumberTag")) {
+ // isOK = true;
+ // } else {
+ // System.out.println(instructionTargeter.getClass());
+ // }
+ // }
+ // if (!isOK) {
+ // target_vec.add(ih);
+ // buf.append(ih.toString(true) + " ");
+ // ih.next = ih.prev = null;
+ // } else {
+ // ih.dispose();
+ // }
+ // } 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, false);
+ }
+
+ /**
+ * 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, false);
+ }
+
+ /**
+ * 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 maxAdditionalBytes = 0;
+ int index = 0, count = 0;
+ int[] pos = new int[length];
+
+ // Pass 0: Sanity checks
+ if (check) {
+ checkInstructionList();
+ }
+
+ // 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.opcode) {
+ case Constants.JSR:
+ case Constants.GOTO:
+ maxAdditionalBytes += 2;
+ break;
+
+ case Constants.TABLESWITCH:
+ case Constants.LOOKUPSWITCH:
+ maxAdditionalBytes += 3;
+ break;
+ }
+ index += i.getLength();
+ }
+
+ // OPTIMIZE positions will only move around if there have been expanding instructions
+ // if (max_additional_bytes==0...) {
+ //
+ // }
+
+ /*
+ * 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.
+ */
+ boolean nonZeroOffset = false;
+ int offset = 0;
+ for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+ if (ih instanceof BranchHandle) {
+ offset += ((BranchHandle) ih).updatePosition(offset, maxAdditionalBytes);
+ if (offset != 0) {
+ nonZeroOffset = true;
+ }
+ }
+ }
+ if (nonZeroOffset) {
+ /*
+ * 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();
+ }
+ }
+
+ positions = new int[count]; // Trim to proper size
+ System.arraycopy(pos, 0, positions, 0, count);
+ }
+
+ private void checkInstructionList() {
+ for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+ Instruction i = ih.instruction;
+
+ if (i instanceof InstructionBranch) { // target instruction within list?
+ Instruction inst = ((InstructionBranch) 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 InstructionSelect) {
+ InstructionHandle[] targets = ((InstructionSelect) 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.");
+ }
+
+ }
+ }
+ }
+
+ /**
+ * 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;
+ }
+ byte[] byteCode = b.toByteArray();
+ if (byteCode.length > Constants.MAX_CODE_SIZE) {
+ throw new ClassGenException("Code size too big: " + byteCode.length);
+ }
+
+ return byteCode;
+ }
+
+ /**
+ * @return an array of instructions without target information for branch instructions.
+ */
+ public Instruction[] getInstructions() {
+ ByteSequence bytes = new ByteSequence(getByteCode());
+ ArrayList<Instruction> instructions = new ArrayList<Instruction>();
+
+ try {
+ while (bytes.available() > 0) {
+ instructions.add(Instruction.readInstruction(bytes));
+ }
+ } catch (IOException e) {
+ throw new ClassGenException(e.toString());
+ }
+
+ Instruction[] result = new Instruction[instructions.size()];
+ instructions.toArray(result);
+ return result;
+ }
+
+ @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) + "\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 positions;
+ }
+
+ /**
+ * @return complete, i.e., deep copy of this list
+ */
+ public InstructionList copy() {
+ HashMap<InstructionHandle, InstructionHandle> map = new HashMap<InstructionHandle, InstructionHandle>();
+ 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 InstructionBranch) {
+ map.put(ih, il.append((InstructionBranch) 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 InstructionBranch) {
+ InstructionBranch bi = (InstructionBranch) i;
+ InstructionBranch bc = (InstructionBranch) c;
+ InstructionHandle itarget = bi.getTarget(); // old target
+
+ // New target is in hash map
+ bc.setTarget(map.get(itarget));
+
+ if (bi instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH
+ InstructionHandle[] itargets = ((InstructionSelect) bi).getTargets();
+ InstructionHandle[] ctargets = ((InstructionSelect) 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(ConstantPool old_cp, ConstantPool new_cp) {
+ for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+ Instruction i = ih.instruction;
+ if (i.isConstantPoolInstruction()) {
+ InstructionCP ci = (InstructionCP) 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 better memory utilization, because the system then may reuse the instruction handles. This
+ * method is typically called right after <href="MethodGen.html#getMethod()">MethodGen.getMethod()</a>.
+ */
+ 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 InstructionBranch) {
+ InstructionBranch b = (InstructionBranch) i;
+ InstructionHandle target = b.getTarget();
+
+ if (target == old_target) {
+ b.setTarget(new_target);
+ }
+
+ if (b instanceof InstructionSelect) { // Either LOOKUPSWITCH or TABLESWITCH
+ InstructionHandle[] targets = ((InstructionSelect) b).getTargets();
+
+ for (int j = 0; j < targets.length; j++) {
+ if (targets[j] == old_target) {
+ ((InstructionSelect) 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);
+ }
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java
new file mode 100644
index 000000000..b4e00c027
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionSelect.java
@@ -0,0 +1,291 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.util.ByteSequence;
+
+/**
+ * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions.
+ *
+ * @version $Id: InstructionSelect.java,v 1.4 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see LOOKUPSWITCH
+ * @see TABLESWITCH
+ * @see InstructionList
+ */
+public abstract class InstructionSelect extends InstructionBranch {
+ protected int[] match; // matches, i.e., case 1: ...
+ protected int[] indices; // target offsets
+ protected InstructionHandle[] targets; // target objects in instruction list
+ protected int fixedLength; // fixed length defined by subclasses
+ protected int matchLength; // number of cases
+ protected int padding = 0; // number of pad bytes for alignment
+
+ protected short 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 target default instruction target
+ */
+ InstructionSelect(short opcode, int[] match, InstructionHandle[] targets, InstructionHandle target) {
+ super(opcode, target);
+
+ this.targets = targets;
+ for (int i = 0; i < targets.length; i++) {
+ notifyTarget(null, targets[i], this);
+ }
+
+ this.match = match;
+
+ if ((matchLength = match.length) != targets.length) {
+ throw new ClassGenException("Match and target array have not the same length");
+ }
+
+ indices = new int[matchLength];
+ }
+
+ 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 - positionOfThisInstruction;
+ }
+
+ /**
+ * 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) {
+ positionOfThisInstruction += 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 - (positionOfThisInstruction + 1) % 4) % 4;
+ length = (short) (fixedLength + padding); // Update length
+
+ return length - old_length;
+ }
+
+ /**
+ * 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);
+ }
+
+ targetIndex = getTargetOffset(); // Write default target offset
+ out.writeInt(targetIndex);
+ }
+
+ public InstructionSelect(short opcode, ByteSequence bytes) throws IOException {
+ super(opcode);
+ 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)
+ targetIndex = bytes.readInt();
+ }
+
+ /**
+ * @return mnemonic for instruction
+ */
+ public String toString(boolean verbose) {
+ StringBuffer buf = new StringBuffer(super.toString(verbose));
+
+ if (verbose) {
+ for (int i = 0; i < matchLength; i++) {
+ String s = "null";
+
+ if (targets[i] != null) {
+ s = targets[i].getInstruction().toString();
+ }
+
+ buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})");
+ }
+ } 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;
+ }
+
+ /**
+ * @param old_ih old target
+ * @param new_ih new target
+ */
+ public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
+ boolean targeted = false;
+
+ if (targetInstruction == 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 (targetInstruction == ih) {
+ return true;
+ }
+
+ for (int i = 0; i < targets.length; i++) {
+ if (targets[i] == ih) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * 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;
+ }
+
+ public boolean equals(Object other) {
+ return this == other;
+ }
+
+ public int hashCode() {
+ return opcode * 37;
+ }
+
+ /**
+ * @return array of match targets
+ */
+ public InstructionHandle[] getTargets() {
+ return targets;
+ }
+
+ public int getLength() {
+ return length;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java
new file mode 100644
index 000000000..99054cbff
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionShort.java
@@ -0,0 +1,92 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Instruction that needs one short
+ */
+public class InstructionShort extends Instruction {
+ private final short value;
+
+ public InstructionShort(short opcode, short value) {
+ super(opcode);
+ this.value = value;
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ out.writeByte(opcode);
+ out.writeShort(value);
+ }
+
+ public String toString(boolean verbose) {
+ return super.toString(verbose) + " " + value;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof InstructionShort)) {
+ return false;
+ }
+ InstructionShort o = (InstructionShort) other;
+ return o.opcode == opcode && o.value == value;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + value;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java
new file mode 100644
index 000000000..950ed3fa9
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InstructionTargeter.java
@@ -0,0 +1,70 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * Denote that a class targets InstructionHandles within an InstructionList. Namely
+ * the following implementers:
+ *
+ * @see BranchHandle
+ * @see LocalVariableGen
+ * @see CodeExceptionGen
+ * @version $Id: InstructionTargeter.java,v 1.3 2008/05/28 23:52:57 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public interface InstructionTargeter {
+ public boolean containsTarget(InstructionHandle ih);
+ public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih);
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java
new file mode 100644
index 000000000..b3c7ba85a
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeDynamic.java
@@ -0,0 +1,129 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.aspectj.apache.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantInvokeDynamic;
+import org.aspectj.apache.bcel.classfile.ConstantNameAndType;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * INVOKEDYNAMIC
+ *
+ * @author Andy Clement
+ */
+public final class InvokeDynamic extends InvokeInstruction {
+
+ public InvokeDynamic(int index, int zeroes) {
+ super(Constants.INVOKEDYNAMIC, index);
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ out.writeByte(opcode);
+ out.writeShort(index);
+ out.writeShort(0);
+ }
+
+ public String toString(ConstantPool cp) {
+ return super.toString(cp) + " " + index;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof InvokeDynamic)) {
+ return false;
+ }
+ InvokeDynamic o = (InvokeDynamic) other;
+ return o.opcode == opcode && o.index == index;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + index;
+ }
+
+ public Type getReturnType(ConstantPool cp) {
+ return Type.getReturnType(getSignature(cp));
+ }
+
+ public Type[] getArgumentTypes(ConstantPool cp) {
+ return Type.getArgumentTypes(getSignature(cp));
+ }
+
+ public String getSignature(ConstantPool cp) {
+ if (signature == null) {
+ ConstantInvokeDynamic cid = (ConstantInvokeDynamic)cp.getConstant(index);
+ ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex());
+ signature = cp.getConstantUtf8(cnat.getSignatureIndex()).getValue();
+ }
+ return signature;
+ }
+
+ @Override
+ public String getName(ConstantPool cp) {
+ if (name == null) {
+ ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(index);
+ ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex());
+ name = cp.getConstantUtf8(cnat.getNameIndex()).getValue();
+ }
+ return name;
+ }
+
+ public String getClassName(ConstantPool cp) {
+ throw new IllegalStateException("there is no classname for invokedynamic");
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java
new file mode 100644
index 000000000..89cd43474
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/InvokeInstruction.java
@@ -0,0 +1,137 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.util.StringTokenizer;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Constant;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * Super class for the INVOKExxx family of instructions.
+ *
+ * @version $Id: InvokeInstruction.java,v 1.6 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class InvokeInstruction extends FieldOrMethod {
+
+ /**
+ * @param index to constant pool
+ */
+ public InvokeInstruction(short opcode, int index) {
+ super(opcode, index);
+ }
+
+ /**
+ * @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
+ */
+ public int consumeStack(ConstantPool cpg) {
+ String signature = getSignature(cpg);
+ int sum = Type.getArgumentSizes(signature);
+ if (opcode != Constants.INVOKESTATIC) {
+ sum += 1;
+ }
+ 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
+ */
+ public int produceStack(ConstantPool cpg) {
+ return getReturnType(cpg).getSize();
+ }
+
+ /**
+ * @return return type of referenced method.
+ */
+ public Type getType(ConstantPool cpg) {
+ return getReturnType(cpg);
+ }
+
+ /**
+ * @return name of referenced method.
+ */
+ public String getMethodName(ConstantPool cpg) {
+ return getName(cpg);
+ }
+
+ /**
+ * @return return type of referenced method.
+ */
+ public Type getReturnType(ConstantPool cpg) {
+ return Type.getReturnType(getSignature(cpg));
+ }
+
+ /**
+ * @return argument types of referenced method.
+ */
+ public Type[] getArgumentTypes(ConstantPool cpg) {
+ return Type.getArgumentTypes(getSignature(cpg));
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java
new file mode 100644
index 000000000..c8ebcba4c
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LOOKUPSWITCH.java
@@ -0,0 +1,112 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.util.ByteSequence;
+
+/**
+ * LOOKUPSWITCH - Switch with unordered set of values
+ *
+ * @version $Id: LOOKUPSWITCH.java,v 1.5 2011/04/05 15:15:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class LOOKUPSWITCH extends InstructionSelect {
+
+ public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) {
+ super(LOOKUPSWITCH, match, targets, target);
+ // Alignment remainer assumed 0 here, until dump time
+ length = (short) (9 + matchLength * 8);
+ fixedLength = length;
+ }
+
+ /**
+ * Dump instruction as byte code to stream out.
+ *
+ * @param out Output stream
+ */
+ public void dump(DataOutputStream out) throws IOException {
+ super.dump(out);
+ out.writeInt(matchLength); // npairs
+
+ for (int i = 0; i < matchLength; i++) {
+ out.writeInt(match[i]); // match-offset pairs
+ out.writeInt(indices[i] = getTargetOffset(targets[i]));
+ }
+ }
+
+ /**
+ * Read needed data (e.g. index) from file.
+ */
+ public LOOKUPSWITCH(ByteSequence bytes) throws IOException {
+ super(Constants.LOOKUPSWITCH, bytes); // reads padding
+
+ matchLength = bytes.readInt();
+ fixedLength = (short) (9 + matchLength * 8);
+ length = (short) (fixedLength + padding);
+
+ match = new int[matchLength];
+ indices = new int[matchLength];
+ targets = new InstructionHandle[matchLength];
+
+ for (int i = 0; i < matchLength; i++) {
+ match[i] = bytes.readInt();
+ indices[i] = bytes.readInt();
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java
new file mode 100644
index 000000000..237720c7b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberGen.java
@@ -0,0 +1,130 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.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.
+ *
+ * @version $Id: LineNumberGen.java,v 1.5 2008/05/28 23:53:00 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see LineNumber
+ * @see MethodGen
+ */
+public class LineNumberGen
+ implements InstructionTargeter, Cloneable, java.io.Serializable
+{
+ 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);
+ }
+
+ /**
+ * @return true, if ih is target of this line number
+ */
+ public boolean containsTarget(InstructionHandle ih) {
+ return 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);
+ }
+
+ /**
+ * 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) {
+ InstructionBranch.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; }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java
new file mode 100644
index 000000000..fe1d56c27
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LineNumberTag.java
@@ -0,0 +1,44 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+
+package org.aspectj.apache.bcel.generic;
+
+/**
+ * we don't actually target instructions, but instructions target us.
+ */
+public class LineNumberTag extends Tag {
+
+ private final int lineNumber;
+
+ public LineNumberTag(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ public String toString() {
+ return "line " + lineNumber;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof LineNumberTag)) return false;
+ return lineNumber == ((LineNumberTag)other).lineNumber;
+ }
+
+ public int hashCode() {
+ return lineNumber;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java
new file mode 100644
index 000000000..b701e7274
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableGen.java
@@ -0,0 +1,220 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.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.
+ *
+ * @version $Id: LocalVariableGen.java,v 1.7 2008/08/28 00:04:23 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see LocalVariable
+ * @see MethodGen
+ */
+public class LocalVariableGen implements InstructionTargeter, Cloneable, java.io.Serializable {
+ 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);
+ }
+
+ /**
+ * 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 il instruction list (byte code) which this variable belongs to
+ * @param cp constant pool
+ */
+ public LocalVariable getLocalVariable(ConstantPool 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);
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setType(Type type) {
+ this.type = type;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public InstructionHandle getStart() {
+ return start;
+ }
+
+ public InstructionHandle getEnd() {
+ return end;
+ }
+
+ public void setStart(InstructionHandle start) {
+ InstructionBranch.notifyTarget(this.start, start, this);
+ this.start = start;
+ }
+
+ public void setEnd(InstructionHandle end) {
+ InstructionBranch.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;
+ }
+
+ /**
+ * 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;
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java
new file mode 100644
index 000000000..7a4fab4e9
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/LocalVariableTag.java
@@ -0,0 +1,96 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.generic;
+
+public final class LocalVariableTag extends Tag {
+ private final String signature;
+ private String name;
+ private int slot;
+ private final int startPosition;
+ private boolean remapped = false;
+
+ private int hashCode = 0;
+ private Type type; // not always known, in which case signature has to be used
+
+ // AMC - pr101047, two local vars with the same name can share the same slot, but must in that case
+ // have different start positions.
+ public LocalVariableTag(String signature, String name, int slot, int startPosition) {
+ this.signature = signature;
+ this.name = name;
+ this.slot = slot;
+ this.startPosition = startPosition;
+ }
+
+ public LocalVariableTag(Type type, String signature, String name, int slot, int startPosition) {
+ this.type = type;
+ this.signature = signature;
+ this.name = name;
+ this.slot = slot;
+ this.startPosition = startPosition;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getSlot() {
+ return slot;
+ }
+
+ public String getType() {
+ return signature;
+ }
+
+ public Type getRealType() {
+ return type;
+ }
+
+ public void updateSlot(int newSlot) {
+ this.slot = newSlot;
+ this.remapped = true;
+ this.hashCode = 0;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ this.hashCode = 0;
+ }
+
+ public boolean isRemapped() {
+ return this.remapped;
+ }
+
+ public String toString() {
+ return "local " + slot + ": " + signature + " " + name;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof LocalVariableTag)) {
+ return false;
+ }
+ LocalVariableTag o = (LocalVariableTag) other;
+ return o.slot == slot && o.startPosition == startPosition && o.signature.equals(signature) && o.name.equals(name);
+ }
+
+ public int hashCode() {
+ if (hashCode == 0) {
+ int ret = signature.hashCode();
+ ret = 37 * ret + name.hashCode();
+ ret = 37 * ret + slot;
+ ret = 37 * ret + startPosition;
+ hashCode = ret;
+ }
+ return hashCode;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java
new file mode 100644
index 000000000..94a213a25
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java
@@ -0,0 +1,183 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.ExceptionConstants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * MULTIANEWARRAY - Create new mutidimensional array of references
+ *
+ * <PRE>
+ * Stack: ..., count1, [count2, ...] -&gt; ..., arrayref
+ * </PRE>
+ *
+ * @version $Id: MULTIANEWARRAY.java,v 1.4 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class MULTIANEWARRAY extends InstructionCP {
+ private short dimensions;
+
+ public MULTIANEWARRAY(int index, short dimensions) {
+ super(Constants.MULTIANEWARRAY, index);
+ this.dimensions = 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);
+ }
+
+ /**
+ * 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;
+ // }
+
+ /**
+ * @return number of dimensions to be created
+ */
+ public final short getDimensions() {
+ return dimensions;
+ }
+
+ /**
+ * @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(ConstantPool 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(ConstantPool 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);
+ // }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof MULTIANEWARRAY)) {
+ return false;
+ }
+ MULTIANEWARRAY o = (MULTIANEWARRAY) other;
+ return o.opcode == opcode && o.index == index && o.dimensions == dimensions;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + index * (dimensions + 17);
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java
new file mode 100644
index 000000000..3938beb35
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/MethodGen.java
@@ -0,0 +1,1169 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.Code;
+import org.aspectj.apache.bcel.classfile.CodeException;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.ExceptionTable;
+import org.aspectj.apache.bcel.classfile.LineNumber;
+import org.aspectj.apache.bcel.classfile.LineNumberTable;
+import org.aspectj.apache.bcel.classfile.LocalVariable;
+import org.aspectj.apache.bcel.classfile.LocalVariableTable;
+import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.classfile.Utility;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnos;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeParamAnnos;
+
+/**
+ * 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.
+ *
+ * @version $Id: MethodGen.java,v 1.17 2011/05/19 23:23:46 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
+ * @see InstructionList
+ * @see Method
+ */
+public class MethodGen extends FieldGenOrMethodGen {
+ private String classname;
+ private Type[] parameterTypes;
+ private String[] parameterNames;
+ private int maxLocals;
+ private int maxStack;
+ private InstructionList il;
+
+ // Indicates whether to produce code attributes for LineNumberTable and LocalVariableTable, like javac -O
+ private boolean stripAttributes;
+
+ private int highestLineNumber = 0;
+
+ private ArrayList<LocalVariableGen> localVariablesList = new ArrayList<LocalVariableGen>();
+ private ArrayList<LineNumberGen> lineNumbersList = new ArrayList<LineNumberGen>();
+ private ArrayList<CodeExceptionGen> exceptionsList = new ArrayList<CodeExceptionGen>();
+ private ArrayList<String> exceptionsThrown = new ArrayList<String>();
+ private ArrayList<Attribute> codeAttributesList = new ArrayList<Attribute>();
+ private List<AnnotationGen>[] param_annotations; // Array of lists containing AnnotationGen objects
+ private boolean hasParameterAnnotations = false;
+ private boolean haveUnpackedParameterAnnotations = false;
+
+ /**
+ * 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, ConstantPool cp) {
+
+ this.modifiers = access_flags;
+ this.type = return_type;
+ this.parameterTypes = arg_types;
+ this.parameterNames = arg_names;
+ this.name = method_name;
+ this.classname = class_name;
+ this.il = il;
+ this.cp = cp;
+
+ // OPTIMIZE this code messes with the local variables - do we need it?
+ // 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);
+ // }
+ // }
+ // }
+ }
+
+ public int getHighestlinenumber() {
+ return highestLineNumber;
+ }
+
+ /**
+ * 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, ConstantPool cp) {
+ this(m, class_name, cp, false);
+ }
+
+ // OPTIMIZE should always use tags and never anything else!
+ public MethodGen(Method m, String class_name, ConstantPool cp, boolean useTags) {
+ this(m.getModifiers(),
+ // OPTIMIZE implementation of getReturnType() and getArgumentTypes() on Method seems weak
+ m.getReturnType(), m.getArgumentTypes(), null /* may be overridden anyway */, m.getName(), class_name, ((m
+ .getModifiers() & (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 code = (Code) a;
+ setMaxStack(code.getMaxStack());
+ setMaxLocals(code.getMaxLocals());
+
+ CodeException[] ces = code.getExceptionTable();
+
+ InstructionHandle[] arrayOfInstructions = il.getInstructionsAsArray();
+
+ // process the exception table
+ // -
+ if (ces != null) {
+ for (CodeException ce : ces) {
+ int type = ce.getCatchType();
+ ObjectType catchType = null;
+
+ if (type > 0) {
+ String cen = m.getConstantPool().getConstantString_CONSTANTClass(type);
+ catchType = 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, arrayOfInstructions);// il.findHandle(end_pc);
+ end = end.getPrev(); // Make it inclusive
+ }
+
+ addExceptionHandler(il.findHandle(ce.getStartPC(), arrayOfInstructions), end, il.findHandle(ce
+ .getHandlerPC(), arrayOfInstructions), catchType);
+ }
+ }
+
+ Attribute[] codeAttrs = code.getAttributes();
+ for (int j = 0; j < codeAttrs.length; j++) {
+ a = codeAttrs[j];
+
+ if (a instanceof LineNumberTable) {
+ LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable();
+ if (useTags) {
+ // abracadabra, lets create tags rather than linenumbergens.
+ for (int k = 0; k < ln.length; k++) {
+ LineNumber l = ln[k];
+ int lnum = l.getLineNumber();
+ if (lnum > highestLineNumber) {
+ highestLineNumber = lnum;
+ }
+ LineNumberTag lt = new LineNumberTag(lnum);
+ il.findHandle(l.getStartPC(), arrayOfInstructions, true).addTargeter(lt);
+ }
+ } else {
+ for (int k = 0; k < ln.length; k++) {
+ LineNumber l = ln[k];
+ addLineNumber(il.findHandle(l.getStartPC(), arrayOfInstructions, true), l.getLineNumber());
+ }
+ }
+ } else if (a instanceof LocalVariableTable) {
+
+ // Lets have a go at creating Tags directly
+ if (useTags) {
+ LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
+
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ Type t = Type.getType(l.getSignature());
+ LocalVariableTag lvt = new LocalVariableTag(t, l.getSignature(), l.getName(), l.getIndex(), l
+ .getStartPC());
+ InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions, true);
+ byte b = t.getType();
+ if (b != Constants.T_ADDRESS) {
+ int increment = t.getSize();
+ if (l.getIndex() + increment > maxLocals) {
+ maxLocals = l.getIndex() + increment;
+ }
+ }
+ int end = l.getStartPC() + l.getLength();
+ do {
+ start.addTargeter(lvt);
+ start = start.getNext();
+ } while (start != null && start.getPosition() < end);
+ }
+ } else {
+
+ LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
+
+ removeLocalVariables();
+
+ for (int k = 0; k < lv.length; k++) {
+ LocalVariable l = lv[k];
+ InstructionHandle start = il.findHandle(l.getStartPC(), arrayOfInstructions);
+ InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions);
+ // AMC, this actually gives us the first instruction AFTER the range,
+ // so move back one... (findHandle can't cope with mid-instruction indices)
+ if (end != null) {
+ end = end.getPrev();
+ }
+ // 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 if (a instanceof RuntimeAnnos) {
+ RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) a;
+ List<AnnotationGen> l = runtimeAnnotations.getAnnotations();
+ annotationList.addAll(l);
+ // for (Iterator<AnnotationGen> it = l.iterator(); it.hasNext();) {
+ // AnnotationGen element = it.next();
+ // addAnnotation(new AnnotationGen(element, cp, false));
+ // }
+ } else {
+ addAttribute(a);
+ }
+ }
+ }
+
+ public LocalVariableGen addLocalVariable(String name, Type type, int slot, InstructionHandle start, InstructionHandle end) {
+ int size = type.getSize();
+ if (slot + size > maxLocals) {
+ maxLocals = slot + size;
+ }
+ LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
+ int i = localVariablesList.indexOf(l);
+ if (i >= 0) {
+ localVariablesList.set(i, l); // Overwrite if necessary
+ } else {
+ localVariablesList.add(l);
+ }
+ return l;
+ }
+
+ /**
+ * 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, maxLocals, 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) {
+ localVariablesList.remove(l);
+ }
+
+ /**
+ * Remove all local variables.
+ */
+ public void removeLocalVariables() {
+ localVariablesList.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 = localVariablesList.size();
+ LocalVariableGen[] lg = new LocalVariableGen[size];
+ localVariablesList.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(ConstantPool 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);
+ }
+
+ /**
+ * 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);
+ lineNumbersList.add(l);
+ return l;
+ }
+
+ /**
+ * Remove a line number.
+ */
+ public void removeLineNumber(LineNumberGen l) {
+ lineNumbersList.remove(l);
+ }
+
+ /**
+ * Remove all line numbers.
+ */
+ public void removeLineNumbers() {
+ lineNumbersList.clear();
+ }
+
+ /*
+ * @return array of line numbers
+ */
+ public LineNumberGen[] getLineNumbers() {
+ LineNumberGen[] lg = new LineNumberGen[lineNumbersList.size()];
+ lineNumbersList.toArray(lg);
+ return lg;
+ }
+
+ /**
+ * @return 'LineNumberTable' attribute for all the local variables of this method.
+ */
+ public LineNumberTable getLineNumberTable(ConstantPool cp) {
+ int size = lineNumbersList.size();
+ LineNumber[] ln = new LineNumber[size];
+
+ for (int i = 0; i < size; i++) {
+ ln[i] = lineNumbersList.get(i).getLineNumber();
+ }
+
+ return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp);
+ }
+
+ /**
+ * 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);
+ exceptionsList.add(c);
+ return c;
+ }
+
+ /**
+ * Remove an exception handler.
+ */
+ public void removeExceptionHandler(CodeExceptionGen c) {
+ exceptionsList.remove(c);
+ }
+
+ /**
+ * Remove all line numbers.
+ */
+ public void removeExceptionHandlers() {
+ exceptionsList.clear();
+ }
+
+ /*
+ * @return array of declared exception handlers
+ */
+ public CodeExceptionGen[] getExceptionHandlers() {
+ CodeExceptionGen[] cg = new CodeExceptionGen[exceptionsList.size()];
+ exceptionsList.toArray(cg);
+ return cg;
+ }
+
+ /**
+ * @return code exceptions for `Code' attribute
+ */
+ private CodeException[] getCodeExceptions() {
+ int size = exceptionsList.size();
+ CodeException[] c_exc = new CodeException[size];
+
+ try {
+ for (int i = 0; i < size; i++) {
+ CodeExceptionGen c = exceptionsList.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) {
+ exceptionsThrown.add(class_name);
+ }
+
+ /**
+ * Remove an exception.
+ */
+ public void removeException(String c) {
+ exceptionsThrown.remove(c);
+ }
+
+ /**
+ * Remove all exceptions.
+ */
+ public void removeExceptions() {
+ exceptionsThrown.clear();
+ }
+
+ /*
+ * @return array of thrown exceptions
+ */
+ public String[] getExceptions() {
+ String[] e = new String[exceptionsThrown.size()];
+ exceptionsThrown.toArray(e);
+ return e;
+ }
+
+ /**
+ * @return `Exceptions' attribute of all the exceptions thrown by this method.
+ */
+ private ExceptionTable getExceptionTable(ConstantPool cp) {
+ int size = exceptionsThrown.size();
+ int[] ex = new int[size];
+
+ try {
+ for (int i = 0; i < size; i++) {
+ ex[i] = cp.addClass(exceptionsThrown.get(i));
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+
+ return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp);
+ }
+
+ /**
+ * 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) {
+ codeAttributesList.add(a);
+ }
+
+ public void addParameterAnnotationsAsAttribute(ConstantPool cp) {
+ if (!hasParameterAnnotations) {
+ return;
+ }
+ Attribute[] attrs = Utility.getParameterAnnotationAttributes(cp, param_annotations);
+ if (attrs != null) {
+ for (int i = 0; i < attrs.length; i++) {
+ addAttribute(attrs[i]);
+ }
+ }
+ }
+
+ /**
+ * Remove a code attribute.
+ */
+ public void removeCodeAttribute(Attribute a) {
+ codeAttributesList.remove(a);
+ }
+
+ /**
+ * Remove all code attributes.
+ */
+ public void removeCodeAttributes() {
+ codeAttributesList.clear();
+ }
+
+ /**
+ * @return all attributes of this method.
+ */
+ public Attribute[] getCodeAttributes() {
+ Attribute[] attributes = new Attribute[codeAttributesList.size()];
+ codeAttributesList.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) {
+ try {
+ byte_code = il.getByteCode();
+ } catch (Exception e) {
+ throw new IllegalStateException("Unexpected problem whilst preparing bytecode for " + this.getClassName() + "."
+ + this.getName() + this.getSignature(), e);
+ }
+ }
+
+ LineNumberTable lnt = null;
+ LocalVariableTable lvt = null;
+ // J5TODO: LocalVariableTypeTable support!
+
+ /*
+ * Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
+ */
+ if ((localVariablesList.size() > 0) && !stripAttributes) {
+ addCodeAttribute(lvt = getLocalVariableTable(cp));
+ }
+
+ if ((lineNumbersList.size() > 0) && !stripAttributes) {
+ 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()) {
+ // Remove any stale code attribute
+ List<Attribute> attributes = getAttributes();
+ for (int i = 0; i < attributes.size(); i++) {
+ Attribute a = attributes.get(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
+ maxStack, maxLocals, byte_code, c_exc, code_attrs, cp);
+
+ addAttribute(code);
+ }
+
+ addAnnotationsAsAttribute(cp);
+ addParameterAnnotationsAsAttribute(cp);
+
+ ExceptionTable et = null;
+
+ if (exceptionsThrown.size() > 0) {
+ addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses
+ }
+
+ Method m = new Method(modifiers, name_index, signature_index, getAttributesImmutable(), cp);
+
+ // Undo effects of adding attributes
+ // OPTIMIZE why redo this? is there a better way to clean up?
+ if (lvt != null) {
+ removeCodeAttribute(lvt);
+ }
+ if (lnt != null) {
+ removeCodeAttribute(lnt);
+ }
+ if (code != null) {
+ removeAttribute(code);
+ }
+ if (et != null) {
+ removeAttribute(et);
+ }
+ // J5TODO: Remove the annotation attributes that may have been added
+ return m;
+ }
+
+ /**
+ * Set maximum number of local variables.
+ */
+ public void setMaxLocals(int m) {
+ maxLocals = m;
+ }
+
+ public int getMaxLocals() {
+ return maxLocals;
+ }
+
+ /**
+ * Set maximum stack size for this method.
+ */
+ public void setMaxStack(int m) {
+ maxStack = m;
+ }
+
+ public int getMaxStack() {
+ return maxStack;
+ }
+
+ /**
+ * @return class that contains this method
+ */
+ public String getClassName() {
+ return classname;
+ }
+
+ public void setClassName(String class_name) {
+ this.classname = class_name;
+ }
+
+ public void setReturnType(Type return_type) {
+ setType(return_type);
+ }
+
+ public Type getReturnType() {
+ return getType();
+ }
+
+ public void setArgumentTypes(Type[] arg_types) {
+ this.parameterTypes = arg_types;
+ }
+
+ public Type[] getArgumentTypes() {
+ return this.parameterTypes;
+ }// OPTIMIZE dont need clone here? (Type[])arg_types.clone(); }
+
+ public void setArgumentType(int i, Type type) {
+ parameterTypes[i] = type;
+ }
+
+ public Type getArgumentType(int i) {
+ return parameterTypes[i];
+ }
+
+ public void setArgumentNames(String[] arg_names) {
+ this.parameterNames = arg_names;
+ }
+
+ public String[] getArgumentNames() {
+ if (parameterNames != null) {
+ return parameterNames.clone();
+ } else {
+ return new String[0];
+ }
+ }
+
+ public void setArgumentName(int i, String name) {
+ parameterNames[i] = name;
+ }
+
+ public String getArgumentName(int i) {
+ return parameterNames[i];
+ }
+
+ public InstructionList getInstructionList() {
+ return il;
+ }
+
+ public void setInstructionList(InstructionList il) {
+ this.il = il;
+ }
+
+ @Override
+ public String getSignature() {
+ return Utility.toMethodSignature(type, parameterTypes);
+ }
+
+ /**
+ * Computes max. stack size by performing control flow analysis.
+ */
+ public void setMaxStack() {
+ if (il != null) {
+ maxStack = getMaxStack(cp, il, getExceptionHandlers());
+ } else {
+ maxStack = 0;
+ }
+ }
+
+ /**
+ * Compute maximum number of local variables based on the parameter count and bytecode usage of variables.
+ */
+ public void setMaxLocals() {
+ setMaxLocals(false);
+ }
+
+ /**
+ * Compute maximum number of local variables.
+ *
+ * @param respectLocalVariableTable if true and the local variable table indicates more are in use
+ * than the code suggests, respect the higher value from the local variable table data.
+ */
+ public void setMaxLocals(boolean respectLocalVariableTable) {
+ if (il != null) {
+ int max = isStatic() ? 0 : 1;
+
+ if (parameterTypes != null) {
+ for (int i = 0; i < parameterTypes.length; i++) {
+ max += parameterTypes[i].getSize();
+ }
+ }
+
+ for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
+ Instruction ins = ih.getInstruction();
+
+ if ((ins instanceof InstructionLV) || (ins instanceof RET)) {
+ int index = ins.getIndex() + ins.getType(cp).getSize();
+
+ if (index > max) {
+ max = index;
+ }
+ }
+ }
+ if (!respectLocalVariableTable || max > maxLocals) {
+ maxLocals = max;
+ }
+ } else {
+ if (!respectLocalVariableTable) {
+ maxLocals = 0;
+ }
+ }
+ }
+
+ public void stripAttributes(boolean flag) {
+ stripAttributes = 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<BranchTarget> branchTargets = new Stack<BranchTarget>();
+ Hashtable<InstructionHandle, BranchTarget> visitedTargets = new Hashtable<InstructionHandle, BranchTarget>();
+
+ 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(ConstantPool cp, InstructionList il, CodeExceptionGen[] et) {
+ BranchStack branchTargets = new BranchStack();
+
+ int stackDepth = 0;
+ int maxStackDepth = 0;
+
+ /*
+ * 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, max = et.length; i < max; i++) {
+ InstructionHandle handlerPos = et[i].getHandlerPC();
+ if (handlerPos != null) {
+ // it must be at least 1 since there is an exception handler
+ maxStackDepth = 1;
+ branchTargets.push(handlerPos, 1);
+ }
+ }
+
+ InstructionHandle ih = il.getStart();
+ while (ih != null) {
+ Instruction instruction = ih.getInstruction();
+ short opcode = instruction.opcode;
+ int prod = instruction.produceStack(cp);
+ int con = instruction.consumeStack(cp);
+ int delta = prod - con;
+
+ stackDepth += delta;
+ if (stackDepth > maxStackDepth) {
+ maxStackDepth = stackDepth;
+ }
+
+ // choose the next instruction based on whether current is a branch.
+ if (instruction instanceof InstructionBranch) {
+ InstructionBranch branch = (InstructionBranch) instruction;
+ if (instruction instanceof InstructionSelect) {
+ // explore all of the select's targets. the default target is handled below.
+ InstructionSelect select = (InstructionSelect) 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.isIfInstruction())) {
+ // 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;
+ }
+
+ /**
+ * 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(modifiers);
+ String signature = Utility.toMethodSignature(type, parameterTypes);
+
+ signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable(cp));
+
+ StringBuffer buf = new StringBuffer(signature);
+
+ if (exceptionsThrown.size() > 0) {
+ for (Iterator<String> e = exceptionsThrown.iterator(); e.hasNext();) {
+ buf.append("\n\t\tthrows " + e.next());
+ }
+ }
+
+ return buf.toString();
+ }
+
+ // J5TODO: Should param_annotations be an array of arrays? Rather than an array of lists, this
+ // is more likely to suggest to the caller it is readonly (which a List does not).
+ /**
+ * Return a list of AnnotationGen objects representing parameter annotations
+ */
+ public List<AnnotationGen> getAnnotationsOnParameter(int i) {
+ ensureExistingParameterAnnotationsUnpacked();
+ if (!hasParameterAnnotations || i > parameterTypes.length) {
+ return null;
+ }
+ return param_annotations[i];
+ }
+
+ /**
+ * Goes through the attributes on the method and identifies any that are RuntimeParameterAnnotations, extracting their contents
+ * and storing them as parameter annotations. There are two kinds of parameter annotation - visible and invisible. Once they
+ * have been unpacked, these attributes are deleted. (The annotations will be rebuilt as attributes when someone builds a Method
+ * object out of this MethodGen object).
+ */
+ private void ensureExistingParameterAnnotationsUnpacked() {
+ if (haveUnpackedParameterAnnotations) {
+ return;
+ }
+ // Find attributes that contain parameter annotation data
+ List<Attribute> attrs = getAttributes();
+ RuntimeParamAnnos paramAnnVisAttr = null;
+ RuntimeParamAnnos paramAnnInvisAttr = null;
+
+ for (Attribute attribute : attrs) {
+ if (attribute instanceof RuntimeParamAnnos) {
+
+ if (!hasParameterAnnotations) {
+ param_annotations = new List[parameterTypes.length];
+ for (int j = 0; j < parameterTypes.length; j++) {
+ param_annotations[j] = new ArrayList<AnnotationGen>();
+ }
+ }
+
+ hasParameterAnnotations = true;
+ RuntimeParamAnnos rpa = (RuntimeParamAnnos) attribute;
+ if (rpa.areVisible()) {
+ paramAnnVisAttr = rpa;
+ } else {
+ paramAnnInvisAttr = rpa;
+ }
+ for (int j = 0; j < parameterTypes.length; j++) {
+ // This returns Annotation[] ...
+ AnnotationGen[] annos = rpa.getAnnotationsOnParameter(j);
+ // ... which needs transforming into an AnnotationGen[] ...
+ // List<AnnotationGen> mutable = makeMutableVersion(immutableArray);
+ // ... then add these to any we already know about
+ for (AnnotationGen anAnnotation : annos) {
+ param_annotations[j].add(anAnnotation);
+ }
+ }
+ }
+ }
+ if (paramAnnVisAttr != null) {
+ removeAttribute(paramAnnVisAttr);
+ }
+ if (paramAnnInvisAttr != null) {
+ removeAttribute(paramAnnInvisAttr);
+ }
+ haveUnpackedParameterAnnotations = true;
+ }
+
+ private List /* AnnotationGen */<AnnotationGen> makeMutableVersion(AnnotationGen[] mutableArray) {
+ List<AnnotationGen> result = new ArrayList<AnnotationGen>();
+ for (int i = 0; i < mutableArray.length; i++) {
+ result.add(new AnnotationGen(mutableArray[i], getConstantPool(), false));
+ }
+ return result;
+ }
+
+ public void addParameterAnnotation(int parameterIndex, AnnotationGen annotation) {
+ ensureExistingParameterAnnotationsUnpacked();
+ if (!hasParameterAnnotations) {
+ param_annotations = new List[parameterTypes.length];
+ hasParameterAnnotations = true;
+ }
+ List<AnnotationGen> existingAnnotations = param_annotations[parameterIndex];
+ if (existingAnnotations != null) {
+ existingAnnotations.add(annotation);
+ } else {
+ List<AnnotationGen> l = new ArrayList<AnnotationGen>();
+ l.add(annotation);
+ param_annotations[parameterIndex] = l;
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java
new file mode 100644
index 000000000..544363f16
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ObjectType.java
@@ -0,0 +1,161 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.Repository;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+
+/**
+ * Denotes reference such as java.lang.String.
+ *
+ * @version $Id: ObjectType.java,v 1.7 2009/09/28 16:39:46 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class ObjectType extends ReferenceType {
+ private String classname;
+
+ /**
+ * @param class_name fully qualified class name, e.g. java.lang.String
+ */
+ public ObjectType(String class_name) {
+ super(Constants.T_REFERENCE, toSignature(class_name));// "L" + class_name.replace('.', '/') + ";");
+ this.classname = class_name;// .replace('/', '.');
+ }
+
+ /**
+ * @param classname eg. java.lang.String
+ * @param signature eg. Ljava/lang/String;
+ */
+ public ObjectType(String classname, String signature) {
+ super(Constants.T_REFERENCE, signature);
+ this.classname = classname;
+ }
+
+ private static String toSignature(String classname) {
+ StringBuffer sig = new StringBuffer();
+ sig.append("L").append(classname.replace('.', '/'));
+ sig.append(";");
+ return sig.toString();
+ }
+
+ /**
+ * @return name of referenced class
+ */
+ public String getClassName() {
+ return classname;
+ }
+
+ /**
+ * @return a hash code value for the object.
+ */
+ @Override
+ public int hashCode() {
+ return classname.hashCode();
+ }
+
+ /**
+ * @return true if both type objects refer to the same class.
+ */
+ @Override
+ public boolean equals(Object type) {
+ return (type instanceof ObjectType) ? ((ObjectType) type).classname.equals(classname) : false;
+ }
+
+ /**
+ * If "this" doesn't reference a class, it references an interface or a non-existant entity.
+ */
+ public boolean referencesClass() {
+ JavaClass jc = Repository.lookupClass(classname);
+ if (jc == null) {
+ return false;
+ } else {
+ return jc.isClass();
+ }
+ }
+
+ /**
+ * If "this" doesn't reference an interface, it references a class or a non-existant entity.
+ */
+ public boolean referencesInterface() {
+ JavaClass jc = Repository.lookupClass(classname);
+ if (jc == null) {
+ return false;
+ } else {
+ return !jc.isClass();
+ }
+ }
+
+ public boolean subclassOf(ObjectType superclass) {
+ if (this.referencesInterface() || superclass.referencesInterface()) {
+ return false;
+ }
+
+ return Repository.instanceOf(this.classname, superclass.classname);
+ }
+
+ /**
+ * Java Virtual Machine Specification edition 2, 5.4.4 Access Control
+ */
+ public boolean accessibleTo(ObjectType accessor) {
+ JavaClass jc = Repository.lookupClass(classname);
+
+ if (jc.isPublic()) {
+ return true;
+ } else {
+ JavaClass acc = Repository.lookupClass(accessor.classname);
+ return acc.getPackageName().equals(jc.getPackageName());
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java
new file mode 100644
index 000000000..0fd2f498d
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/RET.java
@@ -0,0 +1,132 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
+
+/**
+ * RET - Return from subroutine
+ *
+ * <PRE>
+ * Stack: ..., -&gt; ..., address
+ * </PRE>
+ *
+ * @version $Id: RET.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public class RET extends Instruction {
+ private boolean wide;
+ private int index; // index to local variable containing the return address
+
+ public RET(int index, boolean wide) {
+ super(Constants.RET);
+ this.index = index;
+ this.wide = wide;
+ // this.wide = index > org.aspectj.apache.bcel.Constants.MAX_BYTE;
+ }
+
+ public void dump(DataOutputStream out) throws IOException {
+ if (wide) {
+ out.writeByte(Constants.WIDE);
+ }
+ out.writeByte(opcode);
+ if (wide) {
+ out.writeShort(index);
+ } else {
+ out.writeByte(index);
+ }
+ }
+
+ public int getLength() {
+ if (wide) {
+ return 4;
+ } else {
+ return 2;
+ }
+ }
+
+ public final int getIndex() {
+ return index;
+ }
+
+ public final void setIndex(int index) {
+ this.index = index;
+ this.wide = index > Constants.MAX_BYTE;
+ }
+
+ public String toString(boolean verbose) {
+ return super.toString(verbose) + " " + index;
+ }
+
+ public Type getType(ConstantPool cp) {
+ return ReturnaddressType.NO_TARGET;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof RET)) {
+ return false;
+ }
+ RET o = (RET) other;
+ return o.opcode == opcode && o.index == index;
+ }
+
+ public int hashCode() {
+ return opcode * 37 + index;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java
new file mode 100644
index 000000000..1e290f5a4
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReferenceType.java
@@ -0,0 +1,365 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.Repository;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+
+/**
+ * Super class for object and array types.
+ *
+ * @version $Id: ReferenceType.java,v 1.6 2009/09/09 22:18:20 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public abstract class ReferenceType extends Type {
+
+ protected ReferenceType(byte t, String s) {
+ super(t, s);
+ }
+
+ ReferenceType() {
+ super(Constants.T_OBJECT, "<null 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.
+ */
+ public boolean isCastableTo(Type t) {
+ 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.
+ */
+ public boolean isAssignmentCompatibleWith(Type t) {
+ 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).referencesClass()) {
+ /*
+ * 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).referencesClass()) {
+ 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).referencesInterface()) {
+ if (Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) {
+ return true;
+ }
+ }
+ }
+
+ /*
+ * If this is an interface type, then:
+ */
+ if (this instanceof ObjectType && ((ObjectType) this).referencesInterface()) {
+ /*
+ * If T is a class type, then T must be Object (2.4.7).
+ */
+ if (T instanceof ObjectType && ((ObjectType) T).referencesClass()) {
+ 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).referencesInterface()) {
+ 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).referencesClass()) {
+ 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) this).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).referencesInterface()) {
+ 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".
+ */
+ public ReferenceType getFirstCommonSuperclass(ReferenceType t) {
+ 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 <konst@cs.technion.ac.il> */
+
+ 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.lookupClass(thiz.getClassName()).getSuperClasses();// getSuperClasses(thiz.getClassName());
+ JavaClass[] other_sups = Repository.lookupClass(other.getClassName()).getSuperClasses();// 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.
+ // */
+ // public ReferenceType firstCommonSuperclass(ReferenceType t) {
+ // 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/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java
new file mode 100644
index 000000000..a38ffedfd
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/ReturnaddressType.java
@@ -0,0 +1,102 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.generic.InstructionHandle;
+
+/**
+ * Returnaddress, the type JSR or JSR_W instructions push upon the stack.
+ *
+ * see vmspec2 3.3.3
+ * @version $Id: ReturnaddressType.java,v 1.3 2008/05/28 23:52:56 aclement Exp $
+ * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase">Enver Haase</A>
+ */
+public class ReturnaddressType extends Type {
+
+ 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, "<return address>");
+ }
+
+ /**
+ * Creates a ReturnaddressType object with a target.
+ */
+ public ReturnaddressType(InstructionHandle returnTarget) {
+ super(Constants.T_ADDRESS, "<return address targeting "+returnTarget+">");
+ this.returnTarget = returnTarget;
+ }
+
+ /**
+ * Returns if the two Returnaddresses refer to the same target.
+ */
+ public boolean equals(Object rat){
+ if(!(rat instanceof ReturnaddressType))
+ return false;
+
+ return ((ReturnaddressType)rat).returnTarget.equals(this.returnTarget);
+ }
+
+ /**
+ * @return the target of this ReturnaddressType
+ */
+ public InstructionHandle getTarget(){
+ return returnTarget;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java
new file mode 100644
index 000000000..eac6bf364
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/SwitchBuilder.java
@@ -0,0 +1,181 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * 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: SwitchBuilder.java,v 1.2 2008/05/28 23:52:57 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class SwitchBuilder {
+ private int[] match;
+ private InstructionHandle[] targets;
+ private InstructionSelect 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 SwitchBuilder(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) // (almost) empty switch, or just default
+ if (match.length==0) {
+ instruction = new LOOKUPSWITCH(match,targets,target);
+ } else {
+ 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 SwitchBuilder(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);
+ }
+
+ /**
+ * 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++) {
+ int diff = (match[i]-match[i-1]);
+ if(diff > max_gap || diff<0) return false;
+ }
+ return true;
+ }
+
+ public final InstructionSelect getInstruction() {
+ return instruction;
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java
new file mode 100644
index 000000000..5dc26346b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TABLESWITCH.java
@@ -0,0 +1,138 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.util.ByteSequence;
+
+import com.sun.org.apache.bcel.internal.generic.SWITCH;
+
+/**
+ * TABLESWITCH - Switch within given range of values, i.e., low..high
+ *
+ * @version $Id: TABLESWITCH.java,v 1.5 2008/08/28 00:05:29 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see SWITCH
+ */
+public class TABLESWITCH extends InstructionSelect {
+
+ /**
+ * @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 target default branch
+ */
+ public TABLESWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) {
+ super(org.aspectj.apache.bcel.Constants.TABLESWITCH, match, targets, target);
+
+ // if (match_length==0) {
+ // throw new RuntimeException("A tableswitch with no targets should be represented as a LOOKUPSWITCH");
+ // }
+
+ // Alignment remainder assumed 0 here, until dump time
+ length = (short) (13 + matchLength * 4);
+ fixedLength = length;
+ }
+
+ /**
+ * Dump instruction as byte code to stream out.
+ *
+ * @param out Output stream
+ */
+ public void dump(DataOutputStream out) throws IOException {
+ super.dump(out);
+
+ int low = matchLength > 0 ? match[0] : 0;
+ out.writeInt(low);
+
+ int high = matchLength > 0 ? match[matchLength - 1] : 0;
+ out.writeInt(high);
+
+ // See aj bug pr104720
+ // if (match_length==0) out.writeInt(0); // following the switch you need to supply "HIGH-LOW+1" entries
+
+ for (int i = 0; i < matchLength; i++) {
+ out.writeInt(indices[i] = getTargetOffset(targets[i]));
+ }
+ }
+
+ /**
+ * Read needed data (e.g. index) from file.
+ */
+ public TABLESWITCH(ByteSequence bytes) throws IOException {
+ super(Constants.TABLESWITCH, bytes);
+
+ int low = bytes.readInt();
+ int high = bytes.readInt();
+
+ matchLength = high - low + 1;
+ fixedLength = (short) (13 + matchLength * 4);
+ length = (short) (fixedLength + padding);
+
+ match = new int[matchLength];
+ indices = new int[matchLength];
+ targets = new InstructionHandle[matchLength];
+
+ for (int i = low; i <= high; i++) {
+ match[i - low] = i;
+ }
+
+ for (int i = 0; i < matchLength; i++) {
+ indices[i] = bytes.readInt();
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java
new file mode 100644
index 000000000..1d6935e6d
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Tag.java
@@ -0,0 +1,45 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * PARC initial implementation
+ * Andy Clement pushed down into bcel module
+ * ******************************************************************/
+
+package org.aspectj.apache.bcel.generic;
+
+/**
+ * A tag is an instruction-targeter that does not remember its target. Instruction handles will maintain a list of targeters but
+ * there won't be a way to get back from the tag to the instruction. Maintaining these backward/forward links just slows everything
+ * down.
+ */
+public abstract class Tag implements InstructionTargeter, Cloneable {
+
+ public Tag() {
+ }
+
+ // ---- from InstructionTargeter
+ public boolean containsTarget(InstructionHandle ih) {
+ return false;
+ }
+
+ public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) {
+ oldHandle.removeTargeter(this);
+ if (newHandle != null) {
+ newHandle.addTargeter(this);
+ }
+ }
+
+ public Tag copy() {
+ try {
+ return (Tag) clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Sanity check, can't clone me");
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java
new file mode 100644
index 000000000..3a195705c
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/TargetLostException.java
@@ -0,0 +1,101 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * 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.
+ *
+ * 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:
+ *
+ * <PRE>
+ * ...
+ * try {
+ * 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 j=0; j < targeters.length; j++)
+ * targeters[j].updateTarget(targets[i], new_target);
+ * }
+ * }
+ * </PRE>
+ *
+ * @see InstructionHandle
+ * @see InstructionList
+ * @see InstructionTargeter
+ * @version $Id: TargetLostException.java,v 1.3 2008/05/28 23:52:55 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+// OPTIMIZE make unchecked, or get rid of it!
+public final class TargetLostException extends Exception {
+ private InstructionHandle[] targets;
+
+ TargetLostException(InstructionHandle[] t, String mesg) {
+ super(mesg);
+ targets = t;
+ }
+
+ /**
+ * @return list of instructions still being targeted.
+ */
+ public InstructionHandle[] getTargets() { return targets; }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java
new file mode 100644
index 000000000..9ce007b4f
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/generic/Type.java
@@ -0,0 +1,508 @@
+package org.aspectj.apache.bcel.generic;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.ConstantsInitializer;
+import org.aspectj.apache.bcel.classfile.ClassFormatException;
+import org.aspectj.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[]
+ *
+ * @version $Id: Type.java,v 1.14 2011/09/28 01:14:54 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ *
+ * modified: AndyClement 2-mar-05: Removed unnecessary static and optimized
+ */
+public abstract class Type {
+ protected byte type;
+ protected String signature;
+
+ /* 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 STRING = new ObjectType("java.lang.String");
+ public static final ArrayType OBJECT_ARRAY = new ArrayType("java.lang.Object",1);
+ public static final ArrayType STRING_ARRAY = new ArrayType("java.lang.String",1);
+ public static final ArrayType CLASS_ARRAY = new ArrayType("java.lang.Class",1);
+ public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer");
+ public static final ObjectType STRINGBUILDER = new ObjectType("java.lang.StringBuilder");
+ public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable");
+ public static final ObjectType CLASS = new ObjectType("java.lang.Class");
+ public static final ObjectType INTEGER = new ObjectType("java.lang.Integer");
+ public static final ObjectType EXCEPTION = new ObjectType("java.lang.Exception");
+ public static final ObjectType LIST = new ObjectType("java.util.List");
+ public static final ObjectType ITERATOR = new ObjectType("java.util.Iterator");
+ 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, "<unknown object>") {
+ };
+ public static final Type[] STRINGARRAY1 = new Type[] { STRING };
+ public static final Type[] STRINGARRAY2 = new Type[] { STRING, STRING };
+ public static final Type[] STRINGARRAY3 = new Type[] { STRING, STRING, STRING };
+ public static final Type[] STRINGARRAY4 = new Type[] { STRING, STRING, STRING, STRING };
+ public static final Type[] STRINGARRAY5 = new Type[] { STRING, STRING, STRING, STRING, STRING };
+ public static final Type[] STRINGARRAY6 = new Type[] { STRING, STRING, STRING, STRING, STRING, STRING };
+ public static final Type[] STRINGARRAY7 = new Type[] { STRING, STRING, STRING, STRING, STRING, STRING, STRING };
+
+ private static Map<String, Type> commonTypes = new HashMap<String, Type>();
+
+ static {
+ commonTypes.put(STRING.getSignature(), STRING);
+ commonTypes.put(THROWABLE.getSignature(), THROWABLE);
+ commonTypes.put(VOID.getSignature(), VOID);
+ commonTypes.put(BOOLEAN.getSignature(), BOOLEAN);
+ commonTypes.put(BYTE.getSignature(), BYTE);
+ commonTypes.put(SHORT.getSignature(), SHORT);
+ commonTypes.put(CHAR.getSignature(), CHAR);
+ commonTypes.put(INT.getSignature(), INT);
+ commonTypes.put(LONG.getSignature(), LONG);
+ commonTypes.put(DOUBLE.getSignature(), DOUBLE);
+ commonTypes.put(FLOAT.getSignature(), FLOAT);
+ commonTypes.put(CLASS.getSignature(), CLASS);
+ commonTypes.put(OBJECT.getSignature(), OBJECT);
+ commonTypes.put(STRING_ARRAY.getSignature(), STRING_ARRAY);
+ commonTypes.put(CLASS_ARRAY.getSignature(), CLASS_ARRAY);
+ commonTypes.put(OBJECT_ARRAY.getSignature(), OBJECT_ARRAY);
+ commonTypes.put(INTEGER.getSignature(), INTEGER);
+ commonTypes.put(EXCEPTION.getSignature(), EXCEPTION);
+ commonTypes.put(STRINGBUFFER.getSignature(), STRINGBUFFER);
+ commonTypes.put(STRINGBUILDER.getSignature(), STRINGBUILDER);
+ commonTypes.put(LIST.getSignature(), LIST);
+ commonTypes.put(ITERATOR.getSignature(), ITERATOR);
+ ConstantsInitializer.initialize(); // needs calling because it will not have run properly the first time
+ }
+
+ protected Type(byte t, String s) {
+ type = t;
+ signature = s;
+ }
+
+ public String getSignature() {
+ return signature;
+ }
+
+ 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 Type string, e.g. 'int[]'
+ */
+ @Override
+ public String toString() {
+ return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN))) ? signature : Utility
+ .signatureToString(signature, false);
+ }
+
+ public static final Type getType(String signature) {
+ Type t = commonTypes.get(signature);
+ if (t != null) {
+ return t;
+ }
+ byte type = Utility.typeOfSignature(signature);
+ if (type <= Constants.T_VOID) {
+ return BasicType.getType(type);
+ } else if (type == Constants.T_ARRAY) {
+ int dim = 0;
+ do {
+ dim++;
+ } while (signature.charAt(dim) == '[');
+ // Recurse, but just once, if the signature is ok
+ Type componentType = getType(signature.substring(dim));
+ return new ArrayType(componentType, dim);
+ } else { // type == T_REFERENCE
+ // generics awareness
+ int nextAngly = signature.indexOf('<');
+ // Format is 'Lblahblah;'
+ int index = signature.indexOf(';'); // Look for closing ';'
+
+ String typeString = null;
+ if (nextAngly == -1 || nextAngly > index) {
+ typeString = signature.substring(1, index).replace('/', '.');
+ } else {
+ boolean endOfSigReached = false;
+ int posn = nextAngly;
+ int genericDepth = 0;
+ while (!endOfSigReached) {
+ switch (signature.charAt(posn++)) {
+ case '<':
+ genericDepth++;
+ break;
+ case '>':
+ genericDepth--;
+ break;
+ case ';':
+ if (genericDepth == 0) {
+ endOfSigReached = true;
+ }
+ break;
+ default:
+ }
+ }
+ index = posn - 1;
+ typeString = signature.substring(1, nextAngly).replace('/', '.');
+ }
+ // ObjectType doesn't currently store parameterized info
+ return new ObjectType(typeString);
+ }
+ }
+
+ /**
+ * Convert signature to a Type object.
+ *
+ * @param signature signature string such as Ljava/lang/String;
+ * @return type object
+ */
+ public static final TypeHolder getTypeInternal(String signature) throws StringIndexOutOfBoundsException {
+ byte type = Utility.typeOfSignature(signature);
+
+ if (type <= Constants.T_VOID) {
+ return new TypeHolder(BasicType.getType(type), 1);
+ } else if (type == Constants.T_ARRAY) {
+ int dim = 0;
+ do {
+ dim++;
+ } while (signature.charAt(dim) == '[');
+ // Recurse, but just once, if the signature is ok
+ TypeHolder th = getTypeInternal(signature.substring(dim));
+ return new TypeHolder(new ArrayType(th.getType(), dim), dim + th.getConsumed());
+ } else { // type == T_REFERENCE
+ // Format is 'Lblahblah;'
+ int index = signature.indexOf(';'); // Look for closing ';'
+ if (index < 0) {
+ throw new ClassFormatException("Invalid signature: " + signature);
+ }
+
+ // generics awareness
+ int nextAngly = signature.indexOf('<');
+ String typeString = null;
+ if (nextAngly == -1 || nextAngly > index) {
+ typeString = signature.substring(1, index).replace('/', '.');
+ } else {
+ boolean endOfSigReached = false;
+ int posn = nextAngly;
+ int genericDepth = 0;
+ while (!endOfSigReached) {
+ switch (signature.charAt(posn++)) {
+ case '<':
+ genericDepth++;
+ break;
+ case '>':
+ genericDepth--;
+ break;
+ case ';':
+ if (genericDepth == 0) {
+ endOfSigReached = true;
+ }
+ break;
+ default:
+ }
+ }
+ index = posn - 1;
+ typeString = signature.substring(1, nextAngly).replace('/', '.');
+ }
+ // ObjectType doesn't currently store parameterized info
+ return new TypeHolder(new ObjectType(typeString), index + 1);
+ }
+ }
+
+ /**
+ * 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
+ */
+ // OPTIMIZE crap impl
+ public static Type[] getArgumentTypes(String signature) {
+ List<Type> argumentTypes = new ArrayList<Type>();
+ 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) != ')') {
+ TypeHolder th = getTypeInternal(signature.substring(index));
+ argumentTypes.add(th.getType());
+ index += th.getConsumed(); // update position
+ }
+ } catch (StringIndexOutOfBoundsException e) { // Should never occur
+ throw new ClassFormatException("Invalid method signature: " + signature);
+ }
+
+ types = new Type[argumentTypes.size()];
+ argumentTypes.toArray(types);
+ return types;
+ }
+
+ /**
+ * Work out the type of each argument in the signature and return the cumulative sizes of all the types (size means number of
+ * stack slots it consumes, eg double=2, int=1). Unlike the call above, this does minimal unpacking
+ */
+ public static int getArgumentSizes(String signature) {
+ int size = 0;
+ if (signature.charAt(0) != '(') {
+ throw new ClassFormatException("Invalid method signature: " + signature);
+ }
+
+ int index = 1; // current string position
+ try {
+ while (signature.charAt(index) != ')') {
+ byte type = Utility.typeOfSignature(signature.charAt(index));
+ if (type <= Constants.T_VOID) {
+ size += BasicType.getType(type).getSize();
+ index++;
+ } else if (type == Constants.T_ARRAY) {
+ int dim = 0;
+ do {
+ dim++;
+ } while (signature.charAt(dim + index) == '[');
+ TypeHolder th = getTypeInternal(signature.substring(dim + index));
+ size += 1;
+ index += dim + th.getConsumed();
+ } else { // type == T_REFERENCE
+ // Format is 'Lblahblah;'
+ int index2 = signature.indexOf(';', index); // Look for closing ';'
+
+ // generics awareness
+ int nextAngly = signature.indexOf('<', index);
+ if (nextAngly == -1 || nextAngly > index2) {
+ } else {
+ boolean endOfSigReached = false;
+ int posn = nextAngly;
+ int genericDepth = 0;
+ while (!endOfSigReached) {
+ switch (signature.charAt(posn++)) {
+ case '<':
+ genericDepth++;
+ break;
+ case '>':
+ genericDepth--;
+ break;
+ case ';':
+ if (genericDepth == 0) {
+ endOfSigReached = true;
+ }
+ break;
+ default:
+ }
+ }
+ index2 = posn - 1;
+ }
+ size++;
+ index = index2 + 1;
+ }
+ }
+ } catch (StringIndexOutOfBoundsException e) { // Should never occur
+ throw new ClassFormatException("Invalid method signature: " + signature);
+ }
+ return size;
+ }
+
+ /**
+ * Return the size of the type expressed in the signature. The signature should contain only one type.
+ */
+ public static int getTypeSize(String signature) {
+ byte type = Utility.typeOfSignature(signature.charAt(0));
+ if (type <= Constants.T_VOID) {
+ return BasicType.getType(type).getSize();
+ } else if (type == Constants.T_ARRAY) {
+ return 1;
+ } else { // type == T_REFERENCE
+ return 1;
+ }
+ }
+
+ /**
+ * 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 amazingly 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());
+ }
+ }
+
+ 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.Constructor<?> cons) {
+ StringBuffer sb = new StringBuffer("(");
+ Class<?>[] params = cons.getParameterTypes(); // avoid clone
+
+ for (int j = 0; j < params.length; j++) {
+ sb.append(getType(params[j]).getSignature());
+ }
+
+ sb.append(")V");
+ return sb.toString();
+ }
+
+ public static class TypeHolder {
+ private Type t;
+ private int consumed;
+
+ public Type getType() {
+ return t;
+ }
+
+ public int getConsumed() {
+ return consumed;
+ }
+
+ public TypeHolder(Type t, int i) {
+ this.t = t;
+ this.consumed = i;
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java
new file mode 100644
index 000000000..072a7ba52
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ByteSequence.java
@@ -0,0 +1,82 @@
+package org.aspectj.apache.bcel.util;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+import java.io.*;
+
+/**
+ * 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,v 1.3 2008/05/28 23:52:53 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ */
+public final class ByteSequence extends DataInputStream {
+ private ByteArrayStream byte_stream;
+
+ 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(); }
+
+ 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--; }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java
new file mode 100644
index 000000000..f6fcbf5f8
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderReference.java
@@ -0,0 +1,67 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.aspectj.apache.bcel.util;
+
+/**
+ * Implementors should provide access to a ClassLoader instance. The reference can be passed around and cached
+ * but will not cause the code that caches it to have a hard reference to the classloader, so it is easier
+ * to manage the classloader instance. The default implementation will just wrap a classloader object but
+ * more sophisticated implementations could keep a WeakReference to the loader.
+ */
+public interface ClassLoaderReference {
+
+ java.lang.ClassLoader getClassLoader();
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java
new file mode 100644
index 000000000..e3c59556b
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassLoaderRepository.java
@@ -0,0 +1,394 @@
+package org.aspectj.apache.bcel.util;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.aspectj.apache.bcel.classfile.ClassParser;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+import org.aspectj.apache.bcel.util.ClassLoaderRepository.SoftHashMap.SpecialValue;
+
+/**
+ * The repository maintains information about which classes have been loaded.
+ *
+ * It loads its data from the ClassLoader implementation passed into its constructor.
+ *
+ * @see org.aspectj.apache.bcel.Repository
+ *
+ * @version $Id: ClassLoaderRepository.java,v 1.13 2009/09/09 19:56:20 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author David Dixon-Peugh
+ */
+public class ClassLoaderRepository implements Repository {
+ private static java.lang.ClassLoader bootClassLoader = null;
+ private ClassLoaderReference loaderRef;
+
+ // Choice of cache...
+ private WeakHashMap<URL, SoftReference<JavaClass>> localCache = new WeakHashMap<URL, SoftReference<JavaClass>>();
+ private static SoftHashMap /* <URL,JavaClass> */sharedCache = new SoftHashMap(Collections.synchronizedMap(new HashMap<Object, SpecialValue>()));
+
+ // For fast translation of the classname *intentionally not static*
+ private SoftHashMap /* <String,URL> */nameMap = new SoftHashMap(new HashMap(), false);
+
+ public static boolean useSharedCache = System.getProperty("org.aspectj.apache.bcel.useSharedCache", "true").equalsIgnoreCase("true");
+
+ private static int cacheHitsShared = 0;
+ private static int missSharedEvicted = 0; // Misses in shared cache access due to reference GC
+ private long timeManipulatingURLs = 0L;
+ private long timeSpentLoading = 0L;
+ private int classesLoadedCount = 0;
+ private int misses = 0;
+ private int cacheHitsLocal = 0;
+ private int missLocalEvicted = 0; // Misses in local cache access due to reference GC
+
+ public ClassLoaderRepository(java.lang.ClassLoader loader) {
+ this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader());
+ }
+
+ public ClassLoaderRepository(ClassLoaderReference loaderRef) {
+ this.loaderRef = loaderRef;
+ }
+
+ private static synchronized java.lang.ClassLoader getBootClassLoader() {
+ if (bootClassLoader == null) {
+ bootClassLoader = new URLClassLoader(new URL[0]);
+ }
+ return bootClassLoader;
+ }
+
+ // Can track back to its key
+ public static class SoftHashMap extends AbstractMap {
+ private Map<Object, SpecialValue> map;
+ boolean recordMiss = true; // only interested in recording miss stats sometimes
+ private ReferenceQueue rq = new ReferenceQueue();
+
+ public SoftHashMap(Map<Object, SpecialValue> map) {
+ this.map = map;
+ }
+
+ public SoftHashMap() {
+ this(new HashMap());
+ }
+
+ public SoftHashMap(Map map, boolean b) {
+ this(map);
+ this.recordMiss = b;
+ }
+
+ class SpecialValue extends SoftReference {
+ private final Object key;
+
+ SpecialValue(Object k, Object v) {
+ super(v, rq);
+ this.key = k;
+ }
+ }
+
+ private void processQueue() {
+ SpecialValue sv = null;
+ while ((sv = (SpecialValue) rq.poll()) != null) {
+ map.remove(sv.key);
+ }
+ }
+
+ @Override
+ public Object get(Object key) {
+ SpecialValue value = map.get(key);
+ if (value == null)
+ return null;
+ if (value.get() == null) {
+ // it got GC'd
+ map.remove(value.key);
+ if (recordMiss)
+ missSharedEvicted++;
+ return null;
+ } else {
+ return value.get();
+ }
+ }
+
+ @Override
+ public Object put(Object k, Object v) {
+ processQueue();
+ return map.put(k, new SpecialValue(k, v));
+ }
+
+ @Override
+ public Set entrySet() {
+ return map.entrySet();
+ }
+
+ @Override
+ public void clear() {
+ processQueue();
+ map.clear();
+ }
+
+ @Override
+ public int size() {
+ processQueue();
+ return map.size();
+ }
+
+ @Override
+ public Object remove(Object k) {
+ processQueue();
+ SpecialValue value = map.remove(k);
+ if (value == null)
+ return null;
+ if (value.get() != null) {
+ return value.get();
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Store a new JavaClass into this repository as a soft reference and return the reference
+ */
+ private void storeClassAsReference(URL url, JavaClass clazz) {
+ if (useSharedCache) {
+ clazz.setRepository(null); // can't risk setting repository, we'll get in a pickle!
+ sharedCache.put(url, clazz);
+ } else {
+ clazz.setRepository(this);
+ localCache.put(url, new SoftReference<JavaClass>(clazz));
+ }
+ }
+
+ /**
+ * Store a new JavaClass into this Repository.
+ */
+ public void storeClass(JavaClass clazz) {
+ storeClassAsReference(toURL(clazz.getClassName()), clazz);
+ }
+
+ /**
+ * Remove class from repository
+ */
+ public void removeClass(JavaClass clazz) {
+ if (useSharedCache)
+ sharedCache.remove(toURL(clazz.getClassName()));
+ else
+ localCache.remove(toURL(clazz.getClassName()));
+ }
+
+ /**
+ * Find an already defined JavaClass in the local cache.
+ */
+ public JavaClass findClass(String className) {
+ if (useSharedCache)
+ return findClassShared(toURL(className));
+ else
+ return findClassLocal(toURL(className));
+ }
+
+ private JavaClass findClassLocal(URL url) {
+ Object o = localCache.get(url);
+ if (o != null) {
+ o = ((Reference) o).get();
+ if (o != null) {
+ return (JavaClass) o;
+ } else {
+ missLocalEvicted++;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find an already defined JavaClass in the shared cache.
+ */
+ private JavaClass findClassShared(URL url) {
+ return (JavaClass) sharedCache.get(url);
+ }
+
+ private URL toURL(String className) {
+ URL url = (URL) nameMap.get(className);
+ if (url == null) {
+ String classFile = className.replace('.', '/');
+ url = loaderRef.getClassLoader().getResource(classFile + ".class");
+ nameMap.put(className, url);
+ }
+ return url;
+ }
+
+ /**
+ * Lookup a JavaClass object from the Class Name provided.
+ */
+ public JavaClass loadClass(String className) throws ClassNotFoundException {
+
+ // translate to a URL
+ long time = System.currentTimeMillis();
+ java.net.URL url = toURL(className);
+ timeManipulatingURLs += (System.currentTimeMillis() - time);
+ if (url == null)
+ throw new ClassNotFoundException(className + " not found - unable to determine URL");
+
+ JavaClass clazz = null;
+
+ // Look in the appropriate cache
+ if (useSharedCache) {
+ clazz = findClassShared(url);
+ if (clazz != null) {
+ cacheHitsShared++;
+ return clazz;
+ }
+ } else {
+ clazz = findClassLocal(url);
+ if (clazz != null) {
+ cacheHitsLocal++;
+ return clazz;
+ }
+ }
+
+ // Didn't find it in either cache
+ misses++;
+
+ try {
+ // Load it
+ String classFile = className.replace('.', '/');
+ InputStream is = (useSharedCache ? url.openStream() : loaderRef.getClassLoader().getResourceAsStream(
+ classFile + ".class"));
+ if (is == null) {
+ throw new ClassNotFoundException(className + " not found using url " + url);
+ }
+ ClassParser parser = new ClassParser(is, className);
+ clazz = parser.parse();
+
+ // Cache it
+ storeClassAsReference(url, clazz);
+
+ timeSpentLoading += (System.currentTimeMillis() - time);
+ classesLoadedCount++;
+ return clazz;
+ } catch (IOException e) {
+ throw new ClassNotFoundException(e.toString());
+ }
+ }
+
+ /**
+ * Produce a report on cache usage.
+ */
+ public String report() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("BCEL repository report.");
+ if (useSharedCache)
+ sb.append(" (shared cache)");
+ else
+ sb.append(" (local cache)");
+ sb.append(" Total time spent loading: " + timeSpentLoading + "ms.");
+ sb.append(" Time spent manipulating URLs: " + timeManipulatingURLs + "ms.");
+ sb.append(" Classes loaded: " + classesLoadedCount + ".");
+ if (useSharedCache) {
+ sb.append(" Shared cache size: " + sharedCache.size());
+ sb.append(" Shared cache (hits/missDueToEviction): (" + cacheHitsShared + "/" + missSharedEvicted + ").");
+ } else {
+ sb.append(" Local cache size: " + localCache.size());
+ sb.append(" Local cache (hits/missDueToEviction): (" + cacheHitsLocal + "/" + missLocalEvicted + ").");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns an array of the stats, for testing, the order is fixed: 0=time spent loading (static) 1=time spent manipulating URLs
+ * (static) 2=classes loaded (static) 3=cache hits shared (static) 4=misses in shared due to eviction (static) 5=cache hits
+ * local 6=misses in local due to eviction 7=shared cache size
+ */
+ public long[] reportStats() {
+ return new long[] { timeSpentLoading, timeManipulatingURLs, classesLoadedCount, cacheHitsShared, missSharedEvicted,
+ cacheHitsLocal, missLocalEvicted, sharedCache.size() };
+ }
+
+ /**
+ * Reset statistics and clear all caches
+ */
+ public void reset() {
+ timeManipulatingURLs = 0L;
+ timeSpentLoading = 0L;
+ classesLoadedCount = 0;
+ cacheHitsLocal = 0;
+ cacheHitsShared = 0;
+ missSharedEvicted = 0;
+ missLocalEvicted = 0;
+ misses = 0;
+ clear();
+ }
+
+ public JavaClass loadClass(Class clazz) throws ClassNotFoundException {
+ return loadClass(clazz.getName());
+ }
+
+ /** Clear all entries from the local cache */
+ public void clear() {
+ if (useSharedCache)
+ sharedCache.clear();
+ else
+ localCache.clear();
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java
new file mode 100644
index 000000000..b7db332d2
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/ClassPath.java
@@ -0,0 +1,584 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001, 2017 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.aspectj.apache.bcel.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URI;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Responsible for loading (class) files from the CLASSPATH. Inspired by
+ * sun.tools.ClassPath.
+ *
+ * @author M. Dahm
+ * @author Mario Ivankovits
+ * @author Andy Clement
+ */
+public class ClassPath implements Serializable {
+ private static final String JRT_FS = "jrt-fs.jar";
+
+ private static ClassPath SYSTEM_CLASS_PATH = null;
+
+ private PathEntry[] paths;
+ private String class_path;
+
+ public static ClassPath getSystemClassPath() {
+ if (SYSTEM_CLASS_PATH == null) {
+ SYSTEM_CLASS_PATH = new ClassPath();
+ }
+ return SYSTEM_CLASS_PATH;
+ }
+
+ /**
+ * Search for classes in given path.
+ */
+ public ClassPath(String class_path) {
+ this.class_path = class_path;
+
+ ArrayList<PathEntry> vec = new ArrayList<PathEntry>();
+
+ 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 if (file.getName().endsWith("jrt-fs.jar")) { // TODO a bit crude...
+ vec.add(new JImage());
+ } 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;
+ }
+
+ @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;
+ }
+
+ private static final void getPathComponents(String path, ArrayList<String> 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");
+ String vm_version = System.getProperty("java.version");
+
+ ArrayList<String> list = new ArrayList<String>();
+
+ getPathComponents(class_path, list);
+ getPathComponents(boot_path, list);
+
+ ArrayList<String> dirs = new ArrayList<String>();
+ getPathComponents(ext_path, dirs);
+
+ for (Iterator<String> e = dirs.iterator(); e.hasNext();) {
+ File ext_dir = new File(e.next());
+ String[] extensions = ext_dir.list(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ name = name.toLowerCase();
+ return name.endsWith(".zip") || name.endsWith(".jar");
+ }
+ });
+
+ if (extensions != null)
+ for (int i = 0; i < extensions.length; i++)
+ list.add(ext_path + File.separatorChar + extensions[i]);
+ }
+
+ StringBuffer buf = new StringBuffer();
+
+ for (Iterator<String> e = list.iterator(); e.hasNext();) {
+ buf.append(e.next());
+
+ if (e.hasNext())
+ buf.append(File.pathSeparatorChar);
+ }
+
+ // On Java9 the sun.boot.class.path won't be set. System classes accessible through JRT filesystem
+ if (vm_version.startsWith("9") || vm_version.startsWith("10") || vm_version.startsWith("11")) {
+ buf.insert(0, File.pathSeparatorChar);
+ buf.insert(0, System.getProperty("java.home") + File.separator + "lib" + File.separator + JRT_FS);
+ }
+
+ 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, ".class");
+ }
+
+ /**
+ * 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 {
+ InputStream is = getInputStream(name, suffix);
+
+ if (is == null)
+ throw new IOException("Couldn't find: " + name + suffix);
+
+ DataInputStream dis = new DataInputStream(is);
+ byte[] bytes = new byte[is.available()];
+ dis.readFully(bytes);
+ dis.close();
+ is.close();
+
+ return bytes;
+ }
+
+ /**
+ * @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 {
+ abstract ClassFile getClassFile(String name, String suffix) throws IOException;
+ }
+
+ /**
+ * 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 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 size of class file.
+ */
+ public abstract long getSize();
+ }
+
+ private static class Dir extends PathEntry {
+ private String dir;
+
+ 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);
+ }
+
+ @Override
+ public String getPath() {
+ try {
+ return file.getCanonicalPath();
+ } catch (IOException e) {
+ return null;
+ }
+
+ }
+
+ @Override
+ public long getTime() {
+ return file.lastModified();
+ }
+
+ @Override
+ public long getSize() {
+ return file.length();
+ }
+
+ @Override
+ public String getBase() {
+ return dir;
+ }
+
+ } : null;
+ }
+
+ @Override
+ public String toString() {
+ return dir;
+ }
+ }
+
+ private static class JImage extends PathEntry {
+
+ private static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$
+ private static String MODULES_PATH = "modules"; //$NON-NLS-1$
+ private static String JAVA_BASE_PATH = "java.base"; //$NON-NLS-1$
+
+ private java.nio.file.FileSystem fs;
+ private final Map<String, Path> fileMap;
+
+ JImage() {
+ fs = FileSystems.getFileSystem(JRT_URI);
+ fileMap = buildFileMap();
+ }
+
+ private Map<String, Path> buildFileMap() {
+ final Map<String, Path> fileMap = new HashMap<>();
+ final java.nio.file.PathMatcher matcher = fs.getPathMatcher("glob:*.class");
+ Iterable<java.nio.file.Path> roots = fs.getRootDirectories();
+ for (java.nio.file.Path path : roots) {
+ try {
+ Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ if (file.getNameCount() > 2
+ && matcher.matches(file.getFileName())) {
+ Path classPath = file.subpath(2, file.getNameCount());
+ fileMap.put(classPath.toString(), file);
+ }
+
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return fileMap;
+ }
+
+ private static class ByteBasedClassFile implements ClassFile {
+
+ private byte[] bytes;
+ private ByteArrayInputStream bais;
+ private String path;
+ private String base;
+ private long time;
+ private long size;
+
+ public ByteBasedClassFile(byte[] bytes, String path, String base, long time, long size) {
+ this.bytes = bytes;
+ this.path = path;
+ this.base = base;
+ this.time = time;
+ this.size = size;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ // TODO too costly to keep these in inflated form in memory?
+ this.bais = new ByteArrayInputStream(bytes);
+ return this.bais;
+ }
+
+ @Override
+ public String getPath() {
+ return this.path;
+ }
+
+ @Override
+ public String getBase() {
+ return this.base;
+ }
+
+ @Override
+ public long getTime() {
+ return this.time;
+ }
+
+ @Override
+ public long getSize() {
+ return this.size;
+ }
+
+ }
+
+ @Override
+ ClassFile getClassFile(String name, String suffix) throws IOException {
+ // Class files are in here under names like this:
+ // /modules/java.base/java/lang/Object.class (jdk9 b74)
+ // so within a modules top level qualifier and then the java.base module
+ String fileName = name.replace('.', '/') + suffix;
+ Path p = fileMap.get(fileName);
+ if (p == null) {
+ return null;
+ }
+ byte[] bs = Files.readAllBytes(p);
+ BasicFileAttributeView bfav = Files.getFileAttributeView(p, BasicFileAttributeView.class);
+ BasicFileAttributes bfas = bfav.readAttributes();
+ long time = bfas.lastModifiedTime().toMillis();
+ long size = bfas.size();
+ ClassFile cf = new ByteBasedClassFile(bs, "jimage",fileName,time,size);
+ return cf;
+ }
+ }
+
+ private static class Zip extends PathEntry {
+ private ZipFile zip;
+
+ 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);
+ }
+
+ @Override
+ public String getPath() {
+ return entry.toString();
+ }
+
+ @Override
+ public long getTime() {
+ return entry.getTime();
+ }
+
+ @Override
+ public long getSize() {
+ return entry.getSize();
+ }
+
+ @Override
+ public String getBase() {
+ return zip.getName();
+ }
+ } : null;
+ }
+ }
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java
new file mode 100644
index 000000000..259991308
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/DefaultClassLoaderReference.java
@@ -0,0 +1,75 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.aspectj.apache.bcel.util;
+
+/**
+ * Simplistic ClassLoaderReference that merely delegates to a classloader. More sophisticated ones could allow for the
+ * loader to be weakly referenced.
+ *
+ * @author Andy Clement
+ */
+public class DefaultClassLoaderReference implements ClassLoaderReference {
+
+ private java.lang.ClassLoader loader;
+
+ public DefaultClassLoaderReference(java.lang.ClassLoader classLoader) {
+ this.loader = classLoader;
+ }
+
+ public java.lang.ClassLoader getClassLoader() {
+ return loader;
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java
new file mode 100644
index 000000000..a53b9dc35
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/NonCachingClassLoaderRepository.java
@@ -0,0 +1,268 @@
+package org.aspectj.apache.bcel.util;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.aspectj.apache.bcel.classfile.ClassParser;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+
+/**
+ * The repository maintains information about which classes have been loaded.
+ *
+ * It loads its data from the ClassLoader implementation passed into its constructor.
+ *
+ * @see org.aspectj.apache.bcel.Repository
+ *
+ * @version $Id: NonCachingClassLoaderRepository.java,v 1.6 2009/09/09 19:56:20 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author David Dixon-Peugh
+ *
+ */
+public class NonCachingClassLoaderRepository implements Repository {
+ private static java.lang.ClassLoader bootClassLoader = null;
+
+ private final ClassLoaderReference loaderRef;
+ private final Map<String, JavaClass> loadedClasses = new SoftHashMap();
+
+ public static class SoftHashMap extends AbstractMap {
+ private Map<Object, SpecialValue> map;
+ private ReferenceQueue rq = new ReferenceQueue();
+
+ public SoftHashMap(Map<Object, SpecialValue> map) {
+ this.map = map;
+ }
+
+ public SoftHashMap() {
+ this(new HashMap<Object,SpecialValue>());
+ }
+
+ public SoftHashMap(Map<Object,SpecialValue> map, boolean b) {
+ this(map);
+ }
+
+ class SpecialValue extends SoftReference {
+ private final Object key;
+
+ SpecialValue(Object k, Object v) {
+ super(v, rq);
+ this.key = k;
+ }
+ }
+
+ private void processQueue() {
+ SpecialValue sv = null;
+ while ((sv = (SpecialValue) rq.poll()) != null) {
+ map.remove(sv.key);
+ }
+ }
+
+ @Override
+ public Object get(Object key) {
+ SpecialValue value = map.get(key);
+ if (value == null)
+ return null;
+ if (value.get() == null) {
+ // it got GC'd
+ map.remove(value.key);
+ return null;
+ } else {
+ return value.get();
+ }
+ }
+
+ @Override
+ public Object put(Object k, Object v) {
+ processQueue();
+ return map.put(k, new SpecialValue(k, v));
+ }
+
+ @Override
+ public Set entrySet() {
+ return map.entrySet();
+ }
+
+ @Override
+ public void clear() {
+ processQueue();
+ Set<Object> keys = map.keySet();
+ for (Iterator<Object> iterator = keys.iterator(); iterator.hasNext();) {
+ Object name = iterator.next();
+ map.remove(name);
+ }
+ }
+
+ @Override
+ public int size() {
+ processQueue();
+ return map.size();
+ }
+
+ @Override
+ public Object remove(Object k) {
+ processQueue();
+ SpecialValue value = map.remove(k);
+ if (value == null)
+ return null;
+ if (value.get() != null) {
+ return value.get();
+ }
+ return null;
+ }
+ }
+
+ public NonCachingClassLoaderRepository(java.lang.ClassLoader loader) {
+ this.loaderRef = new DefaultClassLoaderReference((loader != null) ? loader : getBootClassLoader());
+ }
+
+ public NonCachingClassLoaderRepository(ClassLoaderReference loaderRef) {
+ this.loaderRef = loaderRef;
+ }
+
+ private static synchronized java.lang.ClassLoader getBootClassLoader() {
+ if (bootClassLoader == null) {
+ bootClassLoader = new URLClassLoader(new URL[0]);
+ }
+ return bootClassLoader;
+ }
+
+ /**
+ * Store a new JavaClass into this Repository.
+ */
+ public void storeClass(JavaClass clazz) {
+ synchronized (loadedClasses) {
+ loadedClasses.put(clazz.getClassName(), clazz);
+ }
+ clazz.setRepository(this);
+ }
+
+ /**
+ * Remove class from repository
+ */
+ public void removeClass(JavaClass clazz) {
+ synchronized (loadedClasses) {
+ loadedClasses.remove(clazz.getClassName());
+ }
+ }
+
+ /**
+ * Find an already defined JavaClass.
+ */
+ public JavaClass findClass(String className) {
+ synchronized (loadedClasses) {
+ if (loadedClasses.containsKey(className)) {
+ return loadedClasses.get(className);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Clear all entries from cache.
+ */
+ public void clear() {
+ synchronized (loadedClasses) {
+ loadedClasses.clear();
+ }
+ }
+
+ /**
+ * Lookup a JavaClass object from the Class Name provided.
+ */
+ public JavaClass loadClass(String className) throws ClassNotFoundException {
+
+ JavaClass javaClass = findClass(className);
+ if (javaClass != null) {
+ return javaClass;
+ }
+
+ javaClass = loadJavaClass(className);
+ storeClass(javaClass);
+
+ return javaClass;
+ }
+
+ public JavaClass loadClass(Class clazz) throws ClassNotFoundException {
+ return loadClass(clazz.getName());
+ }
+
+ private JavaClass loadJavaClass(String className) throws ClassNotFoundException {
+ String classFile = className.replace('.', '/');
+ try {
+ InputStream is = loaderRef.getClassLoader().getResourceAsStream(classFile + ".class");
+
+ if (is == null) {
+ throw new ClassNotFoundException(className + " not found.");
+ }
+
+ ClassParser parser = new ClassParser(is, className);
+ return parser.parse();
+ } catch (IOException e) {
+ throw new ClassNotFoundException(e.toString());
+ }
+ }
+
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java
new file mode 100644
index 000000000..eea889e61
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/Repository.java
@@ -0,0 +1,98 @@
+package org.aspectj.apache.bcel.util;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import org.aspectj.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
+ * Repository.setRepository method.
+ *
+ * @see org.aspectj.apache.bcel.Repository
+ * @version $Id: Repository.java,v 1.5 2009/09/09 19:56:20 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author David Dixon-Peugh
+ */
+public interface Repository {
+ /**
+ * Store the provided class under "clazz.getClassName()"
+ */
+ public void storeClass(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 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();
+}
diff --git a/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java
new file mode 100644
index 000000000..ea0e49216
--- /dev/null
+++ b/bcel-builder/src/main/java/org/aspectj/apache/bcel/util/SyntheticRepository.java
@@ -0,0 +1,195 @@
+package org.aspectj.apache.bcel.util;
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache BCEL" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.WeakHashMap;
+
+import org.aspectj.apache.bcel.classfile.ClassParser;
+import org.aspectj.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(). <br>
+ * 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.aspectj.apache.bcel.Repository
+ *
+ * @version $Id: SyntheticRepository.java,v 1.8 2009/09/09 19:56:20 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author David Dixon-Peugh
+ */
+public class SyntheticRepository implements Repository {
+ private static final String DEFAULT_PATH = ClassPath.getClassPath();
+
+ private static HashMap<ClassPath, SyntheticRepository> _instances = new HashMap<ClassPath, SyntheticRepository>(); // CLASSPATH
+ // X
+ // REPOSITORY
+
+ private ClassPath _path = null;
+ private WeakHashMap<String, JavaClass> _loadedClasses = new WeakHashMap<String, JavaClass>(); // CLASSNAME X JAVACLASS
+
+ private SyntheticRepository(ClassPath path) {
+ _path = path;
+ }
+
+ public static SyntheticRepository getInstance() {
+ return getInstance(ClassPath.getSystemClassPath());
+ }
+
+ public static SyntheticRepository getInstance(ClassPath classPath) {
+ SyntheticRepository rep = _instances.get(classPath);
+
+ if (rep == null) {
+ rep = new SyntheticRepository(classPath);
+ _instances.put(classPath, rep);
+ }
+
+ return rep;
+ }
+
+ /**
+ * Store a new JavaClass instance into this Repository.
+ */
+ public void storeClass(JavaClass clazz) {
+ _loadedClasses.put(clazz.getClassName(), clazz);
+ clazz.setRepository(this);
+ }
+
+ /**
+ * Remove class from repository
+ */
+ public void removeClass(JavaClass clazz) {
+ _loadedClasses.remove(clazz.getClassName());
+ }
+
+ /**
+ * Find an already defined (cached) JavaClass object by name.
+ */
+ public JavaClass findClass(String className) {
+ return _loadedClasses.get(className);
+ }
+
+ /**
+ * Load a JavaClass object for the given class name using the CLASSPATH environment variable.
+ */
+ 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
+
+ try {
+ return loadClass(_path.getInputStream(className), className);
+ } catch (IOException e) {
+ throw new ClassNotFoundException("Exception while looking for class " + className + ": " + e.toString());
+ }
+ }
+
+ /**
+ * Try to find class source via getResourceAsStream().
+ *
+ * @see Class
+ * @return JavaClass object for given runtime class
+ */
+ public JavaClass loadClass(Class clazz) throws ClassNotFoundException {
+ String className = clazz.getName();
+ 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 {
+ JavaClass clazz = findClass(className);
+
+ if (clazz != null) {
+ return clazz;
+ }
+
+ try {
+ if (is != null) {
+ ClassParser parser = new ClassParser(is, className);
+ 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);
+ }
+
+ /**
+ * Clear all entries from cache.
+ */
+ public void clear() {
+ _loadedClasses.clear();
+ }
+}