diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 9ed3c0b1f24..a5ae9ea7b47 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -441,3 +441,6 @@ ec4159ebe7050fcc5dcee8a2d150cf948ecc97db jdk-9+178 252475ccfd84cc249f8d6faf4b7806b5e2c384ce jdk-9+179 a133a7d1007b1456bc62824382fd8ac93b45d329 jdk-10+17 536b81db8075486ca0fe3225d8e59313df5b936c jdk-10+18 +b803e6cff41e72a1e6d8782e1ef7c25a6e3e5ee3 jdk-10+19 +d2982a786f53814367698e63efe6349c9128e1db jdk-9+180 +b656dea9398ef601f7fc08d1a5157a560e0ccbe0 jdk-9+181 diff --git a/corba/.hgtags b/corba/.hgtags index 96e4906862a..3955e7c2528 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -441,3 +441,6 @@ b82b62ed5debda2d98dda597506ef29cf947fbae jdk-10+16 24390da83c5ee9e23ceafbcaff4460a01e37bb3a jdk-9+179 50ff1fd66362f212a8db6de76089d9d0ffa4df0f jdk-10+17 a923b3f30e7bddb4f960059ddfc7978fc63e2e6e jdk-10+18 +28488561cfbcfa4d0d9c489e8afe0155f4231360 jdk-10+19 +6ce6cb8ff41c71c49f23b15e0f0468aca5d52b17 jdk-9+180 +ba71941ad9dba53b8fffb30602ef673eee88696c jdk-9+181 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index bd997249d7d..282c0940830 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -601,3 +601,6 @@ c1f3649a3a42f124b418a5a916dbad13d059b757 jdk-10+15 d2661aa42bff322badbe6c1337fc638d2e0f5730 jdk-9+179 73e2cb8700bfa51304bd4b02f224620859a3f600 jdk-10+17 c9d3317623d48da3327232c81e3f8cfc0d29d888 jdk-10+18 +33b74e13c1457f36041addb8b850831f81ca6e9f jdk-10+19 +d7baadc223e790c08bc69bf7e553bce65b4e7e40 jdk-9+180 +4a443796f6f57842d6a0434ac27ca3d1033ccc20 jdk-9+181 diff --git a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp index fce91a80ad3..c044e9a0181 100644 --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4389,6 +4389,15 @@ void G1CollectedHeap::enqueue_discovered_references(G1ParScanThreadStateSet* per rp->verify_no_references_recorded(); assert(!rp->discovery_enabled(), "should have been disabled"); + // If during an initial mark pause we install a pending list head which is not otherwise reachable + // ensure that it is marked in the bitmap for concurrent marking to discover. + if (collector_state()->during_initial_mark_pause()) { + oop pll_head = Universe::reference_pending_list(); + if (pll_head != NULL) { + _cm->grayRoot(pll_head); + } + } + // FIXME // CM's reference processing also cleans up the string and symbol tables. // Should we do that here also? We could, but it is a serial operation diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index d56e8dd3226..2d9dded4872 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -497,7 +497,11 @@ void Universe::fixup_mirrors(TRAPS) { #define assert_pll_ownership() assert_pll_locked(owned_by_self) oop Universe::reference_pending_list() { - assert_pll_ownership(); + if (Thread::current()->is_VM_thread()) { + assert_pll_locked(is_locked); + } else { + assert_pll_ownership(); + } return _reference_pending_list; } diff --git a/jaxp/.hgtags b/jaxp/.hgtags index d8240378ee2..f8f0cd60f26 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -441,3 +441,6 @@ d109d55cf642bf2b438624e81f94c18c168f9178 jdk-10+16 87243a3131f79e8b3903eaca6b629abc48f08ace jdk-9+179 97d6f14334cfd766f57c296a5a707c8a709aeff0 jdk-10+17 7ba7ebbc304a4817e05b72efa6b45ed635839b98 jdk-10+18 +f5789425c26cee0274d0e2ebabb21faf268f218f jdk-10+19 +9934a03646f91ce55f61f53d8448c629828f8088 jdk-9+180 +ea18d767c9ec50ea7f40bbe6cf7379d3538110f1 jdk-9+181 diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java new file mode 100644 index 00000000000..32dba4c9089 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java @@ -0,0 +1,3527 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.sun.org.apache.bcel.internal; + +import java.util.Arrays; +import java.util.Collections; + +/** + * Constants for the project, mostly defined in the JVM specification. + * + * @version $Id: Const.java 1748987 2016-06-18 12:36:47Z sebb $ + * @since 6.0 (intended to replace the Constants interface) + */ +public final class Const { + + /** + * Java class file format Magic number (0xCAFEBABE) + * + * @see + * The ClassFile Structure in The Java Virtual Machine Specification + */ + public static final int JVM_CLASSFILE_MAGIC = 0xCAFEBABE; + + /** + * Major version number of class files for Java 1.1. + * + * @see #MINOR_1_1 + * + */ + public static final short MAJOR_1_1 = 45; + + /** + * Minor version number of class files for Java 1.1. + * + * @see #MAJOR_1_1 + * + */ + public static final short MINOR_1_1 = 3; + + /** + * Major version number of class files for Java 1.2. + * + * @see #MINOR_1_2 + * + */ + public static final short MAJOR_1_2 = 46; + + /** + * Minor version number of class files for Java 1.2. + * + * @see #MAJOR_1_2 + * + */ + public static final short MINOR_1_2 = 0; + + /** + * Major version number of class files for Java 1.2. + * + * @see #MINOR_1_2 + * + */ + public static final short MAJOR_1_3 = 47; + + /** + * Minor version number of class files for Java 1.3. + * + * @see #MAJOR_1_3 + * + */ + public static final short MINOR_1_3 = 0; + + /** + * Major version number of class files for Java 1.3. + * + * @see #MINOR_1_3 + * + */ + public static final short MAJOR_1_4 = 48; + + /** + * Minor version number of class files for Java 1.4. + * + * @see #MAJOR_1_4 + * + */ + public static final short MINOR_1_4 = 0; + + /** + * Major version number of class files for Java 1.4. + * + * @see #MINOR_1_4 + * + */ + public static final short MAJOR_1_5 = 49; + + /** + * Minor version number of class files for Java 1.5. + * + * @see #MAJOR_1_5 + * + */ + public static final short MINOR_1_5 = 0; + + /** + * Major version number of class files for Java 1.6. + * + * @see #MINOR_1_6 + * + */ + public static final short MAJOR_1_6 = 50; + + /** + * Minor version number of class files for Java 1.6. + * + * @see #MAJOR_1_6 + * + */ + public static final short MINOR_1_6 = 0; + + /** + * Major version number of class files for Java 1.7. + * + * @see #MINOR_1_7 + * + */ + public static final short MAJOR_1_7 = 51; + + /** + * Minor version number of class files for Java 1.7. + * + * @see #MAJOR_1_7 + * + */ + public static final short MINOR_1_7 = 0; + + /** + * Major version number of class files for Java 1.8. + * + * @see #MINOR_1_8 + * + */ + public static final short MAJOR_1_8 = 52; + + /** + * Major version number of class files for Java 9. + * + * @see #MINOR_1_9 + * + */ + public static final short MAJOR_1_9 = 53; + + /** + * Minor version number of class files for Java 1.8. + * + * @see #MAJOR_1_8 + * + */ + public static final short MINOR_1_8 = 0; + + /** + * Minor version number of class files for Java 9. + * + * @see #MAJOR_1_9 + * + */ + public static final short MINOR_1_9 = 0; + + /** + * Default major version number. Class file is for Java 1.1. + * + * @see #MAJOR_1_1 + * + */ + public static final short MAJOR = MAJOR_1_1; + + /** + * Default major version number. Class file is for Java 1.1. + * + * @see #MAJOR_1_1 + * + */ + public static final short MINOR = MINOR_1_1; + + /** + * Maximum value for an unsigned short. + */ + public static final int MAX_SHORT = 65535; // 2^16 - 1 + + /** + * Maximum value for an unsigned byte. + */ + public static final int MAX_BYTE = 255; // 2^8 - 1 + + /** + * One of the access flags for fields, methods, or classes. + * + * @see + * Flag definitions for Fields in the Java Virtual Machine Specification + * (Java SE 8 Edition). + * @see + * Flag definitions for Methods in the Java Virtual Machine Specification + * (Java SE 8 Edition). + * @see + * Flag definitions for Classes in the Java Virtual Machine Specification + * (Java SE 8 Edition). + */ + public static final short ACC_PUBLIC = 0x0001; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_PRIVATE = 0x0002; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_PROTECTED = 0x0004; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_STATIC = 0x0008; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_FINAL = 0x0010; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_SYNCHRONIZED = 0x0020; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_VOLATILE = 0x0040; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_BRIDGE = 0x0040; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_TRANSIENT = 0x0080; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_VARARGS = 0x0080; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_NATIVE = 0x0100; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_INTERFACE = 0x0200; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_ABSTRACT = 0x0400; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_STRICT = 0x0800; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_SYNTHETIC = 0x1000; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_ANNOTATION = 0x2000; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_ENUM = 0x4000; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_MANDATED = (short) 0x8000; + + // Applies to classes compiled by new compilers only + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_SUPER = 0x0020; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short MAX_ACC_FLAG = ACC_ENUM; + + /** + * The names of the access flags. + */ + private static final String[] ACCESS_NAMES = { + "public", "private", "protected", "static", "final", "synchronized", + "volatile", "transient", "native", "interface", "abstract", "strictfp", + "synthetic", "annotation", "enum" + }; + + /** + * @since 6.0 + */ + public static final int ACCESS_NAMES_LENGTH = ACCESS_NAMES.length; + + /** + * @param index + * @return the ACCESS_NAMES entry at the given index + * @since 6.0 + */ + public static String getAccessName(final int index) { + return ACCESS_NAMES[index]; + } + + /* + * The description of the constant pool is at: + * http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4 + * References below are to the individual sections + */ + /** + * Marks a constant pool entry as type UTF-8. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Utf8 = 1; + + /** + * Marks a constant pool entry as type Integer. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Integer = 3; + + /** + * Marks a constant pool entry as type Float. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Float = 4; + + /** + * Marks a constant pool entry as type Long. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Long = 5; + + /** + * Marks a constant pool entry as type Double. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Double = 6; + + /** + * Marks a constant pool entry as a Class + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Class = 7; + + /** + * Marks a constant pool entry as a Field Reference. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Fieldref = 9; + + /** + * Marks a constant pool entry as type String + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_String = 8; + + /** + * Marks a constant pool entry as a Method Reference. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_Methodref = 10; + + /** + * Marks a constant pool entry as an Interface Method Reference. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_InterfaceMethodref = 11; + + /** + * Marks a constant pool entry as a name and type. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_NameAndType = 12; + + /** + * Marks a constant pool entry as a Method Handle. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_MethodHandle = 15; + + /** + * Marks a constant pool entry as a Method Type. + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_MethodType = 16; + + /** + * Marks a constant pool entry as an Invoke Dynamic + * + * @see + * The Constant Pool in The Java Virtual Machine Specification + */ + public static final byte CONSTANT_InvokeDynamic = 18; + + /** + * The names of the types of entries in a constant pool. Use getConstantName + * instead + */ + private static final 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"}; + + /** + * + * @param index + * @return the CONSTANT_NAMES entry at the given index + * @since 6.0 + */ + public static String getConstantName(final int index) { + return CONSTANT_NAMES[index]; + } + + /** + * The name of the static initializer, also called "class + * initialization method" or "interface initialization + * method". This is "<clinit>". + */ + public static final String STATIC_INITIALIZER_NAME = ""; + + /** + * The name of every constructor method in a class, also called + * "instance initialization method". This is + * "<init>". + */ + public static final String CONSTRUCTOR_NAME = ""; + + /** + * The names of the interfaces implemented by arrays + */ + private static final String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"}; + + /** + * @since 6.0 + */ + public static Iterable getInterfacesImplementedByArrays() { + return Collections.unmodifiableList(Arrays.asList(INTERFACES_IMPLEMENTED_BY_ARRAYS)); + } + + /** + * Maximum Constant Pool entries. One of the limitations of the Java Virtual + * Machine. + * + * @see + * The Java Virtual Machine Specification, Java SE 8 Edition, page 330, + * chapter 4.11. + */ + public static final int MAX_CP_ENTRIES = 65535; + + /** + * Maximum code size (plus one; the code size must be LESS than this) One of + * the limitations of the Java Virtual Machine. Note vmspec2 page 152 + * ("Limitations") says: "The amount of code per non-native, non-abstract + * method is limited to 65536 bytes by the sizes of the indices in the + * exception_table of the Code attribute (4.7.3), in the LineNumberTable + * attribute (4.7.8), and in the LocalVariableTable attribute (4.7.9)." + * However this should be taken as an upper limit rather than the defined + * maximum. On page 134 (4.8.1 Static Constants) of the same spec, it says: + * "The value of the code_length item must be less than 65536." The entry in + * the Limitations section has been removed from later versions of the spec; + * it is not present in the Java SE 8 edition. + * + * @see + * The Java Virtual Machine Specification, Java SE 8 Edition, page 104, + * chapter 4.7. + */ + public static final int MAX_CODE_SIZE = 65536; //bytes + + /** + * The maximum number of dimensions in an array ({@value}). One of the + * limitations of the Java Virtual Machine. + * + * @see + * Field Descriptors in The Java Virtual Machine Specification + */ + public static final int MAX_ARRAY_DIMENSIONS = 255; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short NOP = 0; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ACONST_NULL = 1; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ICONST_M1 = 2; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ICONST_0 = 3; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ICONST_1 = 4; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ICONST_2 = 5; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ICONST_3 = 6; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ICONST_4 = 7; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ICONST_5 = 8; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LCONST_0 = 9; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LCONST_1 = 10; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FCONST_0 = 11; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FCONST_1 = 12; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FCONST_2 = 13; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DCONST_0 = 14; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DCONST_1 = 15; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short BIPUSH = 16; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short SIPUSH = 17; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LDC = 18; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LDC_W = 19; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LDC2_W = 20; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ILOAD = 21; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LLOAD = 22; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FLOAD = 23; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DLOAD = 24; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ALOAD = 25; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ILOAD_0 = 26; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ILOAD_1 = 27; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ILOAD_2 = 28; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ILOAD_3 = 29; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LLOAD_0 = 30; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LLOAD_1 = 31; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LLOAD_2 = 32; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LLOAD_3 = 33; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FLOAD_0 = 34; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FLOAD_1 = 35; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FLOAD_2 = 36; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FLOAD_3 = 37; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DLOAD_0 = 38; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DLOAD_1 = 39; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DLOAD_2 = 40; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DLOAD_3 = 41; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ALOAD_0 = 42; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ALOAD_1 = 43; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ALOAD_2 = 44; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ALOAD_3 = 45; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IALOAD = 46; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LALOAD = 47; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FALOAD = 48; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DALOAD = 49; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short AALOAD = 50; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short BALOAD = 51; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short CALOAD = 52; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short SALOAD = 53; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISTORE = 54; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSTORE = 55; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FSTORE = 56; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DSTORE = 57; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ASTORE = 58; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISTORE_0 = 59; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISTORE_1 = 60; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISTORE_2 = 61; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISTORE_3 = 62; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSTORE_0 = 63; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSTORE_1 = 64; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSTORE_2 = 65; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSTORE_3 = 66; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FSTORE_0 = 67; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FSTORE_1 = 68; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FSTORE_2 = 69; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FSTORE_3 = 70; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DSTORE_0 = 71; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DSTORE_1 = 72; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DSTORE_2 = 73; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DSTORE_3 = 74; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ASTORE_0 = 75; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ASTORE_1 = 76; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ASTORE_2 = 77; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ASTORE_3 = 78; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IASTORE = 79; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LASTORE = 80; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FASTORE = 81; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DASTORE = 82; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short AASTORE = 83; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short BASTORE = 84; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short CASTORE = 85; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short SASTORE = 86; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short POP = 87; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short POP2 = 88; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DUP = 89; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DUP_X1 = 90; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DUP_X2 = 91; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DUP2 = 92; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DUP2_X1 = 93; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DUP2_X2 = 94; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short SWAP = 95; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IADD = 96; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LADD = 97; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FADD = 98; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DADD = 99; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISUB = 100; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSUB = 101; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FSUB = 102; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DSUB = 103; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IMUL = 104; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LMUL = 105; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FMUL = 106; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DMUL = 107; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IDIV = 108; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LDIV = 109; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FDIV = 110; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DDIV = 111; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IREM = 112; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LREM = 113; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FREM = 114; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DREM = 115; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INEG = 116; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LNEG = 117; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FNEG = 118; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DNEG = 119; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISHL = 120; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSHL = 121; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ISHR = 122; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LSHR = 123; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IUSHR = 124; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LUSHR = 125; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IAND = 126; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LAND = 127; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IOR = 128; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LOR = 129; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IXOR = 130; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LXOR = 131; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IINC = 132; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short I2L = 133; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short I2F = 134; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short I2D = 135; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short L2I = 136; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short L2F = 137; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short L2D = 138; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short F2I = 139; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short F2L = 140; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short F2D = 141; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short D2I = 142; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short D2L = 143; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short D2F = 144; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short I2B = 145; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INT2BYTE = 145; // Old notation + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short I2C = 146; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INT2CHAR = 146; // Old notation + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short I2S = 147; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INT2SHORT = 147; // Old notation + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LCMP = 148; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FCMPL = 149; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FCMPG = 150; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DCMPL = 151; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DCMPG = 152; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFEQ = 153; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFNE = 154; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFLT = 155; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFGE = 156; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFGT = 157; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFLE = 158; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPEQ = 159; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPNE = 160; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPLT = 161; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPGE = 162; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPGT = 163; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPLE = 164; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ACMPEQ = 165; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IF_ACMPNE = 166; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short GOTO = 167; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short JSR = 168; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short RET = 169; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short TABLESWITCH = 170; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LOOKUPSWITCH = 171; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IRETURN = 172; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short LRETURN = 173; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short FRETURN = 174; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short DRETURN = 175; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ARETURN = 176; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short RETURN = 177; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short GETSTATIC = 178; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short PUTSTATIC = 179; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short GETFIELD = 180; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short PUTFIELD = 181; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INVOKEVIRTUAL = 182; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INVOKESPECIAL = 183; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INVOKESTATIC = 184; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INVOKEINTERFACE = 185; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INVOKEDYNAMIC = 186; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short NEW = 187; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short NEWARRAY = 188; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ANEWARRAY = 189; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ARRAYLENGTH = 190; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short ATHROW = 191; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short CHECKCAST = 192; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short INSTANCEOF = 193; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short MONITORENTER = 194; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short MONITOREXIT = 195; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short WIDE = 196; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short MULTIANEWARRAY = 197; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFNULL = 198; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short IFNONNULL = 199; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short GOTO_W = 200; + + /** + * Java VM opcode. + * + * @see + * Opcode definitions in The Java Virtual Machine Specification + */ + public static final short JSR_W = 201; + + /** + * JVM internal opcode. + * + * @see + * Reserved opcodes in the Java Virtual Machine Specification + */ + public static final short BREAKPOINT = 202; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short LDC_QUICK = 203; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short LDC_W_QUICK = 204; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short LDC2_W_QUICK = 205; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short GETFIELD_QUICK = 206; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short PUTFIELD_QUICK = 207; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short GETFIELD2_QUICK = 208; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short PUTFIELD2_QUICK = 209; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short GETSTATIC_QUICK = 210; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short PUTSTATIC_QUICK = 211; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short GETSTATIC2_QUICK = 212; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short PUTSTATIC2_QUICK = 213; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INVOKEVIRTUAL_QUICK = 214; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INVOKENONVIRTUAL_QUICK = 215; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INVOKESUPER_QUICK = 216; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INVOKESTATIC_QUICK = 217; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INVOKEINTERFACE_QUICK = 218; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INVOKEVIRTUALOBJECT_QUICK = 219; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short NEW_QUICK = 221; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short ANEWARRAY_QUICK = 222; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short MULTIANEWARRAY_QUICK = 223; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short CHECKCAST_QUICK = 224; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INSTANCEOF_QUICK = 225; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short INVOKEVIRTUAL_QUICK_W = 226; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short GETFIELD_QUICK_W = 227; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification + * (version 1) + * @see + * Why the _quick opcodes were removed from the second version of the Java + * Virtual Machine Specification. + */ + public static final short PUTFIELD_QUICK_W = 228; + + /** + * JVM internal opcode. + * + * @see + * Reserved opcodes in the Java Virtual Machine Specification + */ + public static final short IMPDEP1 = 254; + + /** + * JVM internal opcode. + * + * @see + * Reserved opcodes in the Java Virtual Machine Specification + */ + public static final short IMPDEP2 = 255; + + /** + * BCEL virtual instruction for pushing an arbitrary data type onto the + * stack. Will be converted to the appropriate JVM opcode when the class is + * dumped. + */ + public static final short PUSH = 4711; + + /** + * BCEL virtual instruction for either LOOKUPSWITCH or TABLESWITCH. Will be + * converted to the appropriate JVM opcode when the class is dumped. + */ + public static final short SWITCH = 4712; + + /** + * Illegal opcode. + */ + public static final short UNDEFINED = -1; + + /** + * Illegal opcode. + */ + public static final short UNPREDICTABLE = -2; + + /** + * Illegal opcode. + */ + public static final short RESERVED = -3; + + /** + * Mnemonic for an illegal opcode. + */ + public static final String ILLEGAL_OPCODE = ""; + + /** + * Mnemonic for an illegal type. + */ + public static final String ILLEGAL_TYPE = ""; + + /** + * Boolean data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_BOOLEAN = 4; + + /** + * Char data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_CHAR = 5; + + /** + * Float data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_FLOAT = 6; + + /** + * Double data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_DOUBLE = 7; + + /** + * Byte data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_BYTE = 8; + + /** + * Short data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_SHORT = 9; + + /** + * Int data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_INT = 10; + + /** + * Long data type. + * + * @see + * Static Constraints in the Java Virtual Machine Specification + */ + public static final byte T_LONG = 11; + + /** + * Void data type (non-standard). + */ + public static final byte T_VOID = 12; // Non-standard + + /** + * Array data type. + */ + public static final byte T_ARRAY = 13; + + /** + * Object data type. + */ + public static final byte T_OBJECT = 14; + + /** + * Reference data type (deprecated). + */ + public static final byte T_REFERENCE = 14; // Deprecated + + /** + * Unknown data type. + */ + public static final byte T_UNKNOWN = 15; + + /** + * Address data type. + */ + public static final byte T_ADDRESS = 16; + + /** + * The primitive type names corresponding to the T_XX constants, e.g., + * TYPE_NAMES[T_INT] = "int" + */ + private 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", "address" + }; + + /** + * The primitive type names corresponding to the T_XX constants, e.g., + * TYPE_NAMES[T_INT] = "int" + * + * @param index + * @return the type name + * @since 6.0 + */ + public static String getTypeName(final int index) { + return TYPE_NAMES[index]; + } + + /** + * The primitive class names corresponding to the T_XX constants, e.g., + * CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" + */ + private 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, ILLEGAL_TYPE + }; + + /** + * The primitive class names corresponding to the T_XX constants, e.g., + * CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" + * + * @param index + * @return the class name + * @since 6.0 + */ + public static String getClassTypeName(final int index) { + return CLASS_TYPE_NAMES[index]; + } + + /** + * The signature characters corresponding to primitive types, e.g., + * SHORT_TYPE_NAMES[T_INT] = "I" + */ + private 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 + }; + + /** + * + * @param index + * @return the short type name + * @since 6.0 + */ + public static String getShortTypeName(final int index) { + return SHORT_TYPE_NAMES[index]; + } + + /** + * Number of byte code operands for each opcode, i.e., number of bytes after + * the tag byte itself. Indexed by opcode, so NO_OF_OPERANDS[BIPUSH] = the + * number of operands for a bipush instruction. + */ + private static final short[] NO_OF_OPERANDS = { + 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, + 0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, + 0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/, + 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/, + 1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/, + 1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/, + 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/, + 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, + 0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, + 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/, + 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, + 0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/, + 0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/, + 1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/, + 1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/, + 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/, + 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, + 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, + 0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, + 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/, + 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, + 0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/, + 0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/, + 0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/, + 0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/, + 0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/, + 0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/, + 0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/, + 0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/, + 0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/, + 2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/, + 0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/, + 0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/, + 0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/, + 2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/, + 2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/, + 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/, + 2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/, + 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, + 0/*dreturn*/, 0/*areturn*/, 0/*return*/, + 2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/, + 2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/, + 4/*invokeinterface*/, 4/*invokedynamic*/, 2/*new*/, + 1/*newarray*/, 2/*anewarray*/, + 0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/, + 2/*instanceof*/, 0/*monitorenter*/, + 0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/, + 2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/, + 4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/}; + + /** + * + * @param index + * @return Number of byte code operands + * @since 6.0 + */ + public static short getNoOfOperands(final int index) { + return NO_OF_OPERANDS[index]; + } + + /** + * How the byte code operands are to be interpreted for each opcode. Indexed + * by opcode. TYPE_OF_OPERANDS[ILOAD] = an array of shorts describing the + * data types for the instruction. + */ + private 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, T_BYTE, T_BYTE}/*invokedynamic*/, + {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*/}; + + /** + * @since 6.0 + */ + public static short getOperandType(final int opcode, final int index) { + return TYPE_OF_OPERANDS[opcode][index]; + } + + /** + * @since 6.0 + */ + public static long getOperandTypeCount(final int opcode) { + return TYPE_OF_OPERANDS[opcode].length; + } + + /** + * Names of opcodes. Indexed by opcode. OPCODE_NAMES[ALOAD] = "aload". + */ + private 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" + }; + + /** + * @since 6.0 + */ + public static final int OPCODE_NAMES_LENGTH = OPCODE_NAMES.length; + + /** + * @since 6.0 + */ + public static String getOpcodeName(final int index) { + return OPCODE_NAMES[index]; + } + + /** + * Number of words consumed on operand stack by instructions. Indexed by + * opcode. CONSUME_STACK[FALOAD] = number of words consumed from the stack + * by a faload instruction. + */ + private 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*/, UNPREDICTABLE/*invokedynamic*/, 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*/}; + + /** + * + * @param index + * @return Number of words consumed on operand stack + * @since 6.0 + */ + public static int getConsumeStack(final int index) { + return CONSUME_STACK[index]; + } + + /** + * Number of words produced onto operand stack by instructions. Indexed by + * opcode. CONSUME_STACK[DALOAD] = number of words consumed from the stack + * by a daload instruction. + */ + private static final int[] PRODUCE_STACK = { + 0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/, + 1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/, + 2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/, + 2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/, + 2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/, + 1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/, + 1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/, + 2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/, + 2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/, + 0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/, + 0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, + 0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, + 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/, + 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, + 0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/, + 0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/, + 6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/, + 1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/, + 1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/, + 1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/, + 1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/, + 0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/, + 2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/, + 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/, + 1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/, + 0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/, + 0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/, + 0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, + 0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/, + UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/, + UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/, + UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 1/*new*/, 1/*newarray*/, 1/*anewarray*/, + 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/, + 0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/, + 0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/}; + + /** + * + * @param index + * @return Number of words produced onto operand stack + * @since 6.0 + */ + public static int getProduceStack(final int index) { + return PRODUCE_STACK[index]; + } + + /** + * 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_ANNOTATION_DEFAULT = 16; + public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 17; + public static final byte ATTR_ENCLOSING_METHOD = 18; + public static final byte ATTR_STACK_MAP_TABLE = 19; + public static final byte ATTR_BOOTSTRAP_METHODS = 20; + public static final byte ATTR_METHOD_PARAMETERS = 21; + + public static final short KNOWN_ATTRIBUTES = 22; // count of attributes + + private static final String[] ATTRIBUTE_NAMES = { + "SourceFile", "ConstantValue", "Code", "Exceptions", + "LineNumberTable", "LocalVariableTable", + "InnerClasses", "Synthetic", "Deprecated", + "PMGClass", "Signature", "StackMap", + "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", + "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations", + "AnnotationDefault", "LocalVariableTypeTable", "EnclosingMethod", "StackMapTable", + "BootstrapMethods", "MethodParameters" + }; + + /** + * + * @param index + * @return the attribute name + * @since 6.0 + */ + public static String getAttributeName(final int index) { + return ATTRIBUTE_NAMES[index]; + } + + /** + * 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; + + private static final String[] ITEM_NAMES = { + "Bogus", "Integer", "Float", "Double", "Long", + "Null", "InitObject", "Object", "NewObject" + }; + + /** + * + * @param index + * @return the item name + * @since 6.0 + */ + public static String getItemName(final int index) { + return ITEM_NAMES[index]; + } + + /** + * Constants used to identify StackMapEntry types. + * + * For those types which can specify a range, the constant names the lowest + * value. + */ + public static final int SAME_FRAME = 0; + public static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; + public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; + public static final int CHOP_FRAME = 248; + public static final int SAME_FRAME_EXTENDED = 251; + public static final int APPEND_FRAME = 252; + public static final int FULL_FRAME = 255; + + /** + * Constants that define the maximum value of those constants which store + * ranges. + */ + public static final int SAME_FRAME_MAX = 63; + public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_MAX = 127; + public static final int CHOP_FRAME_MAX = 250; + public static final int APPEND_FRAME_MAX = 254; + + // Constants defining the behavior of the Method Handles (JVMS 5.4.3.5) + public static final byte REF_getField = 1; + public static final byte REF_getStatic = 2; + public static final byte REF_putField = 3; + public static final byte REF_putStatic = 4; + public static final byte REF_invokeVirtual = 5; + public static final byte REF_invokeStatic = 6; + public static final byte REF_invokeSpecial = 7; + public static final byte REF_newInvokeSpecial = 8; + public static final byte REF_invokeInterface = 9; + + /** + * The names of the reference_kinds of a CONSTANT_MethodHandle_info. + */ + private static final String[] METHODHANDLE_NAMES = { + "", "getField", "getStatic", "putField", "putStatic", "invokeVirtual", + "invokeStatic", "invokeSpecial", "newInvokeSpecial", "invokeInterface"}; + + /** + * + * @param index + * @return the method handle name + * @since 6.0 + */ + public static String getMethodHandleName(final int index) { + return METHODHANDLE_NAMES[index]; + } + + private Const() { + } // not instantiable + +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Constants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Constants.java deleted file mode 100644 index a5e02cafa5e..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Constants.java +++ /dev/null @@ -1,754 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal; - - -/** - * Constants for the project, mostly defined in the JVM specification. - * - * @author M. Dahm - */ -public interface Constants { - /** Major and minor version of the code. - */ - public final static short MAJOR_1_1 = 45; - public final static short MINOR_1_1 = 3; - public final static short MAJOR_1_2 = 46; - public final static short MINOR_1_2 = 0; - public final static short MAJOR_1_3 = 47; - public final static short MINOR_1_3 = 0; - public final static short MAJOR = MAJOR_1_1; // Defaults - public final static short MINOR = MINOR_1_1; - - /** Maximum value for an unsigned short. - */ - public final static int MAX_SHORT = 65535; // 2^16 - 1 - - /** Maximum value for an unsigned 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; - - // 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 String[] CONSTANT_NAMES = { - "", "CONSTANT_Utf8", "", "CONSTANT_Integer", - "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double", - "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", - "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref", - "CONSTANT_NameAndType" }; - - /** The name of the static initializer, also called "class - * initialization method" or "interface initialization - * method". This is "<clinit>". - */ - public final static String STATIC_INITIALIZER_NAME = ""; - - /** The name of every constructor method in a class, also called - * "instance initialization method". This is "<init>". - */ - public final static String CONSTRUCTOR_NAME = ""; - - /** 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 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 = -1; - public static final short UNPREDICTABLE = -2; - public static final short RESERVED = -3; - public static final String ILLEGAL_OPCODE = ""; - public static final String ILLEGAL_TYPE = ""; - - public static final byte T_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 - }; - - /** - * Number of byte code operands, i.e., number of bytes after the tag byte - * itself. - */ - public static final short[] NO_OF_OPERANDS = { - 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, - 0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, - 0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/, - 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/, - 1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/, - 1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/, - 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/, - 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, - 0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, - 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/, - 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, - 0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/, - 0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/, - 1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/, - 1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/, - 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/, - 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, - 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, - 0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, - 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/, - 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, - 0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/, - 0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/, - 0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/, - 0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/, - 0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/, - 0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/, - 0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/, - 0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/, - 0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/, - 2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/, - 0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/, - 0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/, - 0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/, - 2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/, - 2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/, - 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/, - 2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/, - 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, - 0/*dreturn*/, 0/*areturn*/, 0/*return*/, - 2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/, - 2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/, - 4/*invokeinterface*/, UNDEFINED, 2/*new*/, - 1/*newarray*/, 2/*anewarray*/, - 0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/, - 2/*instanceof*/, 0/*monitorenter*/, - 0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/, - 2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/, - 4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/ - }; - - /** - * 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", ILLEGAL_OPCODE, "new", "newarray", "anewarray", - "arraylength", "athrow", "checkcast", "instanceof", "monitorenter", - "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull", - "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, "impdep1", "impdep2" - }; - - /** - * Number of words 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*/ - }; - - /** - * Number of words produced onto operand stack by instructions. - */ - public static final int[] PRODUCE_STACK = { - 0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/, - 1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/, - 2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/, - 2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/, - 2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/, - 1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/, - 1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/, - 2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/, - 2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/, - 0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/, - 0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, - 0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, - 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/, - 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, - 0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/, - 0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/, - 6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/, - 1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/, - 1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/, - 1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/, - 1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/, - 0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/, - 2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/, - 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/, - 1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/, - 0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/, - 0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/, - 0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, - 0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/, - UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/, - UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/, - UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 1/*new*/, 1/*newarray*/, 1/*anewarray*/, - 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/, - 0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/, - 0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/ - }; - - /** 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_LOCAL_VARIABLE_TYPE_TABLE = 12; - - public static final short KNOWN_ATTRIBUTES = 13; - - public static final String[] ATTRIBUTE_NAMES = { - "SourceFile", "ConstantValue", "Code", "Exceptions", - "LineNumberTable", "LocalVariableTable", - "InnerClasses", "Synthetic", "Deprecated", - "PMGClass", "Signature", "StackMap", - "LocalVariableTypeTable" - }; - - /** 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/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java new file mode 100644 index 00000000000..46cdddebfdd --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java @@ -0,0 +1,130 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal; + +/** + * Exception constants. + * @since 6.0 (intended to replace the InstructionConstant interface) + */ +public final class ExceptionConst { + + /** The mother of all exceptions + */ + public static final Class THROWABLE = Throwable.class; + /** Super class of any run-time exception + */ + public static final Class RUNTIME_EXCEPTION = RuntimeException.class; + /** Super class of any linking exception (aka Linkage Error) + */ + public static final Class LINKING_EXCEPTION = LinkageError.class; + /** Linking Exceptions + */ + public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; + public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; + public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; + public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; + public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; + public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; + public static final Class INSTANTIATION_ERROR = InstantiationError.class; + public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; + public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; + public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; + public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; + public static final Class VERIFY_ERROR = VerifyError.class; + /* UnsupportedClassVersionError is new in JDK 1.2 */ +// public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; + /** Run-Time Exceptions + */ + public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; + public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION + = ArrayIndexOutOfBoundsException.class; + public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; + public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; + public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; + public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; + + /** + * Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual + * Machine Specification + */ + private 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 + private static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { + NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR + }; // Chapter 5.2 + private static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) + private static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; + // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) + private static final Class[] EXCS_ARRAY_EXCEPTION = { + NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION + }; + + /** + * Enum corresponding to the various Exception Class arrays, + * used by {@link ExceptionConst#createExceptions(EXCS, Class...)} + */ + public enum EXCS { + EXCS_CLASS_AND_INTERFACE_RESOLUTION, + EXCS_FIELD_AND_METHOD_RESOLUTION, + EXCS_INTERFACE_METHOD_RESOLUTION, + EXCS_STRING_RESOLUTION, + EXCS_ARRAY_EXCEPTION, + } + + // helper method to merge exception class arrays + private static Class[] mergeExceptions(final Class[] input, final Class ... extraClasses) { + final int extraLen = extraClasses == null ? 0 : extraClasses.length; + final Class[] excs = new Class[input.length + extraLen]; + System.arraycopy(input, 0, excs, 0, input.length); + if (extraLen > 0) { + System.arraycopy(extraClasses, 0, excs, input.length, extraLen); + } + return excs; + } + + /** + * Creates a copy of the specified Exception Class array combined with any additional Exception classes. + * @param type the basic array type + * @param extraClasses additional classes, if any + * @return the merged array + */ + public static Class[] createExceptions(final EXCS type, final Class ... extraClasses) { + switch (type) { + case EXCS_CLASS_AND_INTERFACE_RESOLUTION: + return mergeExceptions(EXCS_CLASS_AND_INTERFACE_RESOLUTION, extraClasses); + case EXCS_ARRAY_EXCEPTION: + return mergeExceptions(EXCS_ARRAY_EXCEPTION, extraClasses); + case EXCS_FIELD_AND_METHOD_RESOLUTION: + return mergeExceptions(EXCS_FIELD_AND_METHOD_RESOLUTION, extraClasses); + case EXCS_INTERFACE_METHOD_RESOLUTION: + return mergeExceptions(EXCS_INTERFACE_METHOD_RESOLUTION, extraClasses); + case EXCS_STRING_RESOLUTION: + return mergeExceptions(EXCS_STRING_RESOLUTION, extraClasses); + default: + throw new AssertionError("Cannot happen; unexpected enum value: " + type); + } + } + + +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConstants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConstants.java deleted file mode 100644 index da004ea462d..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConstants.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal; - - -/** - * Exception constants. - * - * @author E. Haase - */ -public interface ExceptionConstants { - /** The mother of all exceptions - */ - public static final Class THROWABLE = Throwable.class; - - /** Super class of any run-time exception - */ - public static final Class RUNTIME_EXCEPTION = RuntimeException.class; - - /** Super class of any linking exception (aka Linkage Error) - */ - public static final Class LINKING_EXCEPTION = LinkageError.class; - - /** Linking Exceptions - */ - public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; - public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; - public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; - public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; - public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; - public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; - public static final Class INSTANTIATION_ERROR = InstantiationError.class; - public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; - public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; - public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; - public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; - public static final Class VERIFY_ERROR = VerifyError.class; - - /* UnsupportedClassVersionError is new in JDK 1.2 */ - //public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; - - /** Run-Time Exceptions - */ - public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; - public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; - public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; - public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; - public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; - public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; - - /** Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual - * Machine Specification - */ - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { - NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, - EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR - }; // Chapter 5.1 - - public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { - NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR - }; // Chapter 5.2 - - public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) - public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; - // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) - - public static final Class[] EXCS_ARRAY_EXCEPTION = { - NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION - }; - -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java index 14a935f1bb8..eb04969a71f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,189 +17,218 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal; import com.sun.org.apache.bcel.internal.classfile.JavaClass; -import com.sun.org.apache.bcel.internal.util.*; -import java.io.*; +import com.sun.org.apache.bcel.internal.util.SyntheticRepository; /** * The repository maintains informations about class interdependencies, e.g., - * whether a class is a sub-class of another. Delegates actual class loading - * to SyntheticRepository with current class path by default. + * whether a class is a sub-class of another. Delegates actual class loading to + * SyntheticRepository with current class path by default. * * @see com.sun.org.apache.bcel.internal.util.Repository - * @see com.sun.org.apache.bcel.internal.util.SyntheticRepository + * @see SyntheticRepository * - * @author M. Dahm + * @version $Id: Repository.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public abstract class Repository { - private static com.sun.org.apache.bcel.internal.util.Repository _repository = - SyntheticRepository.getInstance(); - /** @return currently used repository instance - */ - public static com.sun.org.apache.bcel.internal.util.Repository getRepository() { - return _repository; - } + private static com.sun.org.apache.bcel.internal.util.Repository repository + = SyntheticRepository.getInstance(); - /** Set repository instance to be used for class loading - */ - public static void setRepository(com.sun.org.apache.bcel.internal.util.Repository rep) { - _repository = rep; - } + /** + * @return currently used repository instance + */ + public static com.sun.org.apache.bcel.internal.util.Repository getRepository() { + return repository; + } - /** 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 = _repository.findClass(class_name); + /** + * Set repository instance to be used for class loading + */ + public static void setRepository(final com.sun.org.apache.bcel.internal.util.Repository rep) { + repository = rep; + } - if(clazz == null) { - return _repository.loadClass(class_name); - } else { - return clazz; - } - } catch(ClassNotFoundException ex) { return null; } - } + /** + * Lookup class somewhere found on your CLASSPATH, or whereever the + * repository instance looks for it. + * + * @return class object for given fully qualified class name + * @throws ClassNotFoundException if the class could not be found or parsed + * correctly + */ + public static JavaClass lookupClass(final String class_name) + throws ClassNotFoundException { + return repository.loadClass(class_name); + } - /** - * Try to find class source via getResourceAsStream(). - * @see Class - * @return JavaClass object for given runtime class - */ - public static JavaClass lookupClass(Class clazz) { - try { - return _repository.loadClass(clazz); - } catch(ClassNotFoundException ex) { return null; } - } + /** + * Try to find class source using the internal repository instance. + * + * @see Class + * @return JavaClass object for given runtime class + * @throws ClassNotFoundException if the class could not be found or parsed + * correctly + */ + public static JavaClass lookupClass(final Class clazz) + throws ClassNotFoundException { + return repository.loadClass(clazz); + } - /** Clear the repository. - */ - public static void clearCache() { - _repository.clear(); - } + /** + * Clear the repository. + */ + public static void clearCache() { + repository.clear(); + } - /** - * Add clazz to repository if there isn't an equally named class already in there. - * - * @return old entry in repository - */ - public static JavaClass addClass(JavaClass clazz) { - JavaClass old = _repository.findClass(clazz.getClassName()); - _repository.storeClass(clazz); - return old; - } + /** + * Add clazz to repository if there isn't an equally named class already in + * there. + * + * @return old entry in repository + */ + public static JavaClass addClass(final JavaClass clazz) { + final JavaClass old = repository.findClass(clazz.getClassName()); + repository.storeClass(clazz); + return old; + } - /** - * Remove class with given (fully qualified) name from repository. - */ - public static void removeClass(String clazz) { - _repository.removeClass(_repository.findClass(clazz)); - } + /** + * Remove class with given (fully qualified) name from repository. + */ + public static void removeClass(final String clazz) { + repository.removeClass(repository.findClass(clazz)); + } - /** - * Remove given class from repository. - */ - public static void removeClass(JavaClass clazz) { - _repository.removeClass(clazz); - } + /** + * Remove given class from repository. + */ + public static void removeClass(final JavaClass clazz) { + repository.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 + * @throws ClassNotFoundException if any of the superclasses can't be found + */ + public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException { + return clazz.getSuperClasses(); + } - /** - * @return list of super classes of clazz in ascending order, i.e., - * Object is always the last element. 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 list of super classes of clazz in ascending order, i.e., Object + * is always the last element. + * @throws ClassNotFoundException if the named class or any of its + * superclasses can't be found + */ + public static JavaClass[] getSuperClasses(final String class_name) throws ClassNotFoundException { + final JavaClass jc = lookupClass(class_name); + return getSuperClasses(jc); + } - /** - * @return all interfaces implemented by class and its super - * classes and the interfaces that those interfaces extend, and so on. - * (Some people call this a transitive hull). - */ - public static JavaClass[] getInterfaces(JavaClass clazz) { - return clazz.getAllInterfaces(); - } + /** + * @return all interfaces implemented by class and its super classes and the + * interfaces that those interfaces extend, and so on. (Some people call + * this a transitive hull). + * @throws ClassNotFoundException if any of the class's superclasses or + * superinterfaces can't be found + */ + public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException { + return clazz.getAllInterfaces(); + } - /** - * @return all interfaces implemented by class and its super - * classes and the interfaces that extend those interfaces, and so on - */ - public static JavaClass[] getInterfaces(String class_name) { - return getInterfaces(lookupClass(class_name)); - } + /** + * @return all interfaces implemented by class and its super classes and the + * interfaces that extend those interfaces, and so on + * @throws ClassNotFoundException if the named class can't be found, or if + * any of its superclasses or superinterfaces can't be found + */ + public static JavaClass[] getInterfaces(final String class_name) throws ClassNotFoundException { + return getInterfaces(lookupClass(class_name)); + } - /** - * Equivalent to runtime "instanceof" operator. - * @return true, if clazz is an instance of super_class - */ - public static boolean instanceOf(JavaClass clazz, JavaClass super_class) { - return clazz.instanceOf(super_class); - } + /** + * Equivalent to runtime "instanceof" operator. + * + * @return true, if clazz is an instance of super_class + * @throws ClassNotFoundException if any superclasses or superinterfaces of + * clazz can't be found + */ + public static boolean instanceOf(final JavaClass clazz, final JavaClass super_class) + throws ClassNotFoundException { + 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 + * @throws ClassNotFoundException if either clazz or super_class can't be + * found + */ + public static boolean instanceOf(final String clazz, final String super_class) + throws ClassNotFoundException { + 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 + * @throws ClassNotFoundException if super_class can't be found + */ + public static boolean instanceOf(final JavaClass clazz, final String super_class) + throws ClassNotFoundException { + 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 instance of super_class + * @throws ClassNotFoundException if clazz can't be found + */ + public static boolean instanceOf(final String clazz, final JavaClass super_class) + throws ClassNotFoundException { + 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 + * @throws ClassNotFoundException if any superclasses or superinterfaces of + * clazz can't be found + */ + public static boolean implementationOf(final JavaClass clazz, final JavaClass inter) + throws ClassNotFoundException { + 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 + * @throws ClassNotFoundException if clazz, inter, or any superclasses or + * superinterfaces of clazz can't be found + */ + public static boolean implementationOf(final String clazz, final String inter) + throws ClassNotFoundException { + 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 + * @throws ClassNotFoundException if inter or any superclasses or + * superinterfaces of clazz can't be found + */ + public static boolean implementationOf(final JavaClass clazz, final String inter) + throws ClassNotFoundException { + 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); - } + /** + * @return true, if clazz is an implementation of interface inter + * @throws ClassNotFoundException if clazz or any superclasses or + * superinterfaces of clazz can't be found + */ + public static boolean implementationOf(final String clazz, final JavaClass inter) + throws ClassNotFoundException { + return implementationOf(lookupClass(clazz), inter); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java index c779c942301..07a9413a47b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,121 +17,199 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; /** - * Super class for all objects that have modifiers like private, final, ... - * I.e. classes, fields, and methods. + * Super class for all objects that have modifiers like private, final, ... I.e. + * classes, fields, and methods. * - * @author M. Dahm + * @version $Id: AccessFlags.java 1748636 2016-06-15 20:45:17Z dbrosius $ */ -public abstract class AccessFlags implements java.io.Serializable { - protected int access_flags; +public abstract class AccessFlags { - public AccessFlags() {} + private int access_flags; - /** - * @param a inital access flags - */ - public AccessFlags(int a) { - access_flags = a; - } - - /** - * @return Access flags of the object aka. "modifiers". - */ - public final int getAccessFlags() { return access_flags; } - - /** - * @return Access flags of the object aka. "modifiers". - */ - public final int getModifiers() { return access_flags; } - - /** Set access flags aka "modifiers". - * @param access_flags Access flags of the object. - */ - public final void setAccessFlags(int access_flags) { - this.access_flags = access_flags; - } - - /** Set access flags aka "modifiers". - * @param access_flags Access flags of the object. - */ - public final void setModifiers(int access_flags) { - setAccessFlags(access_flags); - } - - private final void setFlag(int flag, boolean set) { - if((access_flags & flag) != 0) { // Flag is set already - if(!set) // Delete flag ? - access_flags ^= flag; - } else { // Flag not set - if(set) // Set flag ? - access_flags |= flag; + public AccessFlags() { } - } - public final void isPublic(boolean flag) { setFlag(Constants.ACC_PUBLIC, flag); } - public final boolean isPublic() { - return (access_flags & Constants.ACC_PUBLIC) != 0; - } + /** + * @param a inital access flags + */ + public AccessFlags(final int a) { + access_flags = a; + } - public final void isPrivate(boolean flag) { setFlag(Constants.ACC_PRIVATE, flag); } - public final boolean isPrivate() { - return (access_flags & Constants.ACC_PRIVATE) != 0; - } + /** + * @return Access flags of the object aka. "modifiers". + */ + public final int getAccessFlags() { + return access_flags; + } - public final void isProtected(boolean flag) { setFlag(Constants.ACC_PROTECTED, flag); } - public final boolean isProtected() { - return (access_flags & Constants.ACC_PROTECTED) != 0; - } + /** + * @return Access flags of the object aka. "modifiers". + */ + public final int getModifiers() { + return access_flags; + } - public final void isStatic(boolean flag) { setFlag(Constants.ACC_STATIC, flag); } - public final boolean isStatic() { - return (access_flags & Constants.ACC_STATIC) != 0; - } + /** + * Set access flags aka "modifiers". + * + * @param access_flags Access flags of the object. + */ + public final void setAccessFlags(final int access_flags) { + this.access_flags = access_flags; + } - public final void isFinal(boolean flag) { setFlag(Constants.ACC_FINAL, flag); } - public final boolean isFinal() { - return (access_flags & Constants.ACC_FINAL) != 0; - } + /** + * Set access flags aka "modifiers". + * + * @param access_flags Access flags of the object. + */ + public final void setModifiers(final int access_flags) { + setAccessFlags(access_flags); + } - public final void isSynchronized(boolean flag) { setFlag(Constants.ACC_SYNCHRONIZED, flag); } - public final boolean isSynchronized() { - return (access_flags & Constants.ACC_SYNCHRONIZED) != 0; - } + private void setFlag(final int flag, final boolean set) { + if ((access_flags & flag) != 0) { // Flag is set already + if (!set) { + access_flags ^= flag; + } + } else { // Flag not set + if (set) { + access_flags |= flag; + } + } + } - public final void isVolatile(boolean flag) { setFlag(Constants.ACC_VOLATILE, flag); } - public final boolean isVolatile() { - return (access_flags & Constants.ACC_VOLATILE) != 0; - } + public final void isPublic(final boolean flag) { + setFlag(Const.ACC_PUBLIC, flag); + } - public final void isTransient(boolean flag) { setFlag(Constants.ACC_TRANSIENT, flag); } - public final boolean isTransient() { - return (access_flags & Constants.ACC_TRANSIENT) != 0; - } + public final boolean isPublic() { + return (access_flags & Const.ACC_PUBLIC) != 0; + } - public final void isNative(boolean flag) { setFlag(Constants.ACC_NATIVE, flag); } - public final boolean isNative() { - return (access_flags & Constants.ACC_NATIVE) != 0; - } + public final void isPrivate(final boolean flag) { + setFlag(Const.ACC_PRIVATE, flag); + } - public final void isInterface(boolean flag) { setFlag(Constants.ACC_INTERFACE, flag); } - public final boolean isInterface() { - return (access_flags & Constants.ACC_INTERFACE) != 0; - } + public final boolean isPrivate() { + return (access_flags & Const.ACC_PRIVATE) != 0; + } - public final void isAbstract(boolean flag) { setFlag(Constants.ACC_ABSTRACT, flag); } - public final boolean isAbstract() { - return (access_flags & Constants.ACC_ABSTRACT) != 0; - } + public final void isProtected(final boolean flag) { + setFlag(Const.ACC_PROTECTED, flag); + } - public final void isStrictfp(boolean flag) { setFlag(Constants.ACC_STRICT, flag); } - public final boolean isStrictfp() { - return (access_flags & Constants.ACC_STRICT) != 0; - } + public final boolean isProtected() { + return (access_flags & Const.ACC_PROTECTED) != 0; + } + + public final void isStatic(final boolean flag) { + setFlag(Const.ACC_STATIC, flag); + } + + public final boolean isStatic() { + return (access_flags & Const.ACC_STATIC) != 0; + } + + public final void isFinal(final boolean flag) { + setFlag(Const.ACC_FINAL, flag); + } + + public final boolean isFinal() { + return (access_flags & Const.ACC_FINAL) != 0; + } + + public final void isSynchronized(final boolean flag) { + setFlag(Const.ACC_SYNCHRONIZED, flag); + } + + public final boolean isSynchronized() { + return (access_flags & Const.ACC_SYNCHRONIZED) != 0; + } + + public final void isVolatile(final boolean flag) { + setFlag(Const.ACC_VOLATILE, flag); + } + + public final boolean isVolatile() { + return (access_flags & Const.ACC_VOLATILE) != 0; + } + + public final void isTransient(final boolean flag) { + setFlag(Const.ACC_TRANSIENT, flag); + } + + public final boolean isTransient() { + return (access_flags & Const.ACC_TRANSIENT) != 0; + } + + public final void isNative(final boolean flag) { + setFlag(Const.ACC_NATIVE, flag); + } + + public final boolean isNative() { + return (access_flags & Const.ACC_NATIVE) != 0; + } + + public final void isInterface(final boolean flag) { + setFlag(Const.ACC_INTERFACE, flag); + } + + public final boolean isInterface() { + return (access_flags & Const.ACC_INTERFACE) != 0; + } + + public final void isAbstract(final boolean flag) { + setFlag(Const.ACC_ABSTRACT, flag); + } + + public final boolean isAbstract() { + return (access_flags & Const.ACC_ABSTRACT) != 0; + } + + public final void isStrictfp(final boolean flag) { + setFlag(Const.ACC_STRICT, flag); + } + + public final boolean isStrictfp() { + return (access_flags & Const.ACC_STRICT) != 0; + } + + public final void isSynthetic(final boolean flag) { + setFlag(Const.ACC_SYNTHETIC, flag); + } + + public final boolean isSynthetic() { + return (access_flags & Const.ACC_SYNTHETIC) != 0; + } + + public final void isAnnotation(final boolean flag) { + setFlag(Const.ACC_ANNOTATION, flag); + } + + public final boolean isAnnotation() { + return (access_flags & Const.ACC_ANNOTATION) != 0; + } + + public final void isEnum(final boolean flag) { + setFlag(Const.ACC_ENUM, flag); + } + + public final boolean isEnum() { + return (access_flags & Const.ACC_ENUM) != 0; + } + + public final void isVarArgs(final boolean flag) { + setFlag(Const.ACC_VARARGS, flag); + } + + public final boolean isVarArgs() { + return (access_flags & Const.ACC_VARARGS) != 0; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java new file mode 100644 index 00000000000..c38538995b3 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java @@ -0,0 +1,98 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * Represents the default value of a annotation for a method info + * + * @version $Id: AnnotationDefault 1 2005-02-13 03:15:08Z dbrosius $ + * @since 6.0 + */ +public class AnnotationDefault extends Attribute { + + private ElementValue default_value; + + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + */ + AnnotationDefault(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { + this(name_index, length, (ElementValue) null, constant_pool); + default_value = ElementValue.readElementValue(input, constant_pool); + } + + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param defaultValue the annotation's default value + * @param constant_pool Array of constants + */ + public AnnotationDefault(final int name_index, final int length, final ElementValue defaultValue, final ConstantPool constant_pool) { + super(Const.ATTR_ANNOTATION_DEFAULT, name_index, length, constant_pool); + this.default_value = defaultValue; + } + + /** + * 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(final Visitor v) { + v.visitAnnotationDefault(this); + } + + /** + * @param defaultValue the default value of this methodinfo's annotation + */ + public final void setDefaultValue(final ElementValue defaultValue) { + default_value = defaultValue; + } + + /** + * @return the default value + */ + public final ElementValue getDefaultValue() { + return default_value; + } + + @Override + public Attribute copy(final ConstantPool _constant_pool) { + return (Attribute) clone(); + } + + @Override + public final void dump(final DataOutputStream dos) throws IOException { + super.dump(dos); + default_value.dump(dos); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java new file mode 100644 index 00000000000..5a5288cc317 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java @@ -0,0 +1,69 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * @since 6.0 + */ +public class AnnotationElementValue extends ElementValue +{ + // For annotation element values, this is the annotation + private final AnnotationEntry annotationEntry; + + public AnnotationElementValue(final int type, final AnnotationEntry annotationEntry, + final ConstantPool cpool) + { + super(type, cpool); + if (type != ANNOTATION) { + throw new RuntimeException( + "Only element values of type annotation can be built with this ctor - type specified: " + type); + } + this.annotationEntry = annotationEntry; + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getType()); // u1 type of value (ANNOTATION == '@') + annotationEntry.dump(dos); + } + + @Override + public String stringifyValue() + { + return annotationEntry.toString(); + } + + @Override + public String toString() + { + return stringifyValue(); + } + + public AnnotationEntry getAnnotationEntry() + { + return annotationEntry; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java new file mode 100644 index 00000000000..701e57f8ea0 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java @@ -0,0 +1,172 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * represents one annotation in the annotation table + * + * @version $Id: AnnotationEntry + * @since 6.0 + */ +public class AnnotationEntry implements Node { + + private final int type_index; + private final ConstantPool constant_pool; + private final boolean isRuntimeVisible; + + private List element_value_pairs; + + /* + * Factory method to create an AnnotionEntry from a DataInput + * + * @param input + * @param constant_pool + * @param isRuntimeVisible + * @return the entry + * @throws IOException + */ + public static AnnotationEntry read(final DataInput input, final ConstantPool constant_pool, final boolean isRuntimeVisible) throws IOException { + + final AnnotationEntry annotationEntry = new AnnotationEntry(input.readUnsignedShort(), constant_pool, isRuntimeVisible); + final int num_element_value_pairs = input.readUnsignedShort(); + annotationEntry.element_value_pairs = new ArrayList<>(); + for (int i = 0; i < num_element_value_pairs; i++) { + annotationEntry.element_value_pairs.add( + new ElementValuePair(input.readUnsignedShort(), ElementValue.readElementValue(input, constant_pool), + constant_pool)); + } + return annotationEntry; + } + + public AnnotationEntry(final int type_index, final ConstantPool constant_pool, final boolean isRuntimeVisible) { + this.type_index = type_index; + this.constant_pool = constant_pool; + this.isRuntimeVisible = isRuntimeVisible; + } + + public int getTypeIndex() { + return type_index; + } + + public ConstantPool getConstantPool() { + return constant_pool; + } + + public boolean isRuntimeVisible() { + return isRuntimeVisible; + } + + /** + * 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(final Visitor v) { + v.visitAnnotationEntry(this); + } + + /** + * @return the annotation type name + */ + public String getAnnotationType() { + final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(type_index, Const.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return the annotation type index + */ + public int getAnnotationTypeIndex() { + return type_index; + } + + /** + * @return the number of element value pairs in this annotation entry + */ + public final int getNumElementValuePairs() { + return element_value_pairs.size(); + } + + /** + * @return the element value pairs in this annotation entry + */ + public ElementValuePair[] getElementValuePairs() { + // TODO return List + return element_value_pairs.toArray(new ElementValuePair[element_value_pairs.size()]); + } + + public void dump(final DataOutputStream dos) throws IOException { + dos.writeShort(type_index); // u2 index of type name in cpool + dos.writeShort(element_value_pairs.size()); // u2 element_value pair + // count + for (final ElementValuePair envp : element_value_pairs) { + envp.dump(dos); + } + } + + public void addElementNameValuePair(final ElementValuePair elementNameValuePair) { + element_value_pairs.add(elementNameValuePair); + } + + public String toShortString() { + final StringBuilder result = new StringBuilder(); + result.append("@"); + result.append(getAnnotationType()); + final ElementValuePair[] evPairs = getElementValuePairs(); + if (evPairs.length > 0) { + result.append("("); + for (final ElementValuePair element : evPairs) { + result.append(element.toShortString()); + } + result.append(")"); + } + return result.toString(); + } + + @Override + public String toString() { + return toShortString(); + } + + public static AnnotationEntry[] createAnnotationEntries(final Attribute[] attrs) { + // Find attributes that contain annotation data + final List accumulatedAnnotations = new ArrayList<>(attrs.length); + for (final Attribute attribute : attrs) { + if (attribute instanceof Annotations) { + final Annotations runtimeAnnotations = (Annotations) attribute; + Collections.addAll(accumulatedAnnotations, runtimeAnnotations.getAnnotationEntries()); + } + } + return accumulatedAnnotations.toArray(new AnnotationEntry[accumulatedAnnotations.size()]); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java new file mode 100644 index 00000000000..fb067ac380c --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java @@ -0,0 +1,118 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * base class for annotations + * + * @version $Id: Annotations + * @since 6.0 + */ +public abstract class Annotations extends Attribute { + + private AnnotationEntry[] annotation_table; + private final boolean isRuntimeVisible; + + /** + * @param annotation_type the subclass type of the annotation + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + */ + Annotations(final byte annotation_type, final int name_index, final int length, final DataInput input, + final ConstantPool constant_pool, final boolean isRuntimeVisible) throws IOException { + this(annotation_type, name_index, length, (AnnotationEntry[]) null, constant_pool, isRuntimeVisible); + final int annotation_table_length = input.readUnsignedShort(); + annotation_table = new AnnotationEntry[annotation_table_length]; + for (int i = 0; i < annotation_table_length; i++) { + annotation_table[i] = AnnotationEntry.read(input, constant_pool, isRuntimeVisible); + } + } + + /** + * @param annotation_type the subclass type of the annotation + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param annotation_table the actual annotations + * @param constant_pool Array of constants + */ + public Annotations(final byte annotation_type, final int name_index, final int length, final AnnotationEntry[] annotation_table, + final ConstantPool constant_pool, final boolean isRuntimeVisible) { + super(annotation_type, name_index, length, constant_pool); + this.annotation_table = annotation_table; + this.isRuntimeVisible = isRuntimeVisible; + } + + /** + * 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(final Visitor v) { + v.visitAnnotation(this); + } + + /** + * @param annotation_table the entries to set in this annotation + */ + public final void setAnnotationTable(final AnnotationEntry[] annotation_table) { + this.annotation_table = annotation_table; + } + + /** + * returns the array of annotation entries in this annotation + */ + public AnnotationEntry[] getAnnotationEntries() { + return annotation_table; + } + + /** + * @return the number of annotation entries in this annotation + */ + public final int getNumAnnotations() { + if (annotation_table == null) { + return 0; + } + return annotation_table.length; + } + + public boolean isRuntimeVisible() { + return isRuntimeVisible; + } + + protected void writeAnnotations(final DataOutputStream dos) throws IOException { + if (annotation_table == null) { + return; + } + dos.writeShort(annotation_table.length); + for (final AnnotationEntry element : annotation_table) { + element.dump(dos); + } + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java new file mode 100644 index 00000000000..c4293ff3b2d --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java @@ -0,0 +1,96 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * @since 6.0 + */ +public class ArrayElementValue extends ElementValue +{ + // For array types, this is the array + private final ElementValue[] evalues; + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append("{"); + for (int i = 0; i < evalues.length; i++) + { + sb.append(evalues[i]); + if ((i + 1) < evalues.length) { + sb.append(","); + } + } + sb.append("}"); + return sb.toString(); + } + + public ArrayElementValue(final int type, final ElementValue[] datums, final ConstantPool cpool) + { + super(type, cpool); + if (type != ARRAY) { + throw new RuntimeException( + "Only element values of type array can be built with this ctor - type specified: " + type); + } + this.evalues = datums; + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getType()); // u1 type of value (ARRAY == '[') + dos.writeShort(evalues.length); + for (final ElementValue evalue : evalues) { + evalue.dump(dos); + } + } + + @Override + public String stringifyValue() + { + final StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int i = 0; i < evalues.length; i++) + { + sb.append(evalues[i].stringifyValue()); + if ((i + 1) < evalues.length) { + sb.append(","); + } + } + sb.append("]"); + return sb.toString(); + } + + public ElementValue[] getElementValuesArray() + { + return evalues; + } + + public int getElementValuesArraySize() + { + return evalues.length; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java index 3ca3d9adc01..0cdda227393 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,255 +17,295 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.HashMap; +import java.util.Map; + +import com.sun.org.apache.bcel.internal.Const; /** * Abstract super class for Attribute objects. Currently the * ConstantValue, SourceFile, Code, * Exceptiontable, LineNumberTable, * LocalVariableTable, InnerClasses and - * Synthetic attributes are supported. The - * Unknown attribute stands for non-standard-attributes. + * Synthetic attributes are supported. The Unknown + * attribute stands for non-standard-attributes. * - * @author M. Dahm - * @see ConstantValue - * @see SourceFile - * @see Code - * @see Unknown - * @see ExceptionTable - * @see LineNumberTable - * @see LocalVariableTable - * @see InnerClasses - * @see Synthetic - * @see Deprecated - * @see Signature -*/ -public abstract class Attribute implements Cloneable, Node, Serializable { - protected int name_index; // Points to attribute name in constant pool - protected int length; // Content length of attribute field - protected byte tag; // Tag to distiguish subclasses - protected ConstantPool constant_pool; + * @version $Id: Attribute.java 1750029 2016-06-23 22:14:38Z sebb $ + * @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 { - protected Attribute(byte tag, int name_index, int length, - ConstantPool constant_pool) { - this.tag = tag; - this.name_index = name_index; - this.length = length; - this.constant_pool = constant_pool; - } + private int name_index; // Points to attribute name in constant pool + private int length; // Content length of attribute field + private final byte tag; // Tag to distinguish subclasses + private ConstantPool 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 abstract void accept(Visitor v); - - /** - * Dump attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public void dump(DataOutputStream file) throws IOException - { - file.writeShort(name_index); - file.writeInt(length); - } - - private static HashMap readers = new HashMap(); - - /** Add an Attribute reader capable of parsing (user-defined) attributes - * named "name". You should not add readers for the standard attributes - * such as "LineNumberTable", because those are handled internally. - * - * @param name the name of the attribute as stored in the class file - * @param r the reader object - */ - public static void addAttributeReader(String name, AttributeReader r) { - readers.put(name, r); - } - - /** Remove attribute reader - * - * @param name the name of the attribute as stored in the class file - */ - public static void removeAttributeReader(String name) { - readers.remove(name); - } - - /* Class method reads one attribute from the input data stream. - * This method must not be accessible from the outside. It is - * called by the Field and Method constructor methods. - * - * @see Field - * @see Method - * @param file Input stream - * @param constant_pool Array of constants - * @return Attribute - * @throws IOException - * @throws ClassFormatException - */ - public static final Attribute readAttribute(DataInputStream file, - ConstantPool constant_pool) - throws IOException, ClassFormatException - { - ConstantUtf8 c; - String name; - int name_index; - int length; - byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute - - // Get class name from constant pool via `name_index' indirection - name_index = (int)file.readUnsignedShort(); - c = (ConstantUtf8)constant_pool.getConstant(name_index, - Constants.CONSTANT_Utf8); - name = c.getBytes(); - - // Length of data in bytes - length = file.readInt(); - - // Compare strings to find known attribute - for(byte i=0; i < Constants.KNOWN_ATTRIBUTES; i++) { - if(name.equals(Constants.ATTRIBUTE_NAMES[i])) { - tag = i; // found! - break; - } + protected Attribute(final byte tag, final int name_index, final int length, final ConstantPool constant_pool) { + this.tag = tag; + this.name_index = name_index; + this.length = length; + this.constant_pool = constant_pool; } - // Call proper constructor, depending on `tag' - switch(tag) { - case Constants.ATTR_UNKNOWN: - AttributeReader r = (AttributeReader)readers.get(name); + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public abstract void accept(Visitor v); - if(r != null) - return r.createAttribute(name_index, length, file, constant_pool); - else - return new Unknown(name_index, length, file, constant_pool); - - case Constants.ATTR_CONSTANT_VALUE: - return new ConstantValue(name_index, length, file, constant_pool); - - case Constants.ATTR_SOURCE_FILE: - return new SourceFile(name_index, length, file, constant_pool); - - case Constants.ATTR_CODE: - return new Code(name_index, length, file, constant_pool); - - case Constants.ATTR_EXCEPTIONS: - return new ExceptionTable(name_index, length, file, constant_pool); - - case Constants.ATTR_LINE_NUMBER_TABLE: - return new LineNumberTable(name_index, length, file, constant_pool); - - case Constants.ATTR_LOCAL_VARIABLE_TABLE: - return new LocalVariableTable(name_index, length, file, constant_pool); - - case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE: - return new LocalVariableTypeTable(name_index, length, file, constant_pool); - - case Constants.ATTR_INNER_CLASSES: - return new InnerClasses(name_index, length, file, constant_pool); - - case Constants.ATTR_SYNTHETIC: - return new Synthetic(name_index, length, file, constant_pool); - - case Constants.ATTR_DEPRECATED: - return new Deprecated(name_index, length, file, constant_pool); - - case Constants.ATTR_PMG: - return new PMGClass(name_index, length, file, constant_pool); - - case Constants.ATTR_SIGNATURE: - return new Signature(name_index, length, file, constant_pool); - - case Constants.ATTR_STACK_MAP: - return new StackMap(name_index, length, file, constant_pool); - - default: // Never reached - throw new IllegalStateException("Ooops! default case reached."); - } - } - - /** - * @return Length of attribute field in bytes. - */ - public final int getLength() { return length; } - - /** - * @param Attribute length in bytes. - */ - public final void setLength(int length) { - this.length = length; - } - - /** - * @param name_index of attribute. - */ - public final void setNameIndex(int name_index) { - this.name_index = name_index; - } - - /** - * @return Name index in constant pool of attribute name. - */ - public final int getNameIndex() { return name_index; } - - /** - * @return Tag of attribute, i.e., its type. Value may not be altered, thus - * there is no setTag() method. - */ - public final byte getTag() { return tag; } - - /** - * @return Constant pool used by this object. - * @see ConstantPool - */ - public final ConstantPool getConstantPool() { return constant_pool; } - - /** - * @param constant_pool Constant pool to be used for this object. - * @see ConstantPool - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } - - /** - * Use copy() if you want to have a deep copy(), i.e., with all references - * copied correctly. - * - * @return shallow copy of this attribute - */ - public Object clone() { - Object o = null; - - try { - o = super.clone(); - } catch(CloneNotSupportedException e) { - e.printStackTrace(); // Never occurs + /** + * Dump attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public void dump(final DataOutputStream file) throws IOException { + file.writeShort(name_index); + file.writeInt(length); } - return o; - } + private static final Map readers = new HashMap<>(); - /** - * @return deep copy of this attribute - */ - public abstract Attribute copy(ConstantPool constant_pool); + /** + * Add an Attribute reader capable of parsing (user-defined) attributes + * named "name". You should not add readers for the standard attributes such + * as "LineNumberTable", because those are handled internally. + * + * @param name the name of the attribute as stored in the class file + * @param r the reader object + */ + public static void addAttributeReader(final String name, final UnknownAttributeReader r) { + readers.put(name, r); + } - /** - * @return attribute name. - */ - public String toString() { - return Constants.ATTRIBUTE_NAMES[tag]; - } + /** + * Remove attribute reader + * + * @param name the name of the attribute as stored in the class file + */ + public static void removeAttributeReader(final String name) { + readers.remove(name); + } + + /** + * Class method reads one attribute from the input data stream. This method + * must not be accessible from the outside. It is called by the Field and + * Method constructor methods. + * + * @see Field + * @see Method + * + * @param file Input stream + * @param constant_pool Array of constants + * @return Attribute + * @throws IOException + * @throws ClassFormatException + */ + public static Attribute readAttribute(final DataInputStream file, final ConstantPool constant_pool) + throws IOException, ClassFormatException { + return readAttribute((DataInput) file, constant_pool); + } + + /** + * Class method reads one attribute from the input data stream. This method + * must not be accessible from the outside. It is called by the Field and + * Method constructor methods. + * + * @see Field + * @see Method + * + * @param file Input stream + * @param constant_pool Array of constants + * @return Attribute + * @throws IOException + * @throws ClassFormatException + * @since 6.0 + */ + public static Attribute readAttribute(final DataInput file, final ConstantPool constant_pool) + throws IOException, ClassFormatException { + byte tag = Const.ATTR_UNKNOWN; // Unknown attribute + // Get class name from constant pool via `name_index' indirection + final int name_index = file.readUnsignedShort(); + final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); + final String name = c.getBytes(); + + // Length of data in bytes + final int length = file.readInt(); + + // Compare strings to find known attribute + for (byte i = 0; i < Const.KNOWN_ATTRIBUTES; i++) { + if (name.equals(Const.getAttributeName(i))) { + tag = i; // found! + break; + } + } + + // Call proper constructor, depending on `tag' + switch (tag) { + case Const.ATTR_UNKNOWN: + final Object r = readers.get(name); + if (r instanceof UnknownAttributeReader) { + return ((UnknownAttributeReader) r).createAttribute(name_index, length, file, constant_pool); + } + return new Unknown(name_index, length, file, constant_pool); + case Const.ATTR_CONSTANT_VALUE: + return new ConstantValue(name_index, length, file, constant_pool); + case Const.ATTR_SOURCE_FILE: + return new SourceFile(name_index, length, file, constant_pool); + case Const.ATTR_CODE: + return new Code(name_index, length, file, constant_pool); + case Const.ATTR_EXCEPTIONS: + return new ExceptionTable(name_index, length, file, constant_pool); + case Const.ATTR_LINE_NUMBER_TABLE: + return new LineNumberTable(name_index, length, file, constant_pool); + case Const.ATTR_LOCAL_VARIABLE_TABLE: + return new LocalVariableTable(name_index, length, file, constant_pool); + case Const.ATTR_INNER_CLASSES: + return new InnerClasses(name_index, length, file, constant_pool); + case Const.ATTR_SYNTHETIC: + return new Synthetic(name_index, length, file, constant_pool); + case Const.ATTR_DEPRECATED: + return new Deprecated(name_index, length, file, constant_pool); + case Const.ATTR_PMG: + return new PMGClass(name_index, length, file, constant_pool); + case Const.ATTR_SIGNATURE: + return new Signature(name_index, length, file, constant_pool); + case Const.ATTR_STACK_MAP: + return new StackMap(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS: + return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: + return new RuntimeInvisibleAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeVisibleParameterAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeInvisibleParameterAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_ANNOTATION_DEFAULT: + return new AnnotationDefault(name_index, length, file, constant_pool); + case Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE: + return new LocalVariableTypeTable(name_index, length, file, constant_pool); + case Const.ATTR_ENCLOSING_METHOD: + return new EnclosingMethod(name_index, length, file, constant_pool); + case Const.ATTR_STACK_MAP_TABLE: + return new StackMap(name_index, length, file, constant_pool); + case Const.ATTR_BOOTSTRAP_METHODS: + return new BootstrapMethods(name_index, length, file, constant_pool); + case Const.ATTR_METHOD_PARAMETERS: + return new MethodParameters(name_index, length, file, constant_pool); + default: + // Never reached + throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag); + } + } + + /** + * @return Name of attribute + * @since 6.0 + */ + public String getName() { + final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return Length of attribute field in bytes. + */ + public final int getLength() { + return length; + } + + /** + * @param length length in bytes. + */ + public final void setLength(final int length) { + this.length = length; + } + + /** + * @param name_index of attribute. + */ + public final void setNameIndex(final int name_index) { + this.name_index = name_index; + } + + /** + * @return Name index in constant pool of attribute name. + */ + public final int getNameIndex() { + return name_index; + } + + /** + * @return Tag of attribute, i.e., its type. Value may not be altered, thus + * there is no setTag() method. + */ + public final byte getTag() { + return tag; + } + + /** + * @return Constant pool used by this object. + * @see ConstantPool + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } + + /** + * @param constant_pool Constant pool to be used for this object. + * @see ConstantPool + */ + public final void setConstantPool(final ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * Use copy() if you want to have a deep copy(), i.e., with all references + * copied correctly. + * + * @return shallow copy of this attribute + */ + @Override + public Object clone() { + Attribute attr = null; + try { + attr = (Attribute) super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + return attr; + } + + /** + * @return deep copy of this attribute + */ + public abstract Attribute copy(ConstantPool _constant_pool); + + /** + * @return attribute name. + */ + @Override + public String toString() { + return Const.getAttributeName(tag); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java index ec9593932ee..094cd84e9b3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java @@ -21,17 +21,20 @@ package com.sun.org.apache.bcel.internal.classfile; - /** * Unknown (non-standard) attributes may be read via user-defined factory * objects that can be registered with the Attribute.addAttributeReader * method. These factory objects should implement this interface. * @see Attribute - * @author M. Dahm + * @version $Id: AttributeReader.java 1748467 2016-06-14 21:05:14Z ggregory $ + * + * @deprecated Use UnknownAttributeReader instead */ +@java.lang.Deprecated public interface AttributeReader { - /** + + /** When this attribute reader is added via the static method Attribute.addAttributeReader, an attribute name is associated with it. As the class file parser parses attributes, it will call various @@ -56,9 +59,6 @@ public interface AttributeReader { returned which will cause the parsing of the class file to fail. @see Attribute#addAttributeReader( String, AttributeReader ) - */ - public Attribute createAttribute(int name_index, - int length, - java.io.DataInputStream file, - ConstantPool constant_pool); + */ + Attribute createAttribute( int name_index, int length, java.io.DataInputStream file, ConstantPool constant_pool ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java new file mode 100644 index 00000000000..d8c617fedc2 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java @@ -0,0 +1,173 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Arrays; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This class represents a bootstrap method attribute, i.e., the bootstrap + * method ref, the number of bootstrap arguments and an array of the + * bootstrap arguments. + * + * @see + * The class File Format : The BootstrapMethods Attribute + * @since 6.0 + */ +public class BootstrapMethod implements Cloneable { + + /** Index of the CONSTANT_MethodHandle_info structure in the constant_pool table */ + private int bootstrap_method_ref; + + /** Array of references to the constant_pool table */ + private int[] bootstrap_arguments; + + + /** + * Initialize from another object. + */ + public BootstrapMethod(final BootstrapMethod c) { + this(c.getBootstrapMethodRef(), c.getBootstrapArguments()); + } + + /** + * Construct object from input stream. + * + * @param input Input stream + * @throws IOException + */ + BootstrapMethod(final DataInput input) throws IOException { + this(input.readUnsignedShort(), input.readUnsignedShort()); + + for (int i = 0; i < bootstrap_arguments.length; i++) { + bootstrap_arguments[i] = input.readUnsignedShort(); + } + } + + // helper method + private BootstrapMethod(final int bootstrap_method_ref, final int num_bootstrap_arguments) { + this(bootstrap_method_ref, new int[num_bootstrap_arguments]); + } + + /** + * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle + * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT__info + */ + public BootstrapMethod(final int bootstrap_method_ref, final int[] bootstrap_arguments) { + this.bootstrap_method_ref = bootstrap_method_ref; + this.bootstrap_arguments = bootstrap_arguments; + } + + /** + * @return index into constant_pool of bootstrap_method + */ + public int getBootstrapMethodRef() { + return bootstrap_method_ref; + } + + /** + * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle + */ + public void setBootstrapMethodRef(final int bootstrap_method_ref) { + this.bootstrap_method_ref = bootstrap_method_ref; + } + + /** + * @return int[] of bootstrap_method indices into constant_pool of CONSTANT__info + */ + public int[] getBootstrapArguments() { + return bootstrap_arguments; + } + + /** + * @return count of number of boostrap arguments + */ + public int getNumBootstrapArguments() { + return bootstrap_arguments.length; + } + + /** + * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT__info + */ + public void setBootstrapArguments(final int[] bootstrap_arguments) { + this.bootstrap_arguments = bootstrap_arguments; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + return "BootstrapMethod(" + bootstrap_method_ref + ", " + bootstrap_arguments.length + ", " + + Arrays.toString(bootstrap_arguments) + ")"; + } + + /** + * @return Resolved string representation + */ + public final String toString( final ConstantPool constant_pool ) { + final StringBuilder buf = new StringBuilder(); + String bootstrap_method_name; + bootstrap_method_name = constant_pool.constantToString(bootstrap_method_ref, + Const.CONSTANT_MethodHandle); + buf.append(Utility.compactClassName(bootstrap_method_name)); + final int num_bootstrap_arguments = bootstrap_arguments.length; + if (num_bootstrap_arguments > 0) { + buf.append("\n Method Arguments:"); + for (int i = 0; i < num_bootstrap_arguments; i++) { + buf.append("\n ").append(i).append(": "); + buf.append(constant_pool.constantToString(constant_pool.getConstant(bootstrap_arguments[i]))); + } + } + return buf.toString(); + } + + /** + * Dump object to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(final DataOutputStream file) throws IOException { + file.writeShort(bootstrap_method_ref); + file.writeShort(bootstrap_arguments.length); + for (final int bootstrap_argument : bootstrap_arguments) { + file.writeShort(bootstrap_argument); + } + } + + /** + * @return deep copy of this object + */ + public BootstrapMethod copy() { + try { + return (BootstrapMethod) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java new file mode 100644 index 00000000000..2aa08b94adc --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java @@ -0,0 +1,148 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This class represents a BootstrapMethods attribute. + * + * @see + * The class File Format : The BootstrapMethods Attribute + * @since 6.0 + */ +public class BootstrapMethods extends Attribute { + + private BootstrapMethod[] bootstrap_methods; // TODO this could be made final (setter is not used) + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public BootstrapMethods(final BootstrapMethods c) { + this(c.getNameIndex(), c.getLength(), c.getBootstrapMethods(), c.getConstantPool()); + } + + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param bootstrap_methods array of bootstrap methods + * @param constant_pool Array of constants + */ + public BootstrapMethods(final int name_index, final int length, final BootstrapMethod[] bootstrap_methods, final ConstantPool constant_pool) { + super(Const.ATTR_BOOTSTRAP_METHODS, name_index, length, constant_pool); + this.bootstrap_methods = bootstrap_methods; + } + + /** + * Construct object from Input stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + BootstrapMethods(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { + this(name_index, length, (BootstrapMethod[]) null, constant_pool); + + final int num_bootstrap_methods = input.readUnsignedShort(); + bootstrap_methods = new BootstrapMethod[num_bootstrap_methods]; + for (int i = 0; i < num_bootstrap_methods; i++) { + bootstrap_methods[i] = new BootstrapMethod(input); + } + } + + /** + * @return array of bootstrap method "records" + */ + public final BootstrapMethod[] getBootstrapMethods() { + return bootstrap_methods; + } + + /** + * @param bootstrap_methods the array of bootstrap methods + */ + public final void setBootstrapMethods(final BootstrapMethod[] bootstrap_methods) { + this.bootstrap_methods = bootstrap_methods; + } + + /** + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitBootstrapMethods(this); + } + + /** + * @return deep copy of this attribute + */ + @Override + public BootstrapMethods copy(final ConstantPool _constant_pool) { + final BootstrapMethods c = (BootstrapMethods) clone(); + c.bootstrap_methods = new BootstrapMethod[bootstrap_methods.length]; + + for (int i = 0; i < bootstrap_methods.length; i++) { + c.bootstrap_methods[i] = bootstrap_methods[i].copy(); + } + c.setConstantPool(_constant_pool); + return c; + } + + /** + * Dump bootstrap methods attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(final DataOutputStream file) throws IOException { + super.dump(file); + + file.writeShort(bootstrap_methods.length); + for (final BootstrapMethod bootstrap_method : bootstrap_methods) { + bootstrap_method.dump(file); + } + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append("BootstrapMethods("); + buf.append(bootstrap_methods.length); + buf.append("):\n"); + for (int i = 0; i < bootstrap_methods.length; i++) { + buf.append(" ").append(i).append(": "); + buf.append(bootstrap_methods[i].toString(super.getConstantPool())).append("\n"); + } + return buf.toString(); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassElementValue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassElementValue.java new file mode 100644 index 00000000000..1a9939c656b --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassElementValue.java @@ -0,0 +1,71 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * @since 6.0 + */ +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 final int idx; + + public ClassElementValue(final int type, final int idx, final ConstantPool cpool) + { + super(type, cpool); + this.idx = idx; + } + + public int getIndex() + { + return idx; + } + + public String getClassString() + { + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(idx, + Const.CONSTANT_Utf8); + return c.getBytes(); + } + + @Override + public String stringifyValue() + { + final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(idx, + Const.CONSTANT_Utf8); + return cu8.getBytes(); + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getType()); // u1 kind of value + dos.writeShort(idx); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java index 6ab8dfa4f2b..b01e59bd257 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java @@ -21,15 +21,30 @@ package com.sun.org.apache.bcel.internal.classfile; - /** * Thrown when the BCEL attempts to read a class file and determines * that the file is malformed or otherwise cannot be interpreted as a * class file. * - * @author M. Dahm + * @version $Id: ClassFormatException.java 1748973 2016-06-18 12:14:42Z sebb $ */ public class ClassFormatException extends RuntimeException { - public ClassFormatException() { super(); } - public ClassFormatException(String s) { super(s); } + + private static final long serialVersionUID = -3569097343160139969L; + + public ClassFormatException() { + super(); + } + + + public ClassFormatException(final String s) { + super(s); + } + + /** + * @since 6.0 + */ + public ClassFormatException(final String message, final Throwable cause) { + super(message, cause); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java index 354891d0181..7e5a22de523 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java @@ -21,10 +21,15 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; -import java.util.zip.*; +import com.sun.org.apache.bcel.internal.Const; /** * Wrapper class that parses a given Java .class file. The method + * exactly with the * JVM specification 1.0. See this paper for * further details about the structure of a bytecode file. * - * @author M. Dahm + * @version $Id: ClassParser.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class ClassParser { - private DataInputStream file; - private ZipFile zip; - private String file_name; - private int class_name_index, superclass_name_index; - private int major, minor; // Compiler version - private int access_flags; // Access rights of parsed class - private int[] interfaces; // Names of implemented interfaces - private ConstantPool constant_pool; // collection of constants - private Field[] fields; // class fields, i.e., its variables - private Method[] methods; // methods defined in the class - private Attribute[] attributes; // attributes defined in the class - private boolean is_zip; // Loaded from zip file - private static final int BUFSIZE = 8192; + private DataInputStream dataInputStream; + private final boolean fileOwned; + private final String file_name; + private String zip_file; + private int class_name_index; + private int superclass_name_index; + private int major; // Compiler version + private int minor; // Compiler version + private int access_flags; // Access rights of parsed class + private int[] interfaces; // Names of implemented interfaces + private ConstantPool constant_pool; // collection of constants + private Field[] fields; // class fields, i.e., its variables + private Method[] methods; // methods defined in the class + private Attribute[] attributes; // attributes defined in the class + private final boolean is_zip; // Loaded from zip file + private static final int BUFSIZE = 8192; - /** - * Parse class from the given stream. - * - * @param file Input stream - * @param file_name File name - */ - public ClassParser(InputStream file, String file_name) { - this.file_name = file_name; - String clazz = file.getClass().getName(); // Not a very clean solution ... - is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); - - if(file instanceof DataInputStream) // Is already a data stream - this.file = (DataInputStream)file; - else - this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE)); - } - - /** Parse class from given .class file. - * - * @param file_name file name - * @throws IOException - */ - public ClassParser(String file_name) throws IOException - { - is_zip = false; - this.file_name = file_name; - file = new DataInputStream(new BufferedInputStream - (new FileInputStream(file_name), BUFSIZE)); - } - - /** Parse class from given .class file in a ZIP-archive - * - * @param file_name file name - * @throws IOException - */ - public ClassParser(String zip_file, String file_name) throws IOException - { - is_zip = true; - zip = new ZipFile(zip_file); - ZipEntry entry = zip.getEntry(file_name); - - this.file_name = file_name; - - file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), - BUFSIZE)); - } - - /** - * Parse the given Java class file and return an object that represents - * the contained data, i.e., constants, methods, fields and commands. - * A ClassFormatException is raised, if the file is not a valid - * .class file. (This does not include verification of the byte code as it - * is performed by the java interpreter). - * - * @return Class object representing the parsed class file - * @throws IOException - * @throws ClassFormatException - */ - public JavaClass parse() throws IOException, ClassFormatException - { - /****************** Read headers ********************************/ - // Check magic tag of class file - readID(); - - // Get compiler version - readVersion(); - - /****************** Read constant pool and related **************/ - // Read constant pool entries - readConstantPool(); - - // Get class information - readClassInfo(); - - // Get interface information, i.e., implemented interfaces - readInterfaces(); - - /****************** Read class fields and methods ***************/ - // Read class fields, i.e., the variables of the class - readFields(); - - // Read class methods, i.e., the functions in the class - readMethods(); - - // Read class attributes - readAttributes(); - - // Check for unknown variables - //Unknown[] u = Unknown.getUnknownAttributes(); - //for(int i=0; i < u.length; i++) - // System.err.println("WARNING: " + u[i]); - - // Everything should have been read now - // if(file.available() > 0) { - // int bytes = file.available(); - // byte[] buf = new byte[bytes]; - // file.read(buf); - - // if(!(is_zip && (buf.length == 1))) { - // System.err.println("WARNING: Trailing garbage at end of " + file_name); - // System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf)); - // } - // } - - // Read everything of interest, so close the file - file.close(); - if(zip != null) - zip.close(); - - // Return the information we have gathered in a new object - return new JavaClass(class_name_index, superclass_name_index, - file_name, major, minor, access_flags, - constant_pool, interfaces, fields, - methods, attributes, is_zip? JavaClass.ZIP : JavaClass.FILE); - } - - /** - * Read information about the attributes of the class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readAttributes() throws IOException, ClassFormatException - { - int attributes_count; - - attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - - for(int i=0; i < attributes_count; i++) - attributes[i] = Attribute.readAttribute(file, constant_pool); - } - - /** - * Read information about the class and its super class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readClassInfo() throws IOException, ClassFormatException - { - access_flags = file.readUnsignedShort(); - - /* Interfaces are implicitely abstract, the flag should be set - * according to the JVM specification. + /** + * Parse class from the given stream. + * + * @param inputStream Input stream + * @param file_name File name */ - if((access_flags & Constants.ACC_INTERFACE) != 0) - access_flags |= Constants.ACC_ABSTRACT; + public ClassParser(final InputStream inputStream, final String file_name) { + this.file_name = file_name; + fileOwned = false; + final String clazz = inputStream.getClass().getName(); // Not a very clean solution ... + is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); + if (inputStream instanceof DataInputStream) { + this.dataInputStream = (DataInputStream) inputStream; + } else { + this.dataInputStream = new DataInputStream(new BufferedInputStream(inputStream, BUFSIZE)); + } + } - if(((access_flags & Constants.ACC_ABSTRACT) != 0) && - ((access_flags & Constants.ACC_FINAL) != 0 )) - throw new ClassFormatException("Class can't be both final and abstract"); - class_name_index = file.readUnsignedShort(); - superclass_name_index = file.readUnsignedShort(); - } - /** - * Read constant pool entries. - * @throws IOException - * @throws ClassFormatException - */ - private final void readConstantPool() throws IOException, ClassFormatException - { - constant_pool = new ConstantPool(file); - } + /** Parse class from given .class file. + * + * @param file_name file name + */ + public ClassParser(final String file_name) { + is_zip = false; + this.file_name = file_name; + fileOwned = true; + } - /** - * Read information about the fields of the class, i.e., its variables. - * @throws IOException - * @throws ClassFormatException - */ - private final void readFields() throws IOException, ClassFormatException - { - int fields_count; - fields_count = file.readUnsignedShort(); - fields = new Field[fields_count]; + /** Parse class from given .class file in a ZIP-archive + * + * @param zip_file zip file name + * @param file_name file name + */ + public ClassParser(final String zip_file, final String file_name) { + is_zip = true; + fileOwned = true; + this.zip_file = zip_file; + this.file_name = file_name; + } - for(int i=0; i < fields_count; i++) - fields[i] = new Field(file, constant_pool); - } - /******************** Private utility methods **********************/ + /** + * Parse the given Java class file and return an object that represents + * the contained data, i.e., constants, methods, fields and commands. + * A ClassFormatException is raised, if the file is not a valid + * .class file. (This does not include verification of the byte code as it + * is performed by the java interpreter). + * + * @return Class object representing the parsed class file + * @throws IOException + * @throws ClassFormatException + */ + public JavaClass parse() throws IOException, ClassFormatException { + ZipFile zip = null; + try { + if (fileOwned) { + if (is_zip) { + zip = new ZipFile(zip_file); + final ZipEntry entry = zip.getEntry(file_name); - /** - * Check whether the header of the file is ok. - * Of course, this has to be the first action on successive file reads. - * @throws IOException - * @throws ClassFormatException - */ - private final void readID() throws IOException, ClassFormatException - { - int magic = 0xCAFEBABE; + if (entry == null) { + throw new IOException("File " + file_name + " not found"); + } - if(file.readInt() != magic) - throw new ClassFormatException(file_name + " is not a Java .class file"); - } - /** - * Read information about the interfaces implemented by this class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readInterfaces() throws IOException, ClassFormatException - { - int interfaces_count; + dataInputStream = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), + BUFSIZE)); + } else { + dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream( + file_name), BUFSIZE)); + } + } + /****************** Read headers ********************************/ + // Check magic tag of class file + readID(); + // Get compiler version + readVersion(); + /****************** Read constant pool and related **************/ + // Read constant pool entries + readConstantPool(); + // Get class information + readClassInfo(); + // Get interface information, i.e., implemented interfaces + readInterfaces(); + /****************** Read class fields and methods ***************/ + // Read class fields, i.e., the variables of the class + readFields(); + // Read class methods, i.e., the functions in the class + readMethods(); + // Read class attributes + readAttributes(); + // Check for unknown variables + //Unknown[] u = Unknown.getUnknownAttributes(); + //for (int i=0; i < u.length; i++) + // System.err.println("WARNING: " + u[i]); + // Everything should have been read now + // if(file.available() > 0) { + // int bytes = file.available(); + // byte[] buf = new byte[bytes]; + // file.read(buf); + // if(!(is_zip && (buf.length == 1))) { + // System.err.println("WARNING: Trailing garbage at end of " + file_name); + // System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf)); + // } + // } + } finally { + // Read everything of interest, so close the file + if (fileOwned) { + try { + if (dataInputStream != null) { + dataInputStream.close(); + } + } catch (final IOException ioe) { + //ignore close exceptions + } + } + try { + if (zip != null) { + zip.close(); + } + } catch (final IOException ioe) { + //ignore close exceptions + } + } + // Return the information we have gathered in a new object + return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, + access_flags, constant_pool, interfaces, fields, methods, attributes, is_zip + ? JavaClass.ZIP + : JavaClass.FILE); + } - interfaces_count = file.readUnsignedShort(); - interfaces = new int[interfaces_count]; - for(int i=0; i < interfaces_count; i++) - interfaces[i] = file.readUnsignedShort(); - } - /** - * Read information about the methods of the class. - * @throws IOException - * @throws ClassFormatException - */ - private final void readMethods() throws IOException, ClassFormatException - { - int methods_count; + /** + * Read information about the attributes of the class. + * @throws IOException + * @throws ClassFormatException + */ + private void readAttributes() throws IOException, ClassFormatException { + final int attributes_count = dataInputStream.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + attributes[i] = Attribute.readAttribute(dataInputStream, constant_pool); + } + } - methods_count = file.readUnsignedShort(); - methods = new Method[methods_count]; - for(int i=0; i < methods_count; i++) - methods[i] = new Method(file, constant_pool); - } - /** - * Read major and minor version of compiler which created the file. - * @throws IOException - * @throws ClassFormatException - */ - private final void readVersion() throws IOException, ClassFormatException - { - minor = file.readUnsignedShort(); - major = file.readUnsignedShort(); - } + /** + * Read information about the class and its super class. + * @throws IOException + * @throws ClassFormatException + */ + private void readClassInfo() throws IOException, ClassFormatException { + access_flags = dataInputStream.readUnsignedShort(); + /* Interfaces are implicitely abstract, the flag should be set + * according to the JVM specification. + */ + if ((access_flags & Const.ACC_INTERFACE) != 0) { + access_flags |= Const.ACC_ABSTRACT; + } + if (((access_flags & Const.ACC_ABSTRACT) != 0) + && ((access_flags & Const.ACC_FINAL) != 0)) { + throw new ClassFormatException("Class " + file_name + " can't be both final and abstract"); + } + class_name_index = dataInputStream.readUnsignedShort(); + superclass_name_index = dataInputStream.readUnsignedShort(); + } + + + /** + * Read constant pool entries. + * @throws IOException + * @throws ClassFormatException + */ + private void readConstantPool() throws IOException, ClassFormatException { + constant_pool = new ConstantPool(dataInputStream); + } + + + /** + * Read information about the fields of the class, i.e., its variables. + * @throws IOException + * @throws ClassFormatException + */ + private void readFields() throws IOException, ClassFormatException { + final int fields_count = dataInputStream.readUnsignedShort(); + fields = new Field[fields_count]; + for (int i = 0; i < fields_count; i++) { + fields[i] = new Field(dataInputStream, constant_pool); + } + } + + + /******************** Private utility methods **********************/ + /** + * Check whether the header of the file is ok. + * Of course, this has to be the first action on successive file reads. + * @throws IOException + * @throws ClassFormatException + */ + private void readID() throws IOException, ClassFormatException { + if (dataInputStream.readInt() != Const.JVM_CLASSFILE_MAGIC) { + throw new ClassFormatException(file_name + " is not a Java .class file"); + } + } + + + /** + * Read information about the interfaces implemented by this class. + * @throws IOException + * @throws ClassFormatException + */ + private void readInterfaces() throws IOException, ClassFormatException { + final int interfaces_count = dataInputStream.readUnsignedShort(); + interfaces = new int[interfaces_count]; + for (int i = 0; i < interfaces_count; i++) { + interfaces[i] = dataInputStream.readUnsignedShort(); + } + } + + + /** + * Read information about the methods of the class. + * @throws IOException + * @throws ClassFormatException + */ + private void readMethods() throws IOException, ClassFormatException { + final int methods_count = dataInputStream.readUnsignedShort(); + methods = new Method[methods_count]; + for (int i = 0; i < methods_count; i++) { + methods[i] = new Method(dataInputStream, constant_pool); + } + } + + + /** + * Read major and minor version of compiler which created the file. + * @throws IOException + * @throws ClassFormatException + */ + private void readVersion() throws IOException, ClassFormatException { + minor = dataInputStream.readUnsignedShort(); + major = dataInputStream.readUnsignedShort(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java index 5f02da73349..6a4ddc31ab4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java @@ -21,9 +21,11 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents a chunk of Java byte code contained in a @@ -37,304 +39,321 @@ import java.io.*; * is used for debugging purposes and LocalVariableTable which * contains information about the local variables. * - * @author M. Dahm + * @version $Id: Code.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Attribute * @see CodeException * @see LineNumberTable * @see LocalVariableTable */ public final class Code extends Attribute { - private int max_stack; // Maximum size of stack used by this method - private int max_locals; // Number of local variables - private int code_length; // Length of code in bytes - private byte[] code; // Actual byte code - private int exception_table_length; - private CodeException[] exception_table; // Table of handled exceptions - private int attributes_count; // Attributes of code: LineNumber - private Attribute[] attributes; // or LocalVariable + private int max_stack; // Maximum size of stack used by this method // TODO this could be made final (setter is not used) + private int max_locals; // Number of local variables // TODO this could be made final (setter is not used) + private byte[] code; // Actual byte code + private CodeException[] exception_table; // Table of handled exceptions + private Attribute[] attributes; // or LocalVariable - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public Code(Code c) { - this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), - c.getCode(), c.getExceptionTable(), c.getAttributes(), - c.getConstantPool()); - } - /** - * @param name_index Index pointing to the name Code - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - */ - Code(int name_index, int length, DataInputStream file, - ConstantPool constant_pool) throws IOException - { - // Initialize with some default values which will be overwritten later - this(name_index, length, - file.readUnsignedShort(), file.readUnsignedShort(), - (byte[])null, (CodeException[])null, (Attribute[])null, - constant_pool); - - code_length = file.readInt(); - code = new byte[code_length]; // Read byte code - file.readFully(code); - - /* Read exception table that contains all regions where an exception - * handler is active, i.e., a try { ... } catch() block. + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. */ - exception_table_length = file.readUnsignedShort(); - exception_table = new CodeException[exception_table_length]; - - for(int i=0; i < exception_table_length; i++) - exception_table[i] = new CodeException(file); - - /* Read all attributes, currently `LineNumberTable' and - * `LocalVariableTable' - */ - attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for(int i=0; i < attributes_count; i++) - attributes[i] = Attribute.readAttribute(file, constant_pool); - - /* Adjust length, because of setAttributes in this(), s.b. length - * is incorrect, because it didn't take the internal attributes - * into account yet! Very subtle bug, fixed in 3.1.1. - */ - this.length = length; - } - - /** - * @param name_index Index pointing to the name Code - * @param length Content length in bytes - * @param max_stack Maximum size of stack - * @param max_locals Number of local variables - * @param code Actual byte code - * @param exception_table Table of handled exceptions - * @param attributes Attributes of code: LineNumber or LocalVariable - * @param constant_pool Array of constants - */ - public Code(int name_index, int length, - int max_stack, int max_locals, - byte[] code, - CodeException[] exception_table, - Attribute[] attributes, - ConstantPool constant_pool) - { - super(Constants.ATTR_CODE, name_index, length, constant_pool); - - this.max_stack = max_stack; - this.max_locals = max_locals; - - setCode(code); - setExceptionTable(exception_table); - setAttributes(attributes); // Overwrites length! - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitCode(this); - } - - /** - * Dump code attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - - file.writeShort(max_stack); - file.writeShort(max_locals); - file.writeInt(code_length); - file.write(code, 0, code_length); - - file.writeShort(exception_table_length); - for(int i=0; i < exception_table_length; i++) - exception_table[i].dump(file); - - file.writeShort(attributes_count); - for(int i=0; i < attributes_count; i++) - attributes[i].dump(file); - } - - /** - * @return Collection of code attributes. - * @see Attribute - */ - public final Attribute[] getAttributes() { return attributes; } - - /** - * @return LineNumberTable of Code, if it has one - */ - public LineNumberTable getLineNumberTable() { - for(int i=0; i < attributes_count; i++) - if(attributes[i] instanceof LineNumberTable) - return (LineNumberTable)attributes[i]; - - return null; - } - - /** - * @return LocalVariableTable of Code, if it has one - */ - public LocalVariableTable getLocalVariableTable() { - for(int i=0; i < attributes_count; i++) - if(attributes[i] instanceof LocalVariableTable) - return (LocalVariableTable)attributes[i]; - - return null; - } - - /** - * @return Actual byte code of the method. - */ - public final byte[] getCode() { return code; } - - /** - * @return Table of handled exceptions. - * @see CodeException - */ - public final CodeException[] getExceptionTable() { return exception_table; } - - /** - * @return Number of local variables. - */ - public final int getMaxLocals() { return max_locals; } - - /** - * @return Maximum size of stack used by this method. - */ - - public final int getMaxStack() { return max_stack; } - - /** - * @return the internal length of this code attribute (minus the first 6 bytes) - * and excluding all its attributes - */ - private final int getInternalLength() { - return 2 /*max_stack*/ + 2 /*max_locals*/ + 4 /*code length*/ - + code_length /*byte-code*/ - + 2 /*exception-table length*/ - + 8 * exception_table_length /* exception table */ - + 2 /* attributes count */; - } - - /** - * @return the full size of this code attribute, minus its first 6 bytes, - * including the size of all its contained attributes - */ - private final int calculateLength() { - int len = 0; - - for(int i=0; i < attributes_count; i++) - len += attributes[i].length + 6 /*attribute header size*/; - - return len + getInternalLength(); - } - - /** - * @param attributes. - */ - public final void setAttributes(Attribute[] attributes) { - this.attributes = attributes; - attributes_count = (attributes == null)? 0 : attributes.length; - length = calculateLength(); // Adjust length - } - - /** - * @param code byte code - */ - public final void setCode(byte[] code) { - this.code = code; - code_length = (code == null)? 0 : code.length; - } - - /** - * @param exception_table exception table - */ - public final void setExceptionTable(CodeException[] exception_table) { - this.exception_table = exception_table; - exception_table_length = (exception_table == null)? 0 : - exception_table.length; - } - - /** - * @param max_locals maximum number of local variables - */ - public final void setMaxLocals(int max_locals) { - this.max_locals = max_locals; - } - - /** - * @param max_stack maximum stack size - */ - public final void setMaxStack(int max_stack) { - this.max_stack = max_stack; - } - - /** - * @return String representation of code chunk. - */ - public final String toString(boolean verbose) { - StringBuffer buf; - - buf = new StringBuffer("Code(max_stack = " + max_stack + - ", max_locals = " + max_locals + - ", code_length = " + code_length + ")\n" + - Utility.codeToString(code, constant_pool, 0, -1, verbose)); - - if(exception_table_length > 0) { - buf.append("\nException handler(s) = \n" + "From\tTo\tHandler\tType\n"); - - for(int i=0; i < exception_table_length; i++) - buf.append(exception_table[i].toString(constant_pool, verbose) + "\n"); + public Code(final Code c) { + this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), c.getCode(), c + .getExceptionTable(), c.getAttributes(), c.getConstantPool()); } - if(attributes_count > 0) { - buf.append("\nAttribute(s) = \n"); - for(int i=0; i < attributes_count; i++) - buf.append(attributes[i].toString() + "\n"); + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + */ + Code(final int name_index, final int length, final DataInput file, final 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); + final int code_length = file.readInt(); + code = new byte[code_length]; // Read byte code + file.readFully(code); + /* Read exception table that contains all regions where an exception + * handler is active, i.e., a try { ... } catch() block. + */ + final int exception_table_length = file.readUnsignedShort(); + exception_table = new CodeException[exception_table_length]; + for (int i = 0; i < exception_table_length; i++) { + exception_table[i] = new CodeException(file); + } + /* Read all attributes, currently `LineNumberTable' and + * `LocalVariableTable' + */ + final int attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + attributes[i] = Attribute.readAttribute(file, constant_pool); + } + /* Adjust length, because of setAttributes in this(), s.b. length + * is incorrect, because it didn't take the internal attributes + * into account yet! Very subtle bug, fixed in 3.1.1. + */ + super.setLength(length); } - return buf.toString(); - } - /** - * @return String representation of code chunk. - */ - public final String toString() { - return toString(true); - } + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param max_stack Maximum size of stack + * @param max_locals Number of local variables + * @param code Actual byte code + * @param exception_table Table of handled exceptions + * @param attributes Attributes of code: LineNumber or LocalVariable + * @param constant_pool Array of constants + */ + public Code(final int name_index, final int length, final int max_stack, final int max_locals, final byte[] code, + final CodeException[] exception_table, final Attribute[] attributes, final ConstantPool constant_pool) { + super(Const.ATTR_CODE, name_index, length, constant_pool); + this.max_stack = max_stack; + this.max_locals = max_locals; + this.code = code != null ? code : new byte[0]; + this.exception_table = exception_table != null ? exception_table : new CodeException[0]; + this.attributes = attributes != null ? attributes : new Attribute[0]; + super.setLength(calculateLength()); // Adjust length + } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - Code c = (Code)clone(); - c.code = (byte[])code.clone(); - c.constant_pool = constant_pool; - c.exception_table = new CodeException[exception_table_length]; - for(int i=0; i < exception_table_length; i++) - c.exception_table[i] = exception_table[i].copy(); + /** + * 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( final Visitor v ) { + v.visitCode(this); + } - c.attributes = new Attribute[attributes_count]; - for(int i=0; i < attributes_count; i++) - c.attributes[i] = attributes[i].copy(constant_pool); - return c; - } + /** + * Dump code attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(max_stack); + file.writeShort(max_locals); + file.writeInt(code.length); + file.write(code, 0, code.length); + file.writeShort(exception_table.length); + for (final CodeException exception : exception_table) { + exception.dump(file); + } + file.writeShort(attributes.length); + for (final Attribute attribute : attributes) { + attribute.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 (final Attribute attribute : attributes) { + if (attribute instanceof LineNumberTable) { + return (LineNumberTable) attribute; + } + } + return null; + } + + + /** + * @return LocalVariableTable of Code, if it has one + */ + public LocalVariableTable getLocalVariableTable() { + for (final Attribute attribute : attributes) { + if (attribute instanceof LocalVariableTable) { + return (LocalVariableTable) attribute; + } + } + 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 exception_table; + } + + + /** + * @return Number of local variables. + */ + public final int getMaxLocals() { + return max_locals; + } + + + /** + * @return Maximum size of stack used by this method. + */ + public final int getMaxStack() { + return max_stack; + } + + + /** + * @return the internal length of this code attribute (minus the first 6 bytes) + * and excluding all its attributes + */ + private int getInternalLength() { + return 2 /*max_stack*/+ 2 /*max_locals*/+ 4 /*code length*/ + + code.length /*byte-code*/ + + 2 /*exception-table length*/ + + 8 * (exception_table == null ? 0 : exception_table.length) /* exception table */ + + 2 /* attributes count */; + } + + + /** + * @return the full size of this code attribute, minus its first 6 bytes, + * including the size of all its contained attributes + */ + private int calculateLength() { + int len = 0; + if (attributes != null) { + for (final Attribute attribute : attributes) { + len += attribute.getLength() + 6 /*attribute header size*/; + } + } + return len + getInternalLength(); + } + + + /** + * @param attributes the attributes to set for this Code + */ + public final void setAttributes( final Attribute[] attributes ) { + this.attributes = attributes != null ? attributes : new Attribute[0]; + super.setLength(calculateLength()); // Adjust length + } + + + /** + * @param code byte code + */ + public final void setCode( final byte[] code ) { + this.code = code != null ? code : new byte[0]; + super.setLength(calculateLength()); // Adjust length + } + + + /** + * @param exception_table exception table + */ + public final void setExceptionTable( final CodeException[] exception_table ) { + this.exception_table = exception_table != null ? exception_table : new CodeException[0]; + super.setLength(calculateLength()); // Adjust length + } + + + /** + * @param max_locals maximum number of local variables + */ + public final void setMaxLocals( final int max_locals ) { + this.max_locals = max_locals; + } + + + /** + * @param max_stack maximum stack size + */ + public final void setMaxStack( final int max_stack ) { + this.max_stack = max_stack; + } + + + /** + * @return String representation of code chunk. + */ + public final String toString( final boolean verbose ) { + final StringBuilder buf = new StringBuilder(100); // CHECKSTYLE IGNORE MagicNumber + buf.append("Code(max_stack = ").append(max_stack).append(", max_locals = ").append( + max_locals).append(", code_length = ").append(code.length).append(")\n").append( + Utility.codeToString(code, super.getConstantPool(), 0, -1, verbose)); + if (exception_table.length > 0) { + buf.append("\nException handler(s) = \n").append("From\tTo\tHandler\tType\n"); + for (final CodeException exception : exception_table) { + buf.append(exception.toString(super.getConstantPool(), verbose)).append("\n"); + } + } + if (attributes.length > 0) { + buf.append("\nAttribute(s) = "); + for (final Attribute attribute : attributes) { + buf.append("\n").append(attribute); + } + } + return buf.toString(); + } + + + /** + * @return String representation of code chunk. + */ + @Override + public final String toString() { + return toString(true); + } + + + /** + * @return deep copy of this attribute + * + * @param _constant_pool the constant pool to duplicate + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + final Code c = (Code) clone(); + if (code != null) { + c.code = new byte[code.length]; + System.arraycopy(code, 0, c.code, 0, code.length); + } + c.setConstantPool(_constant_pool); + c.exception_table = new CodeException[exception_table.length]; + for (int i = 0; i < exception_table.length; i++) { + c.exception_table[i] = exception_table[i].copy(); + } + c.attributes = new Attribute[attributes.length]; + for (int i = 0; i < attributes.length; i++) { + c.attributes[i] = attributes[i].copy(_constant_pool); + } + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java index 0fd1040bb10..2dc72a1dc16 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,176 +20,201 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents an entry in the exception table of the Code * attribute and is used only there. It contains a range in which a * particular exception handler is active. * - * @author M. Dahm + * @version $Id: CodeException.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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. - */ - /** - * Initialize from another object. - */ - public CodeException(CodeException c) { - this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); - } +public final class CodeException implements Cloneable, Node { - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - CodeException(DataInputStream file) throws IOException - { - this(file.readUnsignedShort(), file.readUnsignedShort(), - file.readUnsignedShort(), file.readUnsignedShort()); - } + 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. + */ - /** - * @param start_pc Range in the code the exception handler is active, - * start_pc is inclusive while - * @param end_pc is exclusive - * @param handler_pc Starting address of exception handler, i.e., - * an offset from start of code. - * @param catch_type If zero the handler catches any - * exception, otherwise it points to the exception class which is - * to be caught. - */ - public CodeException(int start_pc, int end_pc, int handler_pc, - int catch_type) - { - this.start_pc = start_pc; - this.end_pc = end_pc; - this.handler_pc = handler_pc; - this.catch_type = catch_type; - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitCodeException(this); - } - /** - * Dump code exception to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeShort(start_pc); - file.writeShort(end_pc); - file.writeShort(handler_pc); - file.writeShort(catch_type); - } + /** + * Initialize from another object. + */ + public CodeException(final CodeException c) { + this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); + } - /** - * @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; } + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + CodeException(final DataInput file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort()); + } - /** - * @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 start_pc Range in the code the exception handler is active, + * start_pc is inclusive while + * @param end_pc is exclusive + * @param handler_pc Starting address of exception handler, i.e., + * an offset from start of code. + * @param catch_type If zero the handler catches any + * exception, otherwise it points to the exception class which is + * to be caught. + */ + public CodeException(final int start_pc, final int end_pc, final int handler_pc, final int catch_type) { + this.start_pc = start_pc; + this.end_pc = end_pc; + this.handler_pc = handler_pc; + this.catch_type = catch_type; + } - /** - * @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; - } + /** + * 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( final Visitor v ) { + v.visitCodeException(this); + } - /** - * @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; - } + /** + * Dump code exception to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump( final DataOutputStream file ) throws IOException { + file.writeShort(start_pc); + file.writeShort(end_pc); + file.writeShort(handler_pc); + file.writeShort(catch_type); + } - /** - * @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; + /** + * @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; + } - if(catch_type == 0) - str = "(0)"; - else - str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false) + - (verbose? "(" + catch_type + ")" : ""); - return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; - } + /** + * @return Exclusive end index of the region where the handler is active. + */ + public final int getEndPC() { + return end_pc; + } - 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 Starting address of exception handler, relative to the code. + */ + public final int getHandlerPC() { + return handler_pc; + } - return null; - } + + /** + * @return Inclusive start index of the region where the handler is active. + */ + public final int getStartPC() { + return start_pc; + } + + + /** + * @param catch_type the type of exception that is caught + */ + public final void setCatchType( final int catch_type ) { + this.catch_type = catch_type; + } + + + /** + * @param end_pc end of handled block + */ + public final void setEndPC( final int end_pc ) { + this.end_pc = end_pc; + } + + + /** + * @param handler_pc where the actual code is + */ + public final void setHandlerPC( final int handler_pc ) { // TODO unused + this.handler_pc = handler_pc; + } + + + /** + * @param start_pc start of handled block + */ + public final void setStartPC( final int start_pc ) { // TODO unused + this.start_pc = start_pc; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = " + + handler_pc + ", catch_type = " + catch_type + ")"; + } + + + /** + * @return String representation. + */ + public final String toString( final ConstantPool cp, final boolean verbose ) { + String str; + if (catch_type == 0) { + str = "(0)"; + } else { + str = Utility.compactClassName(cp.getConstantString(catch_type, Const.CONSTANT_Class), false) + + (verbose ? "(" + catch_type + ")" : ""); + } + return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; + } + + + public final String toString( final ConstantPool cp ) { + return toString(cp, true); + } + + + /** + * @return deep copy of this object + */ + public CodeException copy() { + try { + return (CodeException) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java index 18554f0f649..c7e9c7b1f0a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,98 +17,181 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * Abstract superclass for classes to represent the different constant types - * in the constant pool of a class file. The classes keep closely to - * the JVM specification. + * Abstract superclass for classes to represent the different constant types in + * the constant pool of a class file. The classes keep closely to the JVM + * specification. * - * @author M. Dahm + * @version $Id: Constant.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public abstract class Constant implements Cloneable, Node, Serializable { - /* In fact this tag is redundant since we can distinguish different - * `Constant' objects by their type, i.e., via `instanceof'. In some - * places we will use the tag for switch()es anyway. - * - * First, we want match the specification as closely as possible. Second we - * need the tag as an index to select the corresponding class name from the - * `CONSTANT_NAMES' array. - */ - protected byte tag; +public abstract class Constant implements Cloneable, Node { - Constant(byte tag) { this.tag = tag; } + private static BCELComparator bcelComparator = new BCELComparator() { - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public abstract void accept(Visitor v); + @Override + public boolean equals(final Object o1, final Object o2) { + final Constant THIS = (Constant) o1; + final Constant THAT = (Constant) o2; + return THIS.toString().equals(THAT.toString()); + } - public abstract void dump(DataOutputStream file) throws IOException; + @Override + public int hashCode(final Object o) { + final Constant THIS = (Constant) o; + return THIS.toString().hashCode(); + } + }; - /** - * @return Tag of constant, i.e., its type. No setTag() method to avoid - * confusion. - */ - public final byte getTag() { return tag; } + /* In fact this tag is redundant since we can distinguish different + * `Constant' objects by their type, i.e., via `instanceof'. In some + * places we will use the tag for switch()es anyway. + * + * First, we want match the specification as closely as possible. Second we + * need the tag as an index to select the corresponding class name from the + * `CONSTANT_NAMES' array. + */ + private byte tag; - /** - * @return String representation. - */ - public String toString() { - return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; - } - - /** - * @return deep copy of this constant - */ - public Constant copy() { - try { - return (Constant)super.clone(); - } catch(CloneNotSupportedException e) {} - - return null; - } - - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - - /** - * Read one constant from the given file, the type depends on a tag byte. - * - * @param file Input stream - * @return Constant object - */ - static final Constant readConstant(DataInputStream file) - throws IOException, ClassFormatException - { - byte b = file.readByte(); // Read tag byte - - switch(b) { - case Constants.CONSTANT_Class: return new ConstantClass(file); - case Constants.CONSTANT_Fieldref: return new ConstantFieldref(file); - case Constants.CONSTANT_Methodref: return new ConstantMethodref(file); - case Constants.CONSTANT_InterfaceMethodref: return new - ConstantInterfaceMethodref(file); - case Constants.CONSTANT_String: return new ConstantString(file); - case Constants.CONSTANT_Integer: return new ConstantInteger(file); - case Constants.CONSTANT_Float: return new ConstantFloat(file); - case Constants.CONSTANT_Long: return new ConstantLong(file); - case Constants.CONSTANT_Double: return new ConstantDouble(file); - case Constants.CONSTANT_NameAndType: return new ConstantNameAndType(file); - case Constants.CONSTANT_Utf8: return new ConstantUtf8(file); - default: - throw new ClassFormatException("Invalid byte tag in constant pool: " + b); + Constant(final byte tag) { + this.tag = tag; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public abstract void accept(Visitor v); + + public abstract void dump(DataOutputStream file) throws IOException; + + /** + * @return Tag of constant, i.e., its type. No setTag() method to avoid + * confusion. + */ + public final byte getTag() { + return tag; + } + + /** + * @return String representation. + */ + @Override + public String toString() { + return Const.getConstantName(tag) + "[" + tag + "]"; + } + + /** + * @return deep copy of this constant + */ + public Constant copy() { + try { + return (Constant) super.clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } + + /** + * Read one constant from the given input, the type depends on a tag byte. + * + * @param input Input stream + * @return Constant object + * @since 6.0 made public + */ + public static Constant readConstant(final DataInput input) throws IOException, + ClassFormatException { + final byte b = input.readByte(); // Read tag byte + switch (b) { + case Const.CONSTANT_Class: + return new ConstantClass(input); + case Const.CONSTANT_Fieldref: + return new ConstantFieldref(input); + case Const.CONSTANT_Methodref: + return new ConstantMethodref(input); + case Const.CONSTANT_InterfaceMethodref: + return new ConstantInterfaceMethodref(input); + case Const.CONSTANT_String: + return new ConstantString(input); + case Const.CONSTANT_Integer: + return new ConstantInteger(input); + case Const.CONSTANT_Float: + return new ConstantFloat(input); + case Const.CONSTANT_Long: + return new ConstantLong(input); + case Const.CONSTANT_Double: + return new ConstantDouble(input); + case Const.CONSTANT_NameAndType: + return new ConstantNameAndType(input); + case Const.CONSTANT_Utf8: + return ConstantUtf8.getInstance(input); + case Const.CONSTANT_MethodHandle: + return new ConstantMethodHandle(input); + case Const.CONSTANT_MethodType: + return new ConstantMethodType(input); + case Const.CONSTANT_InvokeDynamic: + return new ConstantInvokeDynamic(input); + default: + throw new ClassFormatException("Invalid byte tag in constant pool: " + b); + } + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * Constant objects are said to be equal when the result of toString() is + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the result of toString(). + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java index 7494c56336f..f5f76813bd7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,104 +17,119 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; -import java.io.*; -import com.sun.org.apache.bcel.internal.Constants; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; /** - * Abstract super class for Fieldref and Methodref constants. + * Abstract super class for Fieldref, Methodref, InterfaceMethodref and + * InvokeDynamic constants. * - * @author M. Dahm - * @see ConstantFieldref - * @see ConstantMethodref - * @see ConstantInterfaceMethodref + * @version $Id: ConstantCP.java 1747278 2016-06-07 17:28:43Z britter $ + * @see ConstantFieldref + * @see ConstantMethodref + * @see ConstantInterfaceMethodref + * @see ConstantInvokeDynamic */ public abstract class ConstantCP extends Constant { - /** References to the constants containing the class and the field signature - */ - protected int class_index, name_and_type_index; - /** - * Initialize from another object. - */ - public ConstantCP(ConstantCP c) { - this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); - } + /** + * References to the constants containing the class and the field signature + */ + // Note that this field is used to store the + // bootstrap_method_attr_index of a ConstantInvokeDynamic. + private int class_index; + // This field has the same meaning for all subclasses. + private int name_and_type_index; - /** - * Initialize instance from file data. - * - * @param tag Constant type tag - * @param file Input stream - * @throws IOException - */ - ConstantCP(byte tag, DataInputStream file) throws IOException - { - this(tag, file.readUnsignedShort(), file.readUnsignedShort()); - } + /** + * Initialize from another object. + */ + public ConstantCP(final ConstantCP c) { + this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); + } - /** - * @param class_index Reference to the class containing the field - * @param name_and_type_index and the field signature - */ - protected ConstantCP(byte tag, int class_index, - int name_and_type_index) { - super(tag); - this.class_index = class_index; - this.name_and_type_index = name_and_type_index; - } + /** + * Initialize instance from file data. + * + * @param tag Constant type tag + * @param file Input stream + * @throws IOException + */ + ConstantCP(final byte tag, final DataInput file) throws IOException { + this(tag, file.readUnsignedShort(), file.readUnsignedShort()); + } - /** - * Dump constant field reference to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeShort(class_index); - file.writeShort(name_and_type_index); - } + /** + * @param class_index Reference to the class containing the field + * @param name_and_type_index and the field signature + */ + protected ConstantCP(final byte tag, final int class_index, final int name_and_type_index) { + super(tag); + this.class_index = class_index; + this.name_and_type_index = name_and_type_index; + } - /** - * @return Reference (index) to class this field or method belongs to. - */ - public final int getClassIndex() { return class_index; } + /** + * Dump constant field reference to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(final DataOutputStream file) throws IOException { + file.writeByte(super.getTag()); + file.writeShort(class_index); + file.writeShort(name_and_type_index); + } - /** - * @return Reference (index) to signature of the field. - */ - public final int getNameAndTypeIndex() { return name_and_type_index; } + /** + * @return Reference (index) to class this constant refers to. + */ + public final int getClassIndex() { + return class_index; + } - /** - * @param class_index points to Constant_class - */ - public final void setClassIndex(int class_index) { - this.class_index = class_index; - } + /** + * @param class_index points to Constant_class + */ + public final void setClassIndex(final int class_index) { + this.class_index = class_index; + } - /** - * @return Class this field belongs to. - */ - public String getClass(ConstantPool cp) { - return cp.constantToString(class_index, Constants.CONSTANT_Class); - } + /** + * @return Reference (index) to signature of the field. + */ + public final int getNameAndTypeIndex() { + return name_and_type_index; + } - /** - * @param name_and_type_index points to Constant_NameAndType - */ - public final void setNameAndTypeIndex(int name_and_type_index) { - this.name_and_type_index = name_and_type_index; - } + /** + * @param name_and_type_index points to Constant_NameAndType + */ + public final void setNameAndTypeIndex(final int name_and_type_index) { + this.name_and_type_index = name_and_type_index; + } - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(class_index = " + class_index + - ", name_and_type_index = " + name_and_type_index + ")"; - } + /** + * @return Class this field belongs to. + */ + public String getClass(final ConstantPool cp) { + return cp.constantToString(class_index, Const.CONSTANT_Class); + } + + /** + * @return String representation. + * + * not final as ConstantInvokeDynamic needs to modify + */ + @Override + public String toString() { + return super.toString() + "(class_index = " + class_index + ", name_and_type_index = " + + name_and_type_index + ")"; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java index faabc476376..605aec326c6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java @@ -21,101 +21,116 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to a (external) class. * - * @author M. Dahm + * @version $Id: ConstantClass.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Constant */ public final class ConstantClass extends Constant implements ConstantObject { - private int name_index; // Identical to ConstantString except for the name - /** - * Initialize from another object. - */ - public ConstantClass(ConstantClass c) { - this(c.getNameIndex()); - } - - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantClass(DataInputStream file) throws IOException - { - this(file.readUnsignedShort()); - } - - /** - * @param name_index Name index in constant pool. Should refer to a - * ConstantUtf8. - */ - public ConstantClass(int name_index) { - super(Constants.CONSTANT_Class); - this.name_index = name_index; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantClass(this); - } - - /** - * Dump constant class to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeShort(name_index); - } - - /** - * @return Name index in constant pool of class name. - */ - public final int getNameIndex() { return name_index; } - - /** - * @param name_index. - */ - public final void setNameIndex(int name_index) { - this.name_index = name_index; - } + private int name_index; // Identical to ConstantString except for the name - /** @return String object - */ - public Object getConstantValue(ConstantPool cp) { - Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8); - return ((ConstantUtf8)c).getBytes(); - } + /** + * Initialize from another object. + */ + public ConstantClass(final ConstantClass c) { + this(c.getNameIndex()); + } - /** @return dereferenced string - */ - public String getBytes(ConstantPool cp) { - return (String)getConstantValue(cp); - } - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(name_index = " + name_index + ")"; - } + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantClass(final DataInput file) throws IOException { + this(file.readUnsignedShort()); + } + + + /** + * @param name_index Name index in constant pool. Should refer to a + * ConstantUtf8. + */ + public ConstantClass(final int name_index) { + super(Const.CONSTANT_Class); + this.name_index = name_index; + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitConstantClass(this); + } + + + /** + * Dump constant class to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeShort(name_index); + } + + + /** + * @return Name index in constant pool of class name. + */ + public final int getNameIndex() { + return name_index; + } + + + /** + * @param name_index the name index in the constant pool of this Constant Class + */ + public final void setNameIndex( final int name_index ) { + this.name_index = name_index; + } + + + /** @return String object + */ + @Override + public Object getConstantValue( final ConstantPool cp ) { + final Constant c = cp.getConstant(name_index, Const.CONSTANT_Utf8); + return ((ConstantUtf8) c).getBytes(); + } + + + /** @return dereferenced string + */ + public String getBytes( final ConstantPool cp ) { + return (String) getConstantValue(cp); + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(name_index = " + name_index + ")"; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java index a1a425679d8..b780571e590 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java @@ -20,89 +20,107 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to a Double object. * - * @author M. Dahm + * @version $Id: ConstantDouble.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant */ public final class ConstantDouble extends Constant implements ConstantObject { - private double bytes; - /** - * @param bytes Data - */ - public ConstantDouble(double bytes) { - super(Constants.CONSTANT_Double); - this.bytes = bytes; - } + private double bytes; - /** - * Initialize from another object. - */ - public ConstantDouble(ConstantDouble c) { - this(c.getBytes()); - } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantDouble(DataInputStream file) throws IOException - { - this(file.readDouble()); - } + /** + * @param bytes Data + */ + public ConstantDouble(final double bytes) { + super(Const.CONSTANT_Double); + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantDouble(this); - } - /** - * Dump constant double to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeDouble(bytes); - } - /** - * @return data, i.e., 8 bytes. - */ - public final double getBytes() { return bytes; } - /** - * @param bytes. - */ - public final void setBytes(double bytes) { - this.bytes = bytes; - } - /** - * @return String representation. - */ - public final String toString() - { - return super.toString() + "(bytes = " + bytes + ")"; - } - /** @return Double object - */ - public Object getConstantValue(ConstantPool cp) { - return bytes; - } + /** + * Initialize from another object. + */ + public ConstantDouble(final ConstantDouble c) { + this(c.getBytes()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantDouble(final DataInput file) throws IOException { + this(file.readDouble()); + } + + + /** + * 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( final Visitor v ) { + v.visitConstantDouble(this); + } + + + /** + * Dump constant double to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeDouble(bytes); + } + + + /** + * @return data, i.e., 8 bytes. + */ + public final double getBytes() { + return bytes; + } + + + /** + * @param bytes the raw bytes that represent the double value + */ + public final void setBytes( final double bytes ) { + this.bytes = bytes; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } + + + /** @return Double object + */ + @Override + public Object getConstantValue( final ConstantPool cp ) { + return new Double(bytes); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java index b6cea00cbc3..a7380aa48ac 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java @@ -21,51 +21,55 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents a constant pool reference to a field. * - * @author M. Dahm + * @version $Id: ConstantFieldref.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class ConstantFieldref extends ConstantCP { - /** - * Initialize from another object. - */ - public ConstantFieldref(ConstantFieldref c) { - super(Constants.CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex()); - } - /** - * Initialize instance from file data. - * - * @param file input stream - * @throws IOException - */ - ConstantFieldref(DataInputStream file) throws IOException - { - super(Constants.CONSTANT_Fieldref, file); - } + /** + * Initialize from another object. + */ + public ConstantFieldref(final ConstantFieldref c) { + super(Const.CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex()); + } - /** - * @param class_index Reference to the class containing the Field - * @param name_and_type_index and the Field signature - */ - public ConstantFieldref(int class_index, - int name_and_type_index) { - super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index); - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of Fields, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantFieldref(this); - } + /** + * Initialize instance from input data. + * + * @param input input stream + * @throws IOException + */ + ConstantFieldref(final DataInput input) throws IOException { + super(Const.CONSTANT_Fieldref, input); + } + + + /** + * @param class_index Reference to the class containing the Field + * @param name_and_type_index and the Field signature + */ + public ConstantFieldref(final int class_index, final int name_and_type_index) { + super(Const.CONSTANT_Fieldref, class_index, name_and_type_index); + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of Fields, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitConstantFieldref(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java index 2b2a68a3760..35ca1a6677f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java @@ -20,88 +20,108 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to a float object. * - * @author M. Dahm + * @version $Id: ConstantFloat.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant */ public final class ConstantFloat extends Constant implements ConstantObject { - private float bytes; - /** - * @param bytes Data - */ - public ConstantFloat(float bytes) - { - super(Constants.CONSTANT_Float); - this.bytes = bytes; - } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public ConstantFloat(ConstantFloat c) { - this(c.getBytes()); - } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantFloat(DataInputStream file) throws IOException - { - this(file.readFloat()); - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantFloat(this); - } - /** - * Dump constant float to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeFloat(bytes); - } - /** - * @return data, i.e., 4 bytes. - */ - public final float getBytes() { return bytes; } - /** - * @param bytes. - */ - public final void setBytes(float bytes) { - this.bytes = bytes; - } + private float bytes; - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(bytes = " + bytes + ")"; - } - /** @return Float object - */ - public Object getConstantValue(ConstantPool cp) { - return bytes; - } + /** + * @param bytes Data + */ + public ConstantFloat(final float bytes) { + super(Const.CONSTANT_Float); + this.bytes = bytes; + } + + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public ConstantFloat(final ConstantFloat c) { + this(c.getBytes()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantFloat(final DataInput file) throws IOException { + this(file.readFloat()); + } + + + /** + * 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( final Visitor v ) { + v.visitConstantFloat(this); + } + + + /** + * Dump constant float to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeFloat(bytes); + } + + + /** + * @return data, i.e., 4 bytes. + */ + public final float getBytes() { + return bytes; + } + + + /** + * @param bytes the raw bytes that represent this float + */ + public final void setBytes( final float bytes ) { + this.bytes = bytes; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } + + + /** @return Float object + */ + @Override + public Object getConstantValue( final ConstantPool cp ) { + return new Float(bytes); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java index 458400145fe..a7d3a06fee4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java @@ -20,94 +20,107 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; - -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to an int object. * - * @author M. Dahm + * @version $Id: ConstantInteger.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant */ public final class ConstantInteger extends Constant implements ConstantObject { - private int bytes; - /** - * @param bytes Data - */ - public ConstantInteger(int bytes) - { - super(Constants.CONSTANT_Integer); - this.bytes = bytes; - } + private int bytes; - /** - * Initialize from another object. - */ - public ConstantInteger(ConstantInteger c) { - this(c.getBytes()); - } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantInteger(DataInputStream file) throws IOException - { - this(file.readInt()); - } + /** + * @param bytes Data + */ + public ConstantInteger(final int bytes) { + super(Const.CONSTANT_Integer); + this.bytes = bytes; + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantInteger(this); - } - /** - * Dump constant integer to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeInt(bytes); - } + /** + * Initialize from another object. + */ + public ConstantInteger(final ConstantInteger c) { + this(c.getBytes()); + } - /** - * @return data, i.e., 4 bytes. - */ - public final int getBytes() { return bytes; } - /** - * @param bytes. - */ - public final void setBytes(int bytes) { - this.bytes = bytes; - } + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantInteger(final DataInput file) throws IOException { + this(file.readInt()); + } - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(bytes = " + bytes + ")"; - } - /** @return Integer object - */ - public Object getConstantValue(ConstantPool cp) { - return 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( final Visitor v ) { + v.visitConstantInteger(this); + } + + + /** + * Dump constant integer to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeInt(bytes); + } + + + /** + * @return data, i.e., 4 bytes. + */ + public final int getBytes() { + return bytes; + } + + + /** + * @param bytes the raw bytes that represent this integer + */ + public final void setBytes( final int bytes ) { + this.bytes = bytes; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } + + + /** @return Integer object + */ + @Override + public Object getConstantValue( final ConstantPool cp ) { + return Integer.valueOf(bytes); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java index a242396d2a0..6ac9c965ada 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java @@ -21,51 +21,55 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents a constant pool reference to an interface method. * - * @author M. Dahm + * @version $Id: ConstantInterfaceMethodref.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class ConstantInterfaceMethodref extends ConstantCP { - /** - * Initialize from another object. - */ - public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) { - super(Constants.CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex()); - } - /** - * Initialize instance from file data. - * - * @param file input stream - * @throws IOException - */ - ConstantInterfaceMethodref(DataInputStream file) throws IOException - { - super(Constants.CONSTANT_InterfaceMethodref, file); - } + /** + * Initialize from another object. + */ + public ConstantInterfaceMethodref(final ConstantInterfaceMethodref c) { + super(Const.CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex()); + } - /** - * @param class_index Reference to the class containing the method - * @param name_and_type_index and the method signature - */ - public ConstantInterfaceMethodref(int class_index, - int name_and_type_index) { - super(Constants.CONSTANT_InterfaceMethodref, class_index, name_and_type_index); - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantInterfaceMethodref(this); - } + /** + * Initialize instance from input data. + * + * @param input input stream + * @throws IOException + */ + ConstantInterfaceMethodref(final DataInput input) throws IOException { + super(Const.CONSTANT_InterfaceMethodref, input); + } + + + /** + * @param class_index Reference to the class containing the method + * @param name_and_type_index and the method signature + */ + public ConstantInterfaceMethodref(final int class_index, final int name_and_type_index) { + super(Const.CONSTANT_InterfaceMethodref, class_index, name_and_type_index); + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitConstantInterfaceMethodref(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java new file mode 100644 index 00000000000..0d4b415dc42 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java @@ -0,0 +1,94 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This class is derived from the abstract {@link Constant} + * and represents a reference to a invoke dynamic. + * + * @see Constant + * @see + * The CONSTANT_InvokeDynamic_info Structure in The Java Virtual Machine Specification + * @since 6.0 + */ +public final class ConstantInvokeDynamic extends ConstantCP { + + /** + * Initialize from another object. + */ + public ConstantInvokeDynamic(final ConstantInvokeDynamic c) { + this(c.getBootstrapMethodAttrIndex(), c.getNameAndTypeIndex()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantInvokeDynamic(final DataInput file) throws IOException { + this(file.readShort(), file.readShort()); + } + + + public ConstantInvokeDynamic(final int bootstrap_method_attr_index, final int name_and_type_index) { + super(Const.CONSTANT_InvokeDynamic, bootstrap_method_attr_index, name_and_type_index); + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitly + * 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( final Visitor v ) { + v.visitConstantInvokeDynamic(this); + } + + /** + * @return Reference (index) to bootstrap method this constant refers to. + * + * Note that this method is a functional duplicate of getClassIndex + * for use by ConstantInvokeDynamic. + * @since 6.0 + */ + public final int getBootstrapMethodAttrIndex() { + return super.getClassIndex(); // AKA bootstrap_method_attr_index + } + + /** + * @return String representation + */ + @Override + public final String toString() { + return super.toString().replace("class_index", "bootstrap_method_attr_index"); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java index 35102789a0d..d5b8d6d295c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java @@ -20,86 +20,107 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to a long object. * - * @author M. Dahm + * @version $Id: ConstantLong.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant */ public final class ConstantLong extends Constant implements ConstantObject { - private long bytes; - /** - * @param bytes Data - */ - public ConstantLong(long bytes) - { - super(Constants.CONSTANT_Long); - this.bytes = bytes; - } - /** - * Initialize from another object. - */ - public ConstantLong(ConstantLong c) { - this(c.getBytes()); - } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantLong(DataInputStream file) throws IOException - { - this(file.readLong()); - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantLong(this); - } - /** - * Dump constant long to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeLong(bytes); - } - /** - * @return data, i.e., 8 bytes. - */ - public final long getBytes() { return bytes; } - /** - * @param bytes. - */ - public final void setBytes(long bytes) { - this.bytes = bytes; - } - /** - * @return String representation. - */ - public final String toString() { - return super.toString() + "(bytes = " + bytes + ")"; - } + private long bytes; - /** @return Long object - */ - public Object getConstantValue(ConstantPool cp) { - return bytes; - } + + /** + * @param bytes Data + */ + public ConstantLong(final long bytes) { + super(Const.CONSTANT_Long); + this.bytes = bytes; + } + + + /** + * Initialize from another object. + */ + public ConstantLong(final ConstantLong c) { + this(c.getBytes()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantLong(final DataInput file) throws IOException { + this(file.readLong()); + } + + + /** + * 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( final Visitor v ) { + v.visitConstantLong(this); + } + + + /** + * Dump constant long to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeLong(bytes); + } + + + /** + * @return data, i.e., 8 bytes. + */ + public final long getBytes() { + return bytes; + } + + + /** + * @param bytes the raw bytes that represent this long + */ + public final void setBytes( final long bytes ) { + this.bytes = bytes; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } + + + /** @return Long object + */ + @Override + public Object getConstantValue( final ConstantPool cp ) { + return Long.valueOf(bytes); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java new file mode 100644 index 00000000000..666f8ff4f49 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java @@ -0,0 +1,124 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This class is derived from the abstract {@link Constant} + * and represents a reference to a method handle. + * + * @see Constant + * @since 6.0 + */ +public final class ConstantMethodHandle extends Constant { + + private int reference_kind; + private int reference_index; + + + /** + * Initialize from another object. + */ + public ConstantMethodHandle(final ConstantMethodHandle c) { + this(c.getReferenceKind(), c.getReferenceIndex()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantMethodHandle(final DataInput file) throws IOException { + this(file.readUnsignedByte(), file.readUnsignedShort()); + } + + + public ConstantMethodHandle(final int reference_kind, final int reference_index) { + super(Const.CONSTANT_MethodHandle); + this.reference_kind = reference_kind; + this.reference_index = reference_index; + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitly + * 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( final Visitor v ) { + v.visitConstantMethodHandle(this); + } + + + /** + * Dump method kind and index to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeByte(reference_kind); + file.writeShort(reference_index); + } + + + public int getReferenceKind() { + return reference_kind; + } + + + public void setReferenceKind(final int reference_kind) { + this.reference_kind = reference_kind; + } + + + public int getReferenceIndex() { + return reference_index; + } + + + public void setReferenceIndex(final int reference_index) { + this.reference_index = reference_index; + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return super.toString() + "(reference_kind = " + reference_kind + + ", reference_index = " + reference_index + ")"; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java new file mode 100644 index 00000000000..ede606a89fd --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java @@ -0,0 +1,110 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This class is derived from the abstract {@link Constant} + * and represents a reference to a method type. + * + * @see Constant + * @since 6.0 + */ +public final class ConstantMethodType extends Constant { + + private int descriptor_index; + + + /** + * Initialize from another object. + */ + public ConstantMethodType(final ConstantMethodType c) { + this(c.getDescriptorIndex()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantMethodType(final DataInput file) throws IOException { + this(file.readUnsignedShort()); + } + + + public ConstantMethodType(final int descriptor_index) { + super(Const.CONSTANT_MethodType); + this.descriptor_index = descriptor_index; + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitly + * 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( final Visitor v ) { + v.visitConstantMethodType(this); + } + + + /** + * Dump name and signature index to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeShort(descriptor_index); + } + + + public int getDescriptorIndex() { + return descriptor_index; + } + + + public void setDescriptorIndex(final int descriptor_index) { + this.descriptor_index = descriptor_index; + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return super.toString() + "(descriptor_index = " + descriptor_index + ")"; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java index f879d0ac875..d3825fc6721 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java @@ -21,51 +21,55 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents a constant pool reference to a method. * - * @author M. Dahm + * @version $Id: ConstantMethodref.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class ConstantMethodref extends ConstantCP { - /** - * Initialize from another object. - */ - public ConstantMethodref(ConstantMethodref c) { - super(Constants.CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex()); - } - /** - * Initialize instance from file data. - * - * @param file input stream - * @throws IOException - */ - ConstantMethodref(DataInputStream file) throws IOException - { - super(Constants.CONSTANT_Methodref, file); - } + /** + * Initialize from another object. + */ + public ConstantMethodref(final ConstantMethodref c) { + super(Const.CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex()); + } - /** - * @param class_index Reference to the class containing the method - * @param name_and_type_index and the method signature - */ - public ConstantMethodref(int class_index, - int name_and_type_index) { - super(Constants.CONSTANT_Methodref, class_index, name_and_type_index); - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantMethodref(this); - } + /** + * Initialize instance from input data. + * + * @param input input stream + * @throws IOException + */ + ConstantMethodref(final DataInput input) throws IOException { + super(Const.CONSTANT_Methodref, input); + } + + + /** + * @param class_index Reference to the class containing the method + * @param name_and_type_index and the method signature + */ + public ConstantMethodref(final int class_index, final int name_and_type_index) { + super(Const.CONSTANT_Methodref, class_index, name_and_type_index); + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitConstantMethodref(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java index 018adb8dfa5..9c793a6c45f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java @@ -21,118 +21,135 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to the name and signature * of a field or method. * - * @author M. Dahm + * @version $Id: ConstantNameAndType.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant */ public final class ConstantNameAndType extends Constant { - private int name_index; // Name of field/method - private int signature_index; // and its signature. - /** - * Initialize from another object. - */ - public ConstantNameAndType(ConstantNameAndType c) { - this(c.getNameIndex(), c.getSignatureIndex()); - } + 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((int)file.readUnsignedShort(), (int)file.readUnsignedShort()); - } - /** - * @param name_index Name of field/method - * @param signature_index and its signature - */ - public ConstantNameAndType(int name_index, - int signature_index) - { - super(Constants.CONSTANT_NameAndType); - this.name_index = name_index; - this.signature_index = signature_index; - } + /** + * Initialize from another object. + */ + public ConstantNameAndType(final ConstantNameAndType c) { + this(c.getNameIndex(), c.getSignatureIndex()); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantNameAndType(this); - } - /** - * Dump name and signature index to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeShort(name_index); - file.writeShort(signature_index); - } + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantNameAndType(final DataInput file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } - /** - * @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); - } + /** + * @param name_index Name of field/method + * @param signature_index and its signature + */ + public ConstantNameAndType(final int name_index, final int signature_index) { + super(Const.CONSTANT_NameAndType); + this.name_index = name_index; + this.signature_index = signature_index; + } - /** - * @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); - } + /** + * 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( final Visitor v ) { + v.visitConstantNameAndType(this); + } - /** - * @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; - } + /** + * Dump name and signature index to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeShort(name_index); + file.writeShort(signature_index); + } - /** - * @return String representation - */ - public final String toString() { - return super.toString() + "(name_index = " + name_index + - ", signature_index = " + signature_index + ")"; - } + + /** + * @return Name index in constant pool of field/method name. + */ + public final int getNameIndex() { + return name_index; + } + + + /** @return name + */ + public final String getName( final ConstantPool cp ) { + return cp.constantToString(getNameIndex(), Const.CONSTANT_Utf8); + } + + + /** + * @return Index in constant pool of field/method signature. + */ + public final int getSignatureIndex() { + return signature_index; + } + + + /** @return signature + */ + public final String getSignature( final ConstantPool cp ) { + return cp.constantToString(getSignatureIndex(), Const.CONSTANT_Utf8); + } + + + /** + * @param name_index the name index of this constant + */ + public final void setNameIndex( final int name_index ) { + this.name_index = name_index; + } + + + /** + * @param signature_index the signature index in the constant pool of this type + */ + public final void setSignatureIndex( final int signature_index ) { + this.signature_index = signature_index; + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return super.toString() + "(name_index = " + name_index + ", signature_index = " + + signature_index + ")"; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java index fbe7d4a6719..a66ca93a93f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java @@ -21,16 +21,16 @@ package com.sun.org.apache.bcel.internal.classfile; - /** * This interface denotes those constants that have a "natural" value, * such as ConstantLong, ConstantString, etc.. * - * @author M. Dahm + * @version $Id: ConstantObject.java 1747278 2016-06-07 17:28:43Z britter $ * @see Constant */ public interface ConstantObject { - /** @return object representing the constant, e.g., Long for ConstantLong - */ - public abstract Object getConstantValue(ConstantPool cp); + + /** @return object representing the constant, e.g., Long for ConstantLong + */ + Object getConstantValue( ConstantPool cp ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java index 8308d1adfdf..390f5cfb1e5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java @@ -21,9 +21,11 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents the constant pool, i.e., a table of constants, of @@ -33,307 +35,342 @@ import java.io.*; * programatically should see * ConstantPoolGen. + * @version $Id: ConstantPool.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Constant * @see com.sun.org.apache.bcel.internal.generic.ConstantPoolGen - * @author M. Dahm */ -public class ConstantPool implements Cloneable, Node, Serializable { - private int constant_pool_count; - private Constant[] constant_pool; +public class ConstantPool implements Cloneable, Node { - /** - * @param constant_pool Array of constants - */ - public ConstantPool(Constant[] constant_pool) - { - setConstantPool(constant_pool); - } + private Constant[] constant_pool; - /** - * Read constants from given file stream. - * - * @param file Input stream - * @throws IOException - * @throws ClassFormatException - */ - ConstantPool(DataInputStream file) throws IOException, ClassFormatException - { - byte tag; - constant_pool_count = file.readUnsignedShort(); - constant_pool = new Constant[constant_pool_count]; - - /* constant_pool[0] is unused by the compiler and may be used freely - * by the implementation. + /** + * @param constant_pool Array of constants */ - for(int i=1; i < constant_pool_count; i++) { - constant_pool[i] = Constant.readConstant(file); - - /* Quote from the JVM specification: - * "All eight byte constants take up two spots in the constant pool. - * If this is the n'th byte in the constant pool, then the next item - * will be numbered n+2" - * - * Thus we have to increment the index counter. - */ - tag = constant_pool[i].getTag(); - if((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) - i++; - } - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantPool(this); - } - - /** - * Resolve constant to a string representation. - * - * @param constant Constant to be printed - * @return String representation - */ - public String constantToString(Constant c) - throws ClassFormatException - { - String str; - int i; - byte tag = c.getTag(); - - switch(tag) { - case Constants.CONSTANT_Class: - i = ((ConstantClass)c).getNameIndex(); - c = getConstant(i, Constants.CONSTANT_Utf8); - str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false); - break; - - case Constants.CONSTANT_String: - i = ((ConstantString)c).getStringIndex(); - c = getConstant(i, Constants.CONSTANT_Utf8); - str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\""; - break; - - case Constants.CONSTANT_Utf8: str = ((ConstantUtf8)c).getBytes(); break; - case Constants.CONSTANT_Double: str = "" + ((ConstantDouble)c).getBytes(); break; - case Constants.CONSTANT_Float: str = "" + ((ConstantFloat)c).getBytes(); break; - case Constants.CONSTANT_Long: str = "" + ((ConstantLong)c).getBytes(); break; - case Constants.CONSTANT_Integer: str = "" + ((ConstantInteger)c).getBytes(); break; - - case Constants.CONSTANT_NameAndType: - str = (constantToString(((ConstantNameAndType)c).getNameIndex(), - Constants.CONSTANT_Utf8) + " " + - constantToString(((ConstantNameAndType)c).getSignatureIndex(), - Constants.CONSTANT_Utf8)); - break; - - case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: - case Constants.CONSTANT_Fieldref: - str = (constantToString(((ConstantCP)c).getClassIndex(), - Constants.CONSTANT_Class) + "." + - constantToString(((ConstantCP)c).getNameAndTypeIndex(), - Constants.CONSTANT_NameAndType)); - break; - - default: // Never reached - throw new RuntimeException("Unknown constant type " + tag); + public ConstantPool(final Constant[] constant_pool) { + this.constant_pool = constant_pool; } - 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(); - } - - - /** - * Retrieve constant at `index' from constant pool and resolve it to - * a string representation. - * - * @param index of constant in constant pool - * @param tag expected type - * @return String representation - */ - public String constantToString(int index, byte tag) - throws ClassFormatException - { - Constant c = getConstant(index, tag); - return constantToString(c); - } - - /** - * Dump constant pool to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public void dump(DataOutputStream file) throws IOException - { - file.writeShort(constant_pool_count); - - for(int i=1; i < constant_pool_count; i++) - if(constant_pool[i] != null) - constant_pool[i].dump(file); - } - - /** - * Get constant from constant pool. - * - * @param index Index in constant pool - * @return Constant value - * @see Constant - */ - public Constant getConstant(int index) { - if (index >= constant_pool.length || index < 0) - throw new ClassFormatException("Invalid constant pool reference: " + - index + ". Constant pool size is: " + - constant_pool.length); - return constant_pool[index]; - } - - /** - * Get constant from constant pool and check whether it has the - * expected type. - * - * @param index Index in constant pool - * @param tag Tag of expected constant, i.e., its type - * @return Constant value - * @see Constant - * @throws ClassFormatException - */ - public Constant getConstant(int index, byte tag) - throws ClassFormatException - { - Constant c; - - c = getConstant(index); - - if(c == null) - throw new ClassFormatException("Constant pool at index " + index + " is null."); - - if(c.getTag() == tag) - return c; - else - throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag] + - "' at index " + index + " and got " + c); - } - - /** - * @return Array of constants. - * @see Constant - */ - public Constant[] getConstantPool() { return constant_pool; } - /** - * Get string from constant pool and bypass the indirection of - * `ConstantClass' and `ConstantString' objects. I.e. these classes have - * an index field that points to another entry of the constant pool of - * type `ConstantUtf8' which contains the real data. - * - * @param index Index in constant pool - * @param tag Tag of expected constant, either ConstantClass or ConstantString - * @return Contents of string reference - * @see ConstantClass - * @see ConstantString - * @throws ClassFormatException - */ - public String getConstantString(int index, byte tag) - throws ClassFormatException - { - Constant c; - int i; - - c = getConstant(index, tag); - - /* This switch() is not that elegant, since the two classes have the - * same contents, they just differ in the name of the index - * field variable. - * But we want to stick to the JVM naming conventions closely though - * we could have solved these more elegantly by using the same - * variable name or by subclassing. + /** + * Read constants from given input stream. + * + * @param input Input stream + * @throws IOException + * @throws ClassFormatException */ - 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); + public ConstantPool(final DataInput input) throws IOException, ClassFormatException { + byte tag; + final int constant_pool_count = input.readUnsignedShort(); + constant_pool = new Constant[constant_pool_count]; + /* constant_pool[0] is unused by the compiler and may be used freely + * by the implementation. + */ + for (int i = 1; i < constant_pool_count; i++) { + constant_pool[i] = Constant.readConstant(input); + /* Quote from the JVM specification: + * "All eight byte constants take up two spots in the constant pool. + * If this is the n'th byte in the constant pool, then the next item + * will be numbered n+2" + * + * Thus we have to increment the index counter. + */ + tag = constant_pool[i].getTag(); + if ((tag == Const.CONSTANT_Double) || (tag == Const.CONSTANT_Long)) { + i++; + } + } } - // Finally get the string from the constant pool - c = getConstant(i, Constants.CONSTANT_Utf8); - return ((ConstantUtf8)c).getBytes(); - } - /** - * @return Length of constant pool. - */ - public int getLength() - { - return constant_pool_count; - } - /** - * @param constant Constant to set - */ - public void setConstant(int index, Constant constant) { - constant_pool[index] = constant; - } - - /** - * @param constant_pool - */ - public void setConstantPool(Constant[] constant_pool) { - this.constant_pool = constant_pool; - constant_pool_count = (constant_pool == null)? 0 : constant_pool.length; - } - /** - * @return String representation. - */ - public String toString() { - StringBuffer buf = new StringBuffer(); - - for(int i=1; i < constant_pool_count; i++) - buf.append(i + ")" + constant_pool[i] + "\n"); - - return buf.toString(); - } - - /** - * @return deep copy of this constant pool - */ - public ConstantPool copy() { - ConstantPool c = null; - - try { - c = (ConstantPool)clone(); - } catch(CloneNotSupportedException e) {} - - c.constant_pool = new Constant[constant_pool_count]; - - for(int i=1; i < constant_pool_count; i++) { - if(constant_pool[i] != null) - c.constant_pool[i] = constant_pool[i].copy(); + /** + * 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( final Visitor v ) { + v.visitConstantPool(this); } - return c; - } + + /** + * Resolve constant to a string representation. + * + * @param c Constant to be printed + * @return String representation + */ + public String constantToString( Constant c ) throws ClassFormatException { + String str; + int i; + final byte tag = c.getTag(); + switch (tag) { + case Const.CONSTANT_Class: + i = ((ConstantClass) c).getNameIndex(); + c = getConstant(i, Const.CONSTANT_Utf8); + str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); + break; + case Const.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = getConstant(i, Const.CONSTANT_Utf8); + str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\""; + break; + case Const.CONSTANT_Utf8: + str = ((ConstantUtf8) c).getBytes(); + break; + case Const.CONSTANT_Double: + str = String.valueOf(((ConstantDouble) c).getBytes()); + break; + case Const.CONSTANT_Float: + str = String.valueOf(((ConstantFloat) c).getBytes()); + break; + case Const.CONSTANT_Long: + str = String.valueOf(((ConstantLong) c).getBytes()); + break; + case Const.CONSTANT_Integer: + str = String.valueOf(((ConstantInteger) c).getBytes()); + break; + case Const.CONSTANT_NameAndType: + str = constantToString(((ConstantNameAndType) c).getNameIndex(), + Const.CONSTANT_Utf8) + + ":" + constantToString(((ConstantNameAndType) c).getSignatureIndex(), + Const.CONSTANT_Utf8); + break; + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + case Const.CONSTANT_Fieldref: + str = constantToString(((ConstantCP) c).getClassIndex(), Const.CONSTANT_Class) + + "." + constantToString(((ConstantCP) c).getNameAndTypeIndex(), + Const.CONSTANT_NameAndType); + break; + case Const.CONSTANT_MethodHandle: + // Note that the ReferenceIndex may point to a Fieldref, Methodref or + // InterfaceMethodref - so we need to peek ahead to get the actual type. + final ConstantMethodHandle cmh = (ConstantMethodHandle) c; + str = Const.getMethodHandleName(cmh.getReferenceKind()) + + " " + constantToString(cmh.getReferenceIndex(), + getConstant(cmh.getReferenceIndex()).getTag()); + break; + case Const.CONSTANT_MethodType: + final ConstantMethodType cmt = (ConstantMethodType) c; + str = constantToString(cmt.getDescriptorIndex(), Const.CONSTANT_Utf8); + break; + case Const.CONSTANT_InvokeDynamic: + final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) c; + str = cid.getBootstrapMethodAttrIndex() + + ":" + constantToString(cid.getNameAndTypeIndex(), + Const.CONSTANT_NameAndType); + break; + default: // Never reached + throw new RuntimeException("Unknown constant type " + tag); + } + return str; + } + + + private static String escape( final String str ) { + final int len = str.length(); + final StringBuilder buf = new StringBuilder(len + 5); + final 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(); + } + + + /** + * Retrieve constant at `index' from constant pool and resolve it to + * a string representation. + * + * @param index of constant in constant pool + * @param tag expected type + * @return String representation + */ + public String constantToString( final int index, final byte tag ) throws ClassFormatException { + final Constant c = getConstant(index, tag); + return constantToString(c); + } + + + /** + * Dump constant pool to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public void dump( final DataOutputStream file ) throws IOException { + file.writeShort(constant_pool.length); + for (int i = 1; i < constant_pool.length; i++) { + if (constant_pool[i] != null) { + constant_pool[i].dump(file); + } + } + } + + + /** + * Get constant from constant pool. + * + * @param index Index in constant pool + * @return Constant value + * @see Constant + */ + public Constant getConstant( final int index ) { + if (index >= constant_pool.length || index < 0) { + throw new ClassFormatException("Invalid constant pool reference: " + index + + ". Constant pool size is: " + constant_pool.length); + } + return constant_pool[index]; + } + + + /** + * Get constant from constant pool and check whether it has the + * expected type. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, i.e., its type + * @return Constant value + * @see Constant + * @throws ClassFormatException + */ + public Constant getConstant( final int index, final byte tag ) throws ClassFormatException { + Constant c; + c = getConstant(index); + if (c == null) { + throw new ClassFormatException("Constant pool at index " + index + " is null."); + } + if (c.getTag() != tag) { + throw new ClassFormatException("Expected class `" + Const.getConstantName(tag) + + "' at index " + index + " and got " + c); + } + return c; + } + + + /** + * @return Array of constants. + * @see Constant + */ + public Constant[] getConstantPool() { + return constant_pool; + } + + + /** + * Get string from constant pool and bypass the indirection of + * `ConstantClass' and `ConstantString' objects. I.e. these classes have + * an index field that points to another entry of the constant pool of + * type `ConstantUtf8' which contains the real data. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, either ConstantClass or ConstantString + * @return Contents of string reference + * @see ConstantClass + * @see ConstantString + * @throws ClassFormatException + */ + public String getConstantString( final int index, final byte tag ) throws ClassFormatException { + Constant c; + int i; + c = getConstant(index, tag); + /* This switch() is not that elegant, since the two classes have the + * same contents, they just differ in the name of the index + * field variable. + * But we want to stick to the JVM naming conventions closely though + * we could have solved these more elegantly by using the same + * variable name or by subclassing. + */ + switch (tag) { + case Const.CONSTANT_Class: + i = ((ConstantClass) c).getNameIndex(); + break; + case Const.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, Const.CONSTANT_Utf8); + return ((ConstantUtf8) c).getBytes(); + } + + + /** + * @return Length of constant pool. + */ + public int getLength() { + return constant_pool == null ? 0 : constant_pool.length; + } + + + /** + * @param constant Constant to set + */ + public void setConstant( final int index, final Constant constant ) { + constant_pool[index] = constant; + } + + + /** + * @param constant_pool + */ + public void setConstantPool( final Constant[] constant_pool ) { + this.constant_pool = constant_pool; + } + + + /** + * @return String representation. + */ + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + for (int i = 1; i < constant_pool.length; i++) { + buf.append(i).append(")").append(constant_pool[i]).append("\n"); + } + return buf.toString(); + } + + + /** + * @return deep copy of this constant pool + */ + public ConstantPool copy() { + ConstantPool c = null; + try { + c = (ConstantPool) clone(); + c.constant_pool = new Constant[constant_pool.length]; + for (int i = 1; i < constant_pool.length; i++) { + if (constant_pool[i] != null) { + c.constant_pool[i] = constant_pool[i].copy(); + } + } + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java index 30744dc695f..a3386b9977c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java @@ -21,94 +21,115 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to a String object. * - * @author M. Dahm + * @version $Id: ConstantString.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Constant */ public final class ConstantString extends Constant implements ConstantObject { - private int string_index; // Identical to ConstantClass except for this name - /** - * Initialize from another object. - */ - public ConstantString(ConstantString c) { - this(c.getStringIndex()); - } - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantString(DataInputStream file) throws IOException - { - this((int)file.readUnsignedShort()); - } - /** - * @param string_index Index of Constant_Utf8 in constant pool - */ - public ConstantString(int string_index) - { - super(Constants.CONSTANT_String); - this.string_index = string_index; - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantString(this); - } - /** - * Dump constant field reference to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeShort(string_index); - } - /** - * @return Index in constant pool of the string (ConstantUtf8). - */ - public final int getStringIndex() { return string_index; } - /** - * @param string_index. - */ - public final void setStringIndex(int string_index) { - this.string_index = string_index; - } - /** - * @return String representation. - */ - public final String toString() - { - return super.toString() + "(string_index = " + string_index + ")"; - } + private int string_index; // Identical to ConstantClass except for this name - /** @return String object - */ - public Object getConstantValue(ConstantPool cp) { - Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8); - return ((ConstantUtf8)c).getBytes(); - } - /** @return dereferenced string - */ - public String getBytes(ConstantPool cp) { - return (String)getConstantValue(cp); - } + /** + * Initialize from another object. + */ + public ConstantString(final ConstantString c) { + this(c.getStringIndex()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantString(final DataInput file) throws IOException { + this(file.readUnsignedShort()); + } + + + /** + * @param string_index Index of Constant_Utf8 in constant pool + */ + public ConstantString(final int string_index) { + super(Const.CONSTANT_String); + this.string_index = string_index; + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitConstantString(this); + } + + + /** + * Dump constant field reference to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeShort(string_index); + } + + + /** + * @return Index in constant pool of the string (ConstantUtf8). + */ + public final int getStringIndex() { + return string_index; + } + + + /** + * @param string_index the index into the constant of the string value + */ + public final void setStringIndex( final int string_index ) { + this.string_index = string_index; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + return super.toString() + "(string_index = " + string_index + ")"; + } + + + /** @return String object + */ + @Override + public Object getConstantValue( final ConstantPool cp ) { + final Constant c = cp.getConstant(string_index, Const.CONSTANT_Utf8); + return ((ConstantUtf8) c).getBytes(); + } + + + /** @return dereferenced string + */ + public String getBytes( final ConstantPool cp ) { + return (String) getConstantValue(cp); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java index 59df746065f..e101551eb2a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,94 +20,193 @@ package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; /** - * This class is derived from the abstract - * Constant class + * This class is derived from the abstract {@link Constant} * and represents a reference to a Utf8 encoded string. * - * @author M. Dahm + * @version $Id: ConstantUtf8.java 1750029 2016-06-23 22:14:38Z sebb $ * @see Constant */ public final class ConstantUtf8 extends Constant { - private String bytes; - /** - * Initialize from another object. - */ - public ConstantUtf8(ConstantUtf8 c) { - this(c.getBytes()); - } + private final String bytes; - /** - * Initialize instance from file data. - * - * @param file Input stream - * @throws IOException - */ - ConstantUtf8(DataInputStream file) throws IOException - { - super(Constants.CONSTANT_Utf8); + // TODO these should perhaps be AtomicInt? + private static volatile int considered = 0; + private static volatile int hits = 0; + private static volatile int skipped = 0; + private static volatile int created = 0; - bytes = file.readUTF(); - } + // Set the size to 0 or below to skip caching entirely + private static final int MAX_CACHED_SIZE = 200; + private static final boolean BCEL_STATISTICS = false; - /** - * @param bytes Data - */ - public ConstantUtf8(String bytes) - { - super(Constants.CONSTANT_Utf8); - if(bytes == null) - throw new IllegalArgumentException("bytes must not be null!"); + private static class CACHE_HOLDER { - this.bytes = bytes; - } + private static final int MAX_CACHE_ENTRIES = 20000; + private static final int INITIAL_CACHE_CAPACITY = (int)(MAX_CACHE_ENTRIES/0.75); - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantUtf8(this); - } + private static final HashMap CACHE = + new LinkedHashMap(INITIAL_CACHE_CAPACITY, 0.75f, true) { + private static final long serialVersionUID = -8506975356158971766L; - /** - * Dump String in Utf8 format to file stream. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeByte(tag); - file.writeUTF(bytes); - } + @Override + protected boolean removeEldestEntry(final Map.Entry eldest) { + return size() > MAX_CACHE_ENTRIES; + } + }; - /** - * @return Data converted to string. - */ - public final String getBytes() { return bytes; } + } - /** - * @param bytes. - */ - public final void setBytes(String bytes) { - this.bytes = bytes; - } + // for accesss by test code + static void printStats() { + System.err.println("Cache hit " + hits + "/" + considered +", " + skipped + " skipped"); + System.err.println("Total of " + created + " ConstantUtf8 objects created"); + } - /** - * @return String representation - */ - public final String toString() - { - return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")"; - } + // for accesss by test code + static void clearStats() { + hits = considered = skipped = created = 0; + } + + static { + if (BCEL_STATISTICS) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + printStats(); + } + }); + } + } + + /** + * @since 6.0 + */ + public static ConstantUtf8 getCachedInstance(final String s) { + if (s.length() > MAX_CACHED_SIZE) { + skipped++; + return new ConstantUtf8(s); + } + considered++; + synchronized (ConstantUtf8.class) { // might be better with a specific lock object + ConstantUtf8 result = CACHE_HOLDER.CACHE.get(s); + if (result != null) { + hits++; + return result; + } + result = new ConstantUtf8(s); + CACHE_HOLDER.CACHE.put(s, result); + return result; + } + } + + /** + * @since 6.0 + */ + public static ConstantUtf8 getInstance(final String s) { + return new ConstantUtf8(s); + } + + /** + * @since 6.0 + */ + public static ConstantUtf8 getInstance (final DataInput input) throws IOException { + return getInstance(input.readUTF()); + } + + /** + * Initialize from another object. + */ + public ConstantUtf8(final ConstantUtf8 c) { + this(c.getBytes()); + } + + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantUtf8(final DataInput file) throws IOException { + super(Const.CONSTANT_Utf8); + bytes = file.readUTF(); + created++; + } + + + /** + * @param bytes Data + */ + public ConstantUtf8(final String bytes) { + super(Const.CONSTANT_Utf8); + if (bytes == null) { + throw new IllegalArgumentException("bytes must not be null!"); + } + this.bytes = bytes; + created++; + } + + + /** + * 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( final Visitor v ) { + v.visitConstantUtf8(this); + } + + + /** + * Dump String in Utf8 format to file stream. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + file.writeByte(super.getTag()); + file.writeUTF(bytes); + } + + + /** + * @return Data converted to string. + */ + public final String getBytes() { + return bytes; + } + + + /** + * @param bytes the raw bytes of this Utf-8 + * @deprecated (since 6.0) + */ + @java.lang.Deprecated + public final void setBytes( final String bytes ) { + throw new UnsupportedOperationException(); + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")"; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java index a3b754ec498..f08bfa73d7b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java @@ -21,125 +21,144 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class is derived from Attribute and represents a constant * value, i.e., a default value for initializing a class field. * This class is instantiated by the Attribute.readAttribute() method. * - * @author M. Dahm + * @version $Id: ConstantValue.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Attribute */ public final class ConstantValue extends Attribute { - private int constantvalue_index; - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public ConstantValue(ConstantValue c) { - this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), - c.getConstantPool()); - } + private int constantvalue_index; - /** - * Construct object from file stream. - * @param name_index Name index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throw IOException - */ - ConstantValue(int name_index, int length, DataInputStream file, - ConstantPool constant_pool) throws IOException - { - this(name_index, length, (int)file.readUnsignedShort(), constant_pool); - } - /** - * @param name_index Name index in constant pool - * @param length Content length in bytes - * @param constantvalue_index Index in constant pool - * @param constant_pool Array of constants - */ - public ConstantValue(int name_index, int length, - int constantvalue_index, - ConstantPool constant_pool) - { - super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); - this.constantvalue_index = constantvalue_index; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitConstantValue(this); - } - /** - * Dump constant value attribute to file stream on binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - file.writeShort(constantvalue_index); - } - /** - * @return Index in constant pool of constant value. - */ - public final int getConstantValueIndex() { return constantvalue_index; } - - /** - * @param constantvalue_index. - */ - public final void setConstantValueIndex(int constantvalue_index) { - this.constantvalue_index = constantvalue_index; - } - - /** - * @return String representation of constant value. - */ - public final String toString() { - Constant c = constant_pool.getConstant(constantvalue_index); - - String buf; - int i; - - // Print constant to string depending on its type - switch(c.getTag()) { - case Constants.CONSTANT_Long: buf = "" + ((ConstantLong)c).getBytes(); break; - case Constants.CONSTANT_Float: buf = "" + ((ConstantFloat)c).getBytes(); break; - case Constants.CONSTANT_Double: buf = "" + ((ConstantDouble)c).getBytes(); break; - case Constants.CONSTANT_Integer: buf = "" + ((ConstantInteger)c).getBytes(); break; - case Constants.CONSTANT_String: - i = ((ConstantString)c).getStringIndex(); - c = constant_pool.getConstant(i, Constants.CONSTANT_Utf8); - buf = "\"" + Utility.convertString(((ConstantUtf8)c).getBytes()) + "\""; - break; - - default: - throw new IllegalStateException("Type of ConstValue invalid: " + c); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public ConstantValue(final ConstantValue c) { + this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool()); } - return buf; - } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - ConstantValue c = (ConstantValue)clone(); - c.constant_pool = constant_pool; - return c; - } + /** + * Construct object from input stream. + * @param name_index Name index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + ConstantValue(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, input.readUnsignedShort(), constant_pool); + } + + + /** + * @param name_index Name index in constant pool + * @param length Content length in bytes + * @param constantvalue_index Index in constant pool + * @param constant_pool Array of constants + */ + public ConstantValue(final int name_index, final int length, final int constantvalue_index, + final ConstantPool constant_pool) { + super(Const.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); + this.constantvalue_index = constantvalue_index; + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitConstantValue(this); + } + + + /** + * Dump constant value attribute to file stream on binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(constantvalue_index); + } + + + /** + * @return Index in constant pool of constant value. + */ + public final int getConstantValueIndex() { + return constantvalue_index; + } + + + /** + * @param constantvalue_index the index info the constant pool of this constant value + */ + public final void setConstantValueIndex( final int constantvalue_index ) { + this.constantvalue_index = constantvalue_index; + } + + + /** + * @return String representation of constant value. + */ + @Override + public final String toString() { + Constant c = super.getConstantPool().getConstant(constantvalue_index); + String buf; + int i; + // Print constant to string depending on its type + switch (c.getTag()) { + case Const.CONSTANT_Long: + buf = String.valueOf(((ConstantLong) c).getBytes()); + break; + case Const.CONSTANT_Float: + buf = String.valueOf(((ConstantFloat) c).getBytes()); + break; + case Const.CONSTANT_Double: + buf = String.valueOf(((ConstantDouble) c).getBytes()); + break; + case Const.CONSTANT_Integer: + buf = String.valueOf(((ConstantInteger) c).getBytes()); + break; + case Const.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = super.getConstantPool().getConstant(i, Const.CONSTANT_Utf8); + buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\""; + break; + default: + throw new IllegalStateException("Type of ConstValue invalid: " + c); + } + return buf; + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + final ConstantValue c = (ConstantValue) clone(); + c.setConstantPool(_constant_pool); + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java index a48fd812345..bcae9fac5d6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java @@ -18,119 +18,123 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class is derived from Attribute and denotes that this is a - * deprecated method. - * It is instantiated from the Attribute.readAttribute() method. + * deprecated method. It is instantiated from the + * Attribute.readAttribute() method. * - * @author M. Dahm - * @see Attribute + * @version $Id: Deprecated.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @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()); - } + private byte[] bytes; - /** - * @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"); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Deprecated(final Deprecated c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); } - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitDeprecated(this); - } + /** + * @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(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { + super(Const.ATTR_DEPRECATED, name_index, length, constant_pool); + this.bytes = bytes; + } - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); + /** + * Construct object from input stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Deprecated(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + if (length > 0) { + bytes = new byte[length]; + input.readFully(bytes); + System.err.println("Deprecated attribute with length > 0"); + } + } - if(length > 0) - file.write(bytes, 0, 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(final Visitor v) { + v.visitDeprecated(this); + } - /** - * @return data bytes. - */ - public final byte[] getBytes() { return bytes; } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump(final DataOutputStream file) throws IOException { + super.dump(file); + if (super.getLength() > 0) { + file.write(bytes, 0, super.getLength()); + } + } - /** - * @param bytes. - */ - public final void setBytes(byte[] bytes) { - this.bytes = bytes; - } + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } - /** - * @return attribute name - */ - public final String toString() { - return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED]; - } + /** + * @param bytes the raw bytes that represents this byte array + */ + public final void setBytes(final byte[] bytes) { + this.bytes = bytes; + } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - Deprecated c = (Deprecated)clone(); + /** + * @return attribute name + */ + @Override + public final String toString() { + return Const.getAttributeName(Const.ATTR_DEPRECATED); + } - if(bytes != null) - c.bytes = (byte[])bytes.clone(); - - c.constant_pool = constant_pool; - return c; - } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool _constant_pool) { + final Deprecated c = (Deprecated) clone(); + if (bytes != null) { + c.bytes = new byte[bytes.length]; + System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); + } + c.setConstantPool(_constant_pool); + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java index a21586c8c9e..9ec50f6d99b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,317 +17,475 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; import java.util.Stack; /** - * Traverses a JavaClass with another Visitor object 'piggy-backed' - * that is applied to all components of a JavaClass object. I.e. this - * class supplies the traversal strategy, other classes can make use - * of it. + * Traverses a JavaClass with another Visitor object 'piggy-backed' that is + * applied to all components of a JavaClass object. I.e. this class supplies the + * traversal strategy, other classes can make use of it. * - * @author M. Dahm + * @version $Id: DescendingVisitor.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class DescendingVisitor implements Visitor { - private JavaClass clazz; - private Visitor visitor; - private Stack stack = new Stack(); - /** @return container of current entitity, i.e., predecessor during traversal - */ - public Object predecessor() { - return predecessor(0); - } + private final JavaClass clazz; - /** - * @param level nesting level, i.e., 0 returns the direct predecessor - * @return container of current entitity, i.e., predecessor during traversal - */ - public Object predecessor(int level) { - int size = stack.size(); + private final Visitor visitor; - if((size < 2) || (level < 0)) - return null; - else - return stack.elementAt(size - (level + 2)); // size - 1 == current - } + private final Stack stack = new Stack<>(); - /** @return current object - */ - public Object current() { - return stack.peek(); - } - - /** - * @param clazz Class to traverse - * @param visitor visitor object to apply to all components - */ - public DescendingVisitor(JavaClass clazz, Visitor visitor) { - this.clazz = clazz; - this.visitor = visitor; - } - - /** - * Start traversal. - */ - public void visit() { clazz.accept(this); } - - public void visitJavaClass(JavaClass clazz) { - stack.push(clazz); - clazz.accept(visitor); - - Field[] fields = clazz.getFields(); - for(int i=0; i < fields.length; i++) - fields[i].accept(this); - - Method[] methods = clazz.getMethods(); - for(int i=0; i < methods.length; i++) - methods[i].accept(this); - - Attribute[] attributes = clazz.getAttributes(); - for(int i=0; i < attributes.length; i++) - attributes[i].accept(this); - - clazz.getConstantPool().accept(this); - stack.pop(); - } - - public void visitField(Field field) { - stack.push(field); - field.accept(visitor); - - Attribute[] attributes = field.getAttributes(); - for(int i=0; i < attributes.length; i++) - attributes[i].accept(this); - stack.pop(); - } - - public void visitConstantValue(ConstantValue cv) { - stack.push(cv); - cv.accept(visitor); - stack.pop(); - } - - public void visitMethod(Method method) { - stack.push(method); - method.accept(visitor); - - Attribute[] attributes = method.getAttributes(); - for(int i=0; i < attributes.length; i++) - attributes[i].accept(this); - - stack.pop(); - } - - public void visitExceptionTable(ExceptionTable table) { - stack.push(table); - table.accept(visitor); - stack.pop(); - } - - public void visitCode(Code code) { - stack.push(code); - code.accept(visitor); - - CodeException[] table = code.getExceptionTable(); - for(int i=0; i < table.length; i++) - table[i].accept(this); - - Attribute[] attributes = code.getAttributes(); - for(int i=0; i < attributes.length; i++) - attributes[i].accept(this); - stack.pop(); - } - - public void visitCodeException(CodeException ce) { - stack.push(ce); - ce.accept(visitor); - stack.pop(); - } - - public void visitLineNumberTable(LineNumberTable table) { - stack.push(table); - table.accept(visitor); - - LineNumber[] numbers = table.getLineNumberTable(); - for(int i=0; i < numbers.length; i++) - numbers[i].accept(this); - stack.pop(); - } - - public void visitLineNumber(LineNumber number) { - stack.push(number); - number.accept(visitor); - stack.pop(); - } - - public void visitLocalVariableTable(LocalVariableTable table) { - stack.push(table); - table.accept(visitor); - - LocalVariable[] vars = table.getLocalVariableTable(); - for(int i=0; i < vars.length; i++) - vars[i].accept(this); - stack.pop(); - } - - public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) { - stack.push(obj); - obj.accept(visitor); - - LocalVariable[] vars = obj.getLocalVariableTypeTable(); - for(int i=0; i < vars.length; i++) - vars[i].accept(this); - stack.pop(); - } - - public void visitStackMap(StackMap table) { - stack.push(table); - table.accept(visitor); - - StackMapEntry[] vars = table.getStackMap(); - - for(int i=0; i < vars.length; i++) - vars[i].accept(this); - stack.pop(); - } - - public void visitStackMapEntry(StackMapEntry var) { - stack.push(var); - var.accept(visitor); - stack.pop(); - } - - public void visitLocalVariable(LocalVariable var) { - stack.push(var); - var.accept(visitor); - stack.pop(); - } - - public void visitConstantPool(ConstantPool cp) { - stack.push(cp); - cp.accept(visitor); - - Constant[] constants = cp.getConstantPool(); - for(int i=1; i < constants.length; i++) { - if(constants[i] != null) - constants[i].accept(this); + /** + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor() { + return predecessor(0); } - stack.pop(); - } + /** + * @param level nesting level, i.e., 0 returns the direct predecessor + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor(final int level) { + final int size = stack.size(); + if ((size < 2) || (level < 0)) { + return null; + } + return stack.elementAt(size - (level + 2)); // size - 1 == current + } - public void visitConstantClass(ConstantClass constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + /** + * @return current object + */ + public Object current() { + return stack.peek(); + } - public void visitConstantDouble(ConstantDouble constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + /** + * @param clazz Class to traverse + * @param visitor visitor object to apply to all components + */ + public DescendingVisitor(final JavaClass clazz, final Visitor visitor) { + this.clazz = clazz; + this.visitor = visitor; + } - public void visitConstantFieldref(ConstantFieldref constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + /** + * Start traversal. + */ + public void visit() { + clazz.accept(this); + } - public void visitConstantFloat(ConstantFloat constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + @Override + public void visitJavaClass(final JavaClass _clazz) { + stack.push(_clazz); + _clazz.accept(visitor); + final Field[] fields = _clazz.getFields(); + for (final Field field : fields) { + field.accept(this); + } + final Method[] methods = _clazz.getMethods(); + for (final Method method : methods) { + method.accept(this); + } + final Attribute[] attributes = _clazz.getAttributes(); + for (final Attribute attribute : attributes) { + attribute.accept(this); + } + _clazz.getConstantPool().accept(this); + stack.pop(); + } - public void visitConstantInteger(ConstantInteger constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + /** + * @since 6.0 + */ + @Override + public void visitAnnotation(final Annotations annotation) { + stack.push(annotation); + annotation.accept(visitor); + final AnnotationEntry[] entries = annotation.getAnnotationEntries(); + for (final AnnotationEntry entrie : entries) { + entrie.accept(this); + } + stack.pop(); + } - public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + /** + * @since 6.0 + */ + @Override + public void visitAnnotationEntry(final AnnotationEntry annotationEntry) { + stack.push(annotationEntry); + annotationEntry.accept(visitor); + stack.pop(); + } - public void visitConstantLong(ConstantLong constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + @Override + public void visitField(final Field field) { + stack.push(field); + field.accept(visitor); + final Attribute[] attributes = field.getAttributes(); + for (final Attribute attribute : attributes) { + attribute.accept(this); + } + stack.pop(); + } - public void visitConstantMethodref(ConstantMethodref constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + @Override + public void visitConstantValue(final ConstantValue cv) { + stack.push(cv); + cv.accept(visitor); + stack.pop(); + } - public void visitConstantNameAndType(ConstantNameAndType constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + @Override + public void visitMethod(final Method method) { + stack.push(method); + method.accept(visitor); + final Attribute[] attributes = method.getAttributes(); + for (final Attribute attribute : attributes) { + attribute.accept(this); + } + stack.pop(); + } - public void visitConstantString(ConstantString constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + @Override + public void visitExceptionTable(final ExceptionTable table) { + stack.push(table); + table.accept(visitor); + stack.pop(); + } - public void visitConstantUtf8(ConstantUtf8 constant) { - stack.push(constant); - constant.accept(visitor); - stack.pop(); - } + @Override + public void visitCode(final Code code) { + stack.push(code); + code.accept(visitor); + final CodeException[] table = code.getExceptionTable(); + for (final CodeException element : table) { + element.accept(this); + } + final Attribute[] attributes = code.getAttributes(); + for (final Attribute attribute : attributes) { + attribute.accept(this); + } + stack.pop(); + } - public void visitInnerClasses(InnerClasses ic) { - stack.push(ic); - ic.accept(visitor); + @Override + public void visitCodeException(final CodeException ce) { + stack.push(ce); + ce.accept(visitor); + stack.pop(); + } - InnerClass[] ics = ic.getInnerClasses(); - for(int i=0; i < ics.length; i++) - ics[i].accept(this); - stack.pop(); - } + @Override + public void visitLineNumberTable(final LineNumberTable table) { + stack.push(table); + table.accept(visitor); + final LineNumber[] numbers = table.getLineNumberTable(); + for (final LineNumber number : numbers) { + number.accept(this); + } + stack.pop(); + } - public void visitInnerClass(InnerClass inner) { - stack.push(inner); - inner.accept(visitor); - stack.pop(); - } + @Override + public void visitLineNumber(final LineNumber number) { + stack.push(number); + number.accept(visitor); + stack.pop(); + } - public void visitDeprecated(Deprecated attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } + @Override + public void visitLocalVariableTable(final LocalVariableTable table) { + stack.push(table); + table.accept(visitor); + final LocalVariable[] vars = table.getLocalVariableTable(); + for (final LocalVariable var : vars) { + var.accept(this); + } + stack.pop(); + } - public void visitSignature(Signature attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } + @Override + public void visitStackMap(final StackMap table) { + stack.push(table); + table.accept(visitor); + final StackMapEntry[] vars = table.getStackMap(); + for (final StackMapEntry var : vars) { + var.accept(this); + } + stack.pop(); + } - public void visitSourceFile(SourceFile attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } + @Override + public void visitStackMapEntry(final StackMapEntry var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } - public void visitSynthetic(Synthetic attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } + @Override + public void visitLocalVariable(final LocalVariable var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantPool(final ConstantPool cp) { + stack.push(cp); + cp.accept(visitor); + final Constant[] constants = cp.getConstantPool(); + for (int i = 1; i < constants.length; i++) { + if (constants[i] != null) { + constants[i].accept(this); + } + } + stack.pop(); + } + + @Override + public void visitConstantClass(final ConstantClass constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantDouble(final ConstantDouble constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantFieldref(final ConstantFieldref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantFloat(final ConstantFloat constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantInteger(final ConstantInteger constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantInterfaceMethodref( + final ConstantInterfaceMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitConstantInvokeDynamic( + final ConstantInvokeDynamic constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantLong(final ConstantLong constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantMethodref(final ConstantMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantNameAndType(final ConstantNameAndType constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantString(final ConstantString constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitConstantUtf8(final ConstantUtf8 constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + @Override + public void visitInnerClasses(final InnerClasses ic) { + stack.push(ic); + ic.accept(visitor); + final InnerClass[] ics = ic.getInnerClasses(); + for (final InnerClass ic2 : ics) { + ic2.accept(this); + } + stack.pop(); + } + + @Override + public void visitInnerClass(final InnerClass inner) { + stack.push(inner); + inner.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitBootstrapMethods(final BootstrapMethods bm) { + stack.push(bm); + bm.accept(visitor); + // BootstrapMethod[] bms = bm.getBootstrapMethods(); + // for (int i = 0; i < bms.length; i++) + // { + // bms[i].accept(this); + // } + stack.pop(); + } + + @Override + public void visitDeprecated(final Deprecated attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitSignature(final Signature attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitSourceFile(final SourceFile attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitSynthetic(final Synthetic attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + @Override + public void visitUnknown(final Unknown attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitAnnotationDefault(final AnnotationDefault obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitEnclosingMethod(final EnclosingMethod obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) { + stack.push(obj); + obj.accept(visitor); + LocalVariable[] vars = obj.getLocalVariableTypeTable(); + for (LocalVariable var : vars) { + var.accept(this); + } + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitParameterAnnotation(final ParameterAnnotations obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitMethodParameters(final MethodParameters obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitConstantMethodType(final ConstantMethodType obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitConstantMethodHandle(final ConstantMethodHandle obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } + + /** + * @since 6.0 + */ + @Override + public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } - public void visitUnknown(Unknown attribute) { - stack.push(attribute); - attribute.accept(visitor); - stack.pop(); - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java new file mode 100644 index 00000000000..b111bc46b81 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java @@ -0,0 +1,127 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * @version $Id: ElementValue + * @since 6.0 + */ +public abstract class ElementValue +{ + private final int type; + + private final ConstantPool cpool; + + @Override + public String toString() + { + return stringifyValue(); + } + + protected ElementValue(final int type, final 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 final byte STRING = 's'; + public static final byte ENUM_CONSTANT = 'e'; + public static final byte CLASS = 'c'; + public static final byte ANNOTATION = '@'; + public static final byte ARRAY = '['; + public static final byte PRIMITIVE_INT = 'I'; + public static final byte PRIMITIVE_BYTE = 'B'; + public static final byte PRIMITIVE_CHAR = 'C'; + public static final byte PRIMITIVE_DOUBLE = 'D'; + public static final byte PRIMITIVE_FLOAT = 'F'; + public static final byte PRIMITIVE_LONG = 'J'; + public static final byte PRIMITIVE_SHORT = 'S'; + public static final byte PRIMITIVE_BOOLEAN = 'Z'; + + public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool) throws IOException + { + final byte type = input.readByte(); + switch (type) + { + case PRIMITIVE_BYTE: + case PRIMITIVE_CHAR: + case PRIMITIVE_DOUBLE: + case PRIMITIVE_FLOAT: + case PRIMITIVE_INT: + case PRIMITIVE_LONG: + case PRIMITIVE_SHORT: + case PRIMITIVE_BOOLEAN: + case STRING: + return new SimpleElementValue(type, input.readUnsignedShort(), cpool); + + case ENUM_CONSTANT: + return new EnumElementValue(ENUM_CONSTANT, input.readUnsignedShort(), input.readUnsignedShort(), cpool); + + case CLASS: + return new ClassElementValue(CLASS, input.readUnsignedShort(), cpool); + + case ANNOTATION: + // TODO isRuntimeVisible + return new AnnotationElementValue(ANNOTATION, AnnotationEntry.read(input, cpool, false), cpool); + + case ARRAY: + final int numArrayVals = input.readUnsignedShort(); + final ElementValue[] evalues = new ElementValue[numArrayVals]; + for (int j = 0; j < numArrayVals; j++) + { + evalues[j] = ElementValue.readElementValue(input, cpool); + } + return new ArrayElementValue(ARRAY, evalues, cpool); + + default: + throw new RuntimeException("Unexpected element value kind in annotation: " + type); + } + } + + /** @since 6.0 */ + final ConstantPool getConstantPool() { + return cpool; + } + + /** @since 6.0 */ + final int getType() { + return type; + } + + public String toShortString() + { + return stringifyValue(); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValuePair.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValuePair.java new file mode 100644 index 00000000000..6744d1f098b --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValuePair.java @@ -0,0 +1,80 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * an annotation's element value pair + * + * @version $Id: ElementValuePair + * @since 6.0 + */ +public class ElementValuePair +{ + private final ElementValue elementValue; + + private final ConstantPool constantPool; + + private final int elementNameIndex; + + public ElementValuePair(final int elementNameIndex, final ElementValue elementValue, + final ConstantPool constantPool) + { + this.elementValue = elementValue; + this.elementNameIndex = elementNameIndex; + this.constantPool = constantPool; + } + + public String getNameString() + { + final ConstantUtf8 c = (ConstantUtf8) constantPool.getConstant( + elementNameIndex, Const.CONSTANT_Utf8); + return c.getBytes(); + } + + public final ElementValue getValue() + { + return elementValue; + } + + public int getNameIndex() + { + return elementNameIndex; + } + + public String toShortString() + { + final StringBuilder result = new StringBuilder(); + result.append(getNameString()).append("=").append( + getValue().toShortString()); + return result.toString(); + } + + protected void dump(final DataOutputStream dos) throws IOException { + dos.writeShort(elementNameIndex); // u2 name of the element + elementValue.dump(dos); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java index 11b5b22a30b..f2b34e8b390 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java @@ -21,53 +21,283 @@ package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.classfile.*; -import com.sun.org.apache.bcel.internal.*; - /** - * Visitor with empty method bodies, can be extended and used in conjunction with the - * DescendingVisitor class, e.g. - * - * By courtesy of David Spencer. + * Visitor with empty method bodies, can be extended and used in conjunction + * with the DescendingVisitor class, e.g. By courtesy of David Spencer. * * @see DescendingVisitor - * + * @version $Id: EmptyVisitor.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class EmptyVisitor implements Visitor { - protected EmptyVisitor() { } +public class EmptyVisitor implements Visitor +{ + protected EmptyVisitor() + { + } - 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 visitConstantNameAndType(ConstantNameAndType obj) {} - public void visitConstantPool(ConstantPool obj) {} - public void visitConstantString(ConstantString 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 visitLocalVariableTypeTable(LocalVariableTypeTable obj) {} - public void visitMethod(Method obj) {} - public void visitSignature(Signature obj) {} - public void visitSourceFile(SourceFile obj) {} - public void visitSynthetic(Synthetic obj) {} - public void visitUnknown(Unknown obj) {} - public void visitStackMap(StackMap obj) {} - public void visitStackMapEntry(StackMapEntry obj) {} + /** + * @since 6.0 + */ + @Override + public void visitAnnotation(final Annotations obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitParameterAnnotation(final ParameterAnnotations obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitAnnotationEntry(final AnnotationEntry obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitAnnotationDefault(final AnnotationDefault obj) + { + } + + @Override + public void visitCode(final Code obj) + { + } + + @Override + public void visitCodeException(final CodeException obj) + { + } + + @Override + public void visitConstantClass(final ConstantClass obj) + { + } + + @Override + public void visitConstantDouble(final ConstantDouble obj) + { + } + + @Override + public void visitConstantFieldref(final ConstantFieldref obj) + { + } + + @Override + public void visitConstantFloat(final ConstantFloat obj) + { + } + + @Override + public void visitConstantInteger(final ConstantInteger obj) + { + } + + @Override + public void visitConstantInterfaceMethodref(final ConstantInterfaceMethodref obj) + { + } + + @Override + public void visitConstantInvokeDynamic(final ConstantInvokeDynamic obj) + { + } + + @Override + public void visitConstantLong(final ConstantLong obj) + { + } + + @Override + public void visitConstantMethodref(final ConstantMethodref obj) + { + } + + @Override + public void visitConstantNameAndType(final ConstantNameAndType obj) + { + } + + @Override + public void visitConstantPool(final ConstantPool obj) + { + } + + @Override + public void visitConstantString(final ConstantString obj) + { + } + + @Override + public void visitConstantUtf8(final ConstantUtf8 obj) + { + } + + @Override + public void visitConstantValue(final ConstantValue obj) + { + } + + @Override + public void visitDeprecated(final Deprecated obj) + { + } + + @Override + public void visitExceptionTable(final ExceptionTable obj) + { + } + + @Override + public void visitField(final Field obj) + { + } + + @Override + public void visitInnerClass(final InnerClass obj) + { + } + + @Override + public void visitInnerClasses(final InnerClasses obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitBootstrapMethods(final BootstrapMethods obj) + { + } + + @Override + public void visitJavaClass(final JavaClass obj) + { + } + + @Override + public void visitLineNumber(final LineNumber obj) + { + } + + @Override + public void visitLineNumberTable(final LineNumberTable obj) + { + } + + @Override + public void visitLocalVariable(final LocalVariable obj) + { + } + + @Override + public void visitLocalVariableTable(final LocalVariableTable obj) + { + } + + @Override + public void visitMethod(final Method obj) + { + } + + @Override + public void visitSignature(final Signature obj) + { + } + + @Override + public void visitSourceFile(final SourceFile obj) + { + } + + @Override + public void visitSynthetic(final Synthetic obj) + { + } + + @Override + public void visitUnknown(final Unknown obj) + { + } + + @Override + public void visitStackMap(final StackMap obj) + { + } + + @Override + public void visitStackMapEntry(final StackMapEntry obj) + { + } + + /** + * @since 6.0 + @Override + public void visitStackMapTable(StackMapTable obj) + { + } + */ + + /** + * @since 6.0 + @Override + public void visitStackMapTableEntry(StackMapTableEntry obj) + { + } + */ + + /** + * @since 6.0 + */ + @Override + public void visitEnclosingMethod(final EnclosingMethod obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitMethodParameters(final MethodParameters obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitConstantMethodType(final ConstantMethodType obj) + { + } + + /** + * @since 6.0 + */ + @Override + public void visitConstantMethodHandle(final ConstantMethodHandle constantMethodHandle) { + } + + /** + * @since 6.0 + */ + @Override + public void visitParameterAnnotationEntry(final ParameterAnnotationEntry parameterAnnotationEntry) { + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnclosingMethod.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnclosingMethod.java new file mode 100644 index 00000000000..431cabd8771 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnclosingMethod.java @@ -0,0 +1,111 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This attribute exists for local or + * anonymous classes and ... there can be only one. + * + * @since 6.0 + */ +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. + EnclosingMethod(final int nameIndex, final int len, final DataInput input, final ConstantPool cpool) throws IOException { + this(nameIndex, len, input.readUnsignedShort(), input.readUnsignedShort(), cpool); + } + + private EnclosingMethod(final int nameIndex, final int len, final int classIdx,final int methodIdx, final ConstantPool cpool) { + super(Const.ATTR_ENCLOSING_METHOD, nameIndex, len, cpool); + classIndex = classIdx; + methodIndex = methodIdx; + } + + @Override + public void accept(final Visitor v) { + v.visitEnclosingMethod(this); + } + + @Override + public Attribute copy(final ConstantPool constant_pool) { + return (Attribute) clone(); + } + + // Accessors + public final int getEnclosingClassIndex() { + return classIndex; + } + + public final int getEnclosingMethodIndex() { + return methodIndex; + } + + public final void setEnclosingClassIndex(final int idx) { + classIndex = idx; + } + + public final void setEnclosingMethodIndex(final int idx) { + methodIndex = idx; + } + + public final ConstantClass getEnclosingClass() { + final ConstantClass c = + (ConstantClass)super.getConstantPool().getConstant(classIndex,Const.CONSTANT_Class); + return c; + } + + public final ConstantNameAndType getEnclosingMethod() { + if (methodIndex == 0) { + return null; + } + final ConstantNameAndType nat = + (ConstantNameAndType)super.getConstantPool().getConstant(methodIndex,Const.CONSTANT_NameAndType); + return nat; + } + + @Override + public final void dump(final DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(classIndex); + file.writeShort(methodIndex); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java new file mode 100644 index 00000000000..8aff8396a22 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java @@ -0,0 +1,90 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * @since 6.0 + */ +public class EnumElementValue extends ElementValue +{ + // For enum types, these two indices point to the type and value + private final int typeIdx; + + private final int valueIdx; + + public EnumElementValue(final int type, final int typeIdx, final int valueIdx, + final ConstantPool cpool) + { + super(type, cpool); + if (type != ENUM_CONSTANT) { + throw new RuntimeException( + "Only element values of type enum can be built with this ctor - type specified: " + type); + } + this.typeIdx = typeIdx; + this.valueIdx = valueIdx; + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getType()); // u1 type of value (ENUM_CONSTANT == 'e') + dos.writeShort(typeIdx); // u2 + dos.writeShort(valueIdx); // u2 + } + + @Override + public String stringifyValue() + { + final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(valueIdx, + Const.CONSTANT_Utf8); + return cu8.getBytes(); + } + + public String getEnumTypeString() + { + final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(typeIdx, + Const.CONSTANT_Utf8); + return cu8.getBytes();// Utility.signatureToString(cu8.getBytes()); + } + + public String getEnumValueString() + { + final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(valueIdx, + Const.CONSTANT_Utf8); + return cu8.getBytes(); + } + + public int getValueIndex() + { + return valueIdx; + } + + public int getTypeIndex() + { + return typeIdx; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java index 6780e9f534b..29c4c7d2bae 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java @@ -21,9 +21,11 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents the table of exceptions that are thrown by a @@ -33,137 +35,152 @@ import java.io.*; * attribute using the name Exceptions (which is inconsistent * with the other classes). * - * @author M. Dahm + * @version $Id: ExceptionTable.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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()); - } + private int[] exception_index_table; // constant pool - /** - * @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 - */ - public void accept(Visitor v) { - v.visitExceptionTable(this); - } - - /** - * Dump exceptions attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - file.writeShort(number_of_exceptions); - for(int i=0; i < number_of_exceptions; i++) - file.writeShort(exception_index_table[i]); - } - - /** - * @return Array of indices into constant pool of thrown exceptions. - */ - public final int[] getExceptionIndexTable() {return exception_index_table;} - /** - * @return Length of exception table. - */ - public final int getNumberOfExceptions() { return number_of_exceptions; } - - /** - * @return class names of thrown exceptions - */ - public final String[] getExceptionNames() { - String[] names = new String[number_of_exceptions]; - for(int i=0; i < number_of_exceptions; i++) - names[i] = constant_pool.getConstantString(exception_index_table[i], - Constants.CONSTANT_Class). - replace('/', '.'); - return names; - } - - /** - * @param exception_index_table. - * Also redefines number_of_exceptions according to table length. - */ - public final void setExceptionIndexTable(int[] exception_index_table) { - this.exception_index_table = exception_index_table; - number_of_exceptions = (exception_index_table == null)? 0 : - exception_index_table.length; - } - /** - * @return String representation, i.e., a list of thrown exceptions. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(""); - String str; - - for(int i=0; i < number_of_exceptions; i++) { - str = constant_pool.getConstantString(exception_index_table[i], - Constants.CONSTANT_Class); - buf.append(Utility.compactClassName(str, false)); - - if(i < number_of_exceptions - 1) - buf.append(", "); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public ExceptionTable(final ExceptionTable c) { + this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c.getConstantPool()); } - 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.constant_pool = constant_pool; - return c; - } + /** + * @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(final int name_index, final int length, final int[] exception_index_table, + final ConstantPool constant_pool) { + super(Const.ATTR_EXCEPTIONS, name_index, length, constant_pool); + this.exception_index_table = exception_index_table != null ? exception_index_table : new int[0]; + } + + + /** + * Construct object from input stream. + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + ExceptionTable(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { + this(name_index, length, (int[]) null, constant_pool); + final int number_of_exceptions = input.readUnsignedShort(); + exception_index_table = new int[number_of_exceptions]; + for (int i = 0; i < number_of_exceptions; i++) { + exception_index_table[i] = input.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( final Visitor v ) { + v.visitExceptionTable(this); + } + + + /** + * Dump exceptions attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(exception_index_table.length); + for (final int index : exception_index_table) { + file.writeShort(index); + } + } + + + /** + * @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 exception_index_table == null ? 0 : exception_index_table.length; + } + + + /** + * @return class names of thrown exceptions + */ + public final String[] getExceptionNames() { + final String[] names = new String[exception_index_table.length]; + for (int i = 0; i < exception_index_table.length; i++) { + names[i] = super.getConstantPool().getConstantString(exception_index_table[i], + Const.CONSTANT_Class).replace('/', '.'); + } + return names; + } + + + /** + * @param exception_index_table the list of exception indexes + * Also redefines number_of_exceptions according to table length. + */ + public final void setExceptionIndexTable( final int[] exception_index_table ) { + this.exception_index_table = exception_index_table != null ? exception_index_table : new int[0]; + } + + + /** + * @return String representation, i.e., a list of thrown exceptions. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder(); + String str; + buf.append("Exceptions: "); + for (int i = 0; i < exception_index_table.length; i++) { + str = super.getConstantPool().getConstantString(exception_index_table[i], Const.CONSTANT_Class); + buf.append(Utility.compactClassName(str, false)); + if (i < exception_index_table.length - 1) { + buf.append(", "); + } + } + return buf.toString(); + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + final ExceptionTable c = (ExceptionTable) clone(); + if (exception_index_table != null) { + c.exception_index_table = new int[exception_index_table.length]; + System.arraycopy(exception_index_table, 0, c.exception_index_table, 0, + exception_index_table.length); + } + c.setConstantPool(_constant_pool); + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java index a9089fcb1bb..a9073e50a15 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java @@ -21,112 +21,183 @@ package com.sun.org.apache.bcel.internal.classfile; -import com.sun.org.apache.bcel.internal.Constants; +import java.io.DataInput; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.generic.Type; -import java.io.*; +import com.sun.org.apache.bcel.internal.util.BCELComparator; /** * This class represents the field info structure, i.e., the representation * for a variable in the class. See JVM specification for details. * - * @author M. Dahm + * @version $Id: Field.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class Field extends FieldOrMethod { - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Field(Field c) { - super(c); - } - /** - * Construct object from file stream. - * @param file Input stream - */ - Field(DataInputStream file, ConstantPool constant_pool) - throws IOException, ClassFormatException - { - super(file, constant_pool); - } + private static BCELComparator bcelComparator = new BCELComparator() { - /** - * @param access_flags Access rights of field - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature - * @param attributes Collection of attributes - * @param constant_pool Array of constants - */ - public Field(int access_flags, int name_index, int signature_index, - Attribute[] attributes, ConstantPool constant_pool) - { - super(access_flags, name_index, signature_index, attributes, constant_pool); - } + @Override + public boolean equals( final Object o1, final Object o2 ) { + final Field THIS = (Field) o1; + final Field THAT = (Field) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitField(this); - } - /** - * @return constant value associated with this field (may be null) - */ - public final ConstantValue getConstantValue() { - for(int i=0; i < attributes_count; i++) - if(attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) - return (ConstantValue)attributes[i]; + @Override + public int hashCode( final Object o ) { + final Field THIS = (Field) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; - return null; - } - /** - * Return string representation close to declaration format, - * `public static final short MAX = 100', e.g.. - * - * @return String representation of field, including the signature. - */ - public final String toString() { - String name, signature, access; // Short cuts to constant pool - - // Get names from constant pool - access = Utility.accessToString(access_flags); - access = access.equals("")? "" : (access + " "); - signature = Utility.signatureToString(getSignature()); - name = getName(); - - StringBuffer buf = new StringBuffer(access + signature + " " + name); - ConstantValue cv = getConstantValue(); - - if(cv != null) - buf.append(" = " + cv); - - for(int i=0; i < attributes_count; i++) { - Attribute a = attributes[i]; - - if(!(a instanceof ConstantValue)) - buf.append(" [" + a.toString() + "]"); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Field(final Field c) { + super(c); } - return buf.toString(); - } - /** - * @return deep copy of this field - */ - public final Field copy(ConstantPool constant_pool) { - return (Field)copy_(constant_pool); - } + /** + * Construct object from file stream. + * @param file Input stream + */ + Field(final DataInput file, final ConstantPool constant_pool) throws IOException, + ClassFormatException { + super(file, constant_pool); + } - /** - * @return type of field - */ - public Type getType() { - return Type.getReturnType(getSignature()); - } + + /** + * @param access_flags Access rights of field + * @param name_index Points to field name in constant pool + * @param signature_index Points to encoded signature + * @param attributes Collection of attributes + * @param constant_pool Array of constants + */ + public Field(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes, + final ConstantPool constant_pool) { + super(access_flags, name_index, signature_index, attributes, constant_pool); + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitField(this); + } + + + /** + * @return constant value associated with this field (may be null) + */ + public final ConstantValue getConstantValue() { + for (final Attribute attribute : super.getAttributes()) { + if (attribute.getTag() == Const.ATTR_CONSTANT_VALUE) { + return (ConstantValue) attribute; + } + } + return null; + } + + + /** + * Return string representation close to declaration format, + * `public static final short MAX = 100', e.g.. + * + * @return String representation of field, including the signature. + */ + @Override + public final String toString() { + String name; + String signature; + String access; // Short cuts to constant pool + + // Get names from constant pool + access = Utility.accessToString(super.getAccessFlags()); + access = access.isEmpty() ? "" : (access + " "); + signature = Utility.signatureToString(getSignature()); + name = getName(); + final StringBuilder buf = new StringBuilder(64); // CHECKSTYLE IGNORE MagicNumber + buf.append(access).append(signature).append(" ").append(name); + final ConstantValue cv = getConstantValue(); + if (cv != null) { + buf.append(" = ").append(cv); + } + for (final Attribute attribute : super.getAttributes()) { + if (!(attribute instanceof ConstantValue)) { + buf.append(" [").append(attribute).append("]"); + } + } + return buf.toString(); + } + + + /** + * @return deep copy of this field + */ + public final Field copy( final ConstantPool _constant_pool ) { + return (Field) copy_(_constant_pool); + } + + + /** + * @return type of field + */ + public Type getType() { + return Type.getReturnType(getSignature()); + } + + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator( final BCELComparator comparator ) { + bcelComparator = comparator; + } + + + /** + * Return value as defined by given BCELComparator strategy. + * By default two Field objects are said to be equal when + * their names and signatures are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals( final Object obj ) { + return bcelComparator.equals(this, obj); + } + + + /** + * Return value as defined by given BCELComparator strategy. + * By default return the hashcode of the field's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java index 78fa6e837ed..4bcef712e0f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,173 +17,245 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; /** * Abstract super class for fields and methods. * - * @author M. Dahm + * @version $Id: FieldOrMethod.java 1750029 2016-06-23 22:14:38Z sebb $ */ public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node { - protected int name_index; // Points to field name in constant pool - protected int signature_index; // Points to encoded signature - protected int attributes_count;// No. of attributes - protected Attribute[] attributes; // Collection of attributes - protected ConstantPool constant_pool; + private int name_index; // Points to field name in constant pool + private int signature_index; // Points to encoded signature + private Attribute[] attributes; // Collection of attributes + private int attributes_count; // No. of attributes - FieldOrMethod() {} + // @since 6.0 + private AnnotationEntry[] annotationEntries; // annotations defined on the field or method - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - protected FieldOrMethod(FieldOrMethod c) { - this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), - c.getAttributes(), c.getConstantPool()); - } + private ConstantPool constant_pool; - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - * @throws ClassFormatException - */ - protected FieldOrMethod(DataInputStream file, ConstantPool constant_pool) - throws IOException, ClassFormatException - { - this(file.readUnsignedShort(), file.readUnsignedShort(), - file.readUnsignedShort(), null, constant_pool); + private String signatureAttributeString = null; + private boolean searchedForSignatureAttribute = false; - attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for(int i=0; i < attributes_count; i++) - attributes[i] = Attribute.readAttribute(file, constant_pool); - } + FieldOrMethod() { + } - /** - * @param access_flags Access rights of method - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature - * @param attributes Collection of attributes - * @param constant_pool Array of constants - */ - protected FieldOrMethod(int access_flags, int name_index, int signature_index, - Attribute[] attributes, ConstantPool constant_pool) - { - this.access_flags = access_flags; - this.name_index = name_index; - this.signature_index = signature_index; - this.constant_pool = constant_pool; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + protected FieldOrMethod(final FieldOrMethod c) { + this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), + c.getAttributes(), c.getConstantPool()); + } - setAttributes(attributes); - } + /** + * Construct object from file stream. + * + * @param file Input stream + * @throws IOException + * @throws ClassFormatException + * @deprecated (6.0) Use + * {@link #FieldOrMethod(java.io.DataInput, ConstantPool)} instead. + */ + @java.lang.Deprecated + protected FieldOrMethod(final DataInputStream file, + final ConstantPool constant_pool) throws IOException, + ClassFormatException { + this((DataInput) file, constant_pool); + } - /** - * Dump object to file stream on binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeShort(access_flags); - file.writeShort(name_index); - file.writeShort(signature_index); - file.writeShort(attributes_count); + /** + * Construct object from file stream. + * + * @param file Input stream + * @throws IOException + * @throws ClassFormatException + */ + protected FieldOrMethod(final DataInput file, + final ConstantPool constant_pool) throws IOException, ClassFormatException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, + constant_pool); + attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for (int i = 0; i < attributes_count; i++) { + attributes[i] = Attribute.readAttribute(file, constant_pool); + } + } - for(int i=0; i < attributes_count; i++) - attributes[i].dump(file); - } + /** + * @param access_flags Access rights of method + * @param name_index Points to field name in constant pool + * @param signature_index Points to encoded signature + * @param attributes Collection of attributes + * @param constant_pool Array of constants + */ + protected FieldOrMethod(final int access_flags, final int name_index, final int signature_index, + final Attribute[] attributes, final ConstantPool constant_pool) { + super(access_flags); + this.name_index = name_index; + this.signature_index = signature_index; + this.constant_pool = constant_pool; + setAttributes(attributes); + } - /** - * @return Collection of object attributes. - */ - public final Attribute[] getAttributes() { return attributes; } + /** + * Dump object to file stream on binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(final DataOutputStream file) throws IOException { + file.writeShort(super.getAccessFlags()); + file.writeShort(name_index); + file.writeShort(signature_index); + file.writeShort(attributes_count); - /** - * @param attributes Collection of object attributes. - */ - public final void setAttributes(Attribute[] attributes) { - this.attributes = attributes; - attributes_count = (attributes == null)? 0 : attributes.length; - } + for(int i=0; i < attributes_count; i++) { + attributes[i].dump(file); + } + } - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { return constant_pool; } + /** + * @return Collection of object attributes. + */ + public final Attribute[] getAttributes() { + return attributes; + } - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } + /** + * @param attributes Collection of object attributes. + */ + public final void setAttributes(final Attribute[] attributes) { + this.attributes = attributes; + this.attributes_count = attributes != null ? attributes.length : 0; + } - /** - * @return Index in constant pool of object's name. - */ - public final int getNameIndex() { return name_index; } + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } - /** - * @param name_index Index in constant pool of object's name. - */ - public final void setNameIndex(int name_index) { - this.name_index = name_index; - } + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(final ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } - /** - * @return Index in constant pool of field signature. - */ - public final int getSignatureIndex() { return signature_index; } + /** + * @return Index in constant pool of object's name. + */ + public final int getNameIndex() { + return name_index; + } - /** - * @param signature_index Index in constant pool of field signature. - */ - public final void setSignatureIndex(int signature_index) { - this.signature_index = signature_index; - } + /** + * @param name_index Index in constant pool of object's name. + */ + public final void setNameIndex(final int name_index) { + this.name_index = name_index; + } - /** - * @return Name of object, i.e., method name or field name - */ - public final String getName() { - ConstantUtf8 c; - c = (ConstantUtf8)constant_pool.getConstant(name_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } + /** + * @return Index in constant pool of field signature. + */ + public final int getSignatureIndex() { + return signature_index; + } - /** - * @return String representation of object's type signature (java style) - */ - public final String getSignature() { - ConstantUtf8 c; - c = (ConstantUtf8)constant_pool.getConstant(signature_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } + /** + * @param signature_index Index in constant pool of field signature. + */ + public final void setSignatureIndex(final int signature_index) { + this.signature_index = signature_index; + } - /** - * @return deep copy of this field - */ - protected FieldOrMethod copy_(ConstantPool constant_pool) { - FieldOrMethod c = null; + /** + * @return Name of object, i.e., method name or field name + */ + public final String getName() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); + return c.getBytes(); + } - try { - c = (FieldOrMethod)clone(); - } catch(CloneNotSupportedException e) {} + /** + * @return String representation of object's type signature (java style) + */ + public final String getSignature() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8); + return c.getBytes(); + } - c.constant_pool = constant_pool; - c.attributes = new Attribute[attributes_count]; + /** + * @return deep copy of this field + */ + protected FieldOrMethod copy_(final ConstantPool _constant_pool) { + FieldOrMethod c = null; - for(int i=0; i < attributes_count; i++) - c.attributes[i] = attributes[i].copy(constant_pool); + try { + c = (FieldOrMethod) clone(); + } catch (final CloneNotSupportedException e) { + // ignored, but will cause NPE ... + } - return c; - } + c.constant_pool = constant_pool; + c.attributes = new Attribute[attributes_count]; + c.attributes_count = attributes_count; + + for (int i = 0; i < attributes_count; i++) { + c.attributes[i] = attributes[i].copy(constant_pool); + } + + return c; + } + + /** + * @return Annotations on the field or method + * @since 6.0 + */ + public AnnotationEntry[] getAnnotationEntries() { + if (annotationEntries == null) { + annotationEntries = AnnotationEntry.createAnnotationEntries(getAttributes()); + } + + return annotationEntries; + } + + /** + * 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. + * + * @since 6.0 + */ + public final String getGenericSignature() { + if (!searchedForSignatureAttribute) { + boolean found = false; + for (int i = 0; !found && i < attributes.length; i++) { + if (attributes[i] instanceof Signature) { + signatureAttributeString = ((Signature) attributes[i]) + .getSignature(); + found = true; + } + } + searchedForSignatureAttribute = true; + } + return signatureAttributeString; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java index 32372eb7458..39ac0ac70b1 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java @@ -21,168 +21,201 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * 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. * - * @author M. Dahm + * @version $Id: InnerClass.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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()); - } + private int inner_class_index; + private int outer_class_index; + private int inner_name_index; + private int inner_access_flags; - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - InnerClass(DataInputStream file) throws IOException - { - this(file.readUnsignedShort(), file.readUnsignedShort(), - file.readUnsignedShort(), file.readUnsignedShort()); - } - /** - * @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(Visitor v) { - v.visitInnerClass(this); - } - /** - * Dump inner class attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeShort(inner_class_index); - file.writeShort(outer_class_index); - file.writeShort(inner_name_index); - file.writeShort(inner_access_flags); - } - /** - * @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. - */ - 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); + /** + * Initialize from another object. + */ + public InnerClass(final InnerClass c) { + this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c + .getInnerAccessFlags()); } - else - outer_class_name = ""; - if(inner_name_index != 0) - inner_name = ((ConstantUtf8)constant_pool. - getConstant(inner_name_index, Constants.CONSTANT_Utf8)).getBytes(); - else - inner_name = ""; - access = Utility.accessToString(inner_access_flags, true); - access = access.equals("")? "" : (access + " "); + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + InnerClass(final DataInput file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort()); + } - 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) {} + /** + * @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(final int inner_class_index, final int outer_class_index, final int inner_name_index, + final int inner_access_flags) { + this.inner_class_index = inner_class_index; + this.outer_class_index = outer_class_index; + this.inner_name_index = inner_name_index; + this.inner_access_flags = inner_access_flags; + } - return 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 + */ + @Override + public void accept( final Visitor v ) { + v.visitInnerClass(this); + } + + + /** + * Dump inner class attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump( final 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 access flags for this inner class + */ + public final void setInnerAccessFlags( final int inner_access_flags ) { + this.inner_access_flags = inner_access_flags; + } + + + /** + * @param inner_class_index index into the constant pool for this class + */ + public final void setInnerClassIndex( final int inner_class_index ) { + this.inner_class_index = inner_class_index; + } + + + /** + * @param inner_name_index index into the constant pool for this class's name + */ + public final void setInnerNameIndex( final int inner_name_index ) { // TODO unused + this.inner_name_index = inner_name_index; + } + + + /** + * @param outer_class_index index into the constant pool for the owning class + */ + public final void setOuterClassIndex( final int outer_class_index ) { // TODO unused + 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( final ConstantPool constant_pool ) { + String outer_class_name; + String inner_name; + String inner_class_name = constant_pool.getConstantString(inner_class_index, + Const.CONSTANT_Class); + inner_class_name = Utility.compactClassName(inner_class_name); + if (outer_class_index != 0) { + outer_class_name = constant_pool.getConstantString(outer_class_index, + Const.CONSTANT_Class); + outer_class_name = " of class " + Utility.compactClassName(outer_class_name); + } else { + outer_class_name = ""; + } + if (inner_name_index != 0) { + inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index, + Const.CONSTANT_Utf8)).getBytes(); + } else { + inner_name = "(anonymous)"; + } + String access = Utility.accessToString(inner_access_flags, true); + access = access.isEmpty() ? "" : (access + " "); + return " " + access + inner_name + "=class " + inner_class_name + outer_class_name; + } + + + /** + * @return deep copy of this object + */ + public InnerClass copy() { + try { + return (InnerClass) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java index ee12da6f781..bb4cdad6754 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java @@ -21,9 +21,11 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class is derived from Attribute and denotes that this class @@ -31,118 +33,129 @@ import java.io.*; * to the source file of this class. * It is instantiated from the Attribute.readAttribute() method. * - * @author M. Dahm + * @version $Id: InnerClasses.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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()); - } + private InnerClass[] inner_classes; - /** - * @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); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public InnerClasses(final InnerClasses c) { + this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool()); + } - 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 - */ - public void accept(Visitor v) { - v.visitInnerClasses(this); - } - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - file.writeShort(number_of_classes); + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param inner_classes array of inner classes attributes + * @param constant_pool Array of constants + */ + public InnerClasses(final int name_index, final int length, final InnerClass[] inner_classes, + final ConstantPool constant_pool) { + super(Const.ATTR_INNER_CLASSES, name_index, length, constant_pool); + this.inner_classes = inner_classes != null ? inner_classes : new InnerClass[0]; + } - 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; } + /** + * Construct object from input stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + InnerClasses(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, (InnerClass[]) null, constant_pool); + final int number_of_classes = input.readUnsignedShort(); + inner_classes = new InnerClass[number_of_classes]; + for (int i = 0; i < number_of_classes; i++) { + inner_classes[i] = new InnerClass(input); + } + } - /** - * @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. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(); + /** + * 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( final Visitor v ) { + v.visitInnerClasses(this); + } - for(int i=0; i < number_of_classes; i++) - buf.append(inner_classes[i].toString(constant_pool) + "\n"); - return buf.toString(); - } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(inner_classes.length); + for (final InnerClass inner_class : inner_classes) { + inner_class.dump(file); + } + } - /** - * @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(); + /** + * @return array of inner class "records" + */ + public final InnerClass[] getInnerClasses() { + return inner_classes; + } - c.constant_pool = constant_pool; - return c; - } + + /** + * @param inner_classes the array of inner classes + */ + public final void setInnerClasses( final InnerClass[] inner_classes ) { + this.inner_classes = inner_classes != null ? inner_classes : new InnerClass[0]; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder(); + buf.append("InnerClasses("); + buf.append(inner_classes.length); + buf.append("):\n"); + for (final InnerClass inner_class : inner_classes) { + buf.append(inner_class.toString(super.getConstantPool())).append("\n"); + } + return buf.toString(); + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + // TODO this could be recoded to use a lower level constructor after creating a copy of the inner classes + final InnerClasses c = (InnerClasses) clone(); + c.inner_classes = new InnerClass[inner_classes.length]; + for (int i = 0; i < inner_classes.length; i++) { + c.inner_classes[i] = inner_classes[i].copy(); + } + c.setConstantPool(_constant_pool); + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java index 2e6c2ba23a3..fc35db70e25 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java @@ -17,772 +17,855 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; +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.List; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.TreeSet; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.util.SyntheticRepository; -import com.sun.org.apache.bcel.internal.util.ClassVector; -import com.sun.org.apache.bcel.internal.util.ClassQueue; -import com.sun.org.apache.bcel.internal.generic.Type; -import com.sun.org.apache.xalan.internal.utils.SecuritySupport; - -import java.io.*; -import java.util.StringTokenizer; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.generic.Type; +import com.sun.org.apache.bcel.internal.util.BCELComparator; +import com.sun.org.apache.bcel.internal.util.ClassQueue; +import com.sun.org.apache.bcel.internal.util.SyntheticRepository; +import jdk.xml.internal.SecuritySupport; /** - * Represents a Java class, i.e., the data structures, constant pool, - * fields, methods and commands contained in a Java .class file. - * See JVM - * specification for details. - - * The intent of this class is to represent a parsed or otherwise existing - * class file. Those interested in programatically generating classes + * Represents a Java class, i.e., the data structures, constant pool, fields, + * methods and commands contained in a Java .class file. See JVM specification for + * details. The intent of this class is to represent a parsed or otherwise + * existing class file. Those interested in programatically generating classes * should see the ClassGen class. - + * + * @version $Id: JavaClass.java 1750227 2016-06-25 21:47:10Z ggregory $ * @see com.sun.org.apache.bcel.internal.generic.ClassGen - * @author M. Dahm */ -public class JavaClass extends AccessFlags implements Cloneable, Node { - private String file_name; - private String package_name; - private String source_file_name = ""; - private int class_name_index; - private int superclass_name_index; - private String class_name; - private String superclass_name; - private int major, minor; // Compiler version - private ConstantPool constant_pool; // Constant pool - private int[] interfaces; // implemented interfaces - private String[] interface_names; - private Field[] fields; // Fields, i.e., variables of class - private Method[] methods; // methods defined in the class - private Attribute[] attributes; // attributes defined in the class - private byte source = HEAP; // Generated in memory - - public static final byte HEAP = 1; - public static final byte FILE = 2; - public static final byte ZIP = 3; - - static boolean debug = false; // Debugging on/off - static char sep = '/'; // directory separator - - /** - * In cases where we go ahead and create something, - * use the default SyntheticRepository, because we - * don't know any better. - */ - private transient com.sun.org.apache.bcel.internal.util.Repository repository = - SyntheticRepository.getInstance(); - - /** - * Constructor gets all contents as arguments. - * - * @param class_name_index Index into constant pool referencing a - * ConstantClass that represents this class. - * @param superclass_name_index Index into constant pool referencing a - * ConstantClass that represents this class's superclass. - * @param file_name File name - * @param major Major compiler version - * @param minor Minor compiler version - * @param access_flags Access rights defined by bit flags - * @param constant_pool Array of constants - * @param interfaces Implemented interfaces - * @param fields Class fields - * @param methods Class methods - * @param attributes Class attributes - * @param source Read from file or generated in memory? - */ - public JavaClass(int class_name_index, - int superclass_name_index, - String file_name, - int major, - int minor, - int access_flags, - ConstantPool constant_pool, - int[] interfaces, - Field[] fields, - Method[] methods, - Attribute[] attributes, - byte source) - { - if(interfaces == null) // Allowed for backward compatibility - interfaces = new int[0]; - if(attributes == null) - this.attributes = new Attribute[0]; - if(fields == null) - fields = new Field[0]; - if(methods == null) - methods = new Method[0]; - - this.class_name_index = class_name_index; - this.superclass_name_index = superclass_name_index; - this.file_name = file_name; - this.major = major; - this.minor = minor; - this.access_flags = access_flags; - this.constant_pool = constant_pool; - this.interfaces = interfaces; - this.fields = fields; - this.methods = methods; - this.attributes = attributes; - this.source = source; - - // Get source file name if available - for(int i=0; i < attributes.length; i++) { - if(attributes[i] instanceof SourceFile) { - source_file_name = ((SourceFile)attributes[i]).getSourceFileName(); - break; - } - } - - /* According to the specification the following entries must be of type - * `ConstantClass' but we check that anyway via the - * `ConstPool.getConstant' method. - */ - class_name = constant_pool.getConstantString(class_name_index, - Constants.CONSTANT_Class); - class_name = Utility.compactClassName(class_name, false); - - int index = class_name.lastIndexOf('.'); - if(index < 0) - package_name = ""; - else - package_name = class_name.substring(0, index); - - if(superclass_name_index > 0) { // May be zero -> class is java.lang.Object - superclass_name = constant_pool.getConstantString(superclass_name_index, - Constants.CONSTANT_Class); - superclass_name = Utility.compactClassName(superclass_name, false); - } - else - superclass_name = "java.lang.Object"; - - interface_names = new String[interfaces.length]; - for(int i=0; i < interfaces.length; i++) { - String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class); - interface_names[i] = Utility.compactClassName(str, false); - } - } - - /** - * Constructor gets all contents as arguments. - * - * @param class_name_index Class name - * @param superclass_name_index Superclass name - * @param file_name File name - * @param major Major compiler version - * @param minor Minor compiler version - * @param access_flags Access rights defined by bit flags - * @param constant_pool Array of constants - * @param interfaces Implemented interfaces - * @param fields Class fields - * @param methods Class methods - * @param attributes Class attributes - */ - public JavaClass(int class_name_index, - int superclass_name_index, - String file_name, - int major, - int minor, - int access_flags, - ConstantPool constant_pool, - int[] interfaces, - Field[] fields, - Method[] methods, - Attribute[] attributes) { - this(class_name_index, superclass_name_index, file_name, major, minor, access_flags, - constant_pool, interfaces, fields, methods, attributes, HEAP); - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitJavaClass(this); - } - - /* Print debug information depending on `JavaClass.debug' - */ - static final void Debug(String str) { - if(debug) - System.out.println(str); - } - - /** - * Dump class to a file. - * - * @param file Output file - * @throws IOException - */ - public void dump(File file) throws IOException - { - String parent = file.getParent(); - - if(parent != null) { - File dir = new File(parent); - - if(dir != null) - 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. - * - * @param file Output stream - * @exception IOException - */ - public void dump(OutputStream file) throws IOException { - dump(new DataOutputStream(file)); - } - - /** - * Dump Java class to output stream in binary format. - * - * @param file Output stream - * @exception IOException - */ - public void dump(DataOutputStream file) throws IOException - { - file.writeInt(0xcafebabe); - file.writeShort(minor); - file.writeShort(major); - - constant_pool.dump(file); - - file.writeShort(access_flags); - file.writeShort(class_name_index); - file.writeShort(superclass_name_index); - - file.writeShort(interfaces.length); - for(int i=0; i < interfaces.length; i++) - file.writeShort(interfaces[i]); - - file.writeShort(fields.length); - for(int i=0; i < fields.length; i++) - fields[i].dump(file); - - file.writeShort(methods.length); - for(int i=0; i < methods.length; i++) - methods[i].dump(file); - - if(attributes != null) { - file.writeShort(attributes.length); - for(int i=0; i < attributes.length; i++) - attributes[i].dump(file); - } - else - file.writeShort(0); - - file.close(); - } - - /** - * @return Attributes of the class. - */ - public Attribute[] getAttributes() { return attributes; } - - /** - * @return Class name. - */ - public String getClassName() { return class_name; } - - /** - * @return Package name. - */ - public String getPackageName() { return package_name; } - - /** - * @return Class name index. - */ - public int getClassNameIndex() { return class_name_index; } - - /** - * @return Constant pool. - */ - public ConstantPool getConstantPool() { return constant_pool; } - - /** - * @return Fields, i.e., variables of the class. Like the JVM spec - * mandates for the classfile format, these fields are those specific to - * this class, and not those of the superclass or superinterfaces. - */ - public Field[] getFields() { return fields; } - - /** - * @return File name of class, aka SourceFile attribute value - */ - public String getFileName() { return file_name; } - - /** - * @return Names of implemented interfaces. - */ - public String[] getInterfaceNames() { return interface_names; } - - /** - * @return Indices in constant pool of implemented interfaces. - */ - public int[] getInterfaceIndices() { return interfaces; } - - /** - * @return Major number of class file version. - */ - public int getMajor() { return major; } - - /** - * @return Methods of the class. - */ - public Method[] getMethods() { return methods; } - - /** - * @return A com.sun.org.apache.bcel.internal.classfile.Method corresponding to - * java.lang.reflect.Method if any - */ - public Method getMethod(java.lang.reflect.Method m) { - for(int i = 0; i < methods.length; i++) { - Method method = methods[i]; - - if(m.getName().equals(method.getName()) && - (m.getModifiers() == method.getModifiers()) && - Type.getSignature(m).equals(method.getSignature())) { - return method; - } - } - - return null; - } - - /** - * @return Minor number of class file version. - */ - public int getMinor() { return minor; } - - /** - * @return sbsolute path to file where this class was read from - */ - public String getSourceFileName() { return source_file_name; } - - /** - * @return Superclass name. - */ - public String getSuperclassName() { return superclass_name; } - - /** - * @return Class name index. - */ - public int getSuperclassNameIndex() { return superclass_name_index; } - - static { - // Debugging ... on/off - String debug = null, sep = null; - - try { - debug = SecuritySupport.getSystemProperty("JavaClass.debug"); - // Get path separator either / or \ usually - sep = SecuritySupport.getSystemProperty("file.separator"); - } - catch (SecurityException e) { - // falls through - } - - if(debug != null) - JavaClass.debug = Boolean.valueOf(debug); - - if(sep != null) - try { - JavaClass.sep = sep.charAt(0); - } catch(StringIndexOutOfBoundsException e) {} // Never reached - } - - /** - * @param attributes . - */ - public void setAttributes(Attribute[] attributes) { - this.attributes = attributes; - } - - /** - * @param class_name . - */ - public void setClassName(String class_name) { - this.class_name = class_name; - } - - /** - * @param class_name_index . - */ - public void setClassNameIndex(int class_name_index) { - this.class_name_index = class_name_index; - } - - /** - * @param constant_pool . - */ - public void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } - - /** - * @param fields . - */ - public void setFields(Field[] fields) { - this.fields = fields; - } - - /** - * Set File name of class, aka SourceFile attribute value - */ - public void setFileName(String file_name) { - this.file_name = file_name; - } - - /** - * @param interface_names . - */ - public void setInterfaceNames(String[] interface_names) { - this.interface_names = interface_names; - } - - /** - * @param interfaces . - */ - public void setInterfaces(int[] interfaces) { - this.interfaces = interfaces; - } - - /** - * @param major . - */ - public void setMajor(int major) { - this.major = major; - } - - /** - * @param methods . - */ - public void setMethods(Method[] methods) { - this.methods = methods; - } - - /** - * @param minor . - */ - public void setMinor(int minor) { - this.minor = minor; - } - - /** - * Set absolute path to file this class was read from. - */ - public void setSourceFileName(String source_file_name) { - this.source_file_name = source_file_name; - } - - /** - * @param superclass_name . - */ - public void setSuperclassName(String superclass_name) { - this.superclass_name = superclass_name; - } - - /** - * @param superclass_name_index . - */ - public void setSuperclassNameIndex(int superclass_name_index) { - this.superclass_name_index = superclass_name_index; - } - - /** - * @return String representing class contents. - */ - public String toString() { - String access = Utility.accessToString(access_flags, true); - access = access.equals("")? "" : (access + " "); - - StringBuffer buf = new StringBuffer(access + - Utility.classOrInterface(access_flags) + - " " + - class_name + " extends " + - Utility.compactClassName(superclass_name, - false) + '\n'); - int size = interfaces.length; - - if(size > 0) { - buf.append("implements\t\t"); - - for(int i=0; i < size; i++) { - buf.append(interface_names[i]); - if(i < size - 1) - buf.append(", "); - } - - buf.append('\n'); - } - - buf.append("filename\t\t" + file_name + '\n'); - buf.append("compiled from\t\t" + source_file_name + '\n'); - buf.append("compiler version\t" + major + "." + minor + '\n'); - buf.append("access flags\t\t" + access_flags + '\n'); - buf.append("constant pool\t\t" + constant_pool.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(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(); - } - - /** - * @return deep copy of this class - */ - public JavaClass copy() { - JavaClass c = null; - - try { - c = (JavaClass)clone(); - } catch(CloneNotSupportedException e) {} - - c.constant_pool = constant_pool.copy(); - c.interfaces = (int[])interfaces.clone(); - c.interface_names = (String[])interface_names.clone(); - - c.fields = new Field[fields.length]; - for(int i=0; i < fields.length; i++) - c.fields[i] = fields[i].copy(c.constant_pool); - - c.methods = new Method[methods.length]; - for(int i=0; i < methods.length; i++) - c.methods[i] = methods[i].copy(c.constant_pool); - - c.attributes = new Attribute[attributes.length]; - for(int i=0; i < attributes.length; i++) - c.attributes[i] = attributes[i].copy(c.constant_pool); - - return c; - } - - public final boolean isSuper() { - return (access_flags & Constants.ACC_SUPER) != 0; - } - - public final boolean isClass() { - return (access_flags & Constants.ACC_INTERFACE) == 0; - } - - /** @return returns either HEAP (generated), FILE, or ZIP - */ - public final byte getSource() { - return source; - } - - /********************* New repository functionality *********************/ - - /** - * Gets the ClassRepository which holds its definition. By default - * this is the same as SyntheticRepository.getInstance(); - */ - public com.sun.org.apache.bcel.internal.util.Repository getRepository() { - return repository; - } - - /** - * Sets the ClassRepository which loaded the JavaClass. - * Should be called immediately after parsing is done. - */ - public void setRepository(com.sun.org.apache.bcel.internal.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; - } - - JavaClass[] super_interfaces = getAllInterfaces(); - - for(int i=0; i < super_interfaces.length; i++) { - if(super_interfaces[i].equals(inter)) { - return true; - } - } - - return false; - } - - /** - * @return the superclass for this JavaClass object, or null if this - * is java.lang.Object - */ - public JavaClass getSuperClass() { - if("java.lang.Object".equals(getClassName())) { - return null; - } - - try { - return repository.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; - ClassVector vec = new ClassVector(); - - for(clazz = clazz.getSuperClass(); clazz != null; - clazz = clazz.getSuperClass()) - { - vec.addElement(clazz); - } - - return vec.toArray(); - } - - /** - * 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] = repository.loadClass(interfaces[i]); - } - } catch(ClassNotFoundException e) { - System.err.println(e); - return null; - } - - return classes; - } - - /** - * Get all interfaces implemented by this JavaClass (transitively). - */ - public JavaClass[] getAllInterfaces() { - ClassQueue queue = new ClassQueue(); - ClassVector vec = new ClassVector(); - - queue.enqueue(this); - - while(!queue.empty()) { - JavaClass clazz = queue.dequeue(); - - JavaClass souper = clazz.getSuperClass(); - JavaClass[] interfaces = clazz.getInterfaces(); - - if(clazz.isInterface()) { - vec.addElement(clazz); - } else { - if(souper != null) { - queue.enqueue(souper); +public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable { + + private String file_name; + private String package_name; + private String source_file_name = ""; + private int class_name_index; + private int superclass_name_index; + private String class_name; + private String superclass_name; + private int major; + private int minor; // Compiler version + private ConstantPool constant_pool; // Constant pool + private int[] interfaces; // implemented interfaces + private String[] interface_names; + private Field[] fields; // Fields, i.e., variables of class + private Method[] methods; // methods defined in the class + private Attribute[] attributes; // attributes defined in the class + private AnnotationEntry[] annotations; // annotations defined on the class + private byte source = HEAP; // Generated in memory + private boolean isAnonymous = false; + private boolean isNested = false; + private boolean computedNestedTypeStatus = false; + public static final byte HEAP = 1; + public static final byte FILE = 2; + public static final byte ZIP = 3; + + private static BCELComparator bcelComparator = new BCELComparator() { + + @Override + public boolean equals(final Object o1, final Object o2) { + final JavaClass THIS = (JavaClass) o1; + final JavaClass THAT = (JavaClass) o2; + return THIS.getClassName().equals(THAT.getClassName()); } - } - for(int i = 0; i < interfaces.length; i++) { - queue.enqueue(interfaces[i]); - } + @Override + public int hashCode(final Object o) { + final JavaClass THIS = (JavaClass) o; + return THIS.getClassName().hashCode(); + } + }; + /** + * In cases where we go ahead and create something, use the default + * SyntheticRepository, because we don't know any better. + */ + private transient com.sun.org.apache.bcel.internal.util.Repository repository + = SyntheticRepository.getInstance(); + + /** + * Constructor gets all contents as arguments. + * + * @param class_name_index Index into constant pool referencing a + * ConstantClass that represents this class. + * @param superclass_name_index Index into constant pool referencing a + * ConstantClass that represents this class's superclass. + * @param file_name File name + * @param major Major compiler version + * @param minor Minor compiler version + * @param access_flags Access rights defined by bit flags + * @param constant_pool Array of constants + * @param interfaces Implemented interfaces + * @param fields Class fields + * @param methods Class methods + * @param attributes Class attributes + * @param source Read from file or generated in memory? + */ + public JavaClass(final int class_name_index, final int superclass_name_index, + final String file_name, final int major, final int minor, final int access_flags, + final ConstantPool constant_pool, int[] interfaces, Field[] fields, + Method[] methods, Attribute[] attributes, final byte source) { + super(access_flags); + if (interfaces == null) { + interfaces = new int[0]; + } + if (attributes == null) { + attributes = new Attribute[0]; + } + if (fields == null) { + fields = new Field[0]; + } + if (methods == null) { + methods = new Method[0]; + } + this.class_name_index = class_name_index; + this.superclass_name_index = superclass_name_index; + this.file_name = file_name; + this.major = major; + this.minor = minor; + this.constant_pool = constant_pool; + this.interfaces = interfaces; + this.fields = fields; + this.methods = methods; + this.attributes = attributes; + this.source = source; + // Get source file name if available + for (final Attribute attribute : attributes) { + if (attribute instanceof SourceFile) { + source_file_name = ((SourceFile) attribute).getSourceFileName(); + break; + } + } + /* According to the specification the following entries must be of type + * `ConstantClass' but we check that anyway via the + * `ConstPool.getConstant' method. + */ + class_name = constant_pool.getConstantString(class_name_index, Const.CONSTANT_Class); + class_name = Utility.compactClassName(class_name, false); + final int index = class_name.lastIndexOf('.'); + if (index < 0) { + package_name = ""; + } else { + package_name = class_name.substring(0, index); + } + if (superclass_name_index > 0) { + // May be zero -> class is java.lang.Object + superclass_name = constant_pool.getConstantString(superclass_name_index, + Const.CONSTANT_Class); + superclass_name = Utility.compactClassName(superclass_name, false); + } else { + superclass_name = "java.lang.Object"; + } + interface_names = new String[interfaces.length]; + for (int i = 0; i < interfaces.length; i++) { + final String str = constant_pool.getConstantString(interfaces[i], Const.CONSTANT_Class); + interface_names[i] = Utility.compactClassName(str, false); + } } - return vec.toArray(); - } + /** + * Constructor gets all contents as arguments. + * + * @param class_name_index Class name + * @param superclass_name_index Superclass name + * @param file_name File name + * @param major Major compiler version + * @param minor Minor compiler version + * @param access_flags Access rights defined by bit flags + * @param constant_pool Array of constants + * @param interfaces Implemented interfaces + * @param fields Class fields + * @param methods Class methods + * @param attributes Class attributes + */ + public JavaClass(final int class_name_index, final int superclass_name_index, + final String file_name, final int major, final int minor, final int access_flags, + final ConstantPool constant_pool, final int[] interfaces, final Field[] fields, + final Method[] methods, final Attribute[] attributes) { + this(class_name_index, superclass_name_index, file_name, major, minor, access_flags, + constant_pool, interfaces, fields, methods, attributes, HEAP); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitly + * 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(final Visitor v) { + v.visitJavaClass(this); + } + + /** + * Dump class to a file. + * + * @param file Output file + * @throws IOException + */ + public void dump(final File file) throws IOException { + final String parent = file.getParent(); + if (parent != null) { + final File dir = new File(parent); + if (!dir.mkdirs()) { // either was not created or already existed + if (!SecuritySupport.isDirectory(dir)) { + throw new IOException("Could not create the directory " + dir); + } + } + } + try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) { + dump(dos); + } + } + + /** + * Dump class to a file named file_name. + * + * @param _file_name Output file name + * @throws IOException + */ + public void dump(final String _file_name) throws IOException { + dump(new File(_file_name)); + } + + /** + * @return class in binary format + */ + public byte[] getBytes() { + final ByteArrayOutputStream s = new ByteArrayOutputStream(); + final DataOutputStream ds = new DataOutputStream(s); + try { + dump(ds); + } catch (final IOException e) { + System.err.println("Error dumping class: " + e.getMessage()); + } finally { + try { + ds.close(); + } catch (final IOException e2) { + System.err.println("Error dumping class: " + e2.getMessage()); + } + } + return s.toByteArray(); + } + + /** + * Dump Java class to output stream in binary format. + * + * @param file Output stream + * @throws IOException + */ + public void dump(final OutputStream file) throws IOException { + dump(new DataOutputStream(file)); + } + + /** + * Dump Java class to output stream in binary format. + * + * @param file Output stream + * @throws IOException + */ + private void dump(final DataOutputStream file) throws IOException { + file.writeInt(Const.JVM_CLASSFILE_MAGIC); + file.writeShort(minor); + file.writeShort(major); + constant_pool.dump(file); + file.writeShort(super.getAccessFlags()); + file.writeShort(class_name_index); + file.writeShort(superclass_name_index); + file.writeShort(interfaces.length); + for (final int interface1 : interfaces) { + file.writeShort(interface1); + } + file.writeShort(fields.length); + for (final Field field : fields) { + field.dump(file); + } + file.writeShort(methods.length); + for (final Method method : methods) { + method.dump(file); + } + if (attributes != null) { + file.writeShort(attributes.length); + for (final Attribute attribute : attributes) { + attribute.dump(file); + } + } else { + file.writeShort(0); + } + file.flush(); + } + + /** + * @return Attributes of the class. + */ + public Attribute[] getAttributes() { + return attributes; + } + + /** + * @return Annotations on the class + * @since 6.0 + */ + public AnnotationEntry[] getAnnotationEntries() { + if (annotations == null) { + annotations = AnnotationEntry.createAnnotationEntries(getAttributes()); + } + + return annotations; + } + + /** + * @return Class name. + */ + public String getClassName() { + return class_name; + } + + /** + * @return Package name. + */ + public String getPackageName() { + return package_name; + } + + /** + * @return Class name index. + */ + public int getClassNameIndex() { + return class_name_index; + } + + /** + * @return Constant pool. + */ + public ConstantPool getConstantPool() { + return constant_pool; + } + + /** + * @return Fields, i.e., variables of the class. Like the JVM spec mandates + * for the classfile format, these fields are those specific to this class, + * and not those of the superclass or superinterfaces. + */ + public Field[] getFields() { + return fields; + } + + /** + * @return File name of class, aka SourceFile attribute value + */ + public String getFileName() { + return file_name; + } + + /** + * @return Names of implemented interfaces. + */ + public String[] getInterfaceNames() { + return interface_names; + } + + /** + * @return Indices in constant pool of implemented interfaces. + */ + public int[] getInterfaceIndices() { + return interfaces; + } + + /** + * @return Major number of class file version. + */ + public int getMajor() { + return major; + } + + /** + * @return Methods of the class. + */ + public Method[] getMethods() { + return methods; + } + + /** + * @return A {@link Method} corresponding to java.lang.reflect.Method if any + */ + public Method getMethod(final java.lang.reflect.Method m) { + for (final Method method : methods) { + if (m.getName().equals(method.getName()) && (m.getModifiers() == method.getModifiers()) + && Type.getSignature(m).equals(method.getSignature())) { + return method; + } + } + return null; + } + + /** + * @return Minor number of class file version. + */ + public int getMinor() { + return minor; + } + + /** + * @return sbsolute path to file where this class was read from + */ + public String getSourceFileName() { + return source_file_name; + } + + /** + * returns the super class name of this class. In the case that this class + * is java.lang.Object, it will return itself (java.lang.Object). This is + * probably incorrect but isn't fixed at this time to not break existing + * clients. + * + * @return Superclass name. + */ + public String getSuperclassName() { + return superclass_name; + } + + /** + * @return Class name index. + */ + public int getSuperclassNameIndex() { + return superclass_name_index; + } + + /** + * @param attributes . + */ + public void setAttributes(final Attribute[] attributes) { + this.attributes = attributes; + } + + /** + * @param class_name . + */ + public void setClassName(final String class_name) { + this.class_name = class_name; + } + + /** + * @param class_name_index . + */ + public void setClassNameIndex(final int class_name_index) { + this.class_name_index = class_name_index; + } + + /** + * @param constant_pool . + */ + public void setConstantPool(final ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * @param fields . + */ + public void setFields(final Field[] fields) { + this.fields = fields; + } + + /** + * Set File name of class, aka SourceFile attribute value + */ + public void setFileName(final String file_name) { + this.file_name = file_name; + } + + /** + * @param interface_names . + */ + public void setInterfaceNames(final String[] interface_names) { + this.interface_names = interface_names; + } + + /** + * @param interfaces . + */ + public void setInterfaces(final int[] interfaces) { + this.interfaces = interfaces; + } + + /** + * @param major . + */ + public void setMajor(final int major) { + this.major = major; + } + + /** + * @param methods . + */ + public void setMethods(final Method[] methods) { + this.methods = methods; + } + + /** + * @param minor . + */ + public void setMinor(final int minor) { + this.minor = minor; + } + + /** + * Set absolute path to file this class was read from. + */ + public void setSourceFileName(final String source_file_name) { + this.source_file_name = source_file_name; + } + + /** + * @param superclass_name . + */ + public void setSuperclassName(final String superclass_name) { + this.superclass_name = superclass_name; + } + + /** + * @param superclass_name_index . + */ + public void setSuperclassNameIndex(final int superclass_name_index) { + this.superclass_name_index = superclass_name_index; + } + + /** + * @return String representing class contents. + */ + @Override + public String toString() { + String access = Utility.accessToString(super.getAccessFlags(), true); + access = access.isEmpty() ? "" : (access + " "); + final StringBuilder buf = new StringBuilder(128); + buf.append(access).append(Utility.classOrInterface(super.getAccessFlags())).append(" ").append( + class_name).append(" extends ").append( + Utility.compactClassName(superclass_name, false)).append('\n'); + final int size = interfaces.length; + if (size > 0) { + buf.append("implements\t\t"); + for (int i = 0; i < size; i++) { + buf.append(interface_names[i]); + if (i < size - 1) { + buf.append(", "); + } + } + buf.append('\n'); + } + buf.append("filename\t\t").append(file_name).append('\n'); + buf.append("compiled from\t\t").append(source_file_name).append('\n'); + buf.append("compiler version\t").append(major).append(".").append(minor).append('\n'); + buf.append("access flags\t\t").append(super.getAccessFlags()).append('\n'); + buf.append("constant pool\t\t").append(constant_pool.getLength()).append(" entries\n"); + buf.append("ACC_SUPER flag\t\t").append(isSuper()).append("\n"); + if (attributes.length > 0) { + buf.append("\nAttribute(s):\n"); + for (final Attribute attribute : attributes) { + buf.append(indent(attribute)); + } + } + final AnnotationEntry[] annotations = getAnnotationEntries(); + if (annotations != null && annotations.length > 0) { + buf.append("\nAnnotation(s):\n"); + for (final AnnotationEntry annotation : annotations) { + buf.append(indent(annotation)); + } + } + if (fields.length > 0) { + buf.append("\n").append(fields.length).append(" fields:\n"); + for (final Field field : fields) { + buf.append("\t").append(field).append('\n'); + } + } + if (methods.length > 0) { + buf.append("\n").append(methods.length).append(" methods:\n"); + for (final Method method : methods) { + buf.append("\t").append(method).append('\n'); + } + } + return buf.toString(); + } + + private static String indent(final Object obj) { + final StringTokenizer tok = new StringTokenizer(obj.toString(), "\n"); + final StringBuilder buf = new StringBuilder(); + while (tok.hasMoreTokens()) { + buf.append("\t").append(tok.nextToken()).append("\n"); + } + return buf.toString(); + } + + /** + * @return deep copy of this class + */ + public JavaClass copy() { + JavaClass c = null; + try { + c = (JavaClass) clone(); + c.constant_pool = constant_pool.copy(); + c.interfaces = interfaces.clone(); + c.interface_names = interface_names.clone(); + c.fields = new Field[fields.length]; + for (int i = 0; i < fields.length; i++) { + c.fields[i] = fields[i].copy(c.constant_pool); + } + c.methods = new Method[methods.length]; + for (int i = 0; i < methods.length; i++) { + c.methods[i] = methods[i].copy(c.constant_pool); + } + c.attributes = new Attribute[attributes.length]; + for (int i = 0; i < attributes.length; i++) { + c.attributes[i] = attributes[i].copy(c.constant_pool); + } + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return c; + } + + public final boolean isSuper() { + return (super.getAccessFlags() & Const.ACC_SUPER) != 0; + } + + public final boolean isClass() { + return (super.getAccessFlags() & Const.ACC_INTERFACE) == 0; + } + + /** + * @since 6.0 + */ + public final boolean isAnonymous() { + computeNestedTypeStatus(); + return this.isAnonymous; + } + + /** + * @since 6.0 + */ + public final boolean isNested() { + computeNestedTypeStatus(); + return this.isNested; + } + + private void computeNestedTypeStatus() { + if (computedNestedTypeStatus) { + return; + } + for (final Attribute attribute : this.attributes) { + if (attribute instanceof InnerClasses) { + final InnerClass[] innerClasses = ((InnerClasses) attribute).getInnerClasses(); + for (final InnerClass innerClasse : innerClasses) { + boolean innerClassAttributeRefersToMe = false; + String inner_class_name = constant_pool.getConstantString(innerClasse.getInnerClassIndex(), + Const.CONSTANT_Class); + inner_class_name = Utility.compactClassName(inner_class_name); + if (inner_class_name.equals(getClassName())) { + innerClassAttributeRefersToMe = true; + } + if (innerClassAttributeRefersToMe) { + this.isNested = true; + if (innerClasse.getInnerNameIndex() == 0) { + this.isAnonymous = true; + } + } + } + } + } + this.computedNestedTypeStatus = true; + } + + /** + * @return returns either HEAP (generated), FILE, or ZIP + */ + public final byte getSource() { + return source; + } + + /** + * ******************* New repository functionality ******************** + */ + /** + * Gets the ClassRepository which holds its definition. By default this is + * the same as SyntheticRepository.getInstance(); + */ + public com.sun.org.apache.bcel.internal.util.Repository getRepository() { + return repository; + } + + /** + * Sets the ClassRepository which loaded the JavaClass. Should be called + * immediately after parsing is done. + */ + public void setRepository(final com.sun.org.apache.bcel.internal.util.Repository repository) { + this.repository = repository; + } + + /** + * Equivalent to runtime "instanceof" operator. + * + * @return true if this JavaClass is derived from the super class + * @throws ClassNotFoundException if superclasses or superinterfaces of this + * object can't be found + */ + public final boolean instanceOf(final JavaClass super_class) throws ClassNotFoundException { + if (this.equals(super_class)) { + return true; + } + final JavaClass[] super_classes = getSuperClasses(); + for (final JavaClass super_classe : super_classes) { + if (super_classe.equals(super_class)) { + return true; + } + } + if (super_class.isInterface()) { + return implementationOf(super_class); + } + return false; + } + + /** + * @return true, if this class is an implementation of interface inter + * @throws ClassNotFoundException if superclasses or superinterfaces of this + * class can't be found + */ + public boolean implementationOf(final JavaClass inter) throws ClassNotFoundException { + if (!inter.isInterface()) { + throw new IllegalArgumentException(inter.getClassName() + " is no interface"); + } + if (this.equals(inter)) { + return true; + } + final JavaClass[] super_interfaces = getAllInterfaces(); + for (final JavaClass super_interface : super_interfaces) { + if (super_interface.equals(inter)) { + return true; + } + } + return false; + } + + /** + * @return the superclass for this JavaClass object, or null if this is + * java.lang.Object + * @throws ClassNotFoundException if the superclass can't be found + */ + public JavaClass getSuperClass() throws ClassNotFoundException { + if ("java.lang.Object".equals(getClassName())) { + return null; + } + return repository.loadClass(getSuperclassName()); + } + + /** + * @return list of super classes of this class in ascending order, i.e., + * java.lang.Object is always the last element + * @throws ClassNotFoundException if any of the superclasses can't be found + */ + public JavaClass[] getSuperClasses() throws ClassNotFoundException { + JavaClass clazz = this; + final List allSuperClasses = new ArrayList<>(); + for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { + allSuperClasses.add(clazz); + } + return allSuperClasses.toArray(new JavaClass[allSuperClasses.size()]); + } + + /** + * Get interfaces directly implemented by this JavaClass. + */ + public JavaClass[] getInterfaces() throws ClassNotFoundException { + final String[] _interfaces = getInterfaceNames(); + final JavaClass[] classes = new JavaClass[_interfaces.length]; + for (int i = 0; i < _interfaces.length; i++) { + classes[i] = repository.loadClass(_interfaces[i]); + } + return classes; + } + + /** + * Get all interfaces implemented by this JavaClass (transitively). + */ + public JavaClass[] getAllInterfaces() throws ClassNotFoundException { + final ClassQueue queue = new ClassQueue(); + final Set allInterfaces = new TreeSet<>(); + queue.enqueue(this); + while (!queue.empty()) { + final JavaClass clazz = queue.dequeue(); + final JavaClass souper = clazz.getSuperClass(); + final JavaClass[] _interfaces = clazz.getInterfaces(); + if (clazz.isInterface()) { + allInterfaces.add(clazz); + } else { + if (souper != null) { + queue.enqueue(souper); + } + } + for (final JavaClass _interface : _interfaces) { + queue.enqueue(_interface); + } + } + return allInterfaces.toArray(new JavaClass[allInterfaces.size()]); + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * JavaClass objects are said to be equal when their class names are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Return the natural ordering of two JavaClasses. This ordering is based on + * the class name + * + * @since 6.0 + */ + @Override + public int compareTo(final JavaClass obj) { + return getClassName().compareTo(obj.getClassName()); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the class name. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java index 55caded5352..5231d822d49 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java @@ -21,111 +21,132 @@ package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import java.io.DataInput; +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. * - * @author M. Dahm + * @version $Id: LineNumber.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see LineNumberTable */ -public final class LineNumber implements Cloneable, Node, Serializable { - private int start_pc; // Program Counter (PC) corresponds to line - private int line_number; // number in source file +public final class LineNumber implements Cloneable, Node { - /** - * Initialize from another object. - */ - public LineNumber(LineNumber c) { - this(c.getStartPC(), c.getLineNumber()); - } + /** Program Counter (PC) corresponds to line */ + private short start_pc; - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - LineNumber(DataInputStream file) throws IOException - { - this(file.readUnsignedShort(), file.readUnsignedShort()); - } + /** number in source file */ + private short line_number; - /** - * @param start_pc Program Counter (PC) corresponds to - * @param line_number line number in source file - */ - public LineNumber(int start_pc, int line_number) - { - this.start_pc = start_pc; - this.line_number = line_number; - } + /** + * Initialize from another object. + * + * @param c the object to copy + */ + public LineNumber(final LineNumber c) { + this(c.getStartPC(), c.getLineNumber()); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLineNumber(this); - } - /** - * Dump line number/pc pair to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - file.writeShort(start_pc); - file.writeShort(line_number); + /** + * Construct object from file stream. + * + * @param file Input stream + * @throws IOEXception if an I/O Exception occurs in readUnsignedShort + */ + LineNumber(final DataInput file) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } - } - /** - * @return Corresponding source line - */ - public final int getLineNumber() { return line_number; } - /** - * @return PC in code - */ - public final int getStartPC() { return start_pc; } + /** + * @param start_pc Program Counter (PC) corresponds to + * @param line_number line number in source file + */ + public LineNumber(final int start_pc, final int line_number) { + this.start_pc = (short) start_pc; + this.line_number = (short)line_number; + } - /** - * @param line_number. - */ - public final void setLineNumber(int line_number) { - this.line_number = line_number; - } - /** - * @param start_pc. - */ - public final void setStartPC(int start_pc) { - this.start_pc = start_pc; - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLineNumber(this); + } - /** - * @return String representation - */ - public final String toString() { - return "LineNumber(" + start_pc + ", " + line_number + ")"; - } - /** - * @return deep copy of this object - */ - public LineNumber copy() { - try { - return (LineNumber)clone(); - } catch(CloneNotSupportedException e) {} + /** + * Dump line number/pc pair to file stream in binary format. + * + * @param file Output file stream + * @throws IOEXception if an I/O Exception occurs in writeShort + */ + public final void dump( final DataOutputStream file ) throws IOException { + file.writeShort(start_pc); + file.writeShort(line_number); + } - return null; - } + + /** + * @return Corresponding source line + */ + public final int getLineNumber() { + return 0xffff & line_number; + } + + + /** + * @return PC in code + */ + public final int getStartPC() { + return 0xffff & start_pc; + } + + + /** + * @param line_number the source line number + */ + public final void setLineNumber( final int line_number ) { + this.line_number = (short) line_number; + } + + + /** + * @param start_pc the pc for this line number + */ + public final void setStartPC( final int start_pc ) { + this.start_pc = (short) start_pc; + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return "LineNumber(" + start_pc + ", " + line_number + ")"; + } + + + /** + * @return deep copy of this object + */ + public LineNumber copy() { + try { + return (LineNumber) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java index a05331b4c01..fee714b3dd8 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,190 +17,194 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import jdk.xml.internal.SecuritySupport; /** - * This class represents a table of line numbers for debugging - * purposes. This attribute is used by the Code attribute. It - * contains pairs of PCs and line numbers. + * This class represents a table of line numbers for debugging purposes. This + * attribute is used by the Code attribute. It contains pairs of PCs + * and line numbers. * - * @author M. Dahm - * @see Code + * @version $Id: LineNumberTable.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see Code * @see LineNumber */ public final class LineNumberTable extends Attribute { - private int line_number_table_length; - private LineNumber[] line_number_table; // Table of line/numbers pairs - /* - * 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()); - } + private static final int MAX_LINE_LENGTH = 72; + private LineNumber[] line_number_table; // Table of line/numbers pairs - /* - * @param name_index Index of name - * @param length Content length in bytes - * @param line_number_table Table of line/numbers pairs - * @param constant_pool Array of constants - */ - public LineNumberTable(int name_index, int length, - LineNumber[] line_number_table, - ConstantPool constant_pool) - { - super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); - setLineNumberTable(line_number_table); - } - /** - * Construct object from file stream. - * @param name_index Index of name - * @param length Content length in bytes - * @param file Input stream - * @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); - line_number_table_length = (file.readUnsignedShort()); - line_number_table = new LineNumber[line_number_table_length]; - - for(int i=0; i < line_number_table_length; i++) - line_number_table[i] = new LineNumber(file); - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLineNumberTable(this); - } - /** - * Dump line number table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - file.writeShort(line_number_table_length); - for(int i=0; i < line_number_table_length; i++) - line_number_table[i].dump(file); - } - - /** - * @return Array of (pc offset, line number) pairs. - */ - public final LineNumber[] getLineNumberTable() { return line_number_table; } - - /** - * @param line_number_table. - */ - public final void setLineNumberTable(LineNumber[] line_number_table) { - this.line_number_table = line_number_table; - - line_number_table_length = (line_number_table == null)? 0 : - line_number_table.length; - } - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(); - StringBuffer line = new StringBuffer(); - - for(int i=0; i < line_number_table_length; i++) { - line.append(line_number_table[i].toString()); - - if(i < line_number_table_length - 1) - line.append(", "); - - if(line.length() > 72) { - line.append('\n'); - buf.append(line); - line.setLength(0); - } + /* + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LineNumberTable(final LineNumberTable c) { + this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); } - buf.append(line); - return buf.toString(); - } - - /** - * Map byte code positions to source code lines. - * - * @param pos byte code offset - * @return corresponding line in source code - */ - public int getSourceLine(int pos) { - int l = 0, r = line_number_table_length-1; - - if(r < 0) // array is empty - return -1; - - int min_index = -1, min=-1; - - /* Do a binary search since the array is ordered. + /* + * @param name_index Index of name + * @param length Content length in bytes + * @param line_number_table Table of line/numbers pairs + * @param constant_pool Array of constants */ - do { - int i = (l + r) / 2; - int j = line_number_table[i].getStartPC(); + public LineNumberTable(final int name_index, final int length, final LineNumber[] line_number_table, + final ConstantPool constant_pool) { + super(Const.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); + this.line_number_table = line_number_table; + } - if(j == pos) - return line_number_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. + /** + * Construct object from input stream. + * + * @param name_index Index of name + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOEXception if an I/O Exception occurs in readUnsignedShort */ - if (min_index < 0) - return -1; + LineNumberTable(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, (LineNumber[]) null, constant_pool); + final int line_number_table_length = input.readUnsignedShort(); + line_number_table = new LineNumber[line_number_table_length]; + for (int i = 0; i < line_number_table_length; i++) { + line_number_table[i] = new LineNumber(input); + } + } - return line_number_table[min_index].getLineNumber(); - } + /** + * 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(final Visitor v) { + v.visitLineNumberTable(this); + } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - LineNumberTable c = (LineNumberTable)clone(); + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOEXception if an I/O Exception occurs in writeShort + */ + @Override + public final void dump(final DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(line_number_table.length); + for (final LineNumber lineNumber : line_number_table) { + lineNumber.dump(file); + } + } - c.line_number_table = new LineNumber[line_number_table_length]; - for(int i=0; i < line_number_table_length; i++) - c.line_number_table[i] = line_number_table[i].copy(); + /** + * @return Array of (pc offset, line number) pairs. + */ + public final LineNumber[] getLineNumberTable() { + return line_number_table; + } - c.constant_pool = constant_pool; - return c; - } + /** + * @param line_number_table the line number entries for this table + */ + public final void setLineNumberTable(final LineNumber[] line_number_table) { + this.line_number_table = line_number_table; + } - public final int getTableLength() { return line_number_table_length; } + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder(); + final StringBuilder line = new StringBuilder(); + + for (int i = 0; i < line_number_table.length; i++) { + line.append(line_number_table[i].toString()); + if (i < line_number_table.length - 1) { + line.append(", "); + } + if ((line.length() > MAX_LINE_LENGTH) && (i < line_number_table.length - 1)) { + line.append(SecuritySupport.NEWLINE); + 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(final int pos) { + int l = 0; + int r = line_number_table.length - 1; + if (r < 0) { + return -1; + } + int min_index = -1; + int min = -1; + /* Do a binary search since the array is ordered. + */ + do { + final int i = (l + r) / 2; + final int j = line_number_table[i].getStartPC(); + if (j == pos) { + return line_number_table[i].getLineNumber(); + } else if (pos < j) { + r = i - 1; + } else { + l = i + 1; + } + /* If exact match can't be found (which is the most common case) + * return the line number that corresponds to the greatest index less + * than pos. + */ + if (j < pos && j > min) { + min = j; + min_index = i; + } + } while (l <= r); + /* It's possible that we did not find any valid entry for the bytecode + * offset we were looking for. + */ + if (min_index < 0) { + return -1; + } + return line_number_table[min_index].getLineNumber(); + } + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool _constant_pool) { + // TODO could use the lower level constructor and thereby allow + // line_number_table to be made final + final LineNumberTable c = (LineNumberTable) clone(); + c.line_number_table = new LineNumber[line_number_table.length]; + for (int i = 0; i < line_number_table.length; i++) { + c.line_number_table[i] = line_number_table[i].copy(); + } + c.setConstantPool(_constant_pool); + return c; + } + + public final int getTableLength() { + return line_number_table == null ? 0 : line_number_table.length; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java index f33140ff3ef..bb812745d90 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,206 +20,245 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents a local variable within a method. It contains its * scope, name, signature and index on the method's frame. * - * @author M. Dahm + * @version $Id: LocalVariable.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see LocalVariableTable */ -public final class LocalVariable - implements Constants, Cloneable, Node, Serializable -{ - private int start_pc; // Range in which the variable is valid - private int length; - private int name_index; // Index in constant pool of variable name - private int signature_index; // Index of variable signature - private int index; /* Variable is `index'th local variable on - * this method's frame. - */ +public final class LocalVariable implements Cloneable, Node { - private ConstantPool constant_pool; + 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); - } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LocalVariable(final LocalVariable c) { + this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(), + c.getConstantPool()); + } - /** - * @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(Visitor v) { - v.visitLocalVariable(this); - } + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + LocalVariable(final DataInput file, final ConstantPool constant_pool) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file + .readUnsignedShort(), file.readUnsignedShort(), constant_pool); + } - /** - * 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; } + /** + * @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(final int start_pc, final int length, final int name_index, final int signature_index, final int index, + final ConstantPool constant_pool) { + this.start_pc = start_pc; + this.length = length; + this.name_index = name_index; + this.signature_index = signature_index; + this.index = index; + this.constant_pool = constant_pool; + } - /** - * @return Variable is valid within getStartPC() .. getStartPC()+getLength() - */ - public final int getLength() { return length; } - /** - * @return Variable name. - */ - public final String getName() { - ConstantUtf8 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( final Visitor v ) { + v.visitLocalVariable(this); + } - c = (ConstantUtf8)constant_pool.getConstant(name_index, CONSTANT_Utf8); - return c.getBytes(); - } - /** - * @return Index in constant pool of variable name. - */ - public final int getNameIndex() { return name_index; } + /** + * Dump local variable to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump( final DataOutputStream file ) throws IOException { + file.writeShort(start_pc); + file.writeShort(length); + file.writeShort(name_index); + file.writeShort(signature_index); + file.writeShort(index); + } - /** - * @return Signature. - */ - public final String getSignature() { - ConstantUtf8 c; - c = (ConstantUtf8)constant_pool.getConstant(signature_index, - CONSTANT_Utf8); - return c.getBytes(); - } - /** - * @return Index in constant pool of variable signature. - */ - public final int getSignatureIndex() { return signature_index; } + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } - /** - * @return index of register where variable is stored - */ - public final int getIndex() { return index; } - /** - * @return Start of range where he variable is valid - */ - public final int getStartPC() { return start_pc; } + /** + * @return Variable is valid within getStartPC() .. getStartPC()+getLength() + */ + public final int getLength() { + return length; + } - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } - /** - * @param length. - */ - public final void setLength(int length) { - this.length = length; - } + /** + * @return Variable name. + */ + public final String getName() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); + return c.getBytes(); + } - /** - * @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; - } + /** + * @return Index in constant pool of variable name. + */ + public final int getNameIndex() { + return name_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 Signature. + */ + public final String getSignature() { + ConstantUtf8 c; + c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8); + return c.getBytes(); + } - /** - * @return string representation. - */ - public final String toString() { - String name = getName(), signature = Utility.signatureToString(getSignature()); - return "LocalVariable(start_pc = " + start_pc + ", length = " + length + - ", index = " + index + ":" + signature + " " + name + ")"; - } + /** + * @return Index in constant pool of variable signature. + */ + public final int getSignatureIndex() { + return signature_index; + } - /** - * @return deep copy of this object - */ - public LocalVariable copy() { - try { - return (LocalVariable)clone(); - } catch(CloneNotSupportedException e) {} - return null; - } + /** + * @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; + } + + + /* + * Helper method shared with LocalVariableTypeTable + */ + final String toStringShared( final boolean typeTable ) { + final String name = getName(); + final String signature = Utility.signatureToString(getSignature(), false); + final String label = "LocalVariable" + (typeTable ? "Types" : "" ); + return label + "(start_pc = " + start_pc + ", length = " + length + ", index = " + + index + ":" + signature + " " + name + ")"; + } + + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool( final ConstantPool constant_pool ) { + this.constant_pool = constant_pool; + } + + + /** + * @param length the length of this local variable + */ + public final void setLength( final int length ) { + this.length = length; + } + + + /** + * @param name_index the index into the constant pool for the name of this variable + */ + public final void setNameIndex( final int name_index ) { // TODO unused + this.name_index = name_index; + } + + + /** + * @param signature_index the index into the constant pool for the signature of this variable + */ + public final void setSignatureIndex( final int signature_index ) { // TODO unused + this.signature_index = signature_index; + } + + + /** + * @param index the index in the local variable table of this variable + */ + public final void setIndex( final int index ) { // TODO unused + this.index = index; + } + + + /** + * @param start_pc Specify range where the local variable is valid. + */ + public final void setStartPC( final int start_pc ) { // TODO unused + this.start_pc = start_pc; + } + + + /** + * @return string representation. + */ + @Override + public final String toString() { + return toStringShared(false); + } + + + /** + * @return deep copy of this object + */ + public LocalVariable copy() { + try { + return (LocalVariable) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java index 88e51f662e3..01d2af1f27d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java @@ -21,143 +21,181 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents colection of local variables in a * method. This attribute is contained in the Code attribute. * - * @author M. Dahm + * @version $Id: LocalVariableTable.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Code * @see LocalVariable */ public class LocalVariableTable extends Attribute { - private int local_variable_table_length; // Table of local - private LocalVariable[] local_variable_table; // variables - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public LocalVariableTable(LocalVariableTable c) { - this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), - c.getConstantPool()); - } + private LocalVariable[] local_variable_table; // variables - /** - * @param name_index Index in constant pool to `LocalVariableTable' - * @param length Content length in bytes - * @param local_variable_table Table of local variables - * @param constant_pool Array of constants - */ - public LocalVariableTable(int name_index, int length, - LocalVariable[] local_variable_table, - ConstantPool constant_pool) - { - super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); - setLocalVariableTable(local_variable_table); - } - /** - * Construct object from file stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - LocalVariableTable(int name_index, int length, DataInputStream file, - ConstantPool constant_pool) throws IOException - { - this(name_index, length, (LocalVariable[])null, constant_pool); - - local_variable_table_length = (file.readUnsignedShort()); - local_variable_table = new LocalVariable[local_variable_table_length]; - - for(int i=0; i < local_variable_table_length; i++) - local_variable_table[i] = new LocalVariable(file, constant_pool); - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLocalVariableTable(this); - } - - /** - * Dump local variable table attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - file.writeShort(local_variable_table_length); - for(int i=0; i < local_variable_table_length; i++) - local_variable_table[i].dump(file); - } - - /** - * @return Array of local variables of method. - */ - public final LocalVariable[] getLocalVariableTable() { - return local_variable_table; - } - - /** @return first matching variable using index - */ - public final LocalVariable getLocalVariable(int index) { - for(int i=0; i < local_variable_table_length; i++) - if(local_variable_table[i].getIndex() == index) - return local_variable_table[i]; - - return null; - } - - public final void setLocalVariableTable(LocalVariable[] local_variable_table) - { - this.local_variable_table = local_variable_table; - local_variable_table_length = (local_variable_table == null)? 0 : - local_variable_table.length; - } - - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer(""); - - for(int i=0; i < local_variable_table_length; i++) { - buf.append(local_variable_table[i].toString()); - - if(i < local_variable_table_length - 1) - buf.append('\n'); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LocalVariableTable(final LocalVariableTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool()); } - return buf.toString(); - } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - LocalVariableTable c = (LocalVariableTable)clone(); + /** + * @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(final int name_index, final int length, final LocalVariable[] local_variable_table, + final ConstantPool constant_pool) { + super(Const.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); + this.local_variable_table = local_variable_table; + } - c.local_variable_table = new LocalVariable[local_variable_table_length]; - for(int i=0; i < local_variable_table_length; i++) - c.local_variable_table[i] = local_variable_table[i].copy(); - c.constant_pool = constant_pool; - return c; - } + /** + * Construct object from input stream. + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + LocalVariableTable(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, (LocalVariable[]) null, constant_pool); + final int local_variable_table_length = input.readUnsignedShort(); + local_variable_table = new LocalVariable[local_variable_table_length]; + for (int i = 0; i < local_variable_table_length; i++) { + local_variable_table[i] = new LocalVariable(input, constant_pool); + } + } - public final int getTableLength() { return local_variable_table_length; } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLocalVariableTable(this); + } + + + /** + * Dump local variable table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(local_variable_table.length); + for (final LocalVariable variable : local_variable_table) { + variable.dump(file); + } + } + + + /** + * @return Array of local variables of method. + */ + public final LocalVariable[] getLocalVariableTable() { + return local_variable_table; + } + + + /** + * + * @param index the variable slot + * + * @return the first LocalVariable that matches the slot or null if not found + * + * @deprecated since 5.2 because multiple variables can share the + * same slot, use getLocalVariable(int index, int pc) instead. + */ + @java.lang.Deprecated + public final LocalVariable getLocalVariable( final int index ) { + for (final LocalVariable variable : local_variable_table) { + if (variable.getIndex() == index) { + return variable; + } + } + return null; + } + + + /** + * + * @param index the variable slot + * @param pc the current pc that this variable is alive + * + * @return the LocalVariable that matches or null if not found + */ + public final LocalVariable getLocalVariable( final int index, final int pc ) { + for (final LocalVariable variable : local_variable_table) { + if (variable.getIndex() == index) { + final int start_pc = variable.getStartPC(); + final int end_pc = start_pc + variable.getLength(); + if ((pc >= start_pc) && (pc <= end_pc)) { + return variable; + } + } + } + return null; + } + + + public final void setLocalVariableTable( final LocalVariable[] local_variable_table ) { + this.local_variable_table = local_variable_table; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < local_variable_table.length; i++) { + buf.append(local_variable_table[i]); + if (i < local_variable_table.length - 1) { + buf.append('\n'); + } + } + return buf.toString(); + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + final LocalVariableTable c = (LocalVariableTable) clone(); + c.local_variable_table = new LocalVariable[local_variable_table.length]; + for (int i = 0; i < local_variable_table.length; i++) { + c.local_variable_table[i] = local_variable_table[i].copy(); + } + c.setConstantPool(_constant_pool); + return c; + } + + + public final int getTableLength() { + return local_variable_table == null ? 0 : local_variable_table.length; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java index 472f53a2b6f..5980b6bb139 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java @@ -2,41 +2,41 @@ * reserved comment block * DO NOT REMOVE OR ALTER! */ -package com.sun.org.apache.bcel.internal.classfile; -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ +package com.sun.org.apache.bcel.internal.classfile; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import com.sun.org.apache.bcel.internal.Const; // 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]; -// } - +// 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; @@ -50,97 +50,102 @@ import java.io.*; // } local_variable_type_table[local_variable_type_table_length]; // } // J5TODO: Needs some testing ! +/** + * @since 6.0 + */ public class LocalVariableTypeTable extends Attribute { - private static final long serialVersionUID = -1082157891095177114L; -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()); - } + private LocalVariable[] local_variable_type_table; // variables - 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(Visitor 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() { - StringBuilder buf = new StringBuilder(); - - 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'); + public LocalVariableTypeTable(final LocalVariableTypeTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool()); } - return buf.toString(); - } + public LocalVariableTypeTable(final int name_index, final int length, + final LocalVariable[] local_variable_table, final ConstantPool constant_pool) { + super(Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool); + this.local_variable_type_table = local_variable_table; + } - /** - * @return deep copy of this attribute - */ - @Override -public Attribute copy(ConstantPool constant_pool) { - LocalVariableTypeTable c = (LocalVariableTypeTable)clone(); + LocalVariableTypeTable(final int nameIdx, final int len, final DataInput input, + final ConstantPool cpool) throws IOException { + this(nameIdx, len, (LocalVariable[]) null, cpool); - 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(); + final int local_variable_type_table_length = input.readUnsignedShort(); + local_variable_type_table = new LocalVariable[local_variable_type_table_length]; - c.constant_pool = constant_pool; - return c; - } + for (int i = 0; i < local_variable_type_table_length; i++) { + local_variable_type_table[i] = new LocalVariable(input, cpool); + } + } - public final int getTableLength() { return local_variable_type_table_length; } + @Override + public void accept(final Visitor v) { + v.visitLocalVariableTypeTable(this); + } + + @Override + public final void dump(final DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(local_variable_type_table.length); + for (final LocalVariable variable : local_variable_type_table) { + variable.dump(file); + } + } + + public final LocalVariable[] getLocalVariableTypeTable() { + return local_variable_type_table; + } + + public final LocalVariable getLocalVariable(final int index) { + for (final LocalVariable variable : local_variable_type_table) { + if (variable.getIndex() == index) { + return variable; + } + } + + return null; + } + + public final void setLocalVariableTable(final LocalVariable[] local_variable_table) { + this.local_variable_type_table = local_variable_table; + } + + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder(); + + for (int i = 0; i < local_variable_type_table.length; i++) { + buf.append(local_variable_type_table[i].toStringShared(true)); + + if (i < local_variable_type_table.length - 1) { + buf.append('\n'); + } + } + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constant_pool) { + final 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.setConstantPool(constant_pool); + return c; + } + + public final int getTableLength() { + return local_variable_type_table == null ? 0 : local_variable_type_table.length; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java index dadd64c2a12..abf0d693726 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java @@ -18,178 +18,242 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; -import com.sun.org.apache.bcel.internal.Constants; +import java.io.DataInput; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.generic.Type; -import java.io.*; +import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * This class represents the method info structure, i.e., the representation - * for a method in the class. See JVM specification for details. - * A method has access flags, a name, a signature and a number of attributes. + * This class represents the method info structure, i.e., the representation for + * a method in the class. See JVM specification for details. A method has access + * flags, a name, a signature and a number of attributes. * - * @author M. Dahm + * @version $Id: Method.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class Method extends FieldOrMethod { - /** - * Empty constructor, all attributes have to be defined via `setXXX' - * methods. Use at your own risk. - */ - public Method() {} - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Method(Method c) { - super(c); - } + private static BCELComparator bcelComparator = new BCELComparator() { - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - * @throws ClassFormatException - */ - Method(DataInputStream file, ConstantPool constant_pool) - throws IOException, ClassFormatException - { - super(file, constant_pool); - } + @Override + public boolean equals(final Object o1, final Object o2) { + final Method THIS = (Method) o1; + final Method THAT = (Method) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } - /** - * @param access_flags Access rights of method - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature - * @param attributes Collection of attributes - * @param constant_pool Array of constants - */ - public Method(int access_flags, int name_index, int signature_index, - Attribute[] attributes, ConstantPool constant_pool) - { - super(access_flags, name_index, signature_index, attributes, constant_pool); - } + @Override + public int hashCode(final Object o) { + final Method THIS = (Method) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitMethod(this); - } + // annotations defined on the parameters of a method + private ParameterAnnotationEntry[] parameterAnnotationEntries; - /** - * @return Code attribute of method, if any - */ - public final Code getCode() { - for(int i=0; i < attributes_count; i++) - if(attributes[i] instanceof Code) - return (Code)attributes[i]; - - return null; - } - - /** - * @return ExceptionTable attribute of method, if any, i.e., list all - * exceptions the method may throw not exception handlers! - */ - public final ExceptionTable getExceptionTable() { - for(int i=0; i < attributes_count; i++) - if(attributes[i] instanceof ExceptionTable) - return (ExceptionTable)attributes[i]; - - return null; - } - - /** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded - * to the Code atribute. - */ - public final LocalVariableTable getLocalVariableTable() { - Code code = getCode(); - - if(code != null) - return code.getLocalVariableTable(); - else - return null; - } - - /** @return LineNumberTable of code attribute if any, i.e. the call is forwarded - * to the Code atribute. - */ - public final LineNumberTable getLineNumberTable() { - Code code = getCode(); - - if(code != null) - return code.getLineNumberTable(); - else - return null; - } - - /** - * Return string representation close to declaration format, - * `public static void _main(String[] args) throws IOException', e.g. - * - * @return String representation of the method. - */ - public final String toString() { - ConstantUtf8 c; - String name, signature, access; // Short cuts to constant pool - StringBuffer buf; - - access = Utility.accessToString(access_flags); - - // Get name and signature from constant pool - c = (ConstantUtf8)constant_pool.getConstant(signature_index, - Constants.CONSTANT_Utf8); - signature = c.getBytes(); - - c = (ConstantUtf8)constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8); - name = c.getBytes(); - - signature = Utility.methodSignatureToString(signature, name, access, true, - getLocalVariableTable()); - buf = new StringBuffer(signature); - - for(int i=0; i < attributes_count; i++) { - Attribute a = attributes[i]; - - if(!((a instanceof Code) || (a instanceof ExceptionTable))) - buf.append(" [" + a.toString() + "]"); + /** + * Empty constructor, all attributes have to be defined via `setXXX' + * methods. Use at your own risk. + */ + public Method() { } - ExceptionTable e = getExceptionTable(); - if(e != null) { - String str = e.toString(); - if(!str.equals("")) - buf.append("\n\t\tthrows " + str); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Method(final Method c) { + super(c); } - return buf.toString(); - } + /** + * Construct object from file stream. + * + * @param file Input stream + * @throws IOException + * @throws ClassFormatException + */ + Method(final DataInput file, final ConstantPool constant_pool) throws IOException, + ClassFormatException { + super(file, constant_pool); + } - /** - * @return deep copy of this method - */ - public final Method copy(ConstantPool constant_pool) { - return (Method)copy_(constant_pool); - } + /** + * @param access_flags Access rights of method + * @param name_index Points to field name in constant pool + * @param signature_index Points to encoded signature + * @param attributes Collection of attributes + * @param constant_pool Array of constants + */ + public Method(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes, + final ConstantPool constant_pool) { + super(access_flags, name_index, signature_index, attributes, constant_pool); + } - /** - * @return return type of method - */ - public Type getReturnType() { - return Type.getReturnType(getSignature()); - } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitMethod(this); + } - /** - * @return array of method argument types - */ - public Type[] getArgumentTypes() { - return Type.getArgumentTypes(getSignature()); - } + /** + * @return Code attribute of method, if any + */ + public final Code getCode() { + for (final Attribute attribute : super.getAttributes()) { + if (attribute instanceof Code) { + return (Code) attribute; + } + } + return null; + } + + /** + * @return ExceptionTable attribute of method, if any, i.e., list all + * exceptions the method may throw not exception handlers! + */ + public final ExceptionTable getExceptionTable() { + for (final Attribute attribute : super.getAttributes()) { + if (attribute instanceof ExceptionTable) { + return (ExceptionTable) attribute; + } + } + return null; + } + + /** + * @return LocalVariableTable of code attribute if any, i.e. the call is + * forwarded to the Code atribute. + */ + public final LocalVariableTable getLocalVariableTable() { + final Code code = getCode(); + if (code == null) { + return null; + } + return code.getLocalVariableTable(); + } + + /** + * @return LineNumberTable of code attribute if any, i.e. the call is + * forwarded to the Code atribute. + */ + public final LineNumberTable getLineNumberTable() { + final Code code = getCode(); + if (code == null) { + return null; + } + return code.getLineNumberTable(); + } + + /** + * Return string representation close to declaration format, e.g. + * 'public static void main(String[] args) throws IOException' + * + * @return String representation of the method. + */ + @Override + public final String toString() { + final String access = Utility.accessToString(super.getAccessFlags()); + // Get name and signature from constant pool + ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(super.getSignatureIndex(), Const.CONSTANT_Utf8); + String signature = c.getBytes(); + c = (ConstantUtf8) super.getConstantPool().getConstant(super.getNameIndex(), Const.CONSTANT_Utf8); + final String name = c.getBytes(); + signature = Utility.methodSignatureToString(signature, name, access, true, + getLocalVariableTable()); + final StringBuilder buf = new StringBuilder(signature); + for (final Attribute attribute : super.getAttributes()) { + if (!((attribute instanceof Code) || (attribute instanceof ExceptionTable))) { + buf.append(" [").append(attribute).append("]"); + } + } + final ExceptionTable e = getExceptionTable(); + if (e != null) { + final String str = e.toString(); + if (!str.isEmpty()) { + buf.append("\n\t\tthrows ").append(str); + } + } + return buf.toString(); + } + + /** + * @return deep copy of this method + */ + public final Method copy(final ConstantPool _constant_pool) { + return (Method) copy_(_constant_pool); + } + + /** + * @return return type of method + */ + public Type getReturnType() { + return Type.getReturnType(getSignature()); + } + + /** + * @return array of method argument types + */ + public Type[] getArgumentTypes() { + return Type.getArgumentTypes(getSignature()); + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * method objects are said to be equal when their names and signatures are + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the method's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } + + /** + * @return Annotations on the parameters of a method + * @since 6.0 + */ + public ParameterAnnotationEntry[] getParameterAnnotationEntries() { + if (parameterAnnotationEntries == null) { + parameterAnnotationEntries = ParameterAnnotationEntry.createParameterAnnotationEntries(getAttributes()); + } + return parameterAnnotationEntries; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java new file mode 100644 index 00000000000..d8bd8c7e78e --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java @@ -0,0 +1,120 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * Entry of the parameters table. + * + * @see + * The class File Format : The MethodParameters Attribute + * @since 6.0 + */ +public class MethodParameter implements Cloneable { + + /** Index of the CONSTANT_Utf8_info structure in the constant_pool table representing the name of the parameter */ + private int name_index; + + /** The access flags */ + private int access_flags; + + public MethodParameter() { + } + + /** + * Construct object from input stream. + * + * @param input Input stream + * @throws java.io.IOException + * @throws ClassFormatException + */ + MethodParameter(final DataInput input) throws IOException { + name_index = input.readUnsignedShort(); + access_flags = input.readUnsignedShort(); + } + + public int getNameIndex() { + return name_index; + } + + public void setNameIndex(final int name_index) { + this.name_index = name_index; + } + + /** + * Returns the name of the parameter. + */ + public String getParameterName(final ConstantPool constant_pool) { + if (name_index == 0) { + return null; + } + return ((ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8)).getBytes(); + } + + public int getAccessFlags() { + return access_flags; + } + + public void setAccessFlags(final int access_flags) { + this.access_flags = access_flags; + } + + public boolean isFinal() { + return (access_flags & Const.ACC_FINAL) != 0; + } + + public boolean isSynthetic() { + return (access_flags & Const.ACC_SYNTHETIC) != 0; + } + + public boolean isMandated() { + return (access_flags & Const.ACC_MANDATED) != 0; + } + + /** + * Dump object to file stream on binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(final DataOutputStream file) throws IOException { + file.writeShort(name_index); + file.writeShort(access_flags); + } + + /** + * @return deep copy of this object + */ + public MethodParameter copy() { + try { + return (MethodParameter) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java new file mode 100644 index 00000000000..0bab2b0b2c6 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java @@ -0,0 +1,90 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * This class represents a MethodParameters attribute. + * + * @see + * The class File Format : The MethodParameters Attribute + * @since 6.0 + */ +public class MethodParameters extends Attribute { + + private MethodParameter[] parameters = new MethodParameter[0]; + + MethodParameters(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { + super(Const.ATTR_METHOD_PARAMETERS, name_index, length, constant_pool); + + final int parameters_count = input.readUnsignedByte(); + parameters = new MethodParameter[parameters_count]; + for (int i = 0; i < parameters_count; i++) { + parameters[i] = new MethodParameter(input); + } + } + + public MethodParameter[] getParameters() { + return parameters; + } + + public void setParameters(final MethodParameter[] parameters) { + this.parameters = parameters; + } + + @Override + public void accept(final Visitor v) { + v.visitMethodParameters(this); + } + + @Override + public Attribute copy(final ConstantPool _constant_pool) { + final MethodParameters c = (MethodParameters) clone(); + c.parameters = new MethodParameter[parameters.length]; + + for (int i = 0; i < parameters.length; i++) { + c.parameters[i] = parameters[i].copy(); + } + c.setConstantPool(_constant_pool); + return c; + } + + /** + * Dump method parameters attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public void dump(final DataOutputStream file) throws IOException { + super.dump(file); + file.writeByte(parameters.length); + for (final MethodParameter parameter : parameters) { + parameter.dump(file); + } + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java index 61e1ab7e1a1..a4abba13723 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java @@ -21,12 +21,12 @@ package com.sun.org.apache.bcel.internal.classfile; - /** * Denote class to have an accept method(); * - * @author M. Dahm + * @version $Id: Node.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface Node { - public void accept(Visitor obj); + + void accept( Visitor obj ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java index ebe72756070..b3fbf8aea2c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java @@ -21,136 +21,157 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class is derived from Attribute and represents a reference - * to a PMG - * attribute. + * to a PMG attribute. * - * @author M. Dahm + * @version $Id: PMGClass.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Attribute */ public final class PMGClass extends Attribute { - private int pmg_class_index, pmg_index; - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public PMGClass(PMGClass c) { - this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(), - c.getConstantPool()); - } + private int pmg_class_index; + private int pmg_index; - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - PMGClass(int name_index, int length, DataInputStream file, - ConstantPool constant_pool) throws IOException - { - this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), - constant_pool); - } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param constant_pool Array of constants - * @param PMGClass_index Index in constant pool to CONSTANT_Utf8 - */ - public PMGClass(int name_index, int length, int pmg_index, int pmg_class_index, - ConstantPool constant_pool) - { - super(Constants.ATTR_PMG, name_index, length, constant_pool); - this.pmg_index = pmg_index; - this.pmg_class_index = pmg_class_index; - } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public PMGClass(final PMGClass c) { + this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(), c + .getConstantPool()); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - System.err.println("Visiting non-standard PMGClass object"); - } - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - file.writeShort(pmg_index); - file.writeShort(pmg_class_index); - } + /** + * Construct object from input stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + PMGClass(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, input.readUnsignedShort(), input.readUnsignedShort(), constant_pool); + } - /** - * @return Index in constant pool of source file name. - */ - public final int getPMGClassIndex() { return pmg_class_index; } - /** - * @param PMGClass_index. - */ - public final void setPMGClassIndex(int pmg_class_index) { - this.pmg_class_index = pmg_class_index; - } + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param pmg_index index in constant pool for source file name + * @param pmg_class_index Index in constant pool to CONSTANT_Utf8 + * @param constant_pool Array of constants + */ + public PMGClass(final int name_index, final int length, final int pmg_index, final int pmg_class_index, + final ConstantPool constant_pool) { + super(Const.ATTR_PMG, name_index, length, constant_pool); + this.pmg_index = pmg_index; + this.pmg_class_index = pmg_class_index; + } - /** - * @return Index in constant pool of source file name. - */ - public final int getPMGIndex() { return pmg_index; } - /** - * @param PMGClass_index. - */ - public final void setPMGIndex(int pmg_index) { - this.pmg_index = pmg_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( final Visitor v ) { + System.err.println("Visiting non-standard PMGClass object"); + } - /** - * @return PMG name. - */ - public final String getPMGName() { - ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(pmg_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } - /** - * @return PMG class name. - */ - public final String getPMGClassName() { - ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(pmg_class_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(pmg_index); + file.writeShort(pmg_class_index); + } - /** - * @return String representation - */ - public final String toString() { - return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")"; - } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - return (PMGClass)clone(); - } + /** + * @return Index in constant pool of source file name. + */ + public final int getPMGClassIndex() { + return pmg_class_index; + } + + + /** + * @param pmg_class_index + */ + public final void setPMGClassIndex( final int pmg_class_index ) { + this.pmg_class_index = pmg_class_index; + } + + + /** + * @return Index in constant pool of source file name. + */ + public final int getPMGIndex() { + return pmg_index; + } + + + /** + * @param pmg_index + */ + public final void setPMGIndex( final int pmg_index ) { + this.pmg_index = pmg_index; + } + + + /** + * @return PMG name. + */ + public final String getPMGName() { + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmg_index, + Const.CONSTANT_Utf8); + return c.getBytes(); + } + + + /** + * @return PMG class name. + */ + public final String getPMGClassName() { + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmg_class_index, + Const.CONSTANT_Utf8); + return c.getBytes(); + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")"; + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + return (Attribute) clone(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java new file mode 100644 index 00000000000..40beccd1834 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java @@ -0,0 +1,95 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * represents one parameter annotation in the parameter annotation table + * + * @version $Id: ParameterAnnotationEntry + * @since 6.0 + */ +public class ParameterAnnotationEntry implements Node { + + private final AnnotationEntry[] annotation_table; + + + /** + * Construct object from input stream. + * + * @param input Input stream + * @throws IOException + */ + ParameterAnnotationEntry(final DataInput input, final ConstantPool constant_pool) throws IOException { + final int annotation_table_length = input.readUnsignedShort(); + annotation_table = new AnnotationEntry[annotation_table_length]; + for (int i = 0; i < annotation_table_length; i++) { + // TODO isRuntimeVisible + annotation_table[i] = AnnotationEntry.read(input, constant_pool, 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( final Visitor v ) { + v.visitParameterAnnotationEntry(this); + } + + /** + * returns the array of annotation entries in this annotation + */ + public AnnotationEntry[] getAnnotationEntries() { + return annotation_table; + } + + public void dump(final DataOutputStream dos) throws IOException { + dos.writeShort(annotation_table.length); + for (final AnnotationEntry entry : annotation_table) { + entry.dump(dos); + } + } + + public static ParameterAnnotationEntry[] createParameterAnnotationEntries(final Attribute[] attrs) { + // Find attributes that contain parameter annotation data + final List accumulatedAnnotations = new ArrayList<>(attrs.length); + for (final Attribute attribute : attrs) { + if (attribute instanceof ParameterAnnotations) { + final ParameterAnnotations runtimeAnnotations = (ParameterAnnotations)attribute; + Collections.addAll(accumulatedAnnotations, runtimeAnnotations.getParameterAnnotationEntries()); + } + } + return accumulatedAnnotations.toArray(new ParameterAnnotationEntry[accumulatedAnnotations.size()]); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java new file mode 100644 index 00000000000..6baf6b7a379 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java @@ -0,0 +1,127 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * base class for parameter annotations + * + * @version $Id: ParameterAnnotations + * @since 6.0 + */ +public abstract class ParameterAnnotations extends Attribute { + + /** Table of parameter annotations */ + private ParameterAnnotationEntry[] parameter_annotation_table; + + /** + * @param parameter_annotation_type the subclass type of the parameter annotation + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + */ + ParameterAnnotations(final byte parameter_annotation_type, final int name_index, final int length, + final DataInput input, final ConstantPool constant_pool) throws IOException { + this(parameter_annotation_type, name_index, length, (ParameterAnnotationEntry[]) null, + constant_pool); + final int num_parameters = input.readUnsignedByte(); + parameter_annotation_table = new ParameterAnnotationEntry[num_parameters]; + for (int i = 0; i < num_parameters; i++) { + parameter_annotation_table[i] = new ParameterAnnotationEntry(input, constant_pool); + } + } + + + /** + * @param parameter_annotation_type the subclass type of the parameter annotation + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param parameter_annotation_table the actual parameter annotations + * @param constant_pool Array of constants + */ + public ParameterAnnotations(final byte parameter_annotation_type, final int name_index, final int length, + final ParameterAnnotationEntry[] parameter_annotation_table, final ConstantPool constant_pool) { + super(parameter_annotation_type, name_index, length, constant_pool); + this.parameter_annotation_table = parameter_annotation_table; + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitParameterAnnotation(this); + } + + + /** + * @param parameter_annotation_table the entries to set in this parameter annotation + */ + public final void setParameterAnnotationTable(final ParameterAnnotationEntry[] parameter_annotation_table ) { + this.parameter_annotation_table = parameter_annotation_table; + } + + + /** + * @return the parameter annotation entry table + */ + public final ParameterAnnotationEntry[] getParameterAnnotationTable() { + return parameter_annotation_table; + } + + + /** + * returns the array of parameter annotation entries in this parameter annotation + */ + public ParameterAnnotationEntry[] getParameterAnnotationEntries() { + return parameter_annotation_table; + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + super.dump(dos); + dos.writeByte(parameter_annotation_table.length); + + for (final ParameterAnnotationEntry element : parameter_annotation_table) { + element.dump(dos); + } + + } + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool constant_pool ) { + return (Attribute) clone(); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleAnnotations.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleAnnotations.java new file mode 100644 index 00000000000..708fcab0dc9 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleAnnotations.java @@ -0,0 +1,70 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * represents an annotation that is represented in the class file but is not + * provided to the JVM. + * + * @version $Id: RuntimeInvisibleAnnotations + * @since 6.0 + */ +public class RuntimeInvisibleAnnotations extends Annotations +{ + /** + * @param name_index + * Index pointing to the name Code + * @param length + * Content length in bytes + * @param input + * Input stream + * @param constant_pool + * Array of constants + */ + public RuntimeInvisibleAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException + { + super(Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS, name_index, length, input, constant_pool, false); + } + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constant_pool) + { + return (Attribute) clone(); + } + + @Override + public final void dump(final DataOutputStream dos) throws IOException + { + super.dump(dos); + writeAnnotations(dos); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleParameterAnnotations.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleParameterAnnotations.java new file mode 100644 index 00000000000..7a785c64f2a --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleParameterAnnotations.java @@ -0,0 +1,48 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * Represents a parameter annotation that is represented in the class file + * but is not provided to the JVM. + * + * @version $Id: RuntimeInvisibleParameterAnnotations + * @since 6.0 + */ +public class RuntimeInvisibleParameterAnnotations extends ParameterAnnotations { + + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + */ + public RuntimeInvisibleParameterAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + super(Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, name_index, length, input, constant_pool); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleAnnotations.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleAnnotations.java new file mode 100644 index 00000000000..38a27676879 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleAnnotations.java @@ -0,0 +1,69 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * represents an annotation that is represented in the class file and is + * provided to the JVM. + * + * @version $Id: RuntimeVisibleAnnotations + * @since 6.0 + */ +public class RuntimeVisibleAnnotations extends Annotations +{ + /** + * @param name_index + * Index pointing to the name Code + * @param length + * Content length in bytes + * @param input + * Input stream + * @param constant_pool + * Array of constants + */ + public RuntimeVisibleAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException + { + super(Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS, name_index, length, input, constant_pool, true); + } + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constant_pool) + { + return (Attribute) clone(); + } + + @Override + public final void dump(final DataOutputStream dos) throws IOException + { + super.dump(dos); + writeAnnotations(dos); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleParameterAnnotations.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleParameterAnnotations.java new file mode 100644 index 00000000000..19cc8c5ab44 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleParameterAnnotations.java @@ -0,0 +1,48 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataInput; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * Represents a parameter annotation that is represented in the class file + * and is provided to the JVM. + * + * @version $Id: RuntimeVisibleParameterAnnotations + * @since 6.0 + */ +public class RuntimeVisibleParameterAnnotations extends ParameterAnnotations { + + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + */ + public RuntimeVisibleParameterAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + super(Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, name_index, length, input, constant_pool); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java index 60bb1ca779e..a0dc33b4321 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java @@ -21,243 +21,254 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.ByteArrayInputStream; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class is derived from Attribute and represents a reference - * to a GJ attribute. + * to a GJ attribute. * - * @author M. Dahm + * @version $Id: Signature.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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()); - } + private int signature_index; - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Signature(int name_index, int length, DataInputStream file, - ConstantPool constant_pool) throws IOException - { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } - /** - * @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 - */ - public void accept(Visitor v) { - System.err.println("Visiting non-standard Signature object"); - v.visitSignature(this); - } - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - 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)constant_pool.getConstant(signature_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } - - /** - * Extends ByteArrayInputStream to make 'unreading' chars possible. - */ - private static final class MyByteArrayInputStream extends ByteArrayInputStream { - 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 boolean identPart(int ch) { - return ch == '/' || ch == ';'; - } - - 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; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Signature(final Signature c) { + this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); } - StringBuffer buf2 = new StringBuffer(); - ch = in.read(); - do { - buf2.append((char)ch); - ch = in.read(); - //System.out.println("within ident:"+ (char)ch); + /** + * Construct object from file stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Signature(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, input.readUnsignedShort(), constant_pool); + } - } while((ch != -1) && (Character.isJavaIdentifierPart((char)ch) || (ch == '/'))); - buf.append(buf2.toString().replace('/', '.')); + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param signature_index Index in constant pool to CONSTANT_Utf8 + * @param constant_pool Array of constants + */ + public Signature(final int name_index, final int length, final int signature_index, final ConstantPool constant_pool) { + super(Const.ATTR_SIGNATURE, name_index, length, constant_pool); + this.signature_index = signature_index; + } - //System.out.println("regular return ident:"+ (char)ch + ":" + buf2); - if(ch != -1) - in.unread(); - } + /** + * 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( final Visitor v ) { + //System.err.println("Visiting non-standard Signature object"); + v.visitSignature(this); + } - private static final void matchGJIdent(MyByteArrayInputStream in, - StringBuffer buf) - { - int ch; - matchIdent(in, buf); + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(signature_index); + } - 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"); + /** + * @return Index in constant pool of source file name. + */ + public final int getSignatureIndex() { + return signature_index; + } - //System.out.println("Still no >"); - buf.append(", "); - in.unread(); - matchGJIdent(in, buf); // Recursive call - } - //System.out.println("Exit >"); + /** + * @param signature_index the index info the constant pool of this signature + */ + public final void setSignatureIndex( final int signature_index ) { + this.signature_index = signature_index; + } - buf.append((char)ch); - } else - in.unread(); - ch = in.read(); - if(identStart(ch)) { - in.unread(); - matchGJIdent(in, buf); - } else if(ch == ')') { - in.unread(); - return; - } else if(ch != ';') - throw new RuntimeException("Illegal signature: " + in.getData() + " read " + - (char)ch); - } + /** + * @return GJ signature. + */ + public final String getSignature() { + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(signature_index, + Const.CONSTANT_Utf8); + return c.getBytes(); + } - public static String translate(String s) { - //System.out.println("Sig:" + s); - StringBuffer buf = new StringBuffer(); + /** + * Extends ByteArrayInputStream to make 'unreading' chars possible. + */ + private static final class MyByteArrayInputStream extends ByteArrayInputStream { - matchGJIdent(new MyByteArrayInputStream(s), buf); + MyByteArrayInputStream(final String data) { + super(data.getBytes()); + } - return buf.toString(); - } - public static final boolean isFormalParameterList(String s) { - return s.startsWith("<") && (s.indexOf(':') > 0); - } + final String getData() { + return new String(buf); + } - public static final boolean isActualParameterList(String s) { - return s.startsWith("L") && s.endsWith(">;"); - } - /** - * @return String representation - */ - public final String toString() { - String s = getSignature(); + final void unread() { + if (pos > 0) { + pos--; + } + } + } - return "Signature(" + s + ")"; - } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - return (Signature)clone(); - } + private static boolean identStart( final int ch ) { + return ch == 'T' || ch == 'L'; + } + + + private static void matchIdent( final MyByteArrayInputStream in, final StringBuilder 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)) { + final StringBuilder buf2 = new StringBuilder(); + 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; + } + final StringBuilder buf2 = new StringBuilder(); + 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 void matchGJIdent( final MyByteArrayInputStream in, final StringBuilder 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( final String s ) { + //System.out.println("Sig:" + s); + final StringBuilder buf = new StringBuilder(); + matchGJIdent(new MyByteArrayInputStream(s), buf); + return buf.toString(); + } + + + // @since 6.0 is no longer final + public static boolean isFormalParameterList( final String s ) { + return s.startsWith("<") && (s.indexOf(':') > 0); + } + + + // @since 6.0 is no longer final + public static boolean isActualParameterList( final String s ) { + return s.startsWith("L") && s.endsWith(">;"); + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + final String s = getSignature(); + return "Signature: " + s; + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + return (Attribute) clone(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java new file mode 100644 index 00000000000..24efbc34d95 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java @@ -0,0 +1,229 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * @since 6.0 + */ +public class SimpleElementValue extends ElementValue +{ + private int index; + + public SimpleElementValue(final int type, final int index, final ConstantPool cpool) + { + super(type, cpool); + this.index = index; + } + + /** + * @return Value entry index in the cpool + */ + public int getIndex() + { + return index; + } + + public void setIndex(final int index) + { + this.index = index; + } + + public String getValueString() + { + if (super.getType() != STRING) { + throw new RuntimeException( + "Dont call getValueString() on a non STRING ElementValue"); + } + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(getIndex(), + Const.CONSTANT_Utf8); + return c.getBytes(); + } + + public int getValueInt() + { + if (super.getType() != PRIMITIVE_INT) { + throw new RuntimeException( + "Dont call getValueString() on a non STRING ElementValue"); + } + final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), + Const.CONSTANT_Integer); + return c.getBytes(); + } + + public byte getValueByte() + { + if (super.getType() != PRIMITIVE_BYTE) { + throw new RuntimeException( + "Dont call getValueByte() on a non BYTE ElementValue"); + } + final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), + Const.CONSTANT_Integer); + return (byte) c.getBytes(); + } + + public char getValueChar() + { + if (super.getType() != PRIMITIVE_CHAR) { + throw new RuntimeException( + "Dont call getValueChar() on a non CHAR ElementValue"); + } + final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), + Const.CONSTANT_Integer); + return (char) c.getBytes(); + } + + public long getValueLong() + { + if (super.getType() != PRIMITIVE_LONG) { + throw new RuntimeException( + "Dont call getValueLong() on a non LONG ElementValue"); + } + final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex()); + return j.getBytes(); + } + + public float getValueFloat() + { + if (super.getType() != PRIMITIVE_FLOAT) { + throw new RuntimeException( + "Dont call getValueFloat() on a non FLOAT ElementValue"); + } + final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex()); + return f.getBytes(); + } + + public double getValueDouble() + { + if (super.getType() != PRIMITIVE_DOUBLE) { + throw new RuntimeException( + "Dont call getValueDouble() on a non DOUBLE ElementValue"); + } + final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex()); + return d.getBytes(); + } + + public boolean getValueBoolean() + { + if (super.getType() != PRIMITIVE_BOOLEAN) { + throw new RuntimeException( + "Dont call getValueBoolean() on a non BOOLEAN ElementValue"); + } + final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); + return bo.getBytes() != 0; + } + + public short getValueShort() + { + if (super.getType() != PRIMITIVE_SHORT) { + throw new RuntimeException( + "Dont call getValueShort() on a non SHORT ElementValue"); + } + final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); + return (short) s.getBytes(); + } + + @Override + public String toString() + { + return stringifyValue(); + } + + // Whatever kind of value it is, return it as a string + @Override + public String stringifyValue() + { + final ConstantPool cpool = super.getConstantPool(); + final int _type = super.getType(); + switch (_type) + { + case PRIMITIVE_INT: + final ConstantInteger c = (ConstantInteger) cpool.getConstant(getIndex(), + Const.CONSTANT_Integer); + return Integer.toString(c.getBytes()); + case PRIMITIVE_LONG: + final ConstantLong j = (ConstantLong) cpool.getConstant(getIndex(), + Const.CONSTANT_Long); + return Long.toString(j.getBytes()); + case PRIMITIVE_DOUBLE: + final ConstantDouble d = (ConstantDouble) cpool.getConstant(getIndex(), + Const.CONSTANT_Double); + return Double.toString(d.getBytes()); + case PRIMITIVE_FLOAT: + final ConstantFloat f = (ConstantFloat) cpool.getConstant(getIndex(), + Const.CONSTANT_Float); + return Float.toString(f.getBytes()); + case PRIMITIVE_SHORT: + final ConstantInteger s = (ConstantInteger) cpool.getConstant(getIndex(), + Const.CONSTANT_Integer); + return Integer.toString(s.getBytes()); + case PRIMITIVE_BYTE: + final ConstantInteger b = (ConstantInteger) cpool.getConstant(getIndex(), + Const.CONSTANT_Integer); + return Integer.toString(b.getBytes()); + case PRIMITIVE_CHAR: + final ConstantInteger ch = (ConstantInteger) cpool.getConstant( + getIndex(), Const.CONSTANT_Integer); + return String.valueOf((char)ch.getBytes()); + case PRIMITIVE_BOOLEAN: + final ConstantInteger bo = (ConstantInteger) cpool.getConstant( + getIndex(), Const.CONSTANT_Integer); + if (bo.getBytes() == 0) { + return "false"; + } + return "true"; + case STRING: + final ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(getIndex(), + Const.CONSTANT_Utf8); + return cu8.getBytes(); + default: + throw new RuntimeException("SimpleElementValue class does not know how to stringify type " + _type); + } + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + final int _type = super.getType(); + 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(getIndex()); + break; + default: + throw new RuntimeException("SimpleElementValue doesnt know how to write out type " + _type); + } + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java index 4942152a5e6..cd79198c3a7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java @@ -21,9 +21,11 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class is derived from Attribute and represents a reference @@ -31,110 +33,122 @@ import java.io.*; * should appear per classfile. The intention of this class is that it is * instantiated from the Attribute.readAttribute() method. * - * @author M. Dahm + * @version $Id: SourceFile.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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()); - } + private int sourcefile_index; - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - SourceFile(int name_index, int length, DataInputStream file, - ConstantPool constant_pool) throws IOException - { - this(name_index, length, file.readUnsignedShort(), constant_pool); - } - /** - * @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; - } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public SourceFile(final SourceFile c) { + this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool()); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitSourceFile(this); - } - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - file.writeShort(sourcefile_index); - } + /** + * Construct object from input stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + SourceFile(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, input.readUnsignedShort(), constant_pool); + } - /** - * @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; - } + /** + * @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(final int name_index, final int length, final int sourcefile_index, final ConstantPool constant_pool) { + super(Const.ATTR_SOURCE_FILE, name_index, length, constant_pool); + this.sourcefile_index = sourcefile_index; + } - /** - * @return Source file name. - */ - public final String getSourceFileName() { - ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(sourcefile_index, - Constants.CONSTANT_Utf8); - return c.getBytes(); - } - /** - * @return String representation - */ - public final String toString() { - return "SourceFile(" + getSourceFileName() + ")"; - } + /** + * 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( final Visitor v ) { + v.visitSourceFile(this); + } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - return (SourceFile)clone(); - } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final 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( final int sourcefile_index ) { + this.sourcefile_index = sourcefile_index; + } + + + /** + * @return Source file name. + */ + public final String getSourceFileName() { + final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(sourcefile_index, + Const.CONSTANT_Utf8); + return c.getBytes(); + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return "SourceFile: " + getSourceFileName(); + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + return (Attribute) clone(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java index 01106aa207d..de4d97c808e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java @@ -21,9 +21,11 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents a stack map attribute used for @@ -34,119 +36,130 @@ import java.io.*; * within the Code attribute of a method. See CLDC specification * 5.3.1.2 * - * @author M. Dahm + * @version $Id: StackMap.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Code * @see StackMapEntry * @see StackMapType */ -public final class StackMap extends Attribute implements Node { - private int map_length; - private StackMapEntry[] map; // Table of stack map entries +public final class StackMap extends Attribute { - /* - * @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); + private StackMapEntry[] map; // Table of stack map entries - 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 - */ - 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. - */ - 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(", "); + /* + * @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(final int name_index, final int length, final StackMapEntry[] map, final ConstantPool constant_pool) { + super(Const.ATTR_STACK_MAP, name_index, length, constant_pool); + this.map = map; } - buf.append(')'); - return buf.toString(); - } + /** + * Construct object from input stream. + * + * @param name_index Index of name + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + StackMap(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { + this(name_index, length, (StackMapEntry[]) null, constant_pool); + final int map_length = input.readUnsignedShort(); + map = new StackMapEntry[map_length]; + for (int i = 0; i < map_length; i++) { + map[i] = new StackMapEntry(input, constant_pool); + } + } - /** - * @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(); + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + file.writeShort(map.length); + for (final StackMapEntry entry : map) { + entry.dump(file); + } + } - c.constant_pool = constant_pool; - return c; - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackMap(this); - } + /** + * @return Array of stack map entries + */ + public final StackMapEntry[] getStackMap() { + return map; + } - public final int getMapLength() { return map_length; } + + /** + * @param map Array of stack map entries + */ + public final void setStackMap( final StackMapEntry[] map ) { + this.map = map; + int len = 2; // Length of 'number_of_entries' field prior to the array of stack maps + for (final StackMapEntry element : map) { + len += element.getMapEntrySize(); + } + setLength(len); + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder("StackMap("); + for (int i = 0; i < map.length; i++) { + buf.append(map[i]); + if (i < map.length - 1) { + buf.append(", "); + } + } + buf.append(')'); + return buf.toString(); + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + final 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.setConstantPool(_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( final Visitor v ) { + v.visitStackMap(this); + } + + + public final int getMapLength() { + return map == null ? 0 : map.length; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java index 8d09356d8cb..b388315e0e9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java @@ -21,156 +21,420 @@ package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import com.sun.org.apache.bcel.internal.Const; /** * 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 * - * @author M. Dahm + * @version $Id: StackMapEntry.java 1750029 2016-06-23 22:14:38Z sebb $ * @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; +public final class StackMapEntry implements Node, Cloneable +{ - /** - * 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); + private int frame_type; + private int byte_code_offset; + private StackMapType[] types_of_locals; + private StackMapType[] types_of_stack_items; + private ConstantPool constant_pool; - types_of_locals = new StackMapType[number_of_locals]; - for(int i=0; i < number_of_locals; i++) - types_of_locals[i] = new StackMapType(file, constant_pool); - number_of_stack_items = file.readShort(); - types_of_stack_items = new StackMapType[number_of_stack_items]; - for(int i=0; i < number_of_stack_items; i++) - types_of_stack_items[i] = new StackMapType(file, constant_pool); - } + /** + * Construct object from input stream. + * + * @param input Input stream + * @throws IOException + */ + StackMapEntry(final DataInput input, final ConstantPool constant_pool) throws IOException { + this(input.readByte() & 0xFF, -1, null, null, 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 (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + byte_code_offset = frame_type - Const.SAME_FRAME; + } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + byte_code_offset = frame_type - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; + types_of_stack_items = new StackMapType[1]; + types_of_stack_items[0] = new StackMapType(input, constant_pool); + } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + byte_code_offset = input.readShort(); + types_of_stack_items = new StackMapType[1]; + types_of_stack_items[0] = new StackMapType(input, constant_pool); + } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { + byte_code_offset = input.readShort(); + } else if (frame_type == Const.SAME_FRAME_EXTENDED) { + byte_code_offset = input.readShort(); + } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { + byte_code_offset = input.readShort(); + final int number_of_locals = frame_type - 251; + types_of_locals = new StackMapType[number_of_locals]; + for (int i = 0; i < number_of_locals; i++) { + types_of_locals[i] = new StackMapType(input, constant_pool); + } + } else if (frame_type == Const.FULL_FRAME) { + byte_code_offset = input.readShort(); + final int number_of_locals = input.readShort(); + types_of_locals = new StackMapType[number_of_locals]; + for (int i = 0; i < number_of_locals; i++) { + types_of_locals[i] = new StackMapType(input, constant_pool); + } + final int number_of_stack_items = input.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(input, constant_pool); + } + } else { + /* Can't happen */ + throw new ClassFormatException ("Invalid frame type found while parsing stack map table: " + frame_type); + } } - 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("}"); + /** + * DO NOT USE + * + * @param byte_code_offset + * @param number_of_locals NOT USED + * @param types_of_locals array of {@link StackMapType}s of locals + * @param number_of_stack_items NOT USED + * @param types_of_stack_items array ot {@link StackMapType}s of stack items + * @param constant_pool the constant pool + * @deprecated Since 6.0, use {@link #StackMapEntry(int, int, StackMapType[], StackMapType[], ConstantPool)} + * instead + */ + @java.lang.Deprecated + public StackMapEntry(final int byte_code_offset, final int number_of_locals, + final StackMapType[] types_of_locals, final int number_of_stack_items, + final StackMapType[] types_of_stack_items, final ConstantPool constant_pool) { + this.byte_code_offset = byte_code_offset; + this.types_of_locals = types_of_locals != null ? types_of_locals : new StackMapType[0]; + this.types_of_stack_items = types_of_stack_items != null ? types_of_stack_items : new StackMapType[0]; + this.constant_pool = constant_pool; } - buf.append(")"); - - return buf.toString(); - } + /** + * Create an instance + * + * @param tag the frame_type to use + * @param byte_code_offset + * @param types_of_locals array of {@link StackMapType}s of locals + * @param types_of_stack_items array ot {@link StackMapType}s of stack items + * @param constant_pool the constant pool + */ + public StackMapEntry(final int tag, final int byte_code_offset, + final StackMapType[] types_of_locals, + final StackMapType[] types_of_stack_items, final ConstantPool constant_pool) { + this.frame_type = tag; + this.byte_code_offset = byte_code_offset; + this.types_of_locals = types_of_locals != null ? types_of_locals : new StackMapType[0]; + this.types_of_stack_items = types_of_stack_items != null ? types_of_stack_items : new StackMapType[0]; + this.constant_pool = constant_pool; + } - 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; } + /** + * Dump stack map entry + * + * @param file Output file stream + * @throws IOException + */ + public final void dump( final DataOutputStream file ) throws IOException { + file.write(frame_type); + if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + // nothing to be done + } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + types_of_stack_items[0].dump(file); + } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + file.writeShort(byte_code_offset); + types_of_stack_items[0].dump(file); + } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { + file.writeShort(byte_code_offset); + } else if (frame_type == Const.SAME_FRAME_EXTENDED) { + file.writeShort(byte_code_offset); + } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { + file.writeShort(byte_code_offset); + for (final StackMapType type : types_of_locals) { + type.dump(file); + } + } else if (frame_type == Const.FULL_FRAME) { + file.writeShort(byte_code_offset); + file.writeShort(types_of_locals.length); + for (final StackMapType type : types_of_locals) { + type.dump(file); + } + file.writeShort(types_of_stack_items.length); + for (final StackMapType type : types_of_stack_items) { + type.dump(file); + } + } else { + /* Can't happen */ + throw new ClassFormatException ("Invalid Stack map table tag: " + frame_type); + } + } - /** - * @return deep copy of this object - */ - public StackMapEntry copy() { - try { - return (StackMapEntry)clone(); - } catch(CloneNotSupportedException e) {} - return null; - } + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder(64); + buf.append("("); + if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + buf.append("SAME"); + } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + buf.append("SAME_LOCALS_1_STACK"); + } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + buf.append("SAME_LOCALS_1_STACK_EXTENDED"); + } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { + buf.append("CHOP ").append(String.valueOf(251-frame_type)); + } else if (frame_type == Const.SAME_FRAME_EXTENDED) { + buf.append("SAME_EXTENDED"); + } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { + buf.append("APPEND ").append(String.valueOf(frame_type-251)); + } else if (frame_type == Const.FULL_FRAME) { + buf.append("FULL"); + } else { + buf.append("UNKNOWN (").append(frame_type).append(")"); + } + buf.append(", offset delta=").append(byte_code_offset); + if (types_of_locals.length > 0) { + buf.append(", locals={"); + for (int i = 0; i < types_of_locals.length; i++) { + buf.append(types_of_locals[i]); + if (i < types_of_locals.length - 1) { + buf.append(", "); + } + } + buf.append("}"); + } + if (types_of_stack_items.length > 0) { + buf.append(", stack items={"); + for (int i = 0; i < types_of_stack_items.length; i++) { + buf.append(types_of_stack_items[i]); + if (i < types_of_stack_items.length - 1) { + buf.append(", "); + } + } + buf.append("}"); + } + buf.append(")"); + return buf.toString(); + } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackMapEntry(this); - } - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { return constant_pool; } + /** + * Calculate stack map entry size + * + */ + int getMapEntrySize() { + if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + return 1; + } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + return 1 + (types_of_stack_items[0].hasIndex() ? 3 : 1); + } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + return 3 + (types_of_stack_items[0].hasIndex() ? 3 : 1); + } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { + return 3; + } else if (frame_type == Const.SAME_FRAME_EXTENDED) { + return 3; + } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { + int len = 3; + for (final StackMapType types_of_local : types_of_locals) { + len += types_of_local.hasIndex() ? 3 : 1; + } + return len; + } else if (frame_type == Const.FULL_FRAME) { + int len = 7; + for (final StackMapType types_of_local : types_of_locals) { + len += types_of_local.hasIndex() ? 3 : 1; + } + for (final StackMapType types_of_stack_item : types_of_stack_items) { + len += types_of_stack_item.hasIndex() ? 3 : 1; + } + return len; + } else { + throw new RuntimeException("Invalid StackMap frame_type: " + frame_type); + } + } - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } + + public void setFrameType( final int f ) { + if (f >= Const.SAME_FRAME && f <= Const.SAME_FRAME_MAX) { + byte_code_offset = f - Const.SAME_FRAME; + } else if (f >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + f <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + byte_code_offset = f - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; + } else if (f == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock + } else if (f >= Const.CHOP_FRAME && f <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock + } else if (f == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock + } else if (f >= Const.APPEND_FRAME && f <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock + } else if (f == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock + } else { + throw new RuntimeException("Invalid StackMap frame_type"); + } + frame_type = f; + } + + + public int getFrameType() { + return frame_type; + } + + + public void setByteCodeOffset( final int new_offset ) { + if (new_offset < 0 || new_offset > 32767) { + throw new RuntimeException("Invalid StackMap offset: " + new_offset); + } + + if (frame_type >= Const.SAME_FRAME && + frame_type <= Const.SAME_FRAME_MAX) { + if (new_offset > Const.SAME_FRAME_MAX) { + frame_type = Const.SAME_FRAME_EXTENDED; + } else { + frame_type = new_offset; + } + } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + if (new_offset > Const.SAME_FRAME_MAX) { + frame_type = Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED; + } else { + frame_type = Const.SAME_LOCALS_1_STACK_ITEM_FRAME + new_offset; + } + } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frame_type >= Const.CHOP_FRAME && + frame_type <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frame_type == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frame_type >= Const.APPEND_FRAME && + frame_type <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock + } else if (frame_type == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock + } else { + throw new RuntimeException("Invalid StackMap frame_type: " + frame_type); + } + byte_code_offset = new_offset; + } + + + /** + * Update the distance (as an offset delta) from this StackMap + * entry to the next. Note that this might cause the the + * frame type to change. Note also that delta may be negative. + * + * @param delta offset delta + */ + public void updateByteCodeOffset(final int delta) { + setByteCodeOffset(byte_code_offset + delta); + } + + + public int getByteCodeOffset() { + return byte_code_offset; + } + + + /** + * + * @deprecated since 6.0 + */ + @java.lang.Deprecated + public void setNumberOfLocals( final int n ) { // TODO unused + } + + + public int getNumberOfLocals() { + return types_of_locals.length; + } + + + public void setTypesOfLocals( final StackMapType[] types ) { + types_of_locals = types != null ? types : new StackMapType[0]; + } + + + public StackMapType[] getTypesOfLocals() { + return types_of_locals; + } + + + /** + * + * @deprecated since 6.0 + */ + @java.lang.Deprecated + public void setNumberOfStackItems( final int n ) { // TODO unused + } + + + public int getNumberOfStackItems() { + return types_of_stack_items.length; + } + + + public void setTypesOfStackItems( final StackMapType[] types ) { + types_of_stack_items = types != null ? types : new StackMapType[0]; + } + + + public StackMapType[] getTypesOfStackItems() { + return types_of_stack_items; + } + + + /** + * @return deep copy of this object + */ + public StackMapEntry copy() { + StackMapEntry e; + try { + e = (StackMapEntry) clone(); + } catch (final CloneNotSupportedException ex) { + throw new Error("Clone Not Supported"); + } + + e.types_of_locals = new StackMapType[types_of_locals.length]; + for (int i = 0; i < types_of_locals.length; i++) { + e.types_of_locals[i] = types_of_locals[i].copy(); + } + e.types_of_stack_items = new StackMapType[types_of_stack_items.length]; + for (int i = 0; i < types_of_stack_items.length; i++) { + e.types_of_stack_items[i] = types_of_stack_items[i].copy(); + } + return e; + } + + + /** + * 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( final Visitor v ) { + v.visitStackMapEntry(this); + } + + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } + + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool( final ConstantPool constant_pool ) { + this.constant_pool = constant_pool; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java index f57fba91d12..2ce5c32f67d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java @@ -21,119 +21,151 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents the type of a local variable or item on stack * used in the StackMap entries. * - * @author M. Dahm + * @version $Id: StackMapType.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see StackMapEntry * @see StackMap - * @see Constants + * @see Const */ 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); + private byte type; + private int index = -1; // Index to CONSTANT_Class or offset + private ConstantPool constant_pool; - if(hasIndex()) - setIndex(file.readShort()); - setConstantPool(constant_pool); - } + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + StackMapType(final DataInput file, final ConstantPool constant_pool) throws IOException { + this(file.readByte(), -1, constant_pool); + if (hasIndex()) { + this.index = file.readShort(); + } + this.constant_pool = constant_pool; + } - /** - * @param type type tag as defined in the Constants interface - * @param index index to constant pool, or byte code offset - */ - public StackMapType(byte type, int index, ConstantPool constant_pool) { - setType(type); - setIndex(index); - setConstantPool(constant_pool); - } - public void setType(byte t) { - if((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) - throw new RuntimeException("Illegal type for StackMapType: " + t); - type = t; - } + /** + * @param type type tag as defined in the Constants interface + * @param index index to constant pool, or byte code offset + */ + public StackMapType(final byte type, final int index, final ConstantPool constant_pool) { + if ((type < Const.ITEM_Bogus) || (type > Const.ITEM_NewObject)) { + throw new RuntimeException("Illegal type for StackMapType: " + type); + } + this.type = type; + this.index = index; + this.constant_pool = constant_pool; + } - 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; } + public void setType( final byte t ) { + if ((t < Const.ITEM_Bogus) || (t > Const.ITEM_NewObject)) { + throw new RuntimeException("Illegal type for StackMapType: " + t); + } + type = t; + } - /** - * 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)); - } + public byte getType() { + return type; + } - 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() + ")"; - } + public void setIndex( final int t ) { + index = t; + } - /** - * @return deep copy of this object - */ - public StackMapType copy() { - try { - return (StackMapType)clone(); - } catch(CloneNotSupportedException e) {} - return null; - } + /** @return index to constant pool if type == ITEM_Object, or offset + * in byte code, if type == ITEM_NewObject, and -1 otherwise + */ + public int getIndex() { + return index; + } - /** - * @return Constant pool used by this object. - */ - public final ConstantPool getConstantPool() { return constant_pool; } - /** - * @param constant_pool Constant pool to be used for this object. - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } + /** + * Dump type entries to file. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump( final 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 == Const.ITEM_Object || type == Const.ITEM_NewObject; + } + + + private String printIndex() { + if (type == Const.ITEM_Object) { + if (index < 0) { + return ", class="; + } + return ", class=" + constant_pool.constantToString(index, Const.CONSTANT_Class); + } else if (type == Const.ITEM_NewObject) { + return ", offset=" + index; + } else { + return ""; + } + } + + + /** + * @return String representation + */ + @Override + public final String toString() { + return "(type=" + Const.getItemName(type) + printIndex() + ")"; + } + + + /** + * @return deep copy of this object + */ + public StackMapType copy() { + try { + return (StackMapType) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + 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( final ConstantPool constant_pool ) { + this.constant_pool = constant_pool; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java index 737067f94cc..b3fd0d0aad3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java @@ -21,9 +21,11 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class is derived from Attribute and declares this class as @@ -34,110 +36,125 @@ import java.io.*; * is intended to be instantiated from the * Attribute.readAttribute() method. * - * @author M. Dahm + * @version $Id: Synthetic.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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()); - } + private byte[] bytes; - /** - * @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"); + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public Synthetic(final Synthetic c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); } - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitSynthetic(this); - } - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - if(length > 0) - file.write(bytes, 0, length); - } - /** - * @return data bytes. - */ - public final byte[] getBytes() { return bytes; } - /** - * @param bytes. - */ - public final void setBytes(byte[] bytes) { - this.bytes = bytes; - } - /** - * @return String representation. - */ - public final String toString() { - StringBuffer buf = new StringBuffer("Synthetic"); + /** + * @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(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { + super(Const.ATTR_SYNTHETIC, name_index, length, constant_pool); + this.bytes = bytes; + } - if(length > 0) - buf.append(" " + Utility.toHexString(bytes)); - return buf.toString(); - } + /** + * Construct object from input stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Synthetic(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + if (length > 0) { + bytes = new byte[length]; + input.readFully(bytes); + System.err.println("Synthetic attribute with length > 0"); + } + } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - Synthetic c = (Synthetic)clone(); - if(bytes != null) - c.bytes = (byte[])bytes.clone(); + /** + * 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( final Visitor v ) { + v.visitSynthetic(this); + } - c.constant_pool = constant_pool; - return c; - } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + if (super.getLength() > 0) { + file.write(bytes, 0, super.getLength()); + } + } + + + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } + + + /** + * @param bytes + */ + public final void setBytes( final byte[] bytes ) { + this.bytes = bytes; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + final StringBuilder buf = new StringBuilder("Synthetic"); + if (super.getLength() > 0) { + buf.append(" ").append(Utility.toHexString(bytes)); + } + return buf.toString(); + } + + + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy( final ConstantPool _constant_pool ) { + final Synthetic c = (Synthetic) clone(); + if (bytes != null) { + c.bytes = new byte[bytes.length]; + System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); + } + c.setConstantPool(_constant_pool); + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java index d5b13965842..7d764850012 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java @@ -21,160 +21,173 @@ package com.sun.org.apache.bcel.internal.classfile; +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; -import java.util.*; +import com.sun.org.apache.bcel.internal.Const; /** * This class represents a reference to an unknown (i.e., * application-specific) attribute of a class. It is instantiated from the - * Attribute.readAttribute() method. Applications that need to - * read in application-specific attributes should create an AttributeReader implementation and - * attach it via Attribute.addAttributeReader. + * {@link Attribute#readAttribute(java.io.DataInput, ConstantPool)} method. + * Applications that need to read in application-specific attributes should create an + * {@link UnknownAttributeReader} implementation and attach it via + * {@link Attribute#addAttributeReader(String, UnknownAttributeReader)}. * - * @see com.sun.org.apache.bcel.internal.classfile.Attribute - * @see com.sun.org.apache.bcel.internal.classfile.AttributeReader - * @author M. Dahm + * @version $Id: Unknown.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see Attribute + * @see UnknownAttributeReader */ public final class Unknown extends Attribute { - private byte[] bytes; - private String name; - private static HashMap unknown_attributes = new HashMap(); + private byte[] bytes; + private final String name; + private static final Map unknown_attributes = new HashMap<>(); - /** @return array of unknown attributes, but just one for each kind. - */ - static Unknown[] getUnknownAttributes() { - Unknown[] unknowns = new Unknown[unknown_attributes.size()]; - Iterator entries = unknown_attributes.values().iterator(); - for(int i=0; entries.hasNext(); i++) - unknowns[i] = (Unknown)entries.next(); - - unknown_attributes.clear(); - return unknowns; - } - - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Unknown(Unknown c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } - - /** - * Create a non-standard attribute. - * - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param bytes Attribute contents - * @param constant_pool Array of constants - */ - public Unknown(int name_index, int length, byte[] bytes, - ConstantPool constant_pool) - { - super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); - this.bytes = bytes; - - name = ((ConstantUtf8)constant_pool.getConstant(name_index, - Constants.CONSTANT_Utf8)).getBytes(); - unknown_attributes.put(name, this); - } - - /** - * Construct object from file stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param file Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Unknown(int name_index, int length, DataInputStream file, - ConstantPool constant_pool) - throws IOException - { - this(name_index, length, (byte [])null, constant_pool); - - if(length > 0) { - bytes = new byte[length]; - file.readFully(bytes); + /** @return array of unknown attributes, but just one for each kind. + */ + static Unknown[] getUnknownAttributes() { + final Unknown[] unknowns = new Unknown[unknown_attributes.size()]; + unknown_attributes.values().toArray(unknowns); + unknown_attributes.clear(); + return unknowns; } - } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitUnknown(this); - } - /** - * Dump unknown bytes to file stream. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(DataOutputStream file) throws IOException - { - super.dump(file); - if(length > 0) - file.write(bytes, 0, length); - } - /** - * @return data bytes. - */ - public final byte[] getBytes() { return bytes; } - /** - * @return name of attribute. - */ - public final String getName() { return name; } - - /** - * @param bytes. - */ - public final void setBytes(byte[] bytes) { - this.bytes = bytes; - } - - /** - * @return String representation. - */ - public final String toString() { - if(length == 0 || bytes == null) - return "(Unknown attribute " + name + ")"; - - String hex; - if(length > 10) { - byte[] tmp = new byte[10]; - System.arraycopy(bytes, 0, tmp, 0, 10); - hex = Utility.toHexString(tmp) + "... (truncated)"; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Unknown(final Unknown c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); } - else - hex = Utility.toHexString(bytes); - return "(Unknown attribute " + name + ": " + hex + ")"; - } - /** - * @return deep copy of this attribute - */ - public Attribute copy(ConstantPool constant_pool) { - Unknown c = (Unknown)clone(); + /** + * 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(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { + super(Const.ATTR_UNKNOWN, name_index, length, constant_pool); + this.bytes = bytes; + name = ((ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8)) + .getBytes(); + unknown_attributes.put(name, this); + } - if(bytes != null) - c.bytes = (byte[])bytes.clone(); - c.constant_pool = constant_pool; - return c; - } + /** + * Construct object from input stream. + * + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Unknown(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) + throws IOException { + this(name_index, length, (byte[]) null, constant_pool); + if (length > 0) { + bytes = new byte[length]; + input.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( final Visitor v ) { + v.visitUnknown(this); + } + + + /** + * Dump unknown bytes to file stream. + * + * @param file Output file stream + * @throws IOException + */ + @Override + public final void dump( final DataOutputStream file ) throws IOException { + super.dump(file); + if (super.getLength() > 0) { + file.write(bytes, 0, super.getLength()); + } + } + + + /** + * @return data bytes. + */ + public final byte[] getBytes() { + return bytes; + } + + + /** + * @return name of attribute. + */ + @Override + public final String getName() { + return name; + } + + + /** + * @param bytes the bytes to set + */ + public final void setBytes( final byte[] bytes ) { + this.bytes = bytes; + } + + + /** + * @return String representation. + */ + @Override + public final String toString() { + if (super.getLength() == 0 || bytes == null) { + return "(Unknown attribute " + name + ")"; + } + String hex; + if (super.getLength() > 10) { + final 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( final ConstantPool _constant_pool ) { + final Unknown c = (Unknown) clone(); + if (bytes != null) { + c.bytes = new byte[bytes.length]; + System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); + } + c.setConstantPool(_constant_pool); + return c; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java new file mode 100644 index 00000000000..956bde4b0d5 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java @@ -0,0 +1,54 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + +/** + * Unknown (non-standard) attributes may be read via user-defined factory + * objects that can be registered with the Attribute.addAttributeReader + * method. These factory objects should implement this interface. + * + * @see Attribute + * @version $Id: UnknownAttributeReader.java 1747278 2016-06-07 17:28:43Z britter $ + * @since 6.0 + */ +public interface UnknownAttributeReader { + + /** + * When this attribute reader is added via the static method Attribute.addAttributeReader, + * an attribute name is associated with it. As the class file parser parses attributes, + * it will call various AttributeReaders based on the name of the attributes it is constructing. + * + * @param name_index An index into the constant pool, indexing a ConstantUtf8 + * that represents the name of the attribute. + * @param length The length of the data contained in the attribute. This is written + * into the constant pool and should agree with what the factory expects the length to be. + * @param file This is the data input that the factory needs to read its data from. + * @param constant_pool This is the constant pool associated with the Attribute that we are constructing. + * + * @return The user-defined AttributeReader should take this data and use + * it to construct an attribute. In the case of errors, a null can be + * returned which will cause the parsing of the class file to fail. + * + * @see Attribute#addAttributeReader(String, UnknownAttributeReader) + */ + Attribute createAttribute( int name_index, int length, java.io.DataInput file, ConstantPool constant_pool ); +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java index 2641b1f62ef..fffa6cae984 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java @@ -18,1344 +18,1431 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.util.ByteSequence; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayReader; +import java.io.CharArrayWriter; +import java.io.FilterReader; +import java.io.FilterWriter; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; import java.util.ArrayList; -import java.util.zip.*; +import java.util.List; +import java.util.Locale; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * Utility functions that do not really belong to any class in particular. * - * @author M. Dahm + * @version $Id: Utility.java 1751107 2016-07-03 02:41:18Z dbrosius $ */ +// @since 6.0 methods are no longer final public abstract class Utility { - private static int consumed_chars; /* How many chars have been consumed - * during parsing in signatureToString(). - * Read by methodSignatureToString(). - * Set by side effect,but only internally. - */ - private static boolean wide=false; /* The `WIDE' instruction is used in the - * byte code to allow 16-bit wide indices - * for local variables. This opcode - * precedes an `ILOAD', e.g.. The opcode - * immediately following takes an extra - * byte which is combined with the - * following byte to form a - * 16-bit value. - */ - /** - * Convert bit field of flags into string such as `static final'. - * - * @param access_flags Access flags - * @return String representation of flags - */ - public static final String accessToString(int access_flags) { - return accessToString(access_flags, false); - } - /** - * Convert bit field of flags into string such as `static final'. - * - * Special case: Classes compiled with new compilers and with the - * `ACC_SUPER' flag would be said to be "synchronized". This is - * because SUN used the same value for the flags `ACC_SUPER' and - * `ACC_SYNCHRONIZED'. - * - * @param access_flags Access flags - * @param for_class access flags are for class qualifiers ? - * @return String representation of flags - */ - public static final String accessToString(int access_flags, - boolean for_class) - { - StringBuffer buf = new StringBuffer(); + private static int unwrap(final ThreadLocal tl) { + return tl.get().intValue(); + } - int p = 0; - for(int i=0; p < Constants.MAX_ACC_FLAG; i++) { // Loop through known flags - p = pow2(i); + private static void wrap(final ThreadLocal tl, final int value) { + tl.set(Integer.valueOf(value)); + } - if((access_flags & p) != 0) { - /* Special case: Classes compiled with new compilers and with the - * `ACC_SUPER' flag would be said to be "synchronized". This is - * because SUN used the same value for the flags `ACC_SUPER' and - * `ACC_SYNCHRONIZED'. + private static ThreadLocal consumed_chars = new ThreadLocal() { + + @Override + protected Integer initialValue() { + return Integer.valueOf(0); + } + };/* How many chars have been consumed + * during parsing in signatureToString(). + * Read by methodSignatureToString(). + * Set by side effect,but only internally. + */ + + private static boolean wide = false; /* The `WIDE' instruction is used in the + * byte code to allow 16-bit wide indices + * for local variables. This opcode + * precedes an `ILOAD', e.g.. The opcode + * immediately following takes an extra + * byte which is combined with the + * following byte to form a + * 16-bit value. + */ + + + /** + * Convert bit field of flags into string such as `static final'. + * + * @param access_flags Access flags + * @return String representation of flags + */ + public static String accessToString(final 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 String accessToString(final int access_flags, final boolean for_class) { + final StringBuilder buf = new StringBuilder(); + int p = 0; + for (int i = 0; p < Const.MAX_ACC_FLAG; i++) { // Loop through known flags + p = pow2(i); + if ((access_flags & p) != 0) { + /* Special case: Classes compiled with new compilers and with the + * `ACC_SUPER' flag would be said to be "synchronized". This is + * because SUN used the same value for the flags `ACC_SUPER' and + * `ACC_SYNCHRONIZED'. + */ + if (for_class && ((p == Const.ACC_SUPER) || (p == Const.ACC_INTERFACE))) { + continue; + } + buf.append(Const.getAccessName(i)).append(" "); + } + } + return buf.toString().trim(); + } + + /** + * @param access_flags the class flags + * + * @return "class" or "interface", depending on the ACC_INTERFACE flag + */ + public static String classOrInterface(final int access_flags) { + return ((access_flags & Const.ACC_INTERFACE) != 0) ? "interface" : "class"; + } + + /** + * Disassemble a byte array of JVM byte codes starting from code line + * `index' and return the disassembled string representation. Decode only + * `num' opcodes (including their operands), use -1 if you want to decompile + * everything. + * + * @param code byte code array + * @param constant_pool Array of constants + * @param index offset in `code' array + * (number of opcodes, not bytes!) + * @param length number of opcodes to decompile, -1 for all + * @param verbose be verbose, e.g. print constant pool index + * @return String representation of byte codes + */ + public static String codeToString(final byte[] code, final ConstantPool constant_pool, + final int index, final int length, final boolean verbose) { + // Should be sufficient // CHECKSTYLE IGNORE MagicNumber + final StringBuilder buf = new StringBuilder(code.length * 20); + try (ByteSequence stream = new ByteSequence(code)) { + for (int i = 0; i < index; i++) { + codeToString(stream, constant_pool, verbose); + } + for (int i = 0; stream.available() > 0; i++) { + if ((length < 0) || (i < length)) { + final String indices = fillup(stream.getIndex() + ":", 6, true, ' '); + buf.append(indices) + .append(codeToString(stream, constant_pool, verbose)) + .append('\n'); + } + } + } catch (final IOException e) { + throw new ClassFormatException("Byte code error: " + buf.toString(), e); + } + return buf.toString(); + } + + public static String codeToString(final byte[] code, final ConstantPool constant_pool, + final int index, final int length) { + return codeToString(code, constant_pool, index, length, true); + } + + /** + * Disassemble a stream of byte codes and return the string representation. + * + * @param bytes stream of bytes + * @param constant_pool Array of constants + * @param verbose be verbose, e.g. print constant pool index + * @return String representation of byte code + * + * @throws IOException if a failure from reading from the bytes argument + * occurs + */ + public static String codeToString(final ByteSequence bytes, final ConstantPool constant_pool, + final boolean verbose) throws IOException { + final short opcode = (short) bytes.readUnsignedByte(); + int default_offset = 0; + int low; + int high; + int npairs; + int index; + int vindex; + int constant; + int[] match; + int[] jump_table; + int no_pad_bytes = 0; + int offset; + final StringBuilder buf = new StringBuilder(Const.getOpcodeName(opcode)); + /* Special case: Skip (0-3) padding bytes, i.e., the + * following bytes are 4-byte-aligned */ - if(for_class && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE))) - continue; - - buf.append(Constants.ACCESS_NAMES[i] + " "); - } - } - - return buf.toString().trim(); - } - - /** - * @return "class" or "interface", depending on the ACC_INTERFACE flag - */ - public static final String classOrInterface(int access_flags) { - return ((access_flags & Constants.ACC_INTERFACE) != 0)? "interface" : "class"; - } - - /** - * Disassemble a byte array of JVM byte codes starting from code line - * `index' and return the disassembled string representation. Decode only - * `num' opcodes (including their operands), use -1 if you want to - * decompile everything. - * - * @param code byte code array - * @param constant_pool Array of constants - * @param index offset in `code' array - * (number of opcodes, not bytes!) - * @param length number of opcodes to decompile, -1 for all - * @param verbose be verbose, e.g. print constant pool index - * @return String representation of byte codes - */ - public static final String codeToString(byte[] code, - ConstantPool constant_pool, - int index, int length, boolean verbose) - { - StringBuffer buf = new StringBuffer(code.length * 20); // Should be sufficient - ByteSequence stream = new ByteSequence(code); - - try { - for(int i=0; i < index; i++) // 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'); + if ((opcode == Const.TABLESWITCH) || (opcode == Const.LOOKUPSWITCH)) { + final int remainder = bytes.getIndex() % 4; + no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; + for (int i = 0; i < no_pad_bytes; i++) { + byte b; + if ((b = bytes.readByte()) != 0) { + System.err.println("Warning: Padding byte != 0 in " + + Const.getOpcodeName(opcode) + ":" + b); + } + } + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); } - } - } catch(IOException e) { - System.out.println(buf.toString()); - e.printStackTrace(); - throw new ClassFormatException("Byte code error: " + e); + switch (opcode) { + /* Table switch has variable length arguments. + */ + case Const.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + buf.append("\tdefault = ").append(default_offset).append(", low = ").append(low) + .append(", high = ").append(high).append("("); + jump_table = new int[high - low + 1]; + for (int i = 0; i < jump_table.length; i++) { + jump_table[i] = offset + bytes.readInt(); + buf.append(jump_table[i]); + if (i < jump_table.length - 1) { + buf.append(", "); + } + } + buf.append(")"); + break; + /* Lookup switch has variable length arguments. + */ + case Const.LOOKUPSWITCH: { + npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + match = new int[npairs]; + jump_table = new int[npairs]; + default_offset += offset; + buf.append("\tdefault = ").append(default_offset).append(", npairs = ").append( + npairs).append(" ("); + for (int i = 0; i < npairs; i++) { + match[i] = bytes.readInt(); + jump_table[i] = offset + bytes.readInt(); + buf.append("(").append(match[i]).append(", ").append(jump_table[i]).append(")"); + if (i < npairs - 1) { + buf.append(", "); + } + } + buf.append(")"); + } + break; + /* Two address bytes + offset from start of byte stream form the + * jump target + */ + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.JSR: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + buf.append("\t\t#").append((bytes.getIndex() - 1) + bytes.readShort()); + break; + /* 32-bit wide jumps + */ + case Const.GOTO_W: + case Const.JSR_W: + buf.append("\t\t#").append((bytes.getIndex() - 1) + bytes.readInt()); + break; + /* Index byte references local variable (register) + */ + case Const.ALOAD: + case Const.ASTORE: + case Const.DLOAD: + case Const.DSTORE: + case Const.FLOAD: + case Const.FSTORE: + case Const.ILOAD: + case Const.ISTORE: + case Const.LLOAD: + case Const.LSTORE: + case Const.RET: + if (wide) { + vindex = bytes.readUnsignedShort(); + wide = false; // Clear flag + } else { + vindex = bytes.readUnsignedByte(); + } + buf.append("\t\t%").append(vindex); + break; + /* + * Remember wide byte which is used to form a 16-bit address in the + * following instruction. Relies on that the method is called again with + * the following opcode. + */ + case Const.WIDE: + wide = true; + buf.append("\t(wide)"); + break; + /* Array of basic type. + */ + case Const.NEWARRAY: + buf.append("\t\t<").append(Const.getTypeName(bytes.readByte())).append(">"); + break; + /* Access object/class fields. + */ + case Const.GETFIELD: + case Const.GETSTATIC: + case Const.PUTFIELD: + case Const.PUTSTATIC: + index = bytes.readUnsignedShort(); + buf.append("\t\t").append( + constant_pool.constantToString(index, Const.CONSTANT_Fieldref)).append( + verbose ? " (" + index + ")" : ""); + break; + /* Operands are references to classes in constant pool + */ + case Const.NEW: + case Const.CHECKCAST: + buf.append("\t"); + //$FALL-THROUGH$ + case Const.INSTANCEOF: + index = bytes.readUnsignedShort(); + buf.append("\t<").append( + constant_pool.constantToString(index, Const.CONSTANT_Class)) + .append(">").append(verbose ? " (" + index + ")" : ""); + break; + /* Operands are references to methods in constant pool + */ + case Const.INVOKESPECIAL: + case Const.INVOKESTATIC: + index = bytes.readUnsignedShort(); + final Constant c = constant_pool.getConstant(index); + // With Java8 operand may be either a CONSTANT_Methodref + // or a CONSTANT_InterfaceMethodref. (markro) + buf.append("\t").append( + constant_pool.constantToString(index, c.getTag())) + .append(verbose ? " (" + index + ")" : ""); + break; + case Const.INVOKEVIRTUAL: + index = bytes.readUnsignedShort(); + buf.append("\t").append( + constant_pool.constantToString(index, Const.CONSTANT_Methodref)) + .append(verbose ? " (" + index + ")" : ""); + break; + case Const.INVOKEINTERFACE: + index = bytes.readUnsignedShort(); + final int nargs = bytes.readUnsignedByte(); // historical, redundant + buf.append("\t").append( + constant_pool + .constantToString(index, Const.CONSTANT_InterfaceMethodref)) + .append(verbose ? " (" + index + ")\t" : "").append(nargs).append("\t") + .append(bytes.readUnsignedByte()); // Last byte is a reserved space + break; + case Const.INVOKEDYNAMIC: + index = bytes.readUnsignedShort(); + buf.append("\t").append( + constant_pool + .constantToString(index, Const.CONSTANT_InvokeDynamic)) + .append(verbose ? " (" + index + ")\t" : "") + .append(bytes.readUnsignedByte()) // Thrid byte is a reserved space + .append(bytes.readUnsignedByte()); // Last byte is a reserved space + break; + /* Operands are references to items in constant pool + */ + case Const.LDC_W: + case Const.LDC2_W: + index = bytes.readUnsignedShort(); + buf.append("\t\t").append( + constant_pool.constantToString(index, constant_pool.getConstant(index) + .getTag())).append(verbose ? " (" + index + ")" : ""); + break; + case Const.LDC: + index = bytes.readUnsignedByte(); + buf.append("\t\t").append( + constant_pool.constantToString(index, constant_pool.getConstant(index) + .getTag())).append(verbose ? " (" + index + ")" : ""); + break; + /* Array of references. + */ + case Const.ANEWARRAY: + index = bytes.readUnsignedShort(); + buf.append("\t\t<").append( + compactClassName(constant_pool.getConstantString(index, + Const.CONSTANT_Class), false)).append(">").append( + verbose ? " (" + index + ")" : ""); + break; + /* Multidimensional array of references. + */ + case Const.MULTIANEWARRAY: { + index = bytes.readUnsignedShort(); + final int dimensions = bytes.readUnsignedByte(); + buf.append("\t<").append( + compactClassName(constant_pool.getConstantString(index, + Const.CONSTANT_Class), false)).append(">\t").append(dimensions) + .append(verbose ? " (" + index + ")" : ""); + } + break; + /* Increment local variable. + */ + case Const.IINC: + if (wide) { + vindex = bytes.readUnsignedShort(); + constant = bytes.readShort(); + wide = false; + } else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("\t\t%").append(vindex).append("\t").append(constant); + break; + default: + if (Const.getNoOfOperands(opcode) > 0) { + for (int i = 0; i < Const.getOperandTypeCount(opcode); i++) { + buf.append("\t\t"); + switch (Const.getOperandType(opcode, i)) { + case Const.T_BYTE: + buf.append(bytes.readByte()); + break; + case Const.T_SHORT: + buf.append(bytes.readShort()); + break; + case Const.T_INT: + buf.append(bytes.readInt()); + break; + default: // Never reached + throw new IllegalStateException("Unreachable default case reached!"); + } + } + } + } + return buf.toString(); } - return buf.toString(); - } + public static String codeToString(final ByteSequence bytes, final ConstantPool constant_pool) + throws IOException { + return codeToString(bytes, constant_pool, true); + } - public static final String codeToString(byte[] code, - ConstantPool constant_pool, - int index, int length) { - return codeToString(code, constant_pool, index, length, true); - } - - /** - * Disassemble a stream of byte codes and return the - * string representation. - * - * @param bytes stream of bytes - * @param constant_pool Array of constants - * @param verbose be verbose, e.g. print constant pool index - * @return String representation of byte code - */ - public static final String codeToString(ByteSequence bytes, - ConstantPool constant_pool, boolean verbose) - throws IOException - { - short opcode = (short)bytes.readUnsignedByte(); - int default_offset=0, low, high, npairs; - int index, vindex, constant; - int[] match, jump_table; - int no_pad_bytes=0, offset; - StringBuffer buf = new StringBuffer(Constants.OPCODE_NAMES[opcode]); - - /* Special case: Skip (0-3) padding bytes, i.e., the - * following bytes are 4-byte-aligned + /** + * Shorten long class names, java/lang/String becomes + * String. + * + * @param str The long class name + * @return Compacted class name */ - if((opcode == Constants.TABLESWITCH) || (opcode == Constants.LOOKUPSWITCH)) { - int remainder = bytes.getIndex() % 4; - no_pad_bytes = (remainder == 0)? 0 : 4 - remainder; - - for(int i=0; i < no_pad_bytes; i++) { - byte b; - - if((b=bytes.readByte()) != 0) - System.err.println("Warning: Padding byte != 0 in " + - Constants.OPCODE_NAMES[opcode] + ":" + b); - } - - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); + public static String compactClassName(final String str) { + return compactClassName(str, true); } - 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 + /** + * Shorten long class name str, i.e., chop off the prefix, + * if the class name starts with this string and the flag chopit is + * true. Slashes / are converted to dots .. + * + * @param str The long class name + * @param prefix The prefix the get rid off + * @param chopit Flag that determines whether chopping is executed or not + * @return Compacted class name */ - 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, - Constants.CONSTANT_Class) + - ">" + (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, - Constants.CONSTANT_Methodref) + - (verbose? " (" + index + ")" : "")); - break; - - case Constants.INVOKEINTERFACE: - index = bytes.readUnsignedShort(); - int nargs = bytes.readUnsignedByte(); // historical, redundant - buf.append("\t" + - constant_pool.constantToString(index, - Constants.CONSTANT_InterfaceMethodref) + - (verbose? " (" + index + ")\t" : "") + nargs + "\t" + - bytes.readUnsignedByte()); // Last byte is a reserved space - break; - - /* Operands are references to items in constant pool - */ - case Constants.LDC_W: case Constants.LDC2_W: - index = bytes.readUnsignedShort(); - - buf.append("\t\t" + constant_pool.constantToString - (index, constant_pool.getConstant(index).getTag()) + - (verbose? " (" + index + ")" : "")); - break; - - case Constants.LDC: - index = bytes.readUnsignedByte(); - - buf.append("\t\t" + - constant_pool.constantToString - (index, constant_pool.getConstant(index).getTag()) + - (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 + ")" : "")); + public static String compactClassName(String str, final String prefix, final boolean chopit) { + final int len = prefix.length(); + str = str.replace('/', '.'); // Is `/' on all systems, even DOS + if (chopit) { + // If string starts with `prefix' and contains no further dots + if (str.startsWith(prefix) && (str.substring(len).indexOf('.') == -1)) { + str = str.substring(len); + } + } + return str; } - break; - /* Increment local variable. + /** + * Shorten long class names, java/lang/String becomes + * java.lang.String, e.g.. If chopit is true the + * prefix java.lang + * is also removed. + * + * @param str The long class name + * @param chopit Flag that determines whether chopping is executed or not + * @return Compacted class name */ - 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; + public static String compactClassName(final String str, final boolean chopit) { + return compactClassName(str, "java.lang.", chopit); + } - default: - if(Constants.NO_OF_OPERANDS[opcode] > 0) { - for(int i=0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) { - buf.append("\t\t"); - switch(Constants.TYPE_OF_OPERANDS[opcode][i]) { - case Constants.T_BYTE: buf.append(bytes.readByte()); break; - case Constants.T_SHORT: buf.append(bytes.readShort()); break; - case Constants.T_INT: buf.append(bytes.readInt()); break; + /** + * @return `flag' with bit `i' set to 1 + */ + public static int setBit(final int flag, final int i) { + return flag | pow2(i); + } - default: // Never reached - System.err.println("Unreachable default case reached!"); - buf.setLength(0); - } + /** + * @return `flag' with bit `i' set to 0 + */ + public static int clearBit(final int flag, final int i) { + final int bit = pow2(i); + return (flag & bit) == 0 ? flag : flag ^ bit; + } + + /** + * @return true, if bit `i' in `flag' is set + */ + public static boolean isSet(final int flag, final int i) { + return (flag & pow2(i)) != 0; + } + + /** + * Converts string containing the method return and argument types to a byte + * code method signature. + * + * @param ret Return type of method + * @param argv Types of method arguments + * @return Byte code representation of method signature + * + * @throws ClassFormatException if the signature is for Void + */ + public static String methodTypeToSignature(final String ret, final String[] argv) + throws ClassFormatException { + final StringBuilder buf = new StringBuilder("("); + String str; + if (argv != null) { + for (final String element : argv) { + str = getSignature(element); + if (str.endsWith("V")) { + throw new ClassFormatException("Invalid type: " + element); + } + buf.append(str); + } } - } + str = getSignature(ret); + buf.append(")").append(str); + return buf.toString(); } - return buf.toString(); - } - - public static final String codeToString(ByteSequence bytes, ConstantPool constant_pool) - throws IOException - { - return codeToString(bytes, constant_pool, true); - } - - /** - * Shorten long class names, java/lang/String becomes - * String. - * - * @param str The long class name - * @return Compacted class name - */ - public static final String compactClassName(String str) { - return compactClassName(str, true); - } - - /** - * Shorten long class name str, i.e., chop off the prefix, - * if the - * class name starts with this string and the flag chopit is true. - * Slashes / are converted to dots .. - * - * @param str The long class name - * @param prefix The prefix the get rid off - * @param chopit Flag that determines whether chopping is executed or not - * @return Compacted class name - */ - public static final String compactClassName(String str, - String prefix, - boolean chopit) - { - int len = prefix.length(); - - str = str.replace('/', '.'); // Is `/' on all systems, even DOS - - if(chopit) { - // If string starts with `prefix' and contains no further dots - if(str.startsWith(prefix) && - (str.substring(len).indexOf('.') == -1)) - str = str.substring(len); + /** + * @param signature Method signature + * @return Array of argument types + * @throws ClassFormatException + */ + public static String[] methodSignatureArgumentTypes(final String signature) + throws ClassFormatException { + return methodSignatureArgumentTypes(signature, true); } - return str; - } - - /** - * Shorten long class names, java/lang/String becomes - * java.lang.String, - * e.g.. If chopit is true the prefix java.lang - * is also removed. - * - * @param str The long class name - * @param chopit Flag that determines whether chopping is executed or not - * @return Compacted class name - */ - public static final String compactClassName(String str, boolean chopit) { - return compactClassName(str, "java.lang.", chopit); - } - - private static final boolean is_digit(char ch) { - return (ch >= '0') && (ch <= '9'); - } - - private static final boolean is_space(char ch) { - return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'); - } - - /** - * @return `flag' with bit `i' set to 1 - */ - public static final int setBit(int flag, int i) { - return flag | pow2(i); - } - - /** - * @return `flag' with bit `i' set to 0 - */ - public static final int clearBit(int flag, int i) { - int bit = pow2(i); - return (flag & bit) == 0? flag : flag ^ bit; - } - - /** - * @return true, if bit `i' in `flag' is set - */ - public static final boolean isSet(int flag, int i) { - return (flag & pow2(i)) != 0; - } - - /** - * Converts string containing the method return and argument types - * to a byte code method signature. - * - * @param ret Return type of method - * @param argv Types of method arguments - * @return Byte code representation of method signature - */ - public final static String methodTypeToSignature(String ret, String[] argv) - throws ClassFormatException - { - StringBuffer buf = new StringBuffer("("); - String str; - - if(argv != null) - for(int i=0; i < argv.length; i++) { - str = getSignature(argv[i]); - - if(str.endsWith("V")) // void can't be a method argument - throw new ClassFormatException("Invalid type: " + argv[i]); - - buf.append(str); - } - - str = getSignature(ret); - - buf.append(")" + str); - - return buf.toString(); - } - - /** - * @param signature Method signature - * @return Array of argument types - * @throws ClassFormatException - */ - public static final String[] methodSignatureArgumentTypes(String signature) - throws ClassFormatException - { - return methodSignatureArgumentTypes(signature, true); - } - - /** - * @param signature Method signature - * @param chopit Shorten class names ? - * @return Array of argument types - * @throws ClassFormatException - */ - public static final String[] methodSignatureArgumentTypes(String signature, - boolean chopit) - throws ClassFormatException - { - ArrayList vec = new ArrayList(); - int index; - String[] types; - - try { // Read all declarations between for `(' and `)' - if(signature.charAt(0) != '(') - throw new ClassFormatException("Invalid method signature: " + signature); - - index = 1; // current string position - - while(signature.charAt(index) != ')') { - vec.add(signatureToString(signature.substring(index), chopit)); - index += consumed_chars; // update position - } - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); + /** + * @param signature Method signature + * @param chopit Shorten class names ? + * @return Array of argument types + * @throws ClassFormatException + */ + public static String[] methodSignatureArgumentTypes(final String signature, final boolean chopit) + throws ClassFormatException { + final List vec = new ArrayList<>(); + int index; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + vec.add(signatureToString(signature.substring(index), chopit)); + //corrected concurrent private static field acess + index += unwrap(consumed_chars); // update position + } + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + return vec.toArray(new String[vec.size()]); } - types = new String[vec.size()]; - vec.toArray(types); - return types; - } - /** - * @param signature Method signature - * @return return type of method - * @throws ClassFormatException - */ - public static final String methodSignatureReturnType(String signature) - throws ClassFormatException - { - return methodSignatureReturnType(signature, true); - } - /** - * @param signature Method signature - * @param chopit Shorten class names ? - * @return return type of method - * @throws ClassFormatException - */ - public static final String methodSignatureReturnType(String signature, - boolean chopit) - throws ClassFormatException - { - int index; - String type; - - try { - // Read return type after `)' - index = signature.lastIndexOf(')') + 1; - type = signatureToString(signature.substring(index), chopit); - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); + /** + * @param signature Method signature + * @return return type of method + * @throws ClassFormatException + */ + public static String methodSignatureReturnType(final String signature) + throws ClassFormatException { + return methodSignatureReturnType(signature, true); } - return type; - } - - /** - * Converts method signature to string with all class names compacted. - * - * @param signature to convert - * @param name of method - * @param access flags of method - * @return Human readable signature - */ - public static final String methodSignatureToString(String signature, - String name, - String access) { - return methodSignatureToString(signature, name, access, true); - } - - public static final String methodSignatureToString(String signature, - String name, - String access, - boolean chopit) { - return methodSignatureToString(signature, name, access, chopit, null); - } - - /** - * A return type signature represents the return value from a method. - * It is a series of bytes in the following grammar: - * - * ::= | V - * - * The character V indicates that the method returns no value. Otherwise, the - * signature indicates the type of the return value. - * An argument signature represents an argument passed to a method: - * - * ::= - * - * A method signature represents the arguments that the method expects, and - * the value that it returns. - * ::= () - * ::= * - * - * This method converts such a string into a Java type declaration like - * `void _main(String[])' and throws a `ClassFormatException' when the parsed - * type is invalid. - * - * @param signature Method signature - * @param name Method name - * @param access Method access rights - * @return Java type declaration - * @throws ClassFormatException - */ - public static final String methodSignatureToString(String signature, - String name, - String access, - boolean chopit, - LocalVariableTable vars) - throws ClassFormatException - { - StringBuffer buf = new StringBuffer("("); - String type; - int index; - int var_index = (access.indexOf("static") >= 0)? 0 : 1; - - try { // Read all declarations between for `(' and `)' - if(signature.charAt(0) != '(') - throw new ClassFormatException("Invalid method signature: " + signature); - - index = 1; // current string position - - while(signature.charAt(index) != ')') { - String param_type = signatureToString(signature.substring(index), chopit); - buf.append(param_type); - - if(vars != null) { - LocalVariable l = vars.getLocalVariable(var_index); - - if(l != null) - buf.append(" " + 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 += consumed_chars; // update position - } - - index++; // update position - - // Read return type after `)' - type = signatureToString(signature.substring(index), chopit); - - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); + /** + * @param signature Method signature + * @param chopit Shorten class names ? + * @return return type of method + * @throws ClassFormatException + */ + public static String methodSignatureReturnType(final String signature, + final boolean chopit) throws ClassFormatException { + int index; + String type; + try { + // Read return type after `)' + index = signature.lastIndexOf(')') + 1; + type = signatureToString(signature.substring(index), chopit); + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + return type; } - if(buf.length() > 1) // Tack off the extra ", " - buf.setLength(buf.length() - 2); + /** + * Converts method signature to string with all class names compacted. + * + * @param signature to convert + * @param name of method + * @param access flags of method + * @return Human readable signature + */ + public static String methodSignatureToString(final String signature, + final String name, final String access) { + return methodSignatureToString(signature, name, access, true); + } - buf.append(")"); + public static String methodSignatureToString(final String signature, + final String name, final String access, final boolean chopit) { + return methodSignatureToString(signature, name, access, chopit, null); + } - return access + ((access.length() > 0)? " " : "") + // May be an empty string - type + " " + name + buf.toString(); - } + /** + * A returntype signature represents the return value from a method. It is a + * series of bytes in the following grammar: + * + *
+     * <return_signature> ::= <field_type> | V
+     * 
+ * + * The character V indicates that the method returns no value. Otherwise, + * the signature indicates the type of the return value. An argument + * signature represents an argument passed to a method: + * + *
+     * <argument_signature> ::= <field_type>
+     * 
+ * + * A method signature represents the arguments that the method expects, and + * the value that it returns. + *
+     * <method_signature> ::= (<arguments_signature>) <return_signature>
+     * <arguments_signature>::= <argument_signature>*
+     * 
+ * + * This method converts such a string into a Java type declaration like + * `void main(String[])' and throws a `ClassFormatException' when the parsed + * type is invalid. + * + * @param signature Method signature + * @param name Method name + * @param access Method access rights + * @param chopit + * @param vars + * @return Java type declaration + * @throws ClassFormatException + */ + public static String methodSignatureToString(final String signature, final String name, + final String access, final boolean chopit, final LocalVariableTable vars) + throws ClassFormatException { + final StringBuilder buf = new StringBuilder("("); + String type; + int index; + int var_index = access.contains("static") ? 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) != ')') { + final String param_type = signatureToString(signature.substring(index), chopit); + buf.append(param_type); + if (vars != null) { + final LocalVariable l = vars.getLocalVariable(var_index, 0); + if (l != null) { + buf.append(" ").append(l.getName()); + } + } else { + buf.append(" arg").append(var_index); + } + if ("double".equals(param_type) || "long".equals(param_type)) { + var_index += 2; + } else { + var_index++; + } + buf.append(", "); + //corrected concurrent private static field acess + index += unwrap(consumed_chars); // update position + } + index++; // update position + // Read return type after `)' + type = signatureToString(signature.substring(index), chopit); + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + if (buf.length() > 1) { + buf.setLength(buf.length() - 2); + } + buf.append(")"); + return access + ((access.length() > 0) ? " " : "") + // May be an empty string + type + " " + name + buf.toString(); + } - // Guess what this does - private static final int pow2(int n) { - return 1 << n; - } + // Guess what this does + private static int pow2(final int n) { + return 1 << n; + } - /** - * Replace all occurences of old in str with new. - * - * @param str String to permute - * @param old String to be replaced - * @param new Replacement string - * @return new String object - */ - public static final String replace(String str, String old, String new_) { - int index, old_index; - StringBuffer buf = new StringBuffer(); + /** + * Replace all occurrences of old in str with + * new. + * + * @param str String to permute + * @param old String to be replaced + * @param new_ Replacement string + * @return new String object + */ + public static String replace(String str, final String old, final String new_) { + int index; + int old_index; + try { + if (str.contains(old)) { // `old' found in str + final StringBuilder buf = new StringBuilder(); + old_index = 0; // String start offset + // While we have something to replace + while ((index = str.indexOf(old, old_index)) != -1) { + buf.append(str.substring(old_index, index)); // append prefix + buf.append(new_); // append replacement + old_index = index + old.length(); // Skip `old'.length chars + } + buf.append(str.substring(old_index)); // append rest of string + str = buf.toString(); + } + } catch (final StringIndexOutOfBoundsException e) { // Should not occur + System.err.println(e); + } + return str; + } - try { - if((index = str.indexOf(old)) != -1) { // `old' found in str - old_index = 0; // String start offset + /** + * Converts signature to string with all class names compacted. + * + * @param signature to convert + * @return Human readable signature + */ + public static String signatureToString(final String signature) { + return signatureToString(signature, true); + } - // 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 + /** + * The field signature represents the value of an argument to a function or + * the value of a variable. It is a series of bytes generated by the + * following grammar: + * + *
+     * <field_signature> ::= <field_type>
+     * <field_type>      ::= <base_type>|<object_type>|<array_type>
+     * <base_type>       ::= B|C|D|F|I|J|S|Z
+     * <object_type>     ::= L<fullclassname>;
+     * <array_type>      ::= [<field_type>
+     *
+     * The meaning of the base types is as follows:
+     * B byte signed byte
+     * C char character
+     * D double double precision IEEE float
+     * F float single precision IEEE float
+     * I int integer
+     * J long long integer
+     * L<fullclassname>; ... an object of the given class
+     * S short signed short
+     * Z boolean true or false
+     * [<field sig> ... array
+     * 
+ * + * This method converts this string into a Java type declaration such as + * `String[]' and throws a `ClassFormatException' when the parsed type is + * invalid. + * + * @param signature Class signature + * @param chopit Flag that determines whether chopping is executed or not + * @return Java type declaration + * @throws ClassFormatException + */ + public static String signatureToString(final String signature, final boolean chopit) { + //corrected concurrent private static field acess + wrap(consumed_chars, 1); // This is the default, read just one char like `B' + try { + switch (signature.charAt(0)) { + case 'B': + return "byte"; + case 'C': + return "char"; + case 'D': + return "double"; + case 'F': + return "float"; + case 'I': + return "int"; + case 'J': + return "long"; + case 'T': { // TypeVariableSignature + final int index = signature.indexOf(';'); // Look for closing `;' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + //corrected concurrent private static field acess + wrap(consumed_chars, index + 1); // "Tblabla;" `T' and `;' are removed + return compactClassName(signature.substring(1, index), chopit); + } + case 'L': { // Full class name + // should this be a while loop? can there be more than + // one generic clause? (markro) + int fromIndex = signature.indexOf('<'); // generic type? + if (fromIndex < 0) { + fromIndex = 0; + } else { + fromIndex = signature.indexOf('>', fromIndex); + if (fromIndex < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + } + final int index = signature.indexOf(';', fromIndex); // Look for closing `;' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + // check to see if there are any TypeArguments + final int bracketIndex = signature.substring(0, index).indexOf('<'); + if (bracketIndex < 0) { + // just a class identifier + wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed + return compactClassName(signature.substring(1, index), chopit); + } - old_index = index + old.length(); // Skip `old'.length chars + // we have TypeArguments; build up partial result + // as we recurse for each TypeArgument + final StringBuilder type = new StringBuilder( + compactClassName(signature.substring(1, bracketIndex), chopit)) + .append("<"); + int consumed_chars = bracketIndex + 1; // Shadows global var + + // check for wildcards + if (signature.charAt(consumed_chars) == '+') { + type.append("? extends "); + consumed_chars++; + } else if (signature.charAt(consumed_chars) == '-') { + type.append("? super "); + consumed_chars++; + } else if (signature.charAt(consumed_chars) == '*') { + // must be at end of signature + if (signature.charAt(consumed_chars + 1) != '>') { + throw new ClassFormatException("Invalid signature: " + signature); + } + if (signature.charAt(consumed_chars + 2) != ';') { + throw new ClassFormatException("Invalid signature: " + signature); + } + wrap(Utility.consumed_chars, consumed_chars + 3); // remove final "*>;" + return type + "?>..."; + } + + // get the first TypeArgument + type.append(signatureToString(signature.substring(consumed_chars), chopit)); + // update our consumed count by the number of characters the for type argument + consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars; + wrap(Utility.consumed_chars, consumed_chars); + + // are there more TypeArguments? + while (signature.charAt(consumed_chars) != '>') { + type.append(", ").append(signatureToString(signature.substring(consumed_chars), chopit)); + // update our consumed count by the number of characters the for type argument + consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars; + wrap(Utility.consumed_chars, consumed_chars); + } + + if (signature.charAt(consumed_chars + 1) != ';') { + throw new ClassFormatException("Invalid signature: " + signature); + } + wrap(Utility.consumed_chars, consumed_chars + 2); // remove final ">;" + return type.append(">").toString(); + } + case 'S': + return "short"; + case 'Z': + return "boolean"; + case '[': { // Array declaration + int n; + StringBuilder brackets; + String type; + int consumed_chars; // Shadows global var + brackets = new StringBuilder(); // Accumulate []'s + // Count opening brackets and look for optional size argument + for (n = 0; signature.charAt(n) == '['; n++) { + brackets.append("[]"); + } + consumed_chars = n; // Remember value + // The rest of the string denotes a `' + type = signatureToString(signature.substring(n), chopit); + //corrected concurrent private static field acess + //Utility.consumed_chars += consumed_chars; is replaced by: + final int _temp = unwrap(Utility.consumed_chars) + consumed_chars; + wrap(Utility.consumed_chars, _temp); + return type + brackets.toString(); + } + case 'V': + return "void"; + default: + throw new ClassFormatException("Invalid signature: `" + signature + "'"); + } + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid signature: " + signature, e); + } + } + + /** + * Parse Java type such as "char", or "java.lang.String[]" and return the + * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" + * respectively. + * + * @param type Java type + * @return byte code signature + */ + public static String getSignature(String type) { + final StringBuilder buf = new StringBuilder(); + final char[] chars = type.toCharArray(); + boolean char_found = false; + boolean delim = false; + int index = -1; + loop: + for (int i = 0; i < chars.length; i++) { + switch (chars[i]) { + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + if (char_found) { + delim = true; + } + break; + case '[': + if (!char_found) { + throw new RuntimeException("Illegal type: " + type); + } + index = i; + break loop; + default: + char_found = true; + if (!delim) { + buf.append(chars[i]); + } + } + } + int brackets = 0; + if (index > 0) { + brackets = countBrackets(type.substring(index)); + } + type = buf.toString(); + buf.setLength(0); + for (int i = 0; i < brackets; i++) { + buf.append('['); + } + boolean found = false; + for (int i = Const.T_BOOLEAN; (i <= Const.T_VOID) && !found; i++) { + if (Const.getTypeName(i).equals(type)) { + found = true; + buf.append(Const.getShortTypeName(i)); + } + } + if (!found) { + buf.append('L').append(type.replace('.', '/')).append(';'); + } + return buf.toString(); + } + + private static int countBrackets(final String brackets) { + final char[] chars = brackets.toCharArray(); + int count = 0; + boolean open = false; + for (final char c : chars) { + switch (c) { + case '[': + if (open) { + throw new RuntimeException("Illegally nested brackets:" + brackets); + } + open = true; + break; + case ']': + if (!open) { + throw new RuntimeException("Illegally nested brackets:" + brackets); + } + open = false; + count++; + break; + default: + // Don't care + break; + } + } + if (open) { + throw new RuntimeException("Illegally nested brackets:" + brackets); + } + return count; + } + + /** + * Return type of method signature as a byte value as defined in + * Constants + * + * @param signature in format described above + * @return type of method signature + * @see Const + * + * @throws ClassFormatException if signature is not a method signature + */ + public static byte typeOfMethodSignature(final 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 (final StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + } + + /** + * Return type of signature as a byte value as defined in Constants + * + * @param signature in format described above + * @return type of signature + * @see Const + * + * @throws ClassFormatException if signature isn't a known type + */ + public static byte typeOfSignature(final String signature) throws ClassFormatException { + try { + switch (signature.charAt(0)) { + case 'B': + return Const.T_BYTE; + case 'C': + return Const.T_CHAR; + case 'D': + return Const.T_DOUBLE; + case 'F': + return Const.T_FLOAT; + case 'I': + return Const.T_INT; + case 'J': + return Const.T_LONG; + case 'L': + case 'T': + return Const.T_REFERENCE; + case '[': + return Const.T_ARRAY; + case 'V': + return Const.T_VOID; + case 'Z': + return Const.T_BOOLEAN; + case 'S': + return Const.T_SHORT; + case '!': + case '+': + case '*': + return typeOfSignature(signature.substring(1)); + default: + throw new ClassFormatException("Invalid method signature: " + signature); + } + } catch (final StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + } + + /** + * Map opcode names to opcode numbers. E.g., return Constants.ALOAD for + * "aload" + */ + public static short searchOpcode(String name) { + name = name.toLowerCase(Locale.ENGLISH); + for (short i = 0; i < Const.OPCODE_NAMES_LENGTH; i++) { + if (Const.getOpcodeName(i).equals(name)) { + return i; + } + } + return -1; + } + + /** + * Convert (signed) byte to (unsigned) short value, i.e., all negative + * values become positive. + */ + private static short byteToShort(final byte b) { + return (b < 0) ? (short) (256 + b) : (short) b; + } + + /** + * Convert bytes into hexadecimal string + * + * @param bytes an array of bytes to convert to hexadecimal + * + * @return bytes as hexadecimal string, e.g. 00 fa 12 ... + */ + public static String toHexString(final byte[] bytes) { + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + final short b = byteToShort(bytes[i]); + final String hex = Integer.toHexString(b); + 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 String format(final int i, final int length, + final boolean left_justify, final 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 String fillup(final String str, final int length, + final boolean left_justify, final char fill) { + final int len = length - str.length(); + final char[] buf = new char[(len < 0) ? 0 : len]; + for (int j = 0; j < buf.length; j++) { + buf[j] = fill; + } + if (left_justify) { + return str + new String(buf); + } + return new String(buf) + str; + } + + static boolean equals(final byte[] a, final byte[] b) { + int size; + if ((size = a.length) != b.length) { + return false; + } + for (int i = 0; i < size; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + public static void printArray(final PrintStream out, final Object[] obj) { + out.println(printArray(obj, true)); + } + + public static void printArray(final PrintWriter out, final Object[] obj) { + out.println(printArray(obj, true)); + } + + public static String printArray(final Object[] obj) { + return printArray(obj, true); + } + + public static String printArray(final Object[] obj, final boolean braces) { + return printArray(obj, braces, false); + } + + public static String printArray(final Object[] obj, final boolean braces, final boolean quote) { + if (obj == null) { + return null; + } + final StringBuilder buf = new StringBuilder(); + if (braces) { + buf.append('{'); + } + for (int i = 0; i < obj.length; i++) { + if (obj[i] != null) { + buf.append(quote ? "\"" : "").append(obj[i]).append(quote ? "\"" : ""); + } else { + buf.append("null"); + } + if (i < obj.length - 1) { + buf.append(", "); + } + } + if (braces) { + buf.append('}'); + } + return buf.toString(); + } + + /** + * @param ch the character to test if it's part of an identifier + * + * @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _) + */ + public static boolean isJavaIdentifierPart(final char ch) { + return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) + || ((ch >= '0') && (ch <= '9')) || (ch == '_'); + } + + /** + * Encode byte array it into Java identifier string, i.e., a string that + * only contains the following characters: (a, ... z, A, ... Z, 0, ... 9, _, + * $). The encoding algorithm itself is not too clever: if the current + * byte's ASCII value already is a valid Java identifier part, leave it as + * it is. Otherwise it writes the escape character($) followed by: + * + *
    + *
  • the ASCII value as a hexadecimal string, if the value is not in the + * range 200..247
  • + *
  • a Java identifier char not used in a lowercase hexadecimal string, if + * the value is in the range 200..247
  • + *
+ * + *

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

+ * + * @param bytes the byte array to convert + * @param compress use gzip to minimize string + * + * @throws IOException if there's a gzip exception + */ + public static String encode(byte[] bytes, final boolean compress) throws IOException { + if (compress) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + GZIPOutputStream gos = new GZIPOutputStream(baos)) { + gos.write(bytes, 0, bytes.length); + bytes = baos.toByteArray(); + } + } + final CharArrayWriter caw = new CharArrayWriter(); + try (JavaWriter jw = new JavaWriter(caw)) { + for (final byte b : bytes) { + final int in = b & 0x000000ff; // Normalize to unsigned + jw.write(in); + } + } + return caw.toString(); + } + + /** + * Decode a string back to a byte array. + * + * @param s the string to convert + * @param uncompress use gzip to uncompress the stream of bytes + * + * @throws IOException if there's a gzip exception + */ + public static byte[] decode(final String s, final boolean uncompress) throws IOException { + byte[] bytes; + try (JavaReader jr = new JavaReader(new CharArrayReader(s.toCharArray())); + ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + int ch; + while ((ch = jr.read()) >= 0) { + bos.write(ch); + } + bytes = bos.toByteArray(); + } + if (uncompress) { + final GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); + final byte[] tmp = new byte[bytes.length * 3]; // Rough estimate + int count = 0; + int b; + while ((b = gis.read()) >= 0) { + tmp[count++] = (byte) b; + } + bytes = new byte[count]; + System.arraycopy(tmp, 0, bytes, 0, count); + } + return bytes; + } + + // A-Z, g-z, _, $ + private static final int FREE_CHARS = 48; + private static int[] CHAR_MAP = new int[FREE_CHARS]; + private static int[] MAP_CHAR = new int[256]; // Reverse map + private static final char ESCAPE_CHAR = '$'; + + static { + int j = 0; + for (int i = 'A'; i <= 'Z'; i++) { + CHAR_MAP[j] = i; + MAP_CHAR[i] = j; + j++; + } + for (int i = 'g'; i <= 'z'; i++) { + CHAR_MAP[j] = i; + MAP_CHAR[i] = j; + j++; + } + CHAR_MAP[j] = '$'; + MAP_CHAR['$'] = j; + j++; + CHAR_MAP[j] = '_'; + MAP_CHAR['_'] = j; + } + + /** + * Decode characters into bytes. Used by decode() + */ + private static class JavaReader extends FilterReader { + + public JavaReader(final Reader in) { + super(in); } - buf.append(str.substring(old_index)); // append rest of string - str = buf.toString(); - } - } catch(StringIndexOutOfBoundsException e) { // Should not occur - System.err.println(e); - } - - return str; - } - - /** - * Converts signature to string with all class names compacted. - * - * @param signature to convert - * @return Human readable signature - */ - public static final String signatureToString(String signature) { - return signatureToString(signature, true); - } - - /** - * The field signature represents the value of an argument to a function or - * the value of a variable. It is a series of bytes generated by the - * following grammar: - * - *
-   *  ::= 
-   *       ::= ||
-   *        ::= B|C|D|F|I|J|S|Z
-   *      ::= L;
-   *       ::= [
-   *
-   * The meaning of the base types is as follows:
-   * B byte signed byte
-   * C char character
-   * D double double precision IEEE float
-   * F float single precision IEEE float
-   * I int integer
-   * J long long integer
-   * L; ... an object of the given class
-   * S short signed short
-   * Z boolean true or false
-   * [ ... array
-   * 
- * - * This method converts this string into a Java type declaration such as - * `String[]' and throws a `ClassFormatException' when the parsed type is - * invalid. - * - * @param signature Class signature - * @param chopit Flag that determines whether chopping is executed or not - * @return Java type declaration - * @throws ClassFormatException - */ - public static final String signatureToString(String signature, - boolean chopit) - { - consumed_chars = 1; // This is the default, read just one char like `B' - - try { - switch(signature.charAt(0)) { - case 'B' : return "byte"; - case 'C' : return "char"; - case 'D' : return "double"; - case 'F' : return "float"; - case 'I' : return "int"; - case 'J' : return "long"; - - case 'L' : { // Full class name - int index = signature.indexOf(';'); // Look for closing `;' - - if(index < 0) - throw new ClassFormatException("Invalid signature: " + signature); - - consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed - - return compactClassName(signature.substring(1, index), chopit); - } - - case 'S' : return "short"; - case 'Z' : return "boolean"; - - case '[' : { // Array declaration - int n; - StringBuffer buf, brackets; - String type; - char ch; - int consumed_chars; // Shadows global var - - brackets = new StringBuffer(); // Accumulate []'s - - // Count opening brackets and look for optional size argument - for(n=0; signature.charAt(n) == '['; n++) - brackets.append("[]"); - - consumed_chars = n; // Remember value - - // The rest of the string denotes a `' - type = signatureToString(signature.substring(n), chopit); - - Utility.consumed_chars += consumed_chars; - return type + brackets.toString(); - } - - case 'V' : return "void"; - - default : throw new ClassFormatException("Invalid signature: `" + - signature + "'"); - } - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid signature: " + e + ":" + signature); - } - } - - /** Parse Java type such as "char", or "java.lang.String[]" and return the - * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" respectively. - * - * @param type Java type - * @return byte code signature - */ - public static String getSignature(String type) { - StringBuffer buf = new StringBuffer(); - char[] chars = type.toCharArray(); - boolean char_found = false, delim = false; - int index = -1; - - loop: - for(int i=0; i < chars.length; i++) { - switch(chars[i]) { - case ' ': case '\t': case '\n': case '\r': case '\f': - if(char_found) - delim = true; - break; - - case '[': - if(!char_found) - throw new RuntimeException("Illegal type: " + type); - - index = i; - break loop; - - default: - char_found = true; - if(!delim) - buf.append(chars[i]); - } - } - - int brackets = 0; - - if(index > 0) - brackets = countBrackets(type.substring(index)); - - type = buf.toString(); - buf.setLength(0); - - for(int i=0; i < brackets; i++) - buf.append('['); - - boolean found = false; - - for(int i=Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) { - if(Constants.TYPE_NAMES[i].equals(type)) { - found = true; - buf.append(Constants.SHORT_TYPE_NAMES[i]); - } - } - - if(!found) // Class name - buf.append('L' + type.replace('.', '/') + ';'); - - return buf.toString(); - } - - private static int countBrackets(String brackets) { - char[] chars = brackets.toCharArray(); - int count = 0; - boolean open = false; - - for(int i=0; iConstants - * - * @param signature in format described above - * @return type of method signature - * @see Constants - */ - public static final byte typeOfMethodSignature(String signature) - throws ClassFormatException - { - int index; - - try { - if(signature.charAt(0) != '(') - throw new ClassFormatException("Invalid method signature: " + signature); - - index = signature.lastIndexOf(')') + 1; - return typeOfSignature(signature.substring(index)); - } catch(StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - /** - * Return type of signature as a byte value as defined in Constants - * - * @param signature in format described above - * @return type of signature - * @see Constants - */ - public static final byte typeOfSignature(String signature) - throws ClassFormatException - { - try { - switch(signature.charAt(0)) { - case 'B' : return Constants.T_BYTE; - case 'C' : return Constants.T_CHAR; - case 'D' : return Constants.T_DOUBLE; - case 'F' : return Constants.T_FLOAT; - case 'I' : return Constants.T_INT; - case 'J' : return Constants.T_LONG; - case 'L' : return Constants.T_REFERENCE; - case '[' : return Constants.T_ARRAY; - case 'V' : return Constants.T_VOID; - case 'Z' : return Constants.T_BOOLEAN; - case 'S' : return Constants.T_SHORT; - default: - throw new ClassFormatException("Invalid method signature: " + signature); - } - } catch(StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - /** Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload" - */ - public static short searchOpcode(String name) { - name = name.toLowerCase(); - - for(short i=0; i < Constants.OPCODE_NAMES.length; i++) - if(Constants.OPCODE_NAMES[i].equals(name)) - return i; - - return -1; - } - - /** - * Convert (signed) byte to (unsigned) short value, i.e., all negative - * values become positive. - */ - private static final short byteToShort(byte b) { - return (b < 0)? (short)(256 + b) : (short)b; - } - - /** Convert bytes into hexidecimal string - * - * @return bytes as hexidecimal string, e.g. 00 FA 12 ... - */ - public static final String toHexString(byte[] bytes) { - StringBuffer buf = new StringBuffer(); - - for(int i=0; i < bytes.length; i++) { - short b = byteToShort(bytes[i]); - String hex = Integer.toString(b, 0x10); - - if(b < 0x10) // just one digit, prepend '0' - 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; - } - - static final boolean equals(byte[] a, byte[] b) { - int size; - - if((size=a.length) != b.length) - return false; - - for(int i=0; i < size; i++) - if(a[i] != b[i]) - return false; - - return true; - } - - public static final void printArray(PrintStream out, Object[] obj) { - out.println(printArray(obj, true)); - } - - public static final void printArray(PrintWriter out, Object[] obj) { - out.println(printArray(obj, true)); - } - - public static final String printArray(Object[] obj) { - return printArray(obj, true); - } - - public static final String printArray(Object[] obj, boolean braces) { - return printArray(obj, braces, false); - } - - public static final String printArray(Object[] obj, boolean braces, - boolean quote) { - if(obj == null) - return null; - - StringBuffer buf = new StringBuffer(); - if(braces) - buf.append('{'); - - for(int i=0; i < obj.length; i++) { - if(obj[i] != null) { - buf.append((quote? "\"" : "") + obj[i].toString() + (quote? "\"" : "")); - } else { - buf.append("null"); - } - - if(i < obj.length - 1) { - buf.append(", "); - } - } - - if(braces) - buf.append('}'); - - return buf.toString(); - } - - /** @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _) - */ - public static boolean isJavaIdentifierPart(char ch) { - return ((ch >= 'a') && (ch <= 'z')) || - ((ch >= 'A') && (ch <= 'Z')) || - ((ch >= '0') && (ch <= '9')) || - (ch == '_'); - } - - /** Encode byte array it into Java identifier string, i.e., a string - * that only contains the following characters: (a, ... z, A, ... Z, - * 0, ... 9, _, $). The encoding algorithm itself is not too - * clever: if the current byte's ASCII value already is a valid Java - * identifier part, leave it as it is. Otherwise it writes the - * escape character($) followed by

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

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

      - * - * @param bytes the byte array to convert - * @param compress use gzip to minimize string - */ - public static String encode(byte[] bytes, boolean compress) throws IOException { - if(compress) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - GZIPOutputStream gos = new GZIPOutputStream(baos); - - gos.write(bytes, 0, bytes.length); - gos.close(); - baos.close(); - - bytes = baos.toByteArray(); - } - - CharArrayWriter caw = new CharArrayWriter(); - JavaWriter jw = new JavaWriter(caw); - - for(int i=0; i < bytes.length; i++) { - int in = bytes[i] & 0x000000ff; // Normalize to unsigned - jw.write(in); - } - - return caw.toString(); - } - - /** Decode a string back to a byte array. - * - * @param bytes the byte array to convert - * @param uncompress use gzip to uncompress the stream of bytes - */ - public static byte[] decode(String s, boolean uncompress) throws IOException { - char[] chars = s.toCharArray(); - - CharArrayReader car = new CharArrayReader(chars); - JavaReader jr = new JavaReader(car); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - - int ch; - - while((ch = jr.read()) >= 0) { - bos.write(ch); - } - - bos.close(); - car.close(); - jr.close(); - - byte[] bytes = bos.toByteArray(); - - if(uncompress) { - GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); - - byte[] tmp = new byte[bytes.length * 3]; // Rough estimate - int count = 0; - int b; - - while((b = gis.read()) >= 0) - tmp[count++] = (byte)b; - - bytes = new byte[count]; - System.arraycopy(tmp, 0, bytes, 0, count); - } - - return bytes; - } - - // A-Z, g-z, _, $ - private static final int FREE_CHARS = 48; - private static int[] CHAR_MAP = new int[FREE_CHARS]; - private static int[] MAP_CHAR = new int[256]; // Reverse map - private static final char ESCAPE_CHAR = '$'; - - static { - int j = 0, k = 0; - for(int i='A'; i <= 'Z'; i++) { - CHAR_MAP[j] = i; - MAP_CHAR[i] = j; - j++; - } - - for(int i='g'; i <= 'z'; i++) { - CHAR_MAP[j] = i; - MAP_CHAR[i] = j; - j++; - } - - CHAR_MAP[j] = '$'; - MAP_CHAR['$'] = j; - j++; - - CHAR_MAP[j] = '_'; - MAP_CHAR['_'] = j; - } - - /** Decode characters into bytes. - * Used by decode() - */ - private static class JavaReader extends FilterReader { - public JavaReader(Reader in) { - super(in); - } - - public int read() throws IOException { - int b = in.read(); - - if(b != ESCAPE_CHAR) { - return b; - } else { - int i = in.read(); - - if(i < 0) - return -1; - - if(((i >= '0') && (i <= '9')) || ((i >= 'a') && (i <= 'f'))) { // Normal escape - int j = in.read(); - - if(j < 0) - return -1; - - char[] tmp = { (char)i, (char)j }; - int s = Integer.parseInt(new String(tmp), 16); - - return s; - } else { // Special escape - return MAP_CHAR[i]; + @Override + public int read() throws IOException { + final int b = in.read(); + if (b != ESCAPE_CHAR) { + return b; + } + final int i = in.read(); + if (i < 0) { + return -1; + } + if (((i >= '0') && (i <= '9')) || ((i >= 'a') && (i <= 'f'))) { // Normal escape + final int j = in.read(); + if (j < 0) { + return -1; + } + final char[] tmp = { + (char) i, (char) j + }; + final int s = Integer.parseInt(new String(tmp), 16); + return s; + } + return MAP_CHAR[i]; } - } - } - public int read(char[] cbuf, int off, int len) throws IOException { - for(int i=0; i < len; i++) - cbuf[off + i] = (char)read(); - - return len; - } - } - - /** Encode bytes into valid java identifier characters. - * Used by encode() - */ - private static class JavaWriter extends FilterWriter { - public JavaWriter(Writer out) { - super(out); - } - - public void write(int b) throws IOException { - if(isJavaIdentifierPart((char)b) && (b != ESCAPE_CHAR)) { - out.write(b); - } else { - out.write(ESCAPE_CHAR); // Escape character - - // Special escape - if(b >= 0 && b < FREE_CHARS) { - out.write(CHAR_MAP[b]); - } else { // Normal escape - char[] tmp = Integer.toHexString(b).toCharArray(); - - if(tmp.length == 1) { - out.write('0'); - out.write(tmp[0]); - } else { - out.write(tmp[0]); - out.write(tmp[1]); - } + @Override + public int read(final char[] cbuf, final int off, final int len) throws IOException { + for (int i = 0; i < len; i++) { + cbuf[off + i] = (char) read(); + } + return len; } - } } - public void write(char[] cbuf, int off, int len) throws IOException { - for(int i=0; i < len; i++) - write(cbuf[off + i]); + /** + * Encode bytes into valid java identifier characters. Used by encode() + */ + private static class JavaWriter extends FilterWriter { + + public JavaWriter(final Writer out) { + super(out); + } + + @Override + public void write(final int b) throws IOException { + if (isJavaIdentifierPart((char) b) && (b != ESCAPE_CHAR)) { + out.write(b); + } else { + out.write(ESCAPE_CHAR); // Escape character + // Special escape + if (b >= 0 && b < FREE_CHARS) { + out.write(CHAR_MAP[b]); + } else { // Normal escape + final char[] tmp = Integer.toHexString(b).toCharArray(); + if (tmp.length == 1) { + out.write('0'); + out.write(tmp[0]); + } else { + out.write(tmp[0]); + out.write(tmp[1]); + } + } + } + } + + @Override + public void write(final char[] cbuf, final int off, final int len) throws IOException { + for (int i = 0; i < len; i++) { + write(cbuf[off + i]); + } + } + + @Override + public void write(final String str, final int off, final int len) throws IOException { + write(str.toCharArray(), off, len); + } } - public void write(String str, int off, int len) throws IOException { - write(str.toCharArray(), off, len); + /** + * Escape all occurences of newline chars '\n', quotes \", etc. + */ + public static String convertString(final String label) { + final char[] ch = label.toCharArray(); + final StringBuilder buf = new StringBuilder(); + for (final char element : ch) { + switch (element) { + 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(element); + break; + } + } + return buf.toString(); } - } - - /** - * Escape all occurences of newline chars '\n', quotes \", etc. - */ - public static final String convertString(String label) { - char[] ch = label.toCharArray(); - StringBuffer buf = new StringBuffer(); - - for(int i=0; i < ch.length; i++) { - switch(ch[i]) { - case '\n': - buf.append("\\n"); break; - case '\r': - buf.append("\\r"); break; - case '\"': - buf.append("\\\""); break; - case '\'': - buf.append("\\'"); break; - case '\\': - buf.append("\\\\"); break; - default: - buf.append(ch[i]); break; - } - } - - return buf.toString(); - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java index 2e7b855f72c..03b64877491 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java @@ -21,49 +21,133 @@ package com.sun.org.apache.bcel.internal.classfile; - /** - * Interface to make use of the Visitor pattern programming style. - * I.e. a class that implements this interface can traverse the contents of - * a Java class just by calling the `accept' method which all classes have. + * Interface to make use of the Visitor pattern programming style. I.e. a class + * that implements this interface can traverse the contents of a Java class just + * by calling the `accept' method which all classes have. * - * Implemented by wish of - * Boris Bokowski. - * - * @author M. Dahm + * @version $Id: Visitor.java 1747278 2016-06-07 17:28:43Z britter $ */ -public interface Visitor { - 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 visitConstantNameAndType(ConstantNameAndType obj); - public void visitConstantPool(ConstantPool obj); - public void visitConstantString(ConstantString 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 visitLocalVariableTypeTable(LocalVariableTypeTable obj); - public void visitMethod(Method obj); - public void visitSignature(Signature obj); - public void visitSourceFile(SourceFile obj); - public void visitSynthetic(Synthetic obj); - public void visitUnknown(Unknown obj); - public void visitStackMap(StackMap obj); - public void visitStackMapEntry(StackMapEntry obj); +public interface Visitor +{ + void visitCode(Code obj); + + void visitCodeException(CodeException obj); + + void visitConstantClass(ConstantClass obj); + + void visitConstantDouble(ConstantDouble obj); + + void visitConstantFieldref(ConstantFieldref obj); + + void visitConstantFloat(ConstantFloat obj); + + void visitConstantInteger(ConstantInteger obj); + + void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj); + + void visitConstantInvokeDynamic(ConstantInvokeDynamic obj); + + void visitConstantLong(ConstantLong obj); + + void visitConstantMethodref(ConstantMethodref obj); + + void visitConstantNameAndType(ConstantNameAndType obj); + + void visitConstantPool(ConstantPool obj); + + void visitConstantString(ConstantString obj); + + void visitConstantUtf8(ConstantUtf8 obj); + + void visitConstantValue(ConstantValue obj); + + void visitDeprecated(Deprecated obj); + + void visitExceptionTable(ExceptionTable obj); + + void visitField(Field obj); + + void visitInnerClass(InnerClass obj); + + void visitInnerClasses(InnerClasses obj); + + void visitJavaClass(JavaClass obj); + + void visitLineNumber(LineNumber obj); + + void visitLineNumberTable(LineNumberTable obj); + + void visitLocalVariable(LocalVariable obj); + + void visitLocalVariableTable(LocalVariableTable obj); + + void visitMethod(Method obj); + + void visitSignature(Signature obj); + + void visitSourceFile(SourceFile obj); + + void visitSynthetic(Synthetic obj); + + void visitUnknown(Unknown obj); + + void visitStackMap(StackMap obj); + + void visitStackMapEntry(StackMapEntry obj); + + /** + * @since 6.0 + */ + void visitAnnotation(Annotations obj); + + /** + * @since 6.0 + */ + void visitParameterAnnotation(ParameterAnnotations obj); + + /** + * @since 6.0 + */ + void visitAnnotationEntry(AnnotationEntry obj); + + /** + * @since 6.0 + */ + void visitAnnotationDefault(AnnotationDefault obj); + + /** + * @since 6.0 + */ + void visitLocalVariableTypeTable(LocalVariableTypeTable obj); + + /** + * @since 6.0 + */ + void visitEnclosingMethod(EnclosingMethod obj); + + /** + * @since 6.0 + */ + void visitBootstrapMethods(BootstrapMethods obj); + + /** + * @since 6.0 + */ + void visitMethodParameters(MethodParameters obj); + + /** + * @since 6.0 + */ + void visitConstantMethodType(ConstantMethodType obj); + + /** + * @since 6.0 + */ + void visitConstantMethodHandle(ConstantMethodHandle obj); + + /** + * @since 6.0 + */ + void visitParameterAnnotationEntry(ParameterAnnotationEntry obj); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/package.html b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/package.html index ff0ab4d23c7..ca3f5198c3c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/package.html +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/package.html @@ -1,8 +1,24 @@ + diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java index fe68c2fecfb..a1357bbfa33 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * AALOAD - Load reference from array *
      Stack: ..., arrayref, index -> value
      * - * @author M. Dahm + * @version $Id: AALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class AALOAD extends ArrayInstruction implements StackProducer { - /** Load reference from array - */ - public AALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.AALOAD); - } + + /** Load reference from array + */ + public AALOAD() { + super(com.sun.org.apache.bcel.internal.Const.AALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitAALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitAALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java index e68c8b853fc..9cdc13fe4a9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * AASTORE - Store into reference array *
      Stack: ..., arrayref, index, value -> ...
      * - * @author M. Dahm + * @version $Id: AASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class AASTORE extends ArrayInstruction implements StackConsumer { - /** Store into reference array - */ - public AASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.AASTORE); - } + + /** Store into reference array + */ + public AASTORE() { + super(com.sun.org.apache.bcel.internal.Const.AASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitAASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitAASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java index 777580befe6..2aa9bf6f7f8 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java @@ -21,41 +21,43 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ACONST_NULL - Push null reference *
      Stack: ... -> ..., null
      * - * @author M. Dahm + * @version $Id: ACONST_NULL.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class ACONST_NULL extends Instruction - implements PushInstruction, TypedInstruction { - /** - * Push null reference - */ - public ACONST_NULL() { - super(com.sun.org.apache.bcel.internal.Constants.ACONST_NULL, (short)1); - } +public class ACONST_NULL extends Instruction implements PushInstruction, TypedInstruction { - /** @return Type.NULL - */ - public Type getType(ConstantPoolGen cp) { - return Type.NULL; - } + /** + * Push null reference + */ + public ACONST_NULL() { + super(com.sun.org.apache.bcel.internal.Const.ACONST_NULL, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitACONST_NULL(this); - } + /** @return Type.NULL + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.NULL; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitACONST_NULL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java index 2b9d3d2ee3c..97892b0f88a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.Const; /** * ALOAD - Load reference from local variable *
      Stack: ... -> ..., objectref
      * - * @author M. Dahm + * @version $Id: ALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ALOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.ALOAD, com.sun.org.apache.bcel.internal.Constants.ALOAD_0); - } - /** Load reference from local variable - * @param n index of local variable - */ - public ALOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ALOAD, com.sun.org.apache.bcel.internal.Constants.ALOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ALOAD() { + super(Const.ALOAD, Const.ALOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitALOAD(this); - } + /** Load reference from local variable + * @param n index of local variable + */ + public ALOAD(final int n) { + super(Const.ALOAD, Const.ALOAD_0, n); + } + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java index 71571a1bb19..93b2979257c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java @@ -21,61 +21,63 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * ANEWARRAY - Create new array of references *
      Stack: ..., count -> ..., arrayref
      * - * @author M. Dahm + * @version $Id: ANEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class ANEWARRAY extends CPInstruction - implements LoadClass, AllocationInstruction, ExceptionThrower, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ANEWARRAY() {} +public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, + ExceptionThrower, StackConsumer, StackProducer { - public ANEWARRAY(int index) { - super(com.sun.org.apache.bcel.internal.Constants.ANEWARRAY, index); - } - - public Class[] getExceptions(){ - Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = - ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; - return cs; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitANEWARRAY(this); - } - - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); - - if (t instanceof ArrayType){ - t = ((ArrayType) t).getBasicType(); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ANEWARRAY() { } - return (t instanceof ObjectType)? (ObjectType) t : null; - } + + public ANEWARRAY(final int index) { + super(com.sun.org.apache.bcel.internal.Const.ANEWARRAY, index); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitANEWARRAY(this); + } + + + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java index ec37dae4d3d..44119d3c84e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ARETURN - Return reference from method *
      Stack: ..., objectref -> <empty>
      * - * @author M. Dahm + * @version $Id: ARETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ARETURN extends ReturnInstruction { - /** - * Return reference from method - */ - public ARETURN() { - super(com.sun.org.apache.bcel.internal.Constants.ARETURN); - } + + /** + * Return reference from method + */ + public ARETURN() { + super(com.sun.org.apache.bcel.internal.Const.ARETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitARETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitARETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java index fdd575e2ea3..f2ea6fbb8e7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java @@ -21,39 +21,46 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * ARRAYLENGTH - Get length of array *
      Stack: ..., arrayref -> ..., length
      * - * @author M. Dahm + * @version $Id: ARRAYLENGTH.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ARRAYLENGTH extends Instruction - implements ExceptionThrower, StackProducer { - /** Get length of array - */ - public ARRAYLENGTH() { - super(com.sun.org.apache.bcel.internal.Constants.ARRAYLENGTH, (short)1); - } + implements ExceptionThrower, StackProducer, StackConsumer /* since 6.0 */ { - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NULL_POINTER_EXCEPTION }; - } + /** Get length of array + */ + public ARRAYLENGTH() { + super(com.sun.org.apache.bcel.internal.Const.ARRAYLENGTH, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitARRAYLENGTH(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NULL_POINTER_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitARRAYLENGTH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java index d2cc7f5e18d..f84d9e4f109 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java @@ -18,42 +18,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.Const; /** * ASTORE - Store reference into local variable *
      Stack ..., objectref -> ... 
      * - * @author M. Dahm + * @version $Id: ASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ASTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.ASTORE, com.sun.org.apache.bcel.internal.Constants.ASTORE_0); - } - /** Store reference into local variable - * @param n index of local variable - */ - public ASTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ASTORE, com.sun.org.apache.bcel.internal.Constants.ASTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ASTORE() { + super(Const.ASTORE, Const.ASTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitASTORE(this); - } + /** + * Store reference into local variable + * + * @param n index of local variable + */ + public ASTORE(final int n) { + super(Const.ASTORE, Const.ASTORE_0, n); + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + super.accept(v); + v.visitASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java index 226bf2c6ec9..695ed0d308c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java @@ -21,39 +21,46 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * ATHROW - Throw exception *
      Stack: ..., objectref -> objectref
      * - * @author M. Dahm + * @version $Id: ATHROW.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ATHROW extends Instruction implements UnconditionalBranch, ExceptionThrower { - /** - * Throw exception - */ - public ATHROW() { - super(com.sun.org.apache.bcel.internal.Constants.ATHROW, (short)1); - } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.THROWABLE }; - } + /** + * Throw exception + */ + public ATHROW() { + super(com.sun.org.apache.bcel.internal.Const.ATHROW, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitUnconditionalBranch(this); - v.visitExceptionThrower(this); - v.visitATHROW(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.THROWABLE + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitUnconditionalBranch(this); + v.visitExceptionThrower(this); + v.visitATHROW(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java index 4944d892cdb..00effb7abdf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java @@ -21,10 +21,10 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote family of instructions that allocates space in the heap. * - * @author M. Dahm + * @version $Id: AllocationInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public interface AllocationInstruction {} +public interface AllocationInstruction { +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java new file mode 100644 index 00000000000..61c08bbe894 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java @@ -0,0 +1,90 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.AnnotationElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; + +/** + * @since 6.0 + */ +public class AnnotationElementValueGen extends ElementValueGen +{ + // For annotation element values, this is the annotation + private final AnnotationEntryGen a; + + public AnnotationElementValueGen(final AnnotationEntryGen a, final ConstantPoolGen cpool) + { + super(ANNOTATION, cpool); + this.a = a; + } + + public AnnotationElementValueGen(final int type, final AnnotationEntryGen annotation, + final ConstantPoolGen cpool) + { + super(type, cpool); + if (type != ANNOTATION) { + throw new RuntimeException( + "Only element values of type annotation can be built with this ctor - type specified: " + type); + } + this.a = annotation; + } + + public AnnotationElementValueGen(final AnnotationElementValue value, + final ConstantPoolGen cpool, final boolean copyPoolEntries) + { + super(ANNOTATION, cpool); + a = new AnnotationEntryGen(value.getAnnotationEntry(), cpool, copyPoolEntries); + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 type of value (ANNOTATION == '@') + a.dump(dos); + } + + @Override + public String stringifyValue() + { + throw new RuntimeException("Not implemented yet"); + } + + /** + * Return immutable variant of this AnnotationElementValueGen + */ + @Override + public ElementValue getElementValue() + { + return new AnnotationElementValue(super.getElementValueType(), + a.getAnnotation(), + getConstantPool().getConstantPool()); + } + + public AnnotationEntryGen getAnnotation() + { + return a; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java new file mode 100644 index 00000000000..2cc540efd22 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java @@ -0,0 +1,362 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValuePair; +import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleParameterAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleParameterAnnotations; + +/** + * @since 6.0 + */ +public class AnnotationEntryGen { + private int typeIndex; + + private List evs; + + private final ConstantPoolGen cpool; + + private boolean isRuntimeVisible = false; + + /** + * Here we are taking a fixed annotation of type Annotation and building a + * modifiable AnnotationGen object. If the pool passed in is for a different + * class file, then copyPoolEntries should have been passed as true as that + * will force us to do a deep copy of the annotation and move the cpool + * entries across. We need to copy the type and the element name value pairs + * and the visibility. + */ + public AnnotationEntryGen(final AnnotationEntry a, final ConstantPoolGen cpool, + final boolean copyPoolEntries) { + this.cpool = cpool; + if (copyPoolEntries) { + typeIndex = cpool.addUtf8(a.getAnnotationType()); + } else { + typeIndex = a.getAnnotationTypeIndex(); + } + isRuntimeVisible = a.isRuntimeVisible(); + evs = copyValues(a.getElementValuePairs(), cpool, copyPoolEntries); + } + + private List copyValues(final ElementValuePair[] in, final ConstantPoolGen cpool, + final boolean copyPoolEntries) { + final List out = new ArrayList<>(); + for (final ElementValuePair nvp : in) { + out.add(new ElementValuePairGen(nvp, cpool, copyPoolEntries)); + } + return out; + } + + private AnnotationEntryGen(final ConstantPoolGen cpool) { + this.cpool = cpool; + } + + /** + * Retrieve an immutable version of this AnnotationGen + */ + public AnnotationEntry getAnnotation() { + final AnnotationEntry a = new AnnotationEntry(typeIndex, cpool.getConstantPool(), + isRuntimeVisible); + for (final ElementValuePairGen element : evs) { + a.addElementNameValuePair(element.getElementNameValuePair()); + } + return a; + } + + public AnnotationEntryGen(final ObjectType type, + final List elements, final boolean vis, + final ConstantPoolGen cpool) { + this.cpool = cpool; + this.typeIndex = cpool.addUtf8(type.getSignature()); + evs = elements; + isRuntimeVisible = vis; + } + + public static AnnotationEntryGen read(final DataInput dis, + final ConstantPoolGen cpool, final boolean b) throws IOException { + final AnnotationEntryGen a = new AnnotationEntryGen(cpool); + a.typeIndex = dis.readUnsignedShort(); + final int elemValuePairCount = dis.readUnsignedShort(); + for (int i = 0; i < elemValuePairCount; i++) { + final int nidx = dis.readUnsignedShort(); + a.addElementNameValuePair(new ElementValuePairGen(nidx, + ElementValueGen.readElementValue(dis, cpool), cpool)); + } + a.isRuntimeVisible(b); + return a; + } + + public void dump(final DataOutputStream dos) throws IOException { + dos.writeShort(typeIndex); // u2 index of type name in cpool + dos.writeShort(evs.size()); // u2 element_value pair count + for (final ElementValuePairGen envp : evs) { + envp.dump(dos); + } + } + + public void addElementNameValuePair(final ElementValuePairGen evp) { + if (evs == null) { + evs = new ArrayList<>(); + } + evs.add(evp); + } + + public int getTypeIndex() { + return typeIndex; + } + + public final String getTypeSignature() { + // ConstantClass c = (ConstantClass)cpool.getConstant(typeIndex); + final ConstantUtf8 utf8 = (ConstantUtf8) cpool + .getConstant(typeIndex/* c.getNameIndex() */); + return utf8.getBytes(); + } + + public final String getTypeName() { + return getTypeSignature();// BCELBUG: Should I use this instead? + // Utility.signatureToString(getTypeSignature()); + } + + /** + * Returns list of ElementNameValuePair objects + */ + public List getValues() { + return evs; + } + + @Override + public String toString() { + final StringBuilder s = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber + s.append("AnnotationGen:[").append(getTypeName()).append(" #").append(evs.size()).append(" {"); + for (int i = 0; i < evs.size(); i++) { + s.append(evs.get(i)); + if (i + 1 < evs.size()) { + s.append(","); + } + } + s.append("}]"); + return s.toString(); + } + + public String toShortString() { + final StringBuilder s = new StringBuilder(); + s.append("@").append(getTypeName()).append("("); + for (int i = 0; i < evs.size(); i++) { + s.append(evs.get(i)); + if (i + 1 < evs.size()) { + s.append(","); + } + } + s.append(")"); + return s.toString(); + } + + private void isRuntimeVisible(final boolean b) { + isRuntimeVisible = b; + } + + public boolean isRuntimeVisible() { + return isRuntimeVisible; + } + + + /** + * 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 annotationEntryGens An array of AnnotationGen objects + */ + static Attribute[] getAnnotationAttributes(final ConstantPoolGen cp, final AnnotationEntryGen[] annotationEntryGens) { + if (annotationEntryGens.length == 0) { + return new Attribute[0]; + } + + try { + int countVisible = 0; + int countInvisible = 0; + + // put the annotations in the right output stream + for (final AnnotationEntryGen a : annotationEntryGens) { + if (a.isRuntimeVisible()) { + countVisible++; + } else { + countInvisible++; + } + } + + final ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); + final ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); + try (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 (final AnnotationEntryGen a : annotationEntryGens) { + if (a.isRuntimeVisible()) { + a.dump(rvaDos); + } else { + a.dump(riaDos); + } + } + } + + final byte[] rvaData = rvaBytes.toByteArray(); + final 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"); + } + + final List newAttributes = new ArrayList<>(); + if (rvaData.length > 2) { + newAttributes.add( + new RuntimeVisibleAnnotations(rvaIndex, rvaData.length, + new DataInputStream(new ByteArrayInputStream(rvaData)), cp.getConstantPool())); + } + if (riaData.length > 2) { + newAttributes.add( + new RuntimeInvisibleAnnotations(riaIndex, riaData.length, + new DataInputStream(new ByteArrayInputStream(riaData)), cp.getConstantPool())); + } + + return newAttributes.toArray(new Attribute[newAttributes.size()]); + } catch (final IOException e) { + System.err.println("IOException whilst processing annotations. " + + e.getMessage()); + } + return null; + } + + + /** + * Annotations against a class are stored in one of four attribute kinds: + * - RuntimeVisibleParameterAnnotations + * - RuntimeInvisibleParameterAnnotations + */ + static Attribute[] getParameterAnnotationAttributes( + final ConstantPoolGen cp, + final List[] /*Array of lists, array size depends on #params */vec) { + final int[] visCount = new int[vec.length]; + int totalVisCount = 0; + final int[] invisCount = new int[vec.length]; + int totalInvisCount = 0; + try { + for (int i = 0; i < vec.length; i++) { + if (vec[i] != null) { + for (final AnnotationEntryGen element : vec[i]) { + if (element.isRuntimeVisible()) { + visCount[i]++; + totalVisCount++; + } else { + invisCount[i]++; + totalInvisCount++; + } + } + } + } + // Lets do the visible ones + final ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); + try (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) { + for (final AnnotationEntryGen element : vec[i]) { + if (element.isRuntimeVisible()) { + element.dump(rvaDos); + } + } + } + } + } + // Lets do the invisible ones + final ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); + try (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) { + for (final AnnotationEntryGen element : vec[i]) { + if (!element.isRuntimeVisible()) { + element.dump(riaDos); + } + } + } + } + } + final byte[] rvaData = rvaBytes.toByteArray(); + final byte[] riaData = riaBytes.toByteArray(); + int rvaIndex = -1; + int riaIndex = -1; + if (totalVisCount > 0) { + rvaIndex = cp.addUtf8("RuntimeVisibleParameterAnnotations"); + } + if (totalInvisCount > 0) { + riaIndex = cp.addUtf8("RuntimeInvisibleParameterAnnotations"); + } + final List newAttributes = new ArrayList<>(); + if (totalVisCount > 0) { + newAttributes + .add(new RuntimeVisibleParameterAnnotations(rvaIndex, + rvaData.length, + new DataInputStream(new ByteArrayInputStream(rvaData)), + cp.getConstantPool())); + } + if (totalInvisCount > 0) { + newAttributes + .add(new RuntimeInvisibleParameterAnnotations(riaIndex, + riaData.length, + new DataInputStream(new ByteArrayInputStream(riaData)), + cp.getConstantPool())); + } + return newAttributes.toArray(new Attribute[newAttributes.size()]); + } catch (final IOException e) { + System.err.println("IOException whilst processing parameter annotations." + + e.getMessage()); + } + return null; + } + +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java index becf27342d0..e44e49c1839 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java @@ -21,53 +21,80 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; + /** * Super class for the family of arithmetic instructions. * - * @author M. Dahm + * @version $Id: ArithmeticInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ArithmeticInstruction extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ArithmeticInstruction() {} +public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - /** - * @param opcode of instruction - */ - protected ArithmeticInstruction(short opcode) { - super(opcode, (short)1); - } - - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(opcode) { - case Constants.DADD: case Constants.DDIV: case Constants.DMUL: - case Constants.DNEG: case Constants.DREM: case Constants.DSUB: - return Type.DOUBLE; - - case Constants.FADD: case Constants.FDIV: case Constants.FMUL: - case Constants.FNEG: case Constants.FREM: case Constants.FSUB: - return Type.FLOAT; - - case Constants.IADD: case Constants.IAND: case Constants.IDIV: - case Constants.IMUL: case Constants.INEG: case Constants.IOR: case Constants.IREM: - case Constants.ISHL: case Constants.ISHR: case Constants.ISUB: - case Constants.IUSHR: case Constants.IXOR: - return Type.INT; - - case Constants.LADD: case Constants.LAND: case Constants.LDIV: - case Constants.LMUL: case Constants.LNEG: case Constants.LOR: case Constants.LREM: - case Constants.LSHL: case Constants.LSHR: case Constants.LSUB: - case Constants.LUSHR: case Constants.LXOR: - return Type.LONG; - - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ArithmeticInstruction() { + } + + + /** + * @param opcode of instruction + */ + protected ArithmeticInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case Const.DADD: + case Const.DDIV: + case Const.DMUL: + case Const.DNEG: + case Const.DREM: + case Const.DSUB: + return Type.DOUBLE; + case Const.FADD: + case Const.FDIV: + case Const.FMUL: + case Const.FNEG: + case Const.FREM: + case Const.FSUB: + return Type.FLOAT; + case Const.IADD: + case Const.IAND: + case Const.IDIV: + case Const.IMUL: + case Const.INEG: + case Const.IOR: + case Const.IREM: + case Const.ISHL: + case Const.ISHR: + case Const.ISUB: + case Const.IUSHR: + case Const.IXOR: + return Type.INT; + case Const.LADD: + case Const.LAND: + case Const.LDIV: + case Const.LMUL: + case Const.LNEG: + case Const.LOR: + case Const.LREM: + case Const.LSHL: + case Const.LSHR: + case Const.LSUB: + case Const.LUSHR: + case Const.LXOR: + return Type.LONG; + default: // Never reached + throw new ClassGenException("Unknown type " + _opcode); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java new file mode 100644 index 00000000000..699b6560cb6 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java @@ -0,0 +1,131 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.classfile.ArrayElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; + +/** + * @since 6.0 + */ +public class ArrayElementValueGen extends ElementValueGen +{ + // J5TODO: Should we make this an array or a list? A list would be easier to + // modify ... + private final List evalues; + + public ArrayElementValueGen(final ConstantPoolGen cp) + { + super(ARRAY, cp); + evalues = new ArrayList<>(); + } + + public ArrayElementValueGen(final int type, final ElementValue[] datums, + final ConstantPoolGen cpool) + { + super(type, cpool); + if (type != ARRAY) { + throw new RuntimeException( + "Only element values of type array can be built with this ctor - type specified: " + type); + } + this.evalues = new ArrayList<>(); + for (final ElementValue datum : datums) { + evalues.add(ElementValueGen.copy(datum, cpool, true)); + } + } + + /** + * Return immutable variant of this ArrayElementValueGen + */ + @Override + public ElementValue getElementValue() + { + final ElementValue[] immutableData = new ElementValue[evalues.size()]; + int i = 0; + for (final ElementValueGen element : evalues) { + immutableData[i++] = element.getElementValue(); + } + return new ArrayElementValue(super.getElementValueType(), + immutableData, + getConstantPool().getConstantPool()); + } + + /** + * @param value + * @param cpool + */ + public ArrayElementValueGen(final ArrayElementValue value, final ConstantPoolGen cpool, + final boolean copyPoolEntries) + { + super(ARRAY, cpool); + evalues = new ArrayList<>(); + final ElementValue[] in = value.getElementValuesArray(); + for (final ElementValue element : in) { + evalues.add(ElementValueGen.copy(element, cpool, copyPoolEntries)); + } + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 type of value (ARRAY == '[') + dos.writeShort(evalues.size()); + for (final ElementValueGen element : evalues) { + element.dump(dos); + } + } + + @Override + public String stringifyValue() + { + final StringBuilder sb = new StringBuilder(); + sb.append("["); + String comma = ""; + for (final ElementValueGen element : evalues) { + sb.append(comma); + comma = ","; + sb.append(element.stringifyValue()); + } + sb.append("]"); + return sb.toString(); + } + + public List getElementValues() + { + return evalues; + } + + public int getElementValuesSize() + { + return evalues.size(); + } + + public void addElement(final ElementValueGen gen) + { + evalues.add(gen); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java index 62e90a44b01..c43a3592533 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java @@ -21,53 +21,70 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * Super class for instructions dealing with array access such as IALOAD. * - * @author M. Dahm + * @version $Id: ArrayInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ArrayInstruction extends Instruction - implements ExceptionThrower, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ArrayInstruction() {} +public abstract class ArrayInstruction extends Instruction implements ExceptionThrower, + TypedInstruction { - /** - * @param opcode of instruction - */ - protected ArrayInstruction(short opcode) { - super(opcode, (short)1); - } - - public Class[] getExceptions() { - return com.sun.org.apache.bcel.internal.ExceptionConstants.EXCS_ARRAY_EXCEPTION; - } - - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(opcode) { - case com.sun.org.apache.bcel.internal.Constants.IALOAD: case com.sun.org.apache.bcel.internal.Constants.IASTORE: - return Type.INT; - case com.sun.org.apache.bcel.internal.Constants.CALOAD: case com.sun.org.apache.bcel.internal.Constants.CASTORE: - return Type.CHAR; - case com.sun.org.apache.bcel.internal.Constants.BALOAD: case com.sun.org.apache.bcel.internal.Constants.BASTORE: - return Type.BYTE; - case com.sun.org.apache.bcel.internal.Constants.SALOAD: case com.sun.org.apache.bcel.internal.Constants.SASTORE: - return Type.SHORT; - case com.sun.org.apache.bcel.internal.Constants.LALOAD: case com.sun.org.apache.bcel.internal.Constants.LASTORE: - return Type.LONG; - case com.sun.org.apache.bcel.internal.Constants.DALOAD: case com.sun.org.apache.bcel.internal.Constants.DASTORE: - return Type.DOUBLE; - case com.sun.org.apache.bcel.internal.Constants.FALOAD: case com.sun.org.apache.bcel.internal.Constants.FASTORE: - return Type.FLOAT; - case com.sun.org.apache.bcel.internal.Constants.AALOAD: case com.sun.org.apache.bcel.internal.Constants.AASTORE: - return Type.OBJECT; - - default: throw new ClassGenException("Oops: unknown case in switch" + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ArrayInstruction() { + } + + + /** + * @param opcode of instruction + */ + protected ArrayInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_ARRAY_EXCEPTION); + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case com.sun.org.apache.bcel.internal.Const.IALOAD: + case com.sun.org.apache.bcel.internal.Const.IASTORE: + return Type.INT; + case com.sun.org.apache.bcel.internal.Const.CALOAD: + case com.sun.org.apache.bcel.internal.Const.CASTORE: + return Type.CHAR; + case com.sun.org.apache.bcel.internal.Const.BALOAD: + case com.sun.org.apache.bcel.internal.Const.BASTORE: + return Type.BYTE; + case com.sun.org.apache.bcel.internal.Const.SALOAD: + case com.sun.org.apache.bcel.internal.Const.SASTORE: + return Type.SHORT; + case com.sun.org.apache.bcel.internal.Const.LALOAD: + case com.sun.org.apache.bcel.internal.Const.LASTORE: + return Type.LONG; + case com.sun.org.apache.bcel.internal.Const.DALOAD: + case com.sun.org.apache.bcel.internal.Const.DASTORE: + return Type.DOUBLE; + case com.sun.org.apache.bcel.internal.Const.FALOAD: + case com.sun.org.apache.bcel.internal.Const.FASTORE: + return Type.FLOAT; + case com.sun.org.apache.bcel.internal.Const.AALOAD: + case com.sun.org.apache.bcel.internal.Const.AASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Oops: unknown case in switch" + _opcode); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java index 035602d8351..8d7b57ebdbc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java @@ -18,106 +18,111 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; /** * Denotes array type, such as int[][] * - * @author M. Dahm + * @version $Id: ArrayType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ 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); - } + private int dimensions; + private Type basic_type; - /** - * Convenience constructor for reference array type, e.g. Object[] - * - * @param class_name complete name of class (java.lang.String, e.g.) - */ - public ArrayType(String class_name, int dimensions) { - this(new ObjectType(class_name), dimensions); - } - - /** - * Constructor for array of given type - * - * @param type type of array (may be an array itself) - */ - public ArrayType(Type type, int dimensions) { - super(Constants.T_ARRAY, ""); - - if((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) - throw new ClassGenException("Invalid number of dimensions: " + dimensions); - - switch(type.getType()) { - case Constants.T_ARRAY: - ArrayType array = (ArrayType)type; - this.dimensions = dimensions + array.dimensions; - basic_type = array.basic_type; - break; - - case Constants.T_VOID: - throw new ClassGenException("Invalid type: void[]"); - - default: // Basic type or reference - this.dimensions = dimensions; - basic_type = type; - break; + /** + * Convenience constructor for array type, e.g. int[] + * + * @param type array type, e.g. T_INT + */ + public ArrayType(final byte type, final int dimensions) { + this(BasicType.getType(type), dimensions); } - StringBuffer buf = new StringBuffer(); - for(int i=0; i < this.dimensions; i++) - buf.append('['); + /** + * Convenience constructor for reference array type, e.g. Object[] + * + * @param class_name complete name of class (java.lang.String, e.g.) + */ + public ArrayType(final String class_name, final int dimensions) { + this(ObjectType.getInstance(class_name), dimensions); + } - buf.append(basic_type.getSignature()); + /** + * Constructor for array of given type + * + * @param type type of array (may be an array itself) + */ + public ArrayType(final Type type, final int dimensions) { + super(Const.T_ARRAY, ""); + if ((dimensions < 1) || (dimensions > Const.MAX_BYTE)) { + throw new ClassGenException("Invalid number of dimensions: " + dimensions); + } + switch (type.getType()) { + case Const.T_ARRAY: + final ArrayType array = (ArrayType) type; + this.dimensions = dimensions + array.dimensions; + basic_type = array.basic_type; + break; + case Const.T_VOID: + throw new ClassGenException("Invalid type: void[]"); + default: // Basic type or reference + this.dimensions = dimensions; + basic_type = type; + break; + } + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < this.dimensions; i++) { + buf.append('['); + } + buf.append(basic_type.getSignature()); + super.setSignature(buf.toString()); + } - signature = buf.toString(); - } + /** + * @return basic type of array, i.e., for int[][][] the basic type is int + */ + public Type getBasicType() { + return basic_type; + } - /** - * @return basic type of array, i.e., for int[][][] the basic type is int - */ - public Type getBasicType() { - return basic_type; - } + /** + * @return element type of array, i.e., for int[][][] the element type is + * int[][] + */ + public Type getElementType() { + if (dimensions == 1) { + return basic_type; + } + return new ArrayType(basic_type, dimensions - 1); + } - /** - * @return 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 number of dimensions of array - */ - public int getDimensions() { return dimensions; } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return basic_type.hashCode() ^ dimensions; + } - /** @return 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; - } + /** + * @return true if both type objects refer to the same array type. + */ + @Override + public boolean equals(final Object _type) { + if (_type instanceof ArrayType) { + final ArrayType array = (ArrayType) _type; + return (array.dimensions == dimensions) && array.basic_type.equals(basic_type); + } + return false; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java index b198401b455..14f0115f9ae 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java @@ -18,37 +18,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * BALOAD - Load byte or boolean from array *
      Stack: ..., arrayref, index -> ..., value
      * - * @author M. Dahm + * @version $Id: BALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BALOAD extends ArrayInstruction implements StackProducer { - /** Load byte or boolean from array - */ - public BALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.BALOAD); - } + /** + * Load byte or boolean from array + */ + public BALOAD() { + super(com.sun.org.apache.bcel.internal.Const.BALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitBALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitBALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java index 67a5fab11a3..cd1bb9f3a7b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java @@ -18,37 +18,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** - * BASTORE - Store into byte or boolean array + * BASTORE - Store into byte or boolean array *
      Stack: ..., arrayref, index, value -> ...
      * - * @author M. Dahm + * @version $Id: BASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BASTORE extends ArrayInstruction implements StackConsumer { - /** Store byte or boolean into array - */ - public BASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.BASTORE); - } + /** + * Store byte or boolean into array + */ + public BASTORE() { + super(com.sun.org.apache.bcel.internal.Const.BASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitBASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitBASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java index bb4e12f858a..c55abd5d900 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java @@ -17,11 +17,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -29,69 +29,80 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
      Stack: ... -> ..., value
      * - * @author M. Dahm + * @version $Id: BIPUSH.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BIPUSH extends Instruction implements ConstantPushInstruction { - private byte b; - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - BIPUSH() {} + private byte b; - /** Push byte on stack - */ - public BIPUSH(byte b) { - super(com.sun.org.apache.bcel.internal.Constants.BIPUSH, (short)2); - this.b = b; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + BIPUSH() { + } - /** - * Dump instruction as byte code to stream out. - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - out.writeByte(b); - } + /** + * Push byte on stack + */ + public BIPUSH(final byte b) { + super(com.sun.org.apache.bcel.internal.Const.BIPUSH, (short) 2); + this.b = b; + } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + b; - } + /** + * Dump instruction as byte code to stream out. + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + super.dump(out); + out.writeByte(b); + } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - length = 2; - b = bytes.readByte(); - } + /** + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + b; + } - public Number getValue() { return Integer.valueOf(b); } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(2); + b = bytes.readByte(); + } - /** @return Type.BYTE - */ - public Type getType(ConstantPoolGen cp) { - return Type.BYTE; - } + @Override + public Number getValue() { + return Integer.valueOf(b); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitBIPUSH(this); - } + /** + * @return Type.BYTE + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.BYTE; + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitBIPUSH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java index 9715ea5324e..be1ac7afb7f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java @@ -18,29 +18,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * BREAKPOINT, JVM dependent, ignored by default * - * @author M. Dahm + * @version $Id: BREAKPOINT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class BREAKPOINT extends Instruction { - public BREAKPOINT() { - super(com.sun.org.apache.bcel.internal.Constants.BREAKPOINT, (short)1); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitBREAKPOINT(this); - } + public BREAKPOINT() { + super(com.sun.org.apache.bcel.internal.Const.BREAKPOINT, (short) 1); + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitBREAKPOINT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java index 00a5def2646..ab432a82f61 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java @@ -18,57 +18,69 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; /** * Denotes basic type such as int. * - * @author M. Dahm + * @version $Id: BasicType.java 1747278 2016-06-07 17:28:43Z britter $ */ 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 com.sun.org.apache.bcel.internal.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); + /** + * Constructor for basic types such as int, long, `void' + * + * @param type one of T_INT, T_BOOLEAN, ..., T_VOID + * @see Const + */ + BasicType(final byte type) { + super(type, Const.getShortTypeName(type)); + if ((type < Const.T_BOOLEAN) || (type > Const.T_VOID)) { + throw new ClassGenException("Invalid type: " + type); + } } - } - /** @return true if both type objects refer to the same type - */ - @Override - public boolean equals(Object type) { - return (type instanceof BasicType)? - ((BasicType)type).type == this.type : false; - } + // @since 6.0 no longer final + public static BasicType getType(final byte type) { + switch (type) { + case Const.T_VOID: + return VOID; + case Const.T_BOOLEAN: + return BOOLEAN; + case Const.T_BYTE: + return BYTE; + case Const.T_SHORT: + return SHORT; + case Const.T_CHAR: + return CHAR; + case Const.T_INT: + return INT; + case Const.T_LONG: + return LONG; + case Const.T_DOUBLE: + return DOUBLE; + case Const.T_FLOAT: + return FLOAT; + default: + throw new ClassGenException("Invalid type: " + type); + } + } - @Override - public int hashCode() { - return type; - } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return super.getType(); + } + + /** + * @return true if both type objects refer to the same type + */ + @Override + public boolean equals(final Object _type) { + return (_type instanceof BasicType) ? ((BasicType) _type).getType() == this.getType() : false; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java index 3ab01f5d821..ebf32b0d47d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java @@ -18,100 +18,110 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * BranchHandle is returned by specialized InstructionList.append() whenever a * BranchInstruction is appended. This is useful when the target of this - * instruction is not known at time of creation and must be set later - * via setTarget(). + * instruction is not known at time of creation and must be set later via + * setTarget(). * * @see InstructionHandle * @see Instruction * @see InstructionList - * @author M. Dahm + * @version $Id: BranchHandle.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class BranchHandle extends InstructionHandle { - private BranchInstruction bi; // An alias in fact, but saves lots of casts - private BranchHandle(BranchInstruction i) { - super(i); - bi = i; - } + // This is also a cache in case the InstructionHandle#swapInstruction() method is used + // See BCEL-273 + private BranchInstruction bi; // An alias in fact, but saves lots of casts - /** Factory methods. - */ - private static BranchHandle bh_list = null; // List of reusable handles - - static final BranchHandle getBranchHandle(BranchInstruction i) { - if(bh_list == null) - return new BranchHandle(i); - else { - BranchHandle bh = bh_list; - bh_list = (BranchHandle)bh.next; - - bh.setInstruction(i); - - return bh; + private BranchHandle(final BranchInstruction i) { + super(i); + bi = i; } - } - /** Handle adds itself to the list of resuable handles. - */ - protected void addHandle() { - next = bh_list; - bh_list = this; - } + /** + * Factory methods. + */ + private static BranchHandle bh_list = null; // List of reusable handles - /* Override InstructionHandle methods: delegate to branch instruction. - * Through this overriding all access to the private i_position field should - * be prevented. - */ - public int getPosition() { return bi.position; } + static BranchHandle getBranchHandle(final BranchInstruction i) { + if (bh_list == null) { + return new BranchHandle(i); + } + final BranchHandle bh = bh_list; + bh_list = (BranchHandle) bh.getNext(); + bh.setInstruction(i); + return bh; + } - void setPosition(int pos) { - i_position = bi.position = pos; - } + /** + * Handle adds itself to the list of resuable handles. + */ + @Override + protected void addHandle() { + super.setNext(bh_list); + bh_list = this; + } - protected int updatePosition(int offset, int max_offset) { - int x = bi.updatePosition(offset, max_offset); - i_position = bi.position; - return x; - } - /** - * Pass new target to instruction. - */ - public void setTarget(InstructionHandle ih) { - bi.setTarget(ih); - } + /* Override InstructionHandle methods: delegate to branch instruction. + * Through this overriding all access to the private i_position field should + * be prevented. + */ + @Override + public int getPosition() { + return bi.getPosition(); + } - /** - * Update target of instruction. - */ - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - bi.updateTarget(old_ih, new_ih); - } + @Override + void setPosition(final int pos) { + // Original code: i_position = bi.position = pos; + bi.setPosition(pos); + super.setPosition(pos); + } - /** - * @return target of instruction. - */ - public InstructionHandle getTarget() { - return bi.getTarget(); - } + @Override + protected int updatePosition(final int offset, final int max_offset) { + final int x = bi.updatePosition(offset, max_offset); + super.setPosition(bi.getPosition()); + return x; + } - /** - * Set new contents. Old instruction is disposed and may not be used anymore. - */ - public void setInstruction(Instruction i) { - super.setInstruction(i); + /** + * Pass new target to instruction. + */ + public void setTarget(final InstructionHandle ih) { + bi.setTarget(ih); + } - if(!(i instanceof BranchInstruction)) - throw new ClassGenException("Assigning " + i + - " to branch handle which is not a branch instruction"); + /** + * Update target of instruction. + */ + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + bi.updateTarget(old_ih, new_ih); + } - bi = (BranchInstruction)i; - } + /** + * @return target of instruction. + */ + public InstructionHandle getTarget() { + return bi.getTarget(); + } + + /** + * Set new contents. Old instruction is disposed and may not be used + * anymore. + */ + @Override // This is only done in order to apply the additional type check; could be merged with super impl. + public void setInstruction(final Instruction i) { // TODO could be package-protected? + super.setInstruction(i); + if (!(i instanceof BranchInstruction)) { + throw new ClassGenException("Assigning " + i + + " to branch handle which is not a branch instruction"); + } + bi = (BranchInstruction) i; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java index 77f5a86af57..c1d92d38f68 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java @@ -18,216 +18,246 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** - * Abstract super class for branching instructions like GOTO, IFEQ, etc.. - * Branch instructions may have a variable length, namely GOTO, JSR, - * LOOKUPSWITCH and TABLESWITCH. + * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch + * instructions may have a variable length, namely GOTO, JSR, LOOKUPSWITCH and + * TABLESWITCH. * * @see InstructionList - * @author M. Dahm + * @version $Id: BranchInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public abstract class BranchInstruction extends Instruction implements InstructionTargeter { - protected int index; // Branch target relative to this instruction - protected InstructionHandle target; // Target object in instruction list - protected int position; // Byte code offset - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - BranchInstruction() {} + private int index; // Branch target relative to this instruction + private InstructionHandle target; // Target object in instruction list + private int position; // Byte code offset - /** Common super constructor - * @param opcodee Instruction opcode - * @param target instruction to branch to - */ - protected BranchInstruction(short opcode, InstructionHandle target) { - super(opcode, (short)3); - setTarget(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + BranchInstruction() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); + /** + * Common super constructor + * + * @param opcode Instruction opcode + * @param target instruction to branch to + */ + protected BranchInstruction(final short opcode, final InstructionHandle target) { + super(opcode, (short) 3); + setTarget(target); + } - index = getTargetOffset(); - - if(Math.abs(index) >= 32767) // too large for short - throw new ClassGenException("Branch target offset too large for short"); - - out.writeShort(index); // May be negative, i.e., point backwards - } - - /** - * @param target branch target - * @return the offset to `target' relative to this instruction - */ - protected int getTargetOffset(InstructionHandle target) { - if(target == null) - throw new ClassGenException("Target of " + super.toString(true) + - " is invalid null handle"); - - int t = target.getPosition(); - - if(t < 0) - throw new ClassGenException("Invalid branch target position offset for " + - super.toString(true) + ":" + t + ":" + target); - - return t - position; - } - - /** - * @return the offset to this instruction's target - */ - protected int getTargetOffset() { return getTargetOffset(target); } - - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition(int offset, int max_offset) { - position += offset; - return 0; - } - - /** - * Long output format: - * - * <position in byte code> - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" - * "<"<target instruction>">" "@"<branch target offset> - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - @Override - public String toString(boolean verbose) { - String s = super.toString(verbose); - String t = "null"; - - if(verbose) { - if(target != null) { - if(target.getInstruction() == this) - t = ""; - else if(target.getInstruction() == null) - t = ""; - else - t = target.getInstruction().toString(false); // Avoid circles - } - } else { - if(target != null) { + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); index = getTargetOffset(); - t = "" + (index + position); - } + if (!isValidShort(index)) { + throw new ClassGenException("Branch target offset too large for short: " + index); + } + out.writeShort(index); // May be negative, i.e., point backwards } - return s + " -> " + t; - } - - /** - * Read needed data (e.g. index) from file. Conversion to a InstructionHandle - * is done in InstructionList(byte[]). - * - * @param bytes input stream - * @param wide wide prefix? - * @see InstructionList - */ - @Override - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - length = 3; - index = bytes.readShort(); - } - - /** - * @return target offset in byte code - */ - public final int getIndex() { return index; } - - /** - * @return target of branch instruction - */ - public InstructionHandle getTarget() { return target; } - - /** - * Set branch target - * @param target branch target - */ - public final void setTarget(InstructionHandle target) { - notifyTargetChanging(this.target, this); - this.target = target; - notifyTargetChanged(this.target, this); - } - - /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen. - * Must be called before the target is actually changed in the - * InstructionTargeter. - */ - static void notifyTargetChanging(InstructionHandle old_ih, - InstructionTargeter t) { - if(old_ih != null) { - old_ih.removeTargeter(t); + /** + * @param _target branch target + * @return the offset to `target' relative to this instruction + */ + protected int getTargetOffset(final InstructionHandle _target) { + if (_target == null) { + throw new ClassGenException("Target of " + super.toString(true) + + " is invalid null handle"); + } + final int t = _target.getPosition(); + if (t < 0) { + throw new ClassGenException("Invalid branch target position offset for " + + super.toString(true) + ":" + t + ":" + _target); + } + return t - position; } - } - /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen. - * Must be called after the target is actually changed in the - * InstructionTargeter. - */ - static void notifyTargetChanged(InstructionHandle new_ih, - InstructionTargeter t) { - if(new_ih != null) { - new_ih.addTargeter(t); + /** + * @return the offset to this instruction's target + */ + protected int getTargetOffset() { + return getTargetOffset(target); } - } - /** - * @param old_ih old target - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - if(target == old_ih) - setTarget(new_ih); - else - throw new ClassGenException("Not targeting " + old_ih + ", but " + target); - } + /** + * 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(final int offset, final int max_offset) { + position += offset; + return 0; + } - /** - * @return true, if ih is target of this instruction - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return (target == ih); - } + /** + * Long output format: + * + * <position in byte code> <name of opcode> "["<opcode + * number>"]" "("<length of instruction>")" "<"<target + * instruction>">" "@"<branch target offset> + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + final String s = super.toString(verbose); + String t = "null"; + if (verbose) { + if (target != null) { + if (target.getInstruction() == this) { + t = ""; + } else if (target.getInstruction() == null) { + t = ""; + } else { + // I'm more interested in the address of the target then + // the instruction located there. + //t = target.getInstruction().toString(false); // Avoid circles + t = "" + target.getPosition(); + } + } + } else { + if (target != null) { + index = target.getPosition(); + // index = getTargetOffset(); crashes if positions haven't been set + // t = "" + (index + position); + t = "" + index; + } + } + return s + " -> " + t; + } + + /** + * Read needed data (e.g. index) from file. Conversion to a + * InstructionHandle is done in InstructionList(byte[]). + * + * @param bytes input stream + * @param wide wide prefix? + * @see InstructionList + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(3); + index = bytes.readShort(); + } + + /** + * @return target offset in byte code + */ + public final int getIndex() { + return index; + } + + /** + * @return target of branch instruction + */ + public InstructionHandle getTarget() { + return target; + } + + /** + * Set branch target + * + * @param target branch target + */ + public void setTarget(final InstructionHandle target) { + notifyTarget(this.target, target, this); + this.target = target; + } + + /** + * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen, + * LineNumberGen + */ + static void notifyTarget(final InstructionHandle old_ih, final InstructionHandle new_ih, + final InstructionTargeter t) { + if (old_ih != null) { + old_ih.removeTargeter(t); + } + if (new_ih != null) { + new_ih.addTargeter(t); + } + } + + /** + * @param old_ih old target + * @param new_ih new target + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + if (target == old_ih) { + setTarget(new_ih); + } else { + throw new ClassGenException("Not targeting " + old_ih + ", but " + target); + } + } + + /** + * @return true, if ih is target of this instruction + */ + @Override + public boolean containsTarget(final InstructionHandle ih) { + return target == ih; + } + + /** + * Inform target that it's not targeted anymore. + */ + @Override + void dispose() { + setTarget(null); + index = -1; + position = -1; + } + + /** + * @return the position + * @since 6.0 + */ + protected int getPosition() { + return position; + } + + /** + * @param position the position to set + * @since 6.0 + */ + protected void setPosition(final int position) { + this.position = position; + } + + /** + * @param index the index to set + * @since 6.0 + */ + protected void setIndex(final int index) { + this.index = index; + } - /** - * Inform target that it's not targeted anymore. - */ - @Override - void dispose() { - setTarget(null); - index=-1; - position=-1; - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java index e0cd6aac454..76c5d00cdd1 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * CALOAD - Load char from array *
      Stack: ..., arrayref, index -> ..., value
      * - * @author M. Dahm + * @version $Id: CALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class CALOAD extends ArrayInstruction implements StackProducer { - /** Load char from array - */ - public CALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.CALOAD); - } + + /** Load char from array + */ + public CALOAD() { + super(com.sun.org.apache.bcel.internal.Const.CALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitCALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitCALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java index 2bb7678b3bb..93ae7a7acbc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * CASTORE - Store into char array *
      Stack: ..., arrayref, index, value -> ...
      * - * @author M. Dahm + * @version $Id: CASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class CASTORE extends ArrayInstruction implements StackConsumer { - /** Store char into array - */ - public CASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.CASTORE); - } + + /** Store char into array + */ + public CASTORE() { + super(com.sun.org.apache.bcel.internal.Const.CASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitCASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitCASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java index 02ebaf3a20f..71612c85cda 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java @@ -21,64 +21,68 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.ExceptionConst; + /** * CHECKCAST - Check whether object is of given type *
      Stack: ..., objectref -> ..., objectref
      * - * @author M. Dahm + * @version $Id: CHECKCAST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class CHECKCAST extends CPInstruction - implements LoadClass, ExceptionThrower, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - CHECKCAST() {} +public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer, + StackConsumer { - /** Check whether object is of given type - * @param n index to class in constant pool - */ - public CHECKCAST(int index) { - super(com.sun.org.apache.bcel.internal.Constants.CHECKCAST, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + CHECKCAST() { + } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = - ExceptionConstants.CLASS_CAST_EXCEPTION; - return cs; - } + /** Check whether object is of given type + * @param index index to class in constant pool + */ + public CHECKCAST(final int index) { + super(com.sun.org.apache.bcel.internal.Const.CHECKCAST, index); + } - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); - if(t instanceof ArrayType) - t = ((ArrayType) t).getBasicType(); + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.CLASS_CAST_EXCEPTION); + } - return (t instanceof ObjectType)? (ObjectType) t : null; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitCHECKCAST(this); - } + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitCHECKCAST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java index 84ac4ef0de1..022dd1ff7f4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java @@ -18,116 +18,127 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantClass; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; import com.sun.org.apache.bcel.internal.util.ByteSequence; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; /** - * Abstract super class for instructions that use an index into the - * constant pool such as LDC, INVOKEVIRTUAL, etc. + * Abstract super class for instructions that use an index into the constant + * pool such as LDC, INVOKEVIRTUAL, etc. * * @see ConstantPoolGen * @see LDC * @see INVOKEVIRTUAL * - * @author M. Dahm + * @version $Id: CPInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public abstract class CPInstruction extends Instruction - implements TypedInstruction, IndexedInstruction -{ - protected int index; // index to constant pool +public abstract class CPInstruction extends Instruction implements TypedInstruction, + IndexedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - CPInstruction() {} + private int index; // index to constant pool - /** - * @param index to constant pool - */ - protected CPInstruction(short opcode, int index) { - super(opcode, (short)3); - setIndex(index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + CPInstruction() { + } - /** - * 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); - } + /** + * @param index to constant pool + */ + protected CPInstruction(final short opcode, final int index) { + super(opcode, (short) 3); + setIndex(index); + } - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< constant pool index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index; - } + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(index); + } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - Constant c = cp.getConstant(index); - String str = cp.constantToString(c); + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" "<"< constant pool index>">" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + index; + } - if(c instanceof ConstantClass) - str = str.replace('.', '/'); + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(final ConstantPool cp) { + final Constant c = cp.getConstant(index); + String str = cp.constantToString(c); + if (c instanceof ConstantClass) { + str = str.replace('.', '/'); + } + return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + str; + } - return com.sun.org.apache.bcel.internal.Constants.OPCODE_NAMES[opcode] + " " + str; - } + /** + * Read needed data (i.e., index) from file. + * + * @param bytes input stream + * @param wide wide prefix? + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + setIndex(bytes.readUnsignedShort()); + super.setLength(3); + } - /** - * Read needed data (i.e., index) from file. - * @param bytes input stream - * @param wide wide prefix? - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - setIndex(bytes.readUnsignedShort()); - length = 3; - } + /** + * @return index in constant pool referred by this instruction. + */ + @Override + public final int getIndex() { + return index; + } - /** - * @return index in constant pool referred by this instruction. - */ - public final int getIndex() { return index; } + /** + * Set the index to constant pool. + * + * @param index in constant pool. + */ + @Override + public void setIndex(final int index) { // TODO could be package-protected? + if (index < 0) { + throw new ClassGenException("Negative index value: " + index); + } + this.index = index; + } - /** - * Set the index to constant pool. - * @param index in constant pool. - */ - public void setIndex(int index) { - if(index < 0) - throw new ClassGenException("Negative index value: " + index); - - this.index = index; - } - - /** @return type related with this instruction. - */ - public Type getType(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - String name = cp.getConstantString(index, com.sun.org.apache.bcel.internal.Constants.CONSTANT_Class); - - if(!name.startsWith("[")) - name = "L" + name + ";"; - - return Type.getType(name); - } + /** + * @return type related with this instruction. + */ + @Override + public Type getType(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + String name = cp.getConstantString(index, com.sun.org.apache.bcel.internal.Const.CONSTANT_Class); + if (!name.startsWith("[")) { + name = "L" + name + ";"; + } + return Type.getType(name); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java new file mode 100644 index 00000000000..249618f6122 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java @@ -0,0 +1,107 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ClassElementValue; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; + +/** + * @since 6.0 + */ +public class ClassElementValueGen extends ElementValueGen +{ + // 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 ClassElementValueGen(final int typeIdx, final ConstantPoolGen cpool) + { + super(ElementValueGen.CLASS, cpool); + this.idx = typeIdx; + } + + public ClassElementValueGen(final ObjectType t, final ConstantPoolGen cpool) + { + super(ElementValueGen.CLASS, cpool); + // this.idx = cpool.addClass(t); + idx = cpool.addUtf8(t.getSignature()); + } + + /** + * Return immutable variant of this ClassElementValueGen + */ + @Override + public ElementValue getElementValue() + { + return new ClassElementValue(super.getElementValueType(), + idx, + getConstantPool().getConstantPool()); + } + + public ClassElementValueGen(final ClassElementValue value, final ConstantPoolGen cpool, + final 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() + { + final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); + return cu8.getBytes(); + // 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(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 kind of value + dos.writeShort(idx); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java index 2e1b4d37e73..435b0704f01 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java @@ -18,401 +18,562 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; -import java.util.Iterator; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AccessFlags; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Annotations; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleAnnotations; +import com.sun.org.apache.bcel.internal.classfile.SourceFile; +import com.sun.org.apache.bcel.internal.util.BCELComparator; /** * Template class for building up a java class. May be initialized with an * existing java class (file). * * @see JavaClass - * @author M. Dahm + * @version $Id: ClassGen.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class ClassGen extends AccessFlags implements Cloneable { - /* Corresponds to the fields found in a JavaClass object. - */ - private String class_name, super_class_name, file_name; - private int class_name_index = -1, superclass_name_index = -1; - private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1; - private ConstantPoolGen cp; // Template for building up constant pool + /* Corresponds to the fields found in a JavaClass object. + */ + private String class_name; + private String super_class_name; + private final String file_name; + private int class_name_index = -1; + private int superclass_name_index = -1; + private int major = Const.MAJOR; + private int minor = Const.MINOR; + private ConstantPoolGen cp; // Template for building up constant pool + // ArrayLists instead of arrays to gather fields, methods, etc. + private final List field_vec = new ArrayList<>(); + private final List method_vec = new ArrayList<>(); + private final List attribute_vec = new ArrayList<>(); + private final List interface_vec = new ArrayList<>(); + private final List annotation_vec = new ArrayList<>(); - // ArrayLists instead of arrays to gather fields, methods, etc. - private ArrayList field_vec = new ArrayList(); - private ArrayList method_vec = new ArrayList(); - private ArrayList attribute_vec = new ArrayList(); - private ArrayList interface_vec = new ArrayList(); + private static BCELComparator _cmp = new BCELComparator() { - /** Convenience constructor to set up some important values initially. - * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers - * @param interfaces implemented interfaces - * @param cp constant pool to use - */ - public ClassGen(String class_name, String super_class_name, String file_name, - int access_flags, String[] interfaces, ConstantPoolGen cp) { - this.class_name = class_name; - this.super_class_name = super_class_name; - this.file_name = file_name; - this.access_flags = access_flags; - this.cp = cp; + @Override + public boolean equals(final Object o1, final Object o2) { + final ClassGen THIS = (ClassGen) o1; + final ClassGen THAT = (ClassGen) o2; + return THIS.getClassName().equals(THAT.getClassName()); + } - // Put everything needed by default into the constant pool and the vectors - if(file_name != null) - addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, - cp.addUtf8(file_name), cp.getConstantPool())); + @Override + public int hashCode(final Object o) { + final ClassGen THIS = (ClassGen) o; + return THIS.getClassName().hashCode(); + } + }; - class_name_index = cp.addClass(class_name); - superclass_name_index = cp.addClass(super_class_name); - - if(interfaces != null) - for(int i=0; i < interfaces.length; i++) - addInterface(interfaces[i]); - } - - /** Convenience constructor to set up some important values initially. - * - * @param class_name fully qualified class name - * @param super_class_name fully qualified superclass name - * @param file_name source file name - * @param access_flags access qualifiers - * @param interfaces implemented interfaces - */ - public ClassGen(String class_name, String super_class_name, String file_name, - int access_flags, String[] interfaces) { - this(class_name, super_class_name, file_name, access_flags, interfaces, - new ConstantPoolGen()); - } - - /** - * Initialize with existing class. - * @param clazz JavaClass object (e.g. read from file) - */ - public ClassGen(JavaClass clazz) { - class_name_index = clazz.getClassNameIndex(); - superclass_name_index = clazz.getSuperclassNameIndex(); - class_name = clazz.getClassName(); - super_class_name = clazz.getSuperclassName(); - file_name = clazz.getSourceFileName(); - access_flags = clazz.getAccessFlags(); - cp = new ConstantPoolGen(clazz.getConstantPool()); - major = clazz.getMajor(); - minor = clazz.getMinor(); - - Attribute[] attributes = clazz.getAttributes(); - Method[] methods = clazz.getMethods(); - Field[] fields = clazz.getFields(); - String[] interfaces = clazz.getInterfaceNames(); - - for(int i=0; i < interfaces.length; i++) - addInterface(interfaces[i]); - - for(int i=0; i < attributes.length; i++) - addAttribute(attributes[i]); - - for(int i=0; i < methods.length; i++) - addMethod(methods[i]); - - for(int i=0; i < fields.length; i++) - addField(fields[i]); - } - - /** - * @return the (finally) built up Java class object. - */ - public JavaClass getJavaClass() { - int[] interfaces = getInterfaces(); - Field[] fields = getFields(); - Method[] methods = getMethods(); - Attribute[] attributes = getAttributes(); - - // Must be last since the above calls may still add something to it - ConstantPool cp = this.cp.getFinalConstantPool(); - - return new JavaClass(class_name_index, superclass_name_index, - file_name, major, minor, access_flags, - cp, interfaces, fields, methods, attributes); - } - - /** - * Add an interface to this class, i.e., this class has to implement it. - * @param name interface to implement (fully qualified class name) - */ - public void addInterface(String name) { - interface_vec.add(name); - } - - /** - * Remove an interface from this class. - * @param name interface to remove (fully qualified name) - */ - public void removeInterface(String name) { - interface_vec.remove(name); - } - - /** - * @return major version number of class file - */ - public int getMajor() { return major; } - - /** Set major version number of class file, default value is 45 (JDK 1.1) - * @param major major version number - */ - public void setMajor(int major) { - this.major = major; - } - - /** Set minor version number of class file, default value is 3 (JDK 1.1) - * @param minor minor version number - */ - public void setMinor(int minor) { - this.minor = minor; - } - - /** - * @return minor version number of class file - */ - public int getMinor() { return minor; } - - /** - * Add an attribute to this class. - * @param a attribute to add - */ - public void addAttribute(Attribute a) { attribute_vec.add(a); } - - /** - * Add a method to this class. - * @param m method to add - */ - public void addMethod(Method m) { method_vec.add(m); } - - /** - * Convenience method. - * - * Add an empty constructor to this class that does nothing but calling super(). - * @param access rights for constructor - */ - public void addEmptyConstructor(int access_flags) { - InstructionList il = new InstructionList(); - il.append(InstructionConstants.THIS); // Push `this' - il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, - "", "()V"))); - il.append(InstructionConstants.RETURN); - - MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, - "", class_name, il, cp); - mg.setMaxStack(1); - addMethod(mg.getMethod()); - } - - /** - * Add a field to this class. - * @param f field to add - */ - public void addField(Field f) { field_vec.add(f); } - - public boolean containsField(Field f) { return field_vec.contains(f); } - - /** @return field object with given name, or null - */ - public Field containsField(String name) { - for(Iterator e=field_vec.iterator(); e.hasNext(); ) { - Field f = (Field)e.next(); - if(f.getName().equals(name)) - return f; + /** + * Convenience constructor to set up some important values initially. + * + * @param class_name fully qualified class name + * @param super_class_name fully qualified superclass name + * @param file_name source file name + * @param access_flags access qualifiers + * @param interfaces implemented interfaces + * @param cp constant pool to use + */ + public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags, + final String[] interfaces, final ConstantPoolGen cp) { + super(access_flags); + this.class_name = class_name; + this.super_class_name = super_class_name; + this.file_name = file_name; + this.cp = cp; + // Put everything needed by default into the constant pool and the vectors + if (file_name != null) { + addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp + .getConstantPool())); + } + class_name_index = cp.addClass(class_name); + superclass_name_index = cp.addClass(super_class_name); + if (interfaces != null) { + for (final String interface1 : interfaces) { + addInterface(interface1); + } + } } - return null; - } - - /** @return method object with given name and signature, or null - */ - public Method containsMethod(String name, String signature) { - for(Iterator e=method_vec.iterator(); e.hasNext();) { - Method m = (Method)e.next(); - if(m.getName().equals(name) && m.getSignature().equals(signature)) - return m; + /** + * Convenience constructor to set up some important values initially. + * + * @param class_name fully qualified class name + * @param super_class_name fully qualified superclass name + * @param file_name source file name + * @param access_flags access qualifiers + * @param interfaces implemented interfaces + */ + public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags, + final String[] interfaces) { + this(class_name, super_class_name, file_name, access_flags, interfaces, + new ConstantPoolGen()); } - return null; - } - - /** - * Remove an attribute from this class. - * @param a attribute to remove - */ - public void removeAttribute(Attribute a) { attribute_vec.remove(a); } - - /** - * Remove a method from this class. - * @param m method to remove - */ - public void removeMethod(Method m) { method_vec.remove(m); } - - /** Replace given method with new one. If the old one does not exist - * add the new_ method to the class anyway. - */ - public void replaceMethod(Method old, Method new_) { - if(new_ == null) - throw new ClassGenException("Replacement method must not be null"); - - int i = method_vec.indexOf(old); - - if(i < 0) - method_vec.add(new_); - else - method_vec.set(i, new_); - } - - /** Replace given field with new one. If the old one does not exist - * add the new_ field to the class anyway. - */ - public void replaceField(Field old, Field new_) { - if(new_ == null) - throw new ClassGenException("Replacement method must not be null"); - - int i = field_vec.indexOf(old); - - if(i < 0) - field_vec.add(new_); - else - field_vec.set(i, new_); - } - - /** - * Remove a field to this class. - * @param f field to remove - */ - public void removeField(Field f) { field_vec.remove(f); } - - public String getClassName() { return class_name; } - public String getSuperclassName() { return super_class_name; } - public String getFileName() { return file_name; } - - public void setClassName(String name) { - class_name = name.replace('/', '.'); - class_name_index = cp.addClass(name); - } - - public void setSuperclassName(String name) { - super_class_name = name.replace('/', '.'); - superclass_name_index = cp.addClass(name); - } - - public Method[] getMethods() { - Method[] methods = new Method[method_vec.size()]; - method_vec.toArray(methods); - return methods; - } - - public void setMethods(Method[] methods) { - method_vec.clear(); - for(int m=0; m annotationGenObjs = new ArrayList<>(); + for (final Attribute attr : attrs) { + if (attr instanceof RuntimeVisibleAnnotations) { + final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr; + final AnnotationEntry[] annos = rva.getAnnotationEntries(); + for (final AnnotationEntry a : annos) { + annotationGenObjs.add(new AnnotationEntryGen(a, + getConstantPool(), false)); + } + } else if (attr instanceof RuntimeInvisibleAnnotations) { + final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr; + final AnnotationEntry[] annos = ria.getAnnotationEntries(); + for (final AnnotationEntry a : annos) { + annotationGenObjs.add(new AnnotationEntryGen(a, + getConstantPool(), false)); + } + } + } + return annotationGenObjs.toArray(new AnnotationEntryGen[annotationGenObjs.size()]); + } + + /** + * @return the (finally) built up Java class object. + */ + public JavaClass getJavaClass() { + final int[] interfaces = getInterfaces(); + final Field[] fields = getFields(); + final Method[] methods = getMethods(); + Attribute[] attributes; + if (annotation_vec.isEmpty()) { + attributes = getAttributes(); + } else { + // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations' + final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries()); + attributes = new Attribute[attribute_vec.size() + annAttributes.length]; + attribute_vec.toArray(attributes); + System.arraycopy(annAttributes, 0, attributes, attribute_vec.size(), annAttributes.length); + } + // Must be last since the above calls may still add something to it + final ConstantPool _cp = this.cp.getFinalConstantPool(); + return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, + super.getAccessFlags(), _cp, interfaces, fields, methods, attributes); + } + + /** + * Add an interface to this class, i.e., this class has to implement it. + * + * @param name interface to implement (fully qualified class name) + */ + public final void addInterface(final String name) { + interface_vec.add(name); + } + + /** + * Remove an interface from this class. + * + * @param name interface to remove (fully qualified name) + */ + public void removeInterface(final String name) { + interface_vec.remove(name); + } + + /** + * @return major version number of class file + */ + public int getMajor() { + return major; + } + + /** + * Set major version number of class file, default value is 45 (JDK 1.1) + * + * @param major major version number + */ + public void setMajor(final int major) { // TODO could be package-protected - only called by test code + this.major = major; + } + + /** + * Set minor version number of class file, default value is 3 (JDK 1.1) + * + * @param minor minor version number + */ + public void setMinor(final int minor) { // TODO could be package-protected - only called by test code + this.minor = minor; + } + + /** + * @return minor version number of class file + */ + public int getMinor() { + return minor; + } + + /** + * Add an attribute to this class. + * + * @param a attribute to add + */ + public final void addAttribute(final Attribute a) { + attribute_vec.add(a); + } + + public final void addAnnotationEntry(final AnnotationEntryGen a) { + annotation_vec.add(a); + } + + /** + * Add a method to this class. + * + * @param m method to add + */ + public final void addMethod(final Method m) { + method_vec.add(m); + } + + /** + * Convenience method. + * + * Add an empty constructor to this class that does nothing but calling + * super(). + * + * @param access_flags rights for constructor + */ + public void addEmptyConstructor(final int access_flags) { + final InstructionList il = new InstructionList(); + il.append(InstructionConst.THIS); // Push `this' + il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "", "()V"))); + il.append(InstructionConst.RETURN); + final MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "", + class_name, il, cp); + mg.setMaxStack(1); + addMethod(mg.getMethod()); + } + + /** + * Add a field to this class. + * + * @param f field to add + */ + public final void addField(final Field f) { + field_vec.add(f); + } + + public boolean containsField(final Field f) { + return field_vec.contains(f); + } + + /** + * @return field object with given name, or null + */ + public Field containsField(final String name) { + for (final Field f : field_vec) { + if (f.getName().equals(name)) { + return f; + } + } + return null; + } + + /** + * @return method object with given name and signature, or null + */ + public Method containsMethod(final String name, final String signature) { + for (final Method m : method_vec) { + if (m.getName().equals(name) && m.getSignature().equals(signature)) { + return m; + } + } + return null; + } + + /** + * Remove an attribute from this class. + * + * @param a attribute to remove + */ + public void removeAttribute(final Attribute a) { + attribute_vec.remove(a); + } + + /** + * Remove a method from this class. + * + * @param m method to remove + */ + public void removeMethod(final Method m) { + method_vec.remove(m); + } + + /** + * Replace given method with new one. If the old one does not exist add the + * new_ method to the class anyway. + */ + public void replaceMethod(final Method old, final Method new_) { + if (new_ == null) { + throw new ClassGenException("Replacement method must not be null"); + } + final int i = method_vec.indexOf(old); + if (i < 0) { + method_vec.add(new_); + } else { + method_vec.set(i, new_); + } + } + + /** + * Replace given field with new one. If the old one does not exist add the + * new_ field to the class anyway. + */ + public void replaceField(final Field old, final Field new_) { + if (new_ == null) { + throw new ClassGenException("Replacement method must not be null"); + } + final int i = field_vec.indexOf(old); + if (i < 0) { + field_vec.add(new_); + } else { + field_vec.set(i, new_); + } + } + + /** + * Remove a field to this class. + * + * @param f field to remove + */ + public void removeField(final Field f) { + field_vec.remove(f); + } + + public String getClassName() { + return class_name; + } + + public String getSuperclassName() { + return super_class_name; + } + + public String getFileName() { + return file_name; + } + + public void setClassName(final String name) { + class_name = name.replace('/', '.'); + class_name_index = cp.addClass(name); + } + + public void setSuperclassName(final String name) { + super_class_name = name.replace('/', '.'); + superclass_name_index = cp.addClass(name); + } + + public Method[] getMethods() { + return method_vec.toArray(new Method[method_vec.size()]); + } + + public void setMethods(final Method[] methods) { + method_vec.clear(); + for (final Method method : methods) { + addMethod(method); + } + } + + public void setMethodAt(final Method method, final int pos) { + method_vec.set(pos, method); + } + + public Method getMethodAt(final int pos) { + return method_vec.get(pos); + } + + public String[] getInterfaceNames() { + final int size = interface_vec.size(); + final String[] interfaces = new String[size]; + interface_vec.toArray(interfaces); + return interfaces; + } + + public int[] getInterfaces() { + final int size = interface_vec.size(); + final int[] interfaces = new int[size]; + for (int i = 0; i < size; i++) { + interfaces[i] = cp.addClass(interface_vec.get(i)); + } + return interfaces; + } + + public Field[] getFields() { + return field_vec.toArray(new Field[field_vec.size()]); + } + + public Attribute[] getAttributes() { + return attribute_vec.toArray(new Attribute[attribute_vec.size()]); + } + + // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here? + public AnnotationEntryGen[] getAnnotationEntries() { + return annotation_vec.toArray(new AnnotationEntryGen[annotation_vec.size()]); + } + + public ConstantPoolGen getConstantPool() { + return cp; + } + + public void setConstantPool(final ConstantPoolGen constant_pool) { + cp = constant_pool; + } + + public void setClassNameIndex(final int class_name_index) { + this.class_name_index = class_name_index; + class_name = cp.getConstantPool().getConstantString(class_name_index, + Const.CONSTANT_Class).replace('/', '.'); + } + + public void setSuperclassNameIndex(final int superclass_name_index) { + this.superclass_name_index = superclass_name_index; + super_class_name = cp.getConstantPool().getConstantString(superclass_name_index, + Const.CONSTANT_Class).replace('/', '.'); + } + + public int getSuperclassNameIndex() { + return superclass_name_index; + } + + public int getClassNameIndex() { + return class_name_index; + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final ClassObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final ClassObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final ClassObserver observer : observers) { + observer.notify(this); + } + } + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return _cmp; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + _cmp = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * ClassGen objects are said to be equal when their class names are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return _cmp.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the class name. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return _cmp.hashCode(this); } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java index 6bc4ee6c534..cd3168ecaa3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java @@ -21,14 +21,26 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared * in the throws clause every time. * - * @author M. Dahm + * @version $Id: ClassGenException.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ClassGenException extends RuntimeException { - public ClassGenException() { super(); } - public ClassGenException(String s) { super(s); } + + private static final long serialVersionUID = 7247369755051242791L; + + public ClassGenException() { + super(); + } + + + public ClassGenException(final String s) { + super(s); + } + + public ClassGenException(final String s, final Throwable initCause) { + super(s, initCause); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java index a01e5b6288c..7229c40cf00 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Implement this interface if you're interested in changes to a ClassGen object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: ClassObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface ClassObserver { - public void notify(ClassGen clazz); + + void notify( ClassGen clazz ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java index 96bd2124f37..2bace2f1836 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java @@ -18,14 +18,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.classfile.CodeException; /** - * This class represents an exception handler, i.e., specifies the region where + * This class represents an exception handler, i.e., specifies the region where * a handler is active and an instruction where the actual handling is done. * pool as parameters. Opposed to the JVM specification the end of the handled * region is set to be inclusive, i.e. all instructions between start and end @@ -33,143 +31,156 @@ import com.sun.org.apache.bcel.internal.classfile.*; * The end of the region is automatically mapped to be exclusive when calling * getCodeException(), i.e., there is no difference semantically. * - * @author M. Dahm - * @see MethodGen - * @see CodeException - * @see InstructionHandle + * @version $Id: CodeExceptionGen.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @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; +public final class CodeExceptionGen implements InstructionTargeter, Cloneable { - /** - * 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; - } + private InstructionHandle start_pc; + private InstructionHandle end_pc; + private InstructionHandle handler_pc; + private ObjectType catch_type; - /** - * Get CodeException object.
      - * - * This relies on that the instruction list has already been dumped - * to byte code or or that the `setPositions' methods has been - * called for the instruction list. - * - * @param cp constant pool - */ - public CodeException getCodeException(ConstantPoolGen cp) { - return new CodeException(start_pc.getPosition(), - end_pc.getPosition() + end_pc.getInstruction().getLength(), - handler_pc.getPosition(), - (catch_type == null)? 0 : cp.addClass(catch_type)); - } - - /* Set start of handler - * @param start_pc Start of handled region (inclusive) - */ - public final void setStartPC(InstructionHandle start_pc) { - BranchInstruction.notifyTargetChanging(this.start_pc, this); - this.start_pc = start_pc; - BranchInstruction.notifyTargetChanged(this.start_pc, this); - } - - /* Set end of handler - * @param end_pc End of handled region (inclusive) - */ - public final void setEndPC(InstructionHandle end_pc) { - BranchInstruction.notifyTargetChanging(this.end_pc, this); - this.end_pc = end_pc; - BranchInstruction.notifyTargetChanged(this.end_pc, this); - } - - /* Set handler code - * @param handler_pc Start of handler - */ - public final void setHandlerPC(InstructionHandle handler_pc) { - BranchInstruction.notifyTargetChanging(this.handler_pc, this); - this.handler_pc = handler_pc; - BranchInstruction.notifyTargetChanged(this.handler_pc, this); - } - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if(start_pc == old_ih) { - targeted = true; - setStartPC(new_ih); + /** + * 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(final InstructionHandle start_pc, final InstructionHandle end_pc, + final InstructionHandle handler_pc, final ObjectType catch_type) { + setStartPC(start_pc); + setEndPC(end_pc); + setHandlerPC(handler_pc); + this.catch_type = catch_type; } - if(end_pc == old_ih) { - targeted = true; - setEndPC(new_ih); + /** + * Get CodeException object.
      + * + * This relies on that the instruction list has already been dumped to byte + * code or or that the `setPositions' methods has been called for the + * instruction list. + * + * @param cp constant pool + */ + public CodeException getCodeException(final ConstantPoolGen cp) { + return new CodeException(start_pc.getPosition(), end_pc.getPosition() + + end_pc.getInstruction().getLength(), handler_pc.getPosition(), + (catch_type == null) ? 0 : cp.addClass(catch_type)); } - if(handler_pc == old_ih) { - targeted = true; - setHandlerPC(new_ih); + + /* Set start of handler + * @param start_pc Start of handled region (inclusive) + */ + public void setStartPC(final InstructionHandle start_pc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.start_pc, start_pc, this); + this.start_pc = start_pc; } - if(!targeted) - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " + - end_pc + ", " + handler_pc + "}"); - } - /** - * @return true, if ih is target of this handler - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); - } - - /** 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; } - - @Override - public String toString() { - return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + /* Set end of handler + * @param end_pc End of handled region (inclusive) + */ + public void setEndPC(final InstructionHandle end_pc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.end_pc, end_pc, this); + this.end_pc = end_pc; + } + + + /* Set handler code + * @param handler_pc Start of handler + */ + public void setHandlerPC(final InstructionHandle handler_pc) { // TODO could be package-protected? + BranchInstruction.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 + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + boolean targeted = false; + if (start_pc == old_ih) { + targeted = true; + setStartPC(new_ih); + } + if (end_pc == old_ih) { + targeted = true; + setEndPC(new_ih); + } + if (handler_pc == old_ih) { + targeted = true; + setHandlerPC(new_ih); + } + if (!targeted) { + throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", " + + end_pc + ", " + handler_pc + "}"); + } + } + + /** + * @return true, if ih is target of this handler + */ + @Override + public boolean containsTarget(final 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(final 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; + } + + @Override + public String toString() { + return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java index b54af3aacf4..25250d27b70 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Wrapper class for `compound' operations, virtual instructions that * don't exist as byte code, but give a useful meaning. For example, @@ -33,10 +32,11 @@ package com.sun.org.apache.bcel.internal.generic; * The interface provides the possibilty for the user to write * `templates' or `macros' for such reuseable code patterns. * - * @author M. Dahm + * @version $Id: CompoundInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see PUSH * @see SWITCH */ public interface CompoundInstruction { - public InstructionList getInstructionList(); + + InstructionList getInstructionList(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java index 4eb12e2e693..58c8a2940a0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,736 +17,773 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.HashMap; +import java.util.Map; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantClass; +import com.sun.org.apache.bcel.internal.classfile.ConstantDouble; +import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; +import com.sun.org.apache.bcel.internal.classfile.ConstantFloat; +import com.sun.org.apache.bcel.internal.classfile.ConstantInteger; +import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic; +import com.sun.org.apache.bcel.internal.classfile.ConstantLong; +import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantString; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; /** - * This class is used to build up a constant pool. The user adds - * constants via `addXXX' methods, `addString', `addClass', - * etc.. These methods return an index into the constant - * pool. Finally, `getFinalConstantPool()' returns the constant pool - * built up. Intermediate versions of the constant pool can be + * This class is used to build up a constant pool. The user adds constants via + * `addXXX' methods, `addString', `addClass', etc.. These methods return an + * index into the constant pool. Finally, `getFinalConstantPool()' returns the + * constant pool built up. Intermediate versions of the constant pool can be * obtained with `getConstantPool()'. A constant pool has capacity for - * Constants.MAX_SHORT entries. Note that the first (0) is used by the - * JVM and that Double and Long constants need two slots. + * Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and + * that Double and Long constants need two slots. * - * @author M. Dahm + * @version $Id: ConstantPoolGen.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Constant */ -public class ConstantPoolGen implements java.io.Serializable { - protected int size = 1024; // Inital size, sufficient in most cases - protected Constant[] constants = new Constant[size]; - protected int index = 1; // First entry (0) used by JVM +public class ConstantPoolGen { - private static final String METHODREF_DELIM = ":"; - private static final String IMETHODREF_DELIM = "#"; - private static final String FIELDREF_DELIM = "&"; - private static final String NAT_DELIM = "%"; + private static final int DEFAULT_BUFFER_SIZE = 256; + private int size; + private Constant[] constants; + private int index = 1; // First entry (0) used by JVM - private static class Index implements java.io.Serializable { - int index; - Index(int i) { index = i; } - } + private static final String METHODREF_DELIM = ":"; + private static final String IMETHODREF_DELIM = "#"; + private static final String FIELDREF_DELIM = "&"; + private static final String NAT_DELIM = "%"; // Name and Type - /** - * Initialize with given array of constants. - * - * @param c array of given constants, new ones will be appended - */ - public ConstantPoolGen(Constant[] cs) { - if(cs.length > size) { - size = cs.length; - constants = new Constant[size]; + private static class Index { + + final int index; + + Index(final int i) { + index = i; + } } - System.arraycopy(cs, 0, constants, 0, cs.length); + /** + * Initialize with given array of constants. + * + * @param cs array of given constants, new ones will be appended + */ + public ConstantPoolGen(final Constant[] cs) { + final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); - if(cs.length > 0) - index = cs.length; + size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64); + constants = new Constant[size]; - for(int i=1; i < index; i++) { - Constant c = constants[i]; + System.arraycopy(cs, 0, constants, 0, cs.length); + if (cs.length > 0) { + index = cs.length; + } - if(c instanceof ConstantString) { - ConstantString s = (ConstantString)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; + for (int i = 1; i < index; i++) { + final Constant c = constants[i]; + if (c instanceof ConstantString) { + final ConstantString s = (ConstantString) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + final String key = u8.getBytes(); + if (!string_table.containsKey(key)) { + string_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantClass) { + final ConstantClass s = (ConstantClass) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + final String key = u8.getBytes(); + if (!class_table.containsKey(key)) { + class_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantNameAndType) { + final ConstantNameAndType n = (ConstantNameAndType) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; - string_table.put(u8.getBytes(), new Index(i)); - } else if(c instanceof ConstantClass) { - ConstantClass s = (ConstantClass)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; + sb.append(u8.getBytes()); + sb.append(NAT_DELIM); + sb.append(u8_2.getBytes()); + final String key = sb.toString(); + sb.delete(0, sb.length()); - class_table.put(u8.getBytes(), new Index(i)); - } else if(c instanceof ConstantNameAndType) { - ConstantNameAndType n = (ConstantNameAndType)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; - ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; + if (!n_a_t_table.containsKey(key)) { + n_a_t_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantUtf8) { + final ConstantUtf8 u = (ConstantUtf8) c; + final String key = u.getBytes(); + if (!utf8_table.containsKey(key)) { + utf8_table.put(key, new Index(i)); + } + } else if (c instanceof ConstantCP) { + final ConstantCP m = (ConstantCP) c; + String class_name; + ConstantUtf8 u8; - n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i)); - } else if(c instanceof ConstantUtf8) { - ConstantUtf8 u = (ConstantUtf8)c; + if (c instanceof ConstantInvokeDynamic) { + class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); + // since name can't begin with digit, can use + // METHODREF_DELIM with out fear of duplicates. + } else { + final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + class_name = u8.getBytes().replace('/', '.'); + } - utf8_table.put(u.getBytes(), new Index(i)); - } else if(c instanceof ConstantCP) { - ConstantCP m = (ConstantCP)c; - ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; - ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; + final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final String method_name = u8.getBytes(); + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + final String signature = u8.getBytes(); - ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; - String class_name = u8.getBytes().replace('/', '.'); + String delim = METHODREF_DELIM; + if (c instanceof ConstantInterfaceMethodref) { + delim = IMETHODREF_DELIM; + } else if (c instanceof ConstantFieldref) { + delim = FIELDREF_DELIM; + } - u8 = (ConstantUtf8)constants[n.getNameIndex()]; - String method_name = u8.getBytes(); + sb.append(class_name); + sb.append(delim); + sb.append(method_name); + sb.append(delim); + sb.append(signature); + final String key = sb.toString(); + sb.delete(0, sb.length()); - u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; - String signature = u8.getBytes(); - - String delim = METHODREF_DELIM; - - if(c instanceof ConstantInterfaceMethodref) - delim = IMETHODREF_DELIM; - else if(c instanceof ConstantFieldref) - delim = FIELDREF_DELIM; - - cp_table.put(class_name + delim + method_name + delim + signature, new Index(i)); - } - } - } - - /** - * Initialize with given constant pool. - */ - public ConstantPoolGen(ConstantPool cp) { - this(cp.getConstantPool()); - } - - /** - * Create empty constant pool. - */ - public ConstantPoolGen() {} - - /** Resize internal array of constants. - */ - protected void adjustSize() { - if(index + 3 >= size) { - Constant[] cs = constants; - - size *= 2; - constants = new Constant[size]; - System.arraycopy(cs, 0, constants, 0, index); - } - } - - private HashMap string_table = new HashMap(); - - /** - * Look for ConstantString in ConstantPool containing String `str'. - * - * @param str String to search for - * @return index on success, -1 otherwise - */ - public int lookupString(String str) { - Index index = (Index)string_table.get(str); - return (index != null)? index.index : -1; - } - - /** - * Add a new String constant to the ConstantPool, if it is not already in there. - * - * @param str String to add - * @return index of entry - */ - public int addString(String str) { - int ret; - - if((ret = lookupString(str)) != -1) - return ret; // Already in CP - - int utf8 = addUtf8(str); - - adjustSize(); - - ConstantString s = new ConstantString(utf8); - - ret = index; - constants[index++] = s; - - string_table.put(str, new Index(ret)); - - return ret; - } - - private HashMap class_table = new HashMap(); - - /** - * Look for ConstantClass in ConstantPool named `str'. - * - * @param str String to search for - * @return index on success, -1 otherwise - */ - public int lookupClass(String str) { - Index index = (Index)class_table.get(str.replace('.', '/')); - return (index != null)? index.index : -1; - } - - private int addClass_(String clazz) { - int ret; - - if((ret = lookupClass(clazz)) != -1) - return ret; // Already in CP - - adjustSize(); - - ConstantClass c = new ConstantClass(addUtf8(clazz)); - - ret = index; - constants[index++] = c; - - class_table.put(clazz, new Index(ret)); - - return ret; - } - - /** - * Add a new Class reference to the ConstantPool, if it is not already in there. - * - * @param str Class to add - * @return index of entry - */ - public int addClass(String str) { - return addClass_(str.replace('.', '/')); - } - - /** - * Add a new Class reference to the ConstantPool for a given type. - * - * @param str Class to add - * @return index of entry - */ - public int addClass(ObjectType type) { - return addClass(type.getClassName()); - } - - /** - * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY - * instruction, e.g. to the ConstantPool. - * - * @param type type of array class - * @return index of entry - */ - public int addArrayClass(ArrayType type) { - return addClass_(type.getSignature()); - } - - /** - * Look for ConstantInteger in ConstantPool. - * - * @param n integer number to look for - * @return index on success, -1 otherwise - */ - public int lookupInteger(int n) { - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantInteger) { - ConstantInteger c = (ConstantInteger)constants[i]; - - if(c.getBytes() == n) - return i; - } + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(i)); + } + } else if (c == null) { // entries may be null + // nothing to do + } else if (c instanceof ConstantInteger) { + // nothing to do + } else if (c instanceof ConstantLong) { + // nothing to do + } else if (c instanceof ConstantFloat) { + // nothing to do + } else if (c instanceof ConstantDouble) { + // nothing to do + } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodType) { + // TODO should this be handled somehow? + } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodHandle) { + // TODO should this be handled somehow? + } else { + assert false : "Unexpected constant type: " + c.getClass().getName(); + } + } } - return -1; - } - - /** - * Add a new Integer constant to the ConstantPool, if it is not already in there. - * - * @param n integer number to add - * @return index of entry - */ - public int addInteger(int n) { - int ret; - - if((ret = lookupInteger(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index++] = new ConstantInteger(n); - - return ret; - } - - /** - * Look for ConstantFloat in ConstantPool. - * - * @param n Float number to look for - * @return index on success, -1 otherwise - */ - public int lookupFloat(float n) { - int bits = Float.floatToIntBits(n); - - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantFloat) { - ConstantFloat c = (ConstantFloat)constants[i]; - - if(Float.floatToIntBits(c.getBytes()) == bits) - return i; - } + /** + * Initialize with given constant pool. + */ + public ConstantPoolGen(final ConstantPool cp) { + this(cp.getConstantPool()); } - return -1; - } - - /** - * Add a new Float constant to the ConstantPool, if it is not already in there. - * - * @param n Float number to add - * @return index of entry - */ - public int addFloat(float n) { - int ret; - - if((ret = lookupFloat(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index++] = new ConstantFloat(n); - - return ret; - } - - private HashMap utf8_table = new HashMap(); - - /** - * Look for ConstantUtf8 in ConstantPool. - * - * @param n Utf8 string to look for - * @return index on success, -1 otherwise - */ - public int lookupUtf8(String n) { - Index index = (Index)utf8_table.get(n); - - return (index != null)? index.index : -1; - } - - /** - * Add a new Utf8 constant to the ConstantPool, if it is not already in there. - * - * @param n Utf8 string to add - * @return index of entry - */ - public int addUtf8(String n) { - int ret; - - if((ret = lookupUtf8(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index++] = new ConstantUtf8(n); - - utf8_table.put(n, new Index(ret)); - - return ret; - } - - /** - * Look for ConstantLong in ConstantPool. - * - * @param n Long number to look for - * @return index on success, -1 otherwise - */ - public int lookupLong(long n) { - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantLong) { - ConstantLong c = (ConstantLong)constants[i]; - - if(c.getBytes() == n) - return i; - } + /** + * Create empty constant pool. + */ + public ConstantPoolGen() { + size = DEFAULT_BUFFER_SIZE; + constants = new Constant[size]; } - return -1; - } - - /** - * Add a new long constant to the ConstantPool, if it is not already in there. - * - * @param n Long number to add - * @return index of entry - */ - public int addLong(long n) { - int ret; - - if((ret = lookupLong(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index] = new ConstantLong(n); - index += 2; // Wastes one entry according to spec - - return ret; - } - - /** - * Look for ConstantDouble in ConstantPool. - * - * @param n Double number to look for - * @return index on success, -1 otherwise - */ - public int lookupDouble(double n) { - long bits = Double.doubleToLongBits(n); - - for(int i=1; i < index; i++) { - if(constants[i] instanceof ConstantDouble) { - ConstantDouble c = (ConstantDouble)constants[i]; - - if(Double.doubleToLongBits(c.getBytes()) == bits) - return i; - } + /** + * Resize internal array of constants. + */ + protected void adjustSize() { + if (index + 3 >= size) { + final Constant[] cs = constants; + size *= 2; + constants = new Constant[size]; + System.arraycopy(cs, 0, constants, 0, index); + } } - return -1; - } + private final Map string_table = new HashMap<>(); - /** - * Add a new double constant to the ConstantPool, if it is not already in there. - * - * @param n Double number to add - * @return index of entry - */ - public int addDouble(double n) { - int ret; - - if((ret = lookupDouble(n)) != -1) - return ret; // Already in CP - - adjustSize(); - - ret = index; - constants[index] = new ConstantDouble(n); - index += 2; // Wastes one entry according to spec - - return ret; - } - - private HashMap n_a_t_table = new HashMap(); - - /** - * Look for ConstantNameAndType in ConstantPool. - * - * @param name of variable/method - * @param signature of variable/method - * @return index on success, -1 otherwise - */ - public int lookupNameAndType(String name, String signature) { - Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature); - return (index != null)? index.index : -1; - } - - /** - * Add a new NameAndType constant to the ConstantPool if it is not already - * in there. - * - * @param n NameAndType string to add - * @return index of entry - */ - public int addNameAndType(String name, String signature) { - int ret; - int name_index, signature_index; - - if((ret = lookupNameAndType(name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - name_index = addUtf8(name); - signature_index = addUtf8(signature); - ret = index; - constants[index++] = new ConstantNameAndType(name_index, signature_index); - - n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret)); - return ret; - } - - private HashMap cp_table = new HashMap(); - - /** - * Look for ConstantMethodref in ConstantPool. - * - * @param class_name Where to find method - * @param method_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupMethodref(String class_name, String method_name, String signature) { - Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name + - METHODREF_DELIM + signature); - return (index != null)? index.index : -1; - } - - public int lookupMethodref(MethodGen method) { - return lookupMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Add a new Methodref constant to the ConstantPool, if it is not already - * in there. - * - * @param n Methodref string to add - * @return index of entry - */ - public int addMethodref(String class_name, String method_name, String signature) { - int ret, class_index, name_and_type_index; - - if((ret = lookupMethodref(class_name, method_name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - name_and_type_index = addNameAndType(method_name, signature); - class_index = addClass(class_name); - ret = index; - constants[index++] = new ConstantMethodref(class_index, name_and_type_index); - - cp_table.put(class_name + METHODREF_DELIM + method_name + - METHODREF_DELIM + signature, new Index(ret)); - - return ret; - } - - public int addMethodref(MethodGen method) { - return addMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Look for ConstantInterfaceMethodref in ConstantPool. - * - * @param class_name Where to find method - * @param method_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupInterfaceMethodref(String class_name, String method_name, String signature) { - Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name + - IMETHODREF_DELIM + signature); - return (index != null)? index.index : -1; - } - - public int lookupInterfaceMethodref(MethodGen method) { - return lookupInterfaceMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already - * in there. - * - * @param n InterfaceMethodref string to add - * @return index of entry - */ - public int addInterfaceMethodref(String class_name, String method_name, String signature) { - int ret, class_index, name_and_type_index; - - if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - class_index = addClass(class_name); - name_and_type_index = addNameAndType(method_name, signature); - ret = index; - constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); - - cp_table.put(class_name + IMETHODREF_DELIM + method_name + - IMETHODREF_DELIM + signature, new Index(ret)); - - return ret; - } - - public int addInterfaceMethodref(MethodGen method) { - return addInterfaceMethodref(method.getClassName(), method.getName(), - method.getSignature()); - } - - /** - * Look for ConstantFieldref in ConstantPool. - * - * @param class_name Where to find method - * @param field_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise - */ - public int lookupFieldref(String class_name, String field_name, String signature) { - Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name + - FIELDREF_DELIM + signature); - return (index != null)? index.index : -1; - } - - /** - * Add a new Fieldref constant to the ConstantPool, if it is not already - * in there. - * - * @param n Fieldref string to add - * @return index of entry - */ - public int addFieldref(String class_name, String field_name, String signature) { - int ret; - int class_index, name_and_type_index; - - if((ret = lookupFieldref(class_name, field_name, signature)) != -1) - return ret; // Already in CP - - adjustSize(); - - class_index = addClass(class_name); - name_and_type_index = addNameAndType(field_name, signature); - ret = index; - constants[index++] = new ConstantFieldref(class_index, name_and_type_index); - - cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret)); - - return ret; - } - - /** - * @param i index in constant pool - * @return constant pool entry at index i - */ - public Constant getConstant(int i) { return constants[i]; } - - /** - * Use with care! - * - * @param i index in constant pool - * @param c new constant pool entry at index i - */ - public void setConstant(int i, Constant c) { constants[i] = c; } - - /** - * @return intermediate constant pool - */ - public ConstantPool getConstantPool() { - return new ConstantPool(constants); - } - - /** - * @return current size of constant pool - */ - public int getSize() { - return index; - } - - /** - * @return constant pool with proper length - */ - public ConstantPool getFinalConstantPool() { - Constant[] cs = new Constant[index]; - - System.arraycopy(constants, 0, cs, 0, index); - - return new ConstantPool(cs); - } - - /** - * @return String representation. - */ - public String toString() { - StringBuffer buf = new StringBuffer(); - - for(int i=1; i < index; i++) - buf.append(i + ")" + constants[i] + "\n"); - - return buf.toString(); - } - - /** Import constant from another ConstantPool and return new index. - */ - public int addConstant(Constant c, ConstantPoolGen cp) { - Constant[] constants = cp.getConstantPool().getConstantPool(); - - switch(c.getTag()) { - case Constants.CONSTANT_String: { - ConstantString s = (ConstantString)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; - - return addString(u8.getBytes()); + /** + * Look for ConstantString in ConstantPool containing String `str'. + * + * @param str String to search for + * @return index on success, -1 otherwise + */ + public int lookupString(final String str) { + final Index index = string_table.get(str); + return (index != null) ? index.index : -1; } - case Constants.CONSTANT_Class: { - ConstantClass s = (ConstantClass)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; - - return addClass(u8.getBytes()); + /** + * Add a new String constant to the ConstantPool, if it is not already in + * there. + * + * @param str String to add + * @return index of entry + */ + public int addString(final String str) { + int ret; + if ((ret = lookupString(str)) != -1) { + return ret; // Already in CP + } + final int utf8 = addUtf8(str); + adjustSize(); + final ConstantString s = new ConstantString(utf8); + ret = index; + constants[index++] = s; + if (!string_table.containsKey(str)) { + string_table.put(str, new Index(ret)); + } + return ret; } - case Constants.CONSTANT_NameAndType: { - ConstantNameAndType n = (ConstantNameAndType)c; - ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; - ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; + private final Map class_table = new HashMap<>(); - return addNameAndType(u8.getBytes(), u8_2.getBytes()); + /** + * Look for ConstantClass in ConstantPool named `str'. + * + * @param str String to search for + * @return index on success, -1 otherwise + */ + public int lookupClass(final String str) { + final Index index = class_table.get(str.replace('.', '/')); + return (index != null) ? index.index : -1; } - case Constants.CONSTANT_Utf8: - return addUtf8(((ConstantUtf8)c).getBytes()); - - case Constants.CONSTANT_Double: - return addDouble(((ConstantDouble)c).getBytes()); - - case Constants.CONSTANT_Float: - return addFloat(((ConstantFloat)c).getBytes()); - - case Constants.CONSTANT_Long: - return addLong(((ConstantLong)c).getBytes()); - - case Constants.CONSTANT_Integer: - return addInteger(((ConstantInteger)c).getBytes()); - - case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: - case Constants.CONSTANT_Fieldref: { - ConstantCP m = (ConstantCP)c; - ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; - ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; - ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; - String class_name = u8.getBytes().replace('/', '.'); - - u8 = (ConstantUtf8)constants[n.getNameIndex()]; - String name = u8.getBytes(); - - u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; - String signature = u8.getBytes(); - - switch(c.getTag()) { - case Constants.CONSTANT_InterfaceMethodref: - return addInterfaceMethodref(class_name, name, signature); - - case Constants.CONSTANT_Methodref: - return addMethodref(class_name, name, signature); - - case Constants.CONSTANT_Fieldref: - return addFieldref(class_name, name, signature); - - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); - } + private int addClass_(final String clazz) { + int ret; + if ((ret = lookupClass(clazz)) != -1) { + return ret; // Already in CP + } + adjustSize(); + final ConstantClass c = new ConstantClass(addUtf8(clazz)); + ret = index; + constants[index++] = c; + if (!class_table.containsKey(clazz)) { + class_table.put(clazz, new Index(ret)); + } + return ret; } - default: // Never reached - throw new RuntimeException("Unknown constant type " + c); + /** + * Add a new Class reference to the ConstantPool, if it is not already in + * there. + * + * @param str Class to add + * @return index of entry + */ + public int addClass(final String str) { + return addClass_(str.replace('.', '/')); + } + + /** + * Add a new Class reference to the ConstantPool for a given type. + * + * @param type Class to add + * @return index of entry + */ + public int addClass(final ObjectType type) { + return addClass(type.getClassName()); + } + + /** + * Add a reference to an array class (e.g. String[][]) as needed by + * MULTIANEWARRAY instruction, e.g. to the ConstantPool. + * + * @param type type of array class + * @return index of entry + */ + public int addArrayClass(final ArrayType type) { + return addClass_(type.getSignature()); + } + + /** + * Look for ConstantInteger in ConstantPool. + * + * @param n integer number to look for + * @return index on success, -1 otherwise + */ + public int lookupInteger(final int n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantInteger) { + final ConstantInteger c = (ConstantInteger) constants[i]; + if (c.getBytes() == n) { + return i; + } + } + } + return -1; + } + + /** + * Add a new Integer constant to the ConstantPool, if it is not already in + * there. + * + * @param n integer number to add + * @return index of entry + */ + public int addInteger(final int n) { + int ret; + if ((ret = lookupInteger(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantInteger(n); + return ret; + } + + /** + * Look for ConstantFloat in ConstantPool. + * + * @param n Float number to look for + * @return index on success, -1 otherwise + */ + public int lookupFloat(final float n) { + final int bits = Float.floatToIntBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantFloat) { + final ConstantFloat c = (ConstantFloat) constants[i]; + if (Float.floatToIntBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; + } + + /** + * Add a new Float constant to the ConstantPool, if it is not already in + * there. + * + * @param n Float number to add + * @return index of entry + */ + public int addFloat(final float n) { + int ret; + if ((ret = lookupFloat(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantFloat(n); + return ret; + } + + private final Map utf8_table = new HashMap<>(); + + /** + * Look for ConstantUtf8 in ConstantPool. + * + * @param n Utf8 string to look for + * @return index on success, -1 otherwise + */ + public int lookupUtf8(final String n) { + final Index index = utf8_table.get(n); + return (index != null) ? index.index : -1; + } + + /** + * Add a new Utf8 constant to the ConstantPool, if it is not already in + * there. + * + * @param n Utf8 string to add + * @return index of entry + */ + public int addUtf8(final String n) { + int ret; + if ((ret = lookupUtf8(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index++] = new ConstantUtf8(n); + if (!utf8_table.containsKey(n)) { + utf8_table.put(n, new Index(ret)); + } + return ret; + } + + /** + * Look for ConstantLong in ConstantPool. + * + * @param n Long number to look for + * @return index on success, -1 otherwise + */ + public int lookupLong(final long n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantLong) { + final ConstantLong c = (ConstantLong) constants[i]; + if (c.getBytes() == n) { + return i; + } + } + } + return -1; + } + + /** + * Add a new long constant to the ConstantPool, if it is not already in + * there. + * + * @param n Long number to add + * @return index of entry + */ + public int addLong(final long n) { + int ret; + if ((ret = lookupLong(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index] = new ConstantLong(n); + index += 2; // Wastes one entry according to spec + return ret; + } + + /** + * Look for ConstantDouble in ConstantPool. + * + * @param n Double number to look for + * @return index on success, -1 otherwise + */ + public int lookupDouble(final double n) { + final long bits = Double.doubleToLongBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantDouble) { + final ConstantDouble c = (ConstantDouble) constants[i]; + if (Double.doubleToLongBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; + } + + /** + * Add a new double constant to the ConstantPool, if it is not already in + * there. + * + * @param n Double number to add + * @return index of entry + */ + public int addDouble(final double n) { + int ret; + if ((ret = lookupDouble(n)) != -1) { + return ret; // Already in CP + } + adjustSize(); + ret = index; + constants[index] = new ConstantDouble(n); + index += 2; // Wastes one entry according to spec + return ret; + } + + private final Map n_a_t_table = new HashMap<>(); + + /** + * Look for ConstantNameAndType in ConstantPool. + * + * @param name of variable/method + * @param signature of variable/method + * @return index on success, -1 otherwise + */ + public int lookupNameAndType(final String name, final String signature) { + final Index _index = n_a_t_table.get(name + NAT_DELIM + signature); + return (_index != null) ? _index.index : -1; + } + + /** + * Add a new NameAndType constant to the ConstantPool if it is not already + * in there. + * + * @param name Name string to add + * @param signature signature string to add + * @return index of entry + */ + public int addNameAndType(final String name, final String signature) { + int ret; + int name_index; + int signature_index; + if ((ret = lookupNameAndType(name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + name_index = addUtf8(name); + signature_index = addUtf8(signature); + ret = index; + constants[index++] = new ConstantNameAndType(name_index, signature_index); + final String key = name + NAT_DELIM + signature; + if (!n_a_t_table.containsKey(key)) { + n_a_t_table.put(key, new Index(ret)); + } + return ret; + } + + private final Map cp_table = new HashMap<>(); + + /** + * Look for ConstantMethodref in ConstantPool. + * + * @param class_name Where to find method + * @param method_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupMethodref(final String class_name, final String method_name, final String signature) { + final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name + + METHODREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + public int lookupMethodref(final MethodGen method) { + return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); + } + + /** + * Add a new Methodref constant to the ConstantPool, if it is not already in + * there. + * + * @param class_name class name string to add + * @param method_name method name string to add + * @param signature method signature string to add + * @return index of entry + */ + public int addMethodref(final String class_name, final String method_name, final String signature) { + int ret; + int class_index; + int name_and_type_index; + if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + name_and_type_index = addNameAndType(method_name, signature); + class_index = addClass(class_name); + ret = index; + constants[index++] = new ConstantMethodref(class_index, name_and_type_index); + final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + public int addMethodref(final MethodGen method) { + return addMethodref(method.getClassName(), method.getName(), method.getSignature()); + } + + /** + * Look for ConstantInterfaceMethodref in ConstantPool. + * + * @param class_name Where to find method + * @param method_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupInterfaceMethodref(final String class_name, final String method_name, final String signature) { + final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name + + IMETHODREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + public int lookupInterfaceMethodref(final MethodGen method) { + return lookupInterfaceMethodref(method.getClassName(), method.getName(), method + .getSignature()); + } + + /** + * Add a new InterfaceMethodref constant to the ConstantPool, if it is not + * already in there. + * + * @param class_name class name string to add + * @param method_name method name string to add + * @param signature signature string to add + * @return index of entry + */ + public int addInterfaceMethodref(final String class_name, final String method_name, final String signature) { + int ret; + int class_index; + int name_and_type_index; + if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + class_index = addClass(class_name); + name_and_type_index = addNameAndType(method_name, signature); + ret = index; + constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); + final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + public int addInterfaceMethodref(final MethodGen method) { + return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); + } + + /** + * Look for ConstantFieldref in ConstantPool. + * + * @param class_name Where to find method + * @param field_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupFieldref(final String class_name, final String field_name, final String signature) { + final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name + + FIELDREF_DELIM + signature); + return (index != null) ? index.index : -1; + } + + /** + * Add a new Fieldref constant to the ConstantPool, if it is not already in + * there. + * + * @param class_name class name string to add + * @param field_name field name string to add + * @param signature signature string to add + * @return index of entry + */ + public int addFieldref(final String class_name, final String field_name, final String signature) { + int ret; + int class_index; + int name_and_type_index; + if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { + return ret; // Already in CP + } + adjustSize(); + class_index = addClass(class_name); + name_and_type_index = addNameAndType(field_name, signature); + ret = index; + constants[index++] = new ConstantFieldref(class_index, name_and_type_index); + final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; + if (!cp_table.containsKey(key)) { + cp_table.put(key, new Index(ret)); + } + return ret; + } + + /** + * @param i index in constant pool + * @return constant pool entry at index i + */ + public Constant getConstant(final int i) { + return constants[i]; + } + + /** + * Use with care! + * + * @param i index in constant pool + * @param c new constant pool entry at index i + */ + public void setConstant(final int i, final Constant c) { + constants[i] = c; + } + + /** + * @return intermediate constant pool + */ + public ConstantPool getConstantPool() { + return new ConstantPool(constants); + } + + /** + * @return current size of constant pool + */ + public int getSize() { + return index; + } + + /** + * @return constant pool with proper length + */ + public ConstantPool getFinalConstantPool() { + final Constant[] cs = new Constant[index]; + System.arraycopy(constants, 0, cs, 0, index); + return new ConstantPool(cs); + } + + /** + * @return String representation. + */ + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(); + for (int i = 1; i < index; i++) { + buf.append(i).append(")").append(constants[i]).append("\n"); + } + return buf.toString(); + } + + /** + * Import constant from another ConstantPool and return new index. + */ + public int addConstant(final Constant c, final ConstantPoolGen cp) { + final Constant[] constants = cp.getConstantPool().getConstantPool(); + switch (c.getTag()) { + case Const.CONSTANT_String: { + final ConstantString s = (ConstantString) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + return addString(u8.getBytes()); + } + case Const.CONSTANT_Class: { + final ConstantClass s = (ConstantClass) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + return addClass(u8.getBytes()); + } + case Const.CONSTANT_NameAndType: { + final ConstantNameAndType n = (ConstantNameAndType) c; + final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; + return addNameAndType(u8.getBytes(), u8_2.getBytes()); + } + case Const.CONSTANT_Utf8: + return addUtf8(((ConstantUtf8) c).getBytes()); + case Const.CONSTANT_Double: + return addDouble(((ConstantDouble) c).getBytes()); + case Const.CONSTANT_Float: + return addFloat(((ConstantFloat) c).getBytes()); + case Const.CONSTANT_Long: + return addLong(((ConstantLong) c).getBytes()); + case Const.CONSTANT_Integer: + return addInteger(((ConstantInteger) c).getBytes()); + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + case Const.CONSTANT_Fieldref: { + final ConstantCP m = (ConstantCP) c; + final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; + ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + final String class_name = u8.getBytes().replace('/', '.'); + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final String name = u8.getBytes(); + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + final String signature = u8.getBytes(); + switch (c.getTag()) { + case Const.CONSTANT_InterfaceMethodref: + return addInterfaceMethodref(class_name, name, signature); + case Const.CONSTANT_Methodref: + return addMethodref(class_name, name, signature); + case Const.CONSTANT_Fieldref: + return addFieldref(class_name, name, signature); + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java index f5fdaa11541..78273d2600c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java @@ -21,16 +21,16 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes a push instruction that produces a literal on the stack * such as SIPUSH, BIPUSH, ICONST, etc. * - * @author M. Dahm + * @version $Id: ConstantPushInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see ICONST * @see SIPUSH */ public interface ConstantPushInstruction extends PushInstruction, TypedInstruction { - public Number getValue(); + + Number getValue(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java index 2a1d8b6c2c3..032880888ce 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java @@ -21,48 +21,62 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; + /** * Super class for the x2y family of instructions. * - * @author M. Dahm + * @version $Id: ConversionInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ConversionInstruction extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ConversionInstruction() {} +public abstract class ConversionInstruction extends Instruction implements TypedInstruction, + StackProducer, StackConsumer { - /** - * @param opcode opcode of instruction - */ - protected ConversionInstruction(short opcode) { - super(opcode, (short)1); - } - - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(opcode) { - case Constants.D2I: case Constants.F2I: case Constants.L2I: - return Type.INT; - case Constants.D2F: case Constants.I2F: case Constants.L2F: - return Type.FLOAT; - case Constants.D2L: case Constants.F2L: case Constants.I2L: - return Type.LONG; - case Constants.F2D: case Constants.I2D: case Constants.L2D: - return Type.DOUBLE; - case Constants.I2B: - return Type.BYTE; - case Constants.I2C: - return Type.CHAR; - case Constants.I2S: - return Type.SHORT; - - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ConversionInstruction() { + } + + + /** + * @param opcode opcode of instruction + */ + protected ConversionInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case Const.D2I: + case Const.F2I: + case Const.L2I: + return Type.INT; + case Const.D2F: + case Const.I2F: + case Const.L2F: + return Type.FLOAT; + case Const.D2L: + case Const.F2L: + case Const.I2L: + return Type.LONG; + case Const.F2D: + case Const.I2D: + case Const.L2D: + return Type.DOUBLE; + case Const.I2B: + return Type.BYTE; + case Const.I2C: + return Type.CHAR; + case Const.I2S: + return Type.SHORT; + default: // Never reached + throw new ClassGenException("Unknown type " + _opcode); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java index 1d5cda8ae83..51fbfa9a19b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * D2F - Convert double to float *
      Stack: ..., value.word1, value.word2 -> ..., result
      * - * @author M. Dahm + * @version $Id: D2F.java 1747278 2016-06-07 17:28:43Z britter $ */ public class D2F extends ConversionInstruction { - /** Convert double to float - */ - public D2F() { - super(com.sun.org.apache.bcel.internal.Constants.D2F); - } + + /** Convert double to float + */ + public D2F() { + super(com.sun.org.apache.bcel.internal.Const.D2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2F(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2F(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java index cdc20b64f0e..2b817ff772c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * D2I - Convert double to int *
      Stack: ..., value.word1, value.word2 -> ..., result
      * - * @author M. Dahm + * @version $Id: D2I.java 1747278 2016-06-07 17:28:43Z britter $ */ public class D2I extends ConversionInstruction { - /** Convert double to int - */ - public D2I() { - super(com.sun.org.apache.bcel.internal.Constants.D2I); - } + + /** Convert double to int + */ + public D2I() { + super(com.sun.org.apache.bcel.internal.Const.D2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2I(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2I(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java index 3774d4826fa..989595fe891 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * D2L - Convert double to long *
      Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: D2L.java 1747278 2016-06-07 17:28:43Z britter $ */ public class D2L extends ConversionInstruction { - /** Convert double to long - */ - public D2L() { - super(com.sun.org.apache.bcel.internal.Constants.D2L); - } + + /** Convert double to long + */ + public D2L() { + super(com.sun.org.apache.bcel.internal.Const.D2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitD2L(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitD2L(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java index af23bf2c94f..f89b99d4cc2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DADD - Add doubles *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result1.word2 * - * @author M. Dahm + * @version $Id: DADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DADD extends ArithmeticInstruction { - /** Add doubles - */ - public DADD() { - super(com.sun.org.apache.bcel.internal.Constants.DADD); - } + + /** Add doubles + */ + public DADD() { + super(com.sun.org.apache.bcel.internal.Const.DADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java index a414eb01432..95055ff002b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DALOAD - Load double from array *
      Stack: ..., arrayref, index -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: DALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DALOAD extends ArrayInstruction implements StackProducer { - /** Load double from array - */ - public DALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.DALOAD); - } + + /** Load double from array + */ + public DALOAD() { + super(com.sun.org.apache.bcel.internal.Const.DALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitDALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitDALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java index c100ead3e54..ad6d09e48e5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DASTORE - Store into double array *
      Stack: ..., arrayref, index, value.word1, value.word2 -> ...
      * - * @author M. Dahm + * @version $Id: DASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DASTORE extends ArrayInstruction implements StackConsumer { - /** Store double into array - */ - public DASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.DASTORE); - } + + /** Store double into array + */ + public DASTORE() { + super(com.sun.org.apache.bcel.internal.Const.DASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitDASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitDASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java index 1d447c93062..2b74d2b3d04 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java @@ -21,40 +21,38 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * DCMPG - Compare doubles: value1 > value2 - *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      - * ..., result + * DCMPG - Compare doubles: value1 > value2 + *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
      * - * @author M. Dahm + * @version $Id: DCMPG.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class DCMPG extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { +public class DCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - public DCMPG() { - super(com.sun.org.apache.bcel.internal.Constants.DCMPG, (short)1); - } + public DCMPG() { + super(com.sun.org.apache.bcel.internal.Const.DCMPG, (short) 1); + } - /** @return Type.DOUBLE - */ - public Type getType(ConstantPoolGen cp) { - return Type.DOUBLE; - } + /** @return Type.DOUBLE + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.DOUBLE; + } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitDCMPG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitDCMPG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java index 3874a682fe6..c466e79e30e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java @@ -21,39 +21,38 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * DCMPL - Compare doubles: value1 < value2 - *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      - * ..., result + * DCMPL - Compare doubles: value1 < value2 + *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
      * - * @author M. Dahm + * @version $Id: DCMPL.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class DCMPL extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - public DCMPL() { - super(com.sun.org.apache.bcel.internal.Constants.DCMPL, (short)1); - } +public class DCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.DOUBLE - */ - public Type getType(ConstantPoolGen cp) { - return Type.DOUBLE; - } + public DCMPL() { + super(com.sun.org.apache.bcel.internal.Const.DCMPL, (short) 1); + } + /** @return Type.DOUBLE + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.DOUBLE; + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitDCMPL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitDCMPL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java index af6154b7659..ed46bfe61b5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java @@ -20,58 +20,67 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DCONST - Push 0.0 or 1.0, other values cause an exception * *
      Stack: ... -> ..., 
      * - * @author M. Dahm + * @version $Id: DCONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class DCONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private double value; +public class DCONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DCONST() {} + private double value; - public DCONST(double f) { - super(com.sun.org.apache.bcel.internal.Constants.DCONST_0, (short)1); - if(f == 0.0) - opcode = com.sun.org.apache.bcel.internal.Constants.DCONST_0; - else if(f == 1.0) - opcode = com.sun.org.apache.bcel.internal.Constants.DCONST_1; - else - throw new ClassGenException("DCONST can be used only for 0.0 and 1.0: " + f); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DCONST() { + } - value = f; - } - public Number getValue() { return Double.valueOf(value); } + public DCONST(final double f) { + super(com.sun.org.apache.bcel.internal.Const.DCONST_0, (short) 1); + if (f == 0.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.DCONST_0); + } else if (f == 1.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.DCONST_1); + } else { + throw new ClassGenException("DCONST can be used only for 0.0 and 1.0: " + f); + } + value = f; + } - /** @return Type.DOUBLE - */ - public Type getType(ConstantPoolGen cp) { - return Type.DOUBLE; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitDCONST(this); - } + @Override + public Number getValue() { + return new Double(value); + } + + + /** @return Type.DOUBLE + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.DOUBLE; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitDCONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java index 1c91493800f..5c794664d70 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DDIV - Divide doubles *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DDIV extends ArithmeticInstruction { - /** Divide doubles - */ - public DDIV() { - super(com.sun.org.apache.bcel.internal.Constants.DDIV); - } + + /** Divide doubles + */ + public DDIV() { + super(com.sun.org.apache.bcel.internal.Const.DDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java index 3e83f1edb30..5f90cfa61c5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DLOAD - Load double from local variable *
      Stack ... -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: DLOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DLOAD() { - super(com.sun.org.apache.bcel.internal.Constants.DLOAD, com.sun.org.apache.bcel.internal.Constants.DLOAD_0); - } - /** Load double from local variable - * @param n index of local variable - */ - public DLOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.DLOAD, com.sun.org.apache.bcel.internal.Constants.DLOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DLOAD() { + super(com.sun.org.apache.bcel.internal.Const.DLOAD, com.sun.org.apache.bcel.internal.Const.DLOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitDLOAD(this); - } + + /** Load double from local variable + * @param n index of local variable + */ + public DLOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.DLOAD, com.sun.org.apache.bcel.internal.Const.DLOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitDLOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java index 908dec0da4f..f48d8c298be 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DMUL - Multiply doubles *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DMUL extends ArithmeticInstruction { - /** Multiply doubles - */ - public DMUL() { - super(com.sun.org.apache.bcel.internal.Constants.DMUL); - } + + /** Multiply doubles + */ + public DMUL() { + super(com.sun.org.apache.bcel.internal.Const.DMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java index 48becc3d66a..67d19fe8388 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DNEG - Negate double *
      Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: DNEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DNEG extends ArithmeticInstruction { - public DNEG() { - super(com.sun.org.apache.bcel.internal.Constants.DNEG); - } + + public DNEG() { + super(com.sun.org.apache.bcel.internal.Const.DNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDNEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java index d1f0bd09d03..e11598af13a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DREM - Remainder of doubles *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DREM extends ArithmeticInstruction { - /** Remainder of doubles - */ - public DREM() { - super(com.sun.org.apache.bcel.internal.Constants.DREM); - } + + /** Remainder of doubles + */ + public DREM() { + super(com.sun.org.apache.bcel.internal.Const.DREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDREM(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java index 7c4906e8c5d..76fa2260aae 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DRETURN - Return double from method *
      Stack: ..., value.word1, value.word2 -> <empty>
      * - * @author M. Dahm + * @version $Id: DRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DRETURN extends ReturnInstruction { - /** Return double from method - */ - public DRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.DRETURN); - } + + /** Return double from method + */ + public DRETURN() { + super(com.sun.org.apache.bcel.internal.Const.DRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitDRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitDRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java index ada5407136f..e8d5808cb3e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DSTORE - Store double into local variable *
      Stack: ..., value.word1, value.word2 -> ... 
      * - * @author M. Dahm + * @version $Id: DSTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - DSTORE() { - super(com.sun.org.apache.bcel.internal.Constants.DSTORE, com.sun.org.apache.bcel.internal.Constants.DSTORE_0); - } - /** Store double into local variable - * @param n index of local variable - */ - public DSTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.DSTORE, com.sun.org.apache.bcel.internal.Constants.DSTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + DSTORE() { + super(com.sun.org.apache.bcel.internal.Const.DSTORE, com.sun.org.apache.bcel.internal.Const.DSTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitDSTORE(this); - } + + /** Store double into local variable + * @param n index of local variable + */ + public DSTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.DSTORE, com.sun.org.apache.bcel.internal.Const.DSTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitDSTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java index 8d6a311d6aa..74984517753 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DSUB - Substract doubles *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: DSUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DSUB extends ArithmeticInstruction { - /** Substract doubles - */ - public DSUB() { - super(com.sun.org.apache.bcel.internal.Constants.DSUB); - } + + /** Substract doubles + */ + public DSUB() { + super(com.sun.org.apache.bcel.internal.Const.DSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitDSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitDSUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java index 2d61cf06218..22dcebfa689 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java @@ -21,31 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP - Duplicate top operand stack word *
      Stack: ..., word -> ..., word, word
      * - * @author M. Dahm + * @version $Id: DUP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP extends StackInstruction implements PushInstruction { - public DUP() { - super(com.sun.org.apache.bcel.internal.Constants.DUP); - } + + public DUP() { + super(com.sun.org.apache.bcel.internal.Const.DUP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitStackInstruction(this); - v.visitDUP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitStackInstruction(this); + v.visitDUP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java index a44f07814e6..1600d0bbf65 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java @@ -21,31 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP2 - Duplicate two top operand stack words *
      Stack: ..., word2, word1 -> ..., word2, word1, word2, word1
      * - * @author M. Dahm + * @version $Id: DUP2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP2 extends StackInstruction implements PushInstruction { - public DUP2() { - super(com.sun.org.apache.bcel.internal.Constants.DUP2); - } + + public DUP2() { + super(com.sun.org.apache.bcel.internal.Const.DUP2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitStackInstruction(this); - v.visitDUP2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitStackInstruction(this); + v.visitDUP2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java index b0b6d4c6fe2..bc73db971cf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP2_X1 - Duplicate two top operand stack words and put three down *
      Stack: ..., word3, word2, word1 -> ..., word2, word1, word3, word2, word1
      * - * @author M. Dahm + * @version $Id: DUP2_X1.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP2_X1 extends StackInstruction { - public DUP2_X1() { - super(com.sun.org.apache.bcel.internal.Constants.DUP2_X1); - } + + public DUP2_X1() { + super(com.sun.org.apache.bcel.internal.Const.DUP2_X1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP2_X1(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP2_X1(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java index 4e394bc4012..6feba7b32ee 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP2_X2 - Duplicate two top operand stack words and put four down *
      Stack: ..., word4, word3, word2, word1 -> ..., word2, word1, word4, word3, word2, word1
      * - * @author M. Dahm + * @version $Id: DUP2_X2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP2_X2 extends StackInstruction { - public DUP2_X2() { - super(com.sun.org.apache.bcel.internal.Constants.DUP2_X2); - } + + public DUP2_X2() { + super(com.sun.org.apache.bcel.internal.Const.DUP2_X2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP2_X2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP2_X2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java index ee895c6571c..357d091febf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP_X1 - Duplicate top operand stack word and put two down *
      Stack: ..., word2, word1 -> ..., word1, word2, word1
      * - * @author M. Dahm + * @version $Id: DUP_X1.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP_X1 extends StackInstruction { - public DUP_X1() { - super(com.sun.org.apache.bcel.internal.Constants.DUP_X1); - } + + public DUP_X1() { + super(com.sun.org.apache.bcel.internal.Const.DUP_X1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP_X1(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP_X1(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java index 5d86a30169b..b6529072a89 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java @@ -21,29 +21,30 @@ package com.sun.org.apache.bcel.internal.generic; - /** * DUP_X2 - Duplicate top operand stack word and put three down *
      Stack: ..., word3, word2, word1 -> ..., word1, word3, word2, word1
      * - * @author M. Dahm + * @version $Id: DUP_X2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class DUP_X2 extends StackInstruction { - public DUP_X2() { - super(com.sun.org.apache.bcel.internal.Constants.DUP_X2); - } + + public DUP_X2() { + super(com.sun.org.apache.bcel.internal.Const.DUP_X2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackInstruction(this); - v.visitDUP_X2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackInstruction(this); + v.visitDUP_X2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java new file mode 100644 index 00000000000..f6a8ace0583 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataInput; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.AnnotationElementValue; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.ArrayElementValue; +import com.sun.org.apache.bcel.internal.classfile.ClassElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.EnumElementValue; +import com.sun.org.apache.bcel.internal.classfile.SimpleElementValue; + +/** + * @since 6.0 + */ +public abstract class ElementValueGen +{ + private final int type; + private final ConstantPoolGen cpGen; + + protected ElementValueGen(final int type, final ConstantPoolGen cpGen) + { + this.type = type; + this.cpGen = cpGen; + } + + /** + * Subtypes return an immutable variant of the ElementValueGen + */ + public abstract ElementValue getElementValue(); + + public int getElementValueType() + { + return type; + } + + public abstract String stringifyValue(); + + public abstract void dump(DataOutputStream dos) throws IOException; + + 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'; + + public static ElementValueGen readElementValue(final DataInput dis, + final ConstantPoolGen cpGen) throws IOException + { + final int type = dis.readUnsignedByte(); + switch (type) + { + case 'B': // byte + return new SimpleElementValueGen(PRIMITIVE_BYTE, dis + .readUnsignedShort(), cpGen); + case 'C': // char + return new SimpleElementValueGen(PRIMITIVE_CHAR, dis + .readUnsignedShort(), cpGen); + case 'D': // double + return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis + .readUnsignedShort(), cpGen); + case 'F': // float + return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis + .readUnsignedShort(), cpGen); + case 'I': // int + return new SimpleElementValueGen(PRIMITIVE_INT, dis + .readUnsignedShort(), cpGen); + case 'J': // long + return new SimpleElementValueGen(PRIMITIVE_LONG, dis + .readUnsignedShort(), cpGen); + case 'S': // short + return new SimpleElementValueGen(PRIMITIVE_SHORT, dis + .readUnsignedShort(), cpGen); + case 'Z': // boolean + return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis + .readUnsignedShort(), cpGen); + case 's': // String + return new SimpleElementValueGen(STRING, dis.readUnsignedShort(), + cpGen); + case 'e': // Enum constant + return new EnumElementValueGen(dis.readUnsignedShort(), dis + .readUnsignedShort(), cpGen); + case 'c': // Class + return new ClassElementValueGen(dis.readUnsignedShort(), cpGen); + case '@': // Annotation + // TODO: isRuntimeVisible ?????????? + // FIXME + return new AnnotationElementValueGen(ANNOTATION, + new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen + .getConstantPool(), true), cpGen, false), cpGen); + case '[': // Array + final int numArrayVals = dis.readUnsignedShort(); + final ElementValue[] evalues = new ElementValue[numArrayVals]; + for (int j = 0; j < numArrayVals; j++) + { + evalues[j] = ElementValue.readElementValue(dis, cpGen + .getConstantPool()); + } + return new ArrayElementValueGen(ARRAY, evalues, cpGen); + default: + throw new RuntimeException("Unexpected element value kind in annotation: " + type); + } + } + + protected ConstantPoolGen getConstantPool() + { + return cpGen; + } + + /** + * Creates an (modifiable) ElementValueGen copy of an (immutable) + * ElementValue - constant pool is assumed correct. + */ + public static ElementValueGen copy(final ElementValue value, + final ConstantPoolGen cpool, final 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 SimpleElementValueGen((SimpleElementValue) value, cpool, + copyPoolEntries); + case 'e': // Enum constant + return new EnumElementValueGen((EnumElementValue) value, cpool, + copyPoolEntries); + case '@': // Annotation + return new AnnotationElementValueGen( + (AnnotationElementValue) value, cpool, copyPoolEntries); + case '[': // Array + return new ArrayElementValueGen((ArrayElementValue) value, cpool, + copyPoolEntries); + case 'c': // Class + return new ClassElementValueGen((ClassElementValue) value, cpool, + copyPoolEntries); + default: + throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); + } + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java new file mode 100644 index 00000000000..5a928375174 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java @@ -0,0 +1,119 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.ElementValuePair; + +/** + * @since 6.0 + */ +public class ElementValuePairGen +{ + private int nameIdx; + + private final ElementValueGen value; + + private final ConstantPoolGen cpool; + + public ElementValuePairGen(final ElementValuePair nvp, final ConstantPoolGen cpool, + final 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(nvp.getNameString()); + } + else + { + nameIdx = nvp.getNameIndex(); + } + value = ElementValueGen.copy(nvp.getValue(), cpool, copyPoolEntries); + } + + /** + * Retrieve an immutable version of this ElementNameValuePairGen + */ + public ElementValuePair getElementNameValuePair() + { + final ElementValue immutableValue = value.getElementValue(); + return new ElementValuePair(nameIdx, immutableValue, cpool + .getConstantPool()); + } + + protected ElementValuePairGen(final int idx, final ElementValueGen value, + final ConstantPoolGen cpool) + { + this.nameIdx = idx; + this.value = value; + this.cpool = cpool; + } + + public ElementValuePairGen(final String name, final ElementValueGen value, + final ConstantPoolGen cpool) + { + this.nameIdx = cpool.addUtf8(name); + this.value = value; + this.cpool = cpool; + } + + protected void dump(final DataOutputStream dos) throws IOException + { + dos.writeShort(nameIdx); // u2 name of the element + value.dump(dos); + } + + public int getNameIndex() + { + return nameIdx; + } + + public final String getNameString() + { + // ConstantString cu8 = (ConstantString)cpool.getConstant(nameIdx); + return ((ConstantUtf8) cpool.getConstant(nameIdx)).getBytes(); + } + + public final ElementValueGen getValue() + { + return value; + } + + @Override + public String toString() + { + return "ElementValuePair:[" + getNameString() + "=" + + value.stringifyValue() + "]"; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java index 275af64d69f..78476f73250 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java @@ -21,191 +21,916 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Supplies empty method bodies to be overridden by subclasses. * - * @author M. Dahm + * @version $Id: EmptyVisitor.java 1747278 2016-06-07 17:28:43Z britter $ */ public abstract class EmptyVisitor implements Visitor { - public void visitStackInstruction(StackInstruction obj) { } - public void visitLocalVariableInstruction(LocalVariableInstruction obj) { } - public void visitBranchInstruction(BranchInstruction obj) { } - public void visitLoadClass(LoadClass obj) { } - public void visitFieldInstruction(FieldInstruction obj) { } - public void visitIfInstruction(IfInstruction obj) { } - public void visitConversionInstruction(ConversionInstruction obj) { } - public void visitPopInstruction(PopInstruction obj) { } - public void visitJsrInstruction(JsrInstruction obj) { } - public void visitGotoInstruction(GotoInstruction obj) { } - public void visitStoreInstruction(StoreInstruction obj) { } - public void visitTypedInstruction(TypedInstruction obj) { } - public void visitSelect(Select obj) { } - public void visitUnconditionalBranch(UnconditionalBranch obj) { } - public void visitPushInstruction(PushInstruction obj) { } - public void visitArithmeticInstruction(ArithmeticInstruction obj) { } - public void visitCPInstruction(CPInstruction obj) { } - public void visitInvokeInstruction(InvokeInstruction obj) { } - public void visitArrayInstruction(ArrayInstruction obj) { } - public void visitAllocationInstruction(AllocationInstruction obj) { } - public void visitReturnInstruction(ReturnInstruction obj) { } - public void visitFieldOrMethod(FieldOrMethod obj) { } - public void visitConstantPushInstruction(ConstantPushInstruction obj) { } - public void visitExceptionThrower(ExceptionThrower obj) { } - public void visitLoadInstruction(LoadInstruction obj) { } - public void visitVariableLengthInstruction(VariableLengthInstruction obj) { } - public void visitStackProducer(StackProducer obj) { } - public void visitStackConsumer(StackConsumer obj) { } - public void visitACONST_NULL(ACONST_NULL obj) { } - public void visitGETSTATIC(GETSTATIC obj) { } - public void visitIF_ICMPLT(IF_ICMPLT obj) { } - public void visitMONITOREXIT(MONITOREXIT obj) { } - public void visitIFLT(IFLT obj) { } - public void visitLSTORE(LSTORE obj) { } - public void visitPOP2(POP2 obj) { } - public void visitBASTORE(BASTORE obj) { } - public void visitISTORE(ISTORE obj) { } - public void visitCHECKCAST(CHECKCAST obj) { } - public void visitFCMPG(FCMPG obj) { } - public void visitI2F(I2F obj) { } - public void visitATHROW(ATHROW obj) { } - public void visitDCMPL(DCMPL obj) { } - public void visitARRAYLENGTH(ARRAYLENGTH obj) { } - public void visitDUP(DUP obj) { } - public void visitINVOKESTATIC(INVOKESTATIC obj) { } - public void visitLCONST(LCONST obj) { } - public void visitDREM(DREM obj) { } - public void visitIFGE(IFGE obj) { } - public void visitCALOAD(CALOAD obj) { } - public void visitLASTORE(LASTORE obj) { } - public void visitI2D(I2D obj) { } - public void visitDADD(DADD obj) { } - public void visitINVOKESPECIAL(INVOKESPECIAL obj) { } - public void visitIAND(IAND obj) { } - public void visitPUTFIELD(PUTFIELD obj) { } - public void visitILOAD(ILOAD obj) { } - public void visitDLOAD(DLOAD obj) { } - public void visitDCONST(DCONST obj) { } - public void visitNEW(NEW obj) { } - public void visitIFNULL(IFNULL obj) { } - public void visitLSUB(LSUB obj) { } - public void visitL2I(L2I obj) { } - public void visitISHR(ISHR obj) { } - public void visitTABLESWITCH(TABLESWITCH obj) { } - public void visitIINC(IINC obj) { } - public void visitDRETURN(DRETURN obj) { } - public void visitFSTORE(FSTORE obj) { } - public void visitDASTORE(DASTORE obj) { } - public void visitIALOAD(IALOAD obj) { } - public void visitDDIV(DDIV obj) { } - public void visitIF_ICMPGE(IF_ICMPGE obj) { } - public void visitLAND(LAND obj) { } - public void visitIDIV(IDIV obj) { } - public void visitLOR(LOR obj) { } - public void visitCASTORE(CASTORE obj) { } - public void visitFREM(FREM obj) { } - public void visitLDC(LDC obj) { } - public void visitBIPUSH(BIPUSH obj) { } - public void visitDSTORE(DSTORE obj) { } - public void visitF2L(F2L obj) { } - public void visitFMUL(FMUL obj) { } - public void visitLLOAD(LLOAD obj) { } - public void visitJSR(JSR obj) { } - public void visitFSUB(FSUB obj) { } - public void visitSASTORE(SASTORE obj) { } - public void visitALOAD(ALOAD obj) { } - public void visitDUP2_X2(DUP2_X2 obj) { } - public void visitRETURN(RETURN obj) { } - public void visitDALOAD(DALOAD obj) { } - public void visitSIPUSH(SIPUSH obj) { } - public void visitDSUB(DSUB obj) { } - public void visitL2F(L2F obj) { } - public void visitIF_ICMPGT(IF_ICMPGT obj) { } - public void visitF2D(F2D obj) { } - public void visitI2L(I2L obj) { } - public void visitIF_ACMPNE(IF_ACMPNE obj) { } - public void visitPOP(POP obj) { } - public void visitI2S(I2S obj) { } - public void visitIFEQ(IFEQ obj) { } - public void visitSWAP(SWAP obj) { } - public void visitIOR(IOR obj) { } - public void visitIREM(IREM obj) { } - public void visitIASTORE(IASTORE obj) { } - public void visitNEWARRAY(NEWARRAY obj) { } - public void visitINVOKEINTERFACE(INVOKEINTERFACE obj) { } - public void visitINEG(INEG obj) { } - public void visitLCMP(LCMP obj) { } - public void visitJSR_W(JSR_W obj) { } - public void visitMULTIANEWARRAY(MULTIANEWARRAY obj) { } - public void visitDUP_X2(DUP_X2 obj) { } - public void visitSALOAD(SALOAD obj) { } - public void visitIFNONNULL(IFNONNULL obj) { } - public void visitDMUL(DMUL obj) { } - public void visitIFNE(IFNE obj) { } - public void visitIF_ICMPLE(IF_ICMPLE obj) { } - public void visitLDC2_W(LDC2_W obj) { } - public void visitGETFIELD(GETFIELD obj) { } - public void visitLADD(LADD obj) { } - public void visitNOP(NOP obj) { } - public void visitFALOAD(FALOAD obj) { } - public void visitINSTANCEOF(INSTANCEOF obj) { } - public void visitIFLE(IFLE obj) { } - public void visitLXOR(LXOR obj) { } - public void visitLRETURN(LRETURN obj) { } - public void visitFCONST(FCONST obj) { } - public void visitIUSHR(IUSHR obj) { } - public void visitBALOAD(BALOAD obj) { } - public void visitDUP2(DUP2 obj) { } - public void visitIF_ACMPEQ(IF_ACMPEQ obj) { } - public void visitIMPDEP1(IMPDEP1 obj) { } - public void visitMONITORENTER(MONITORENTER obj) { } - public void visitLSHL(LSHL obj) { } - public void visitDCMPG(DCMPG obj) { } - public void visitD2L(D2L obj) { } - public void visitIMPDEP2(IMPDEP2 obj) { } - public void visitL2D(L2D obj) { } - public void visitRET(RET obj) { } - public void visitIFGT(IFGT obj) { } - public void visitIXOR(IXOR obj) { } - public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { } - public void visitFASTORE(FASTORE obj) { } - public void visitIRETURN(IRETURN obj) { } - public void visitIF_ICMPNE(IF_ICMPNE obj) { } - public void visitFLOAD(FLOAD obj) { } - public void visitLDIV(LDIV obj) { } - public void visitPUTSTATIC(PUTSTATIC obj) { } - public void visitAALOAD(AALOAD obj) { } - public void visitD2I(D2I obj) { } - public void visitIF_ICMPEQ(IF_ICMPEQ obj) { } - public void visitAASTORE(AASTORE obj) { } - public void visitARETURN(ARETURN obj) { } - public void visitDUP2_X1(DUP2_X1 obj) { } - public void visitFNEG(FNEG obj) { } - public void visitGOTO_W(GOTO_W obj) { } - public void visitD2F(D2F obj) { } - public void visitGOTO(GOTO obj) { } - public void visitISUB(ISUB obj) { } - public void visitF2I(F2I obj) { } - public void visitDNEG(DNEG obj) { } - public void visitICONST(ICONST obj) { } - public void visitFDIV(FDIV obj) { } - public void visitI2B(I2B obj) { } - public void visitLNEG(LNEG obj) { } - public void visitLREM(LREM obj) { } - public void visitIMUL(IMUL obj) { } - public void visitIADD(IADD obj) { } - public void visitLSHR(LSHR obj) { } - public void visitLOOKUPSWITCH(LOOKUPSWITCH obj) { } - public void visitDUP_X1(DUP_X1 obj) { } - public void visitFCMPL(FCMPL obj) { } - public void visitI2C(I2C obj) { } - public void visitLMUL(LMUL obj) { } - public void visitLUSHR(LUSHR obj) { } - public void visitISHL(ISHL obj) { } - public void visitLALOAD(LALOAD obj) { } - public void visitASTORE(ASTORE obj) { } - public void visitANEWARRAY(ANEWARRAY obj) { } - public void visitFRETURN(FRETURN obj) { } - public void visitFADD(FADD obj) { } - public void visitBREAKPOINT(BREAKPOINT obj) { } + + @Override + public void visitStackInstruction( final StackInstruction obj ) { + } + + + @Override + public void visitLocalVariableInstruction( final LocalVariableInstruction obj ) { + } + + + @Override + public void visitBranchInstruction( final BranchInstruction obj ) { + } + + + @Override + public void visitLoadClass( final LoadClass obj ) { + } + + + @Override + public void visitFieldInstruction( final FieldInstruction obj ) { + } + + + @Override + public void visitIfInstruction( final IfInstruction obj ) { + } + + + @Override + public void visitConversionInstruction( final ConversionInstruction obj ) { + } + + + @Override + public void visitPopInstruction( final PopInstruction obj ) { + } + + + @Override + public void visitJsrInstruction( final JsrInstruction obj ) { + } + + + @Override + public void visitGotoInstruction( final GotoInstruction obj ) { + } + + + @Override + public void visitStoreInstruction( final StoreInstruction obj ) { + } + + + @Override + public void visitTypedInstruction( final TypedInstruction obj ) { + } + + + @Override + public void visitSelect( final Select obj ) { + } + + + @Override + public void visitUnconditionalBranch( final UnconditionalBranch obj ) { + } + + + @Override + public void visitPushInstruction( final PushInstruction obj ) { + } + + + @Override + public void visitArithmeticInstruction( final ArithmeticInstruction obj ) { + } + + + @Override + public void visitCPInstruction( final CPInstruction obj ) { + } + + + @Override + public void visitInvokeInstruction( final InvokeInstruction obj ) { + } + + + @Override + public void visitArrayInstruction( final ArrayInstruction obj ) { + } + + + @Override + public void visitAllocationInstruction( final AllocationInstruction obj ) { + } + + + @Override + public void visitReturnInstruction( final ReturnInstruction obj ) { + } + + + @Override + public void visitFieldOrMethod( final FieldOrMethod obj ) { + } + + + @Override + public void visitConstantPushInstruction( final ConstantPushInstruction obj ) { + } + + + @Override + public void visitExceptionThrower( final ExceptionThrower obj ) { + } + + + @Override + public void visitLoadInstruction( final LoadInstruction obj ) { + } + + + @Override + public void visitVariableLengthInstruction( final VariableLengthInstruction obj ) { + } + + + @Override + public void visitStackProducer( final StackProducer obj ) { + } + + + @Override + public void visitStackConsumer( final StackConsumer obj ) { + } + + + @Override + public void visitACONST_NULL( final ACONST_NULL obj ) { + } + + + @Override + public void visitGETSTATIC( final GETSTATIC obj ) { + } + + + @Override + public void visitIF_ICMPLT( final IF_ICMPLT obj ) { + } + + + @Override + public void visitMONITOREXIT( final MONITOREXIT obj ) { + } + + + @Override + public void visitIFLT( final IFLT obj ) { + } + + + @Override + public void visitLSTORE( final LSTORE obj ) { + } + + + @Override + public void visitPOP2( final POP2 obj ) { + } + + + @Override + public void visitBASTORE( final BASTORE obj ) { + } + + + @Override + public void visitISTORE( final ISTORE obj ) { + } + + + @Override + public void visitCHECKCAST( final CHECKCAST obj ) { + } + + + @Override + public void visitFCMPG( final FCMPG obj ) { + } + + + @Override + public void visitI2F( final I2F obj ) { + } + + + @Override + public void visitATHROW( final ATHROW obj ) { + } + + + @Override + public void visitDCMPL( final DCMPL obj ) { + } + + + @Override + public void visitARRAYLENGTH( final ARRAYLENGTH obj ) { + } + + + @Override + public void visitDUP( final DUP obj ) { + } + + + @Override + public void visitINVOKESTATIC( final INVOKESTATIC obj ) { + } + + + @Override + public void visitLCONST( final LCONST obj ) { + } + + + @Override + public void visitDREM( final DREM obj ) { + } + + + @Override + public void visitIFGE( final IFGE obj ) { + } + + + @Override + public void visitCALOAD( final CALOAD obj ) { + } + + + @Override + public void visitLASTORE( final LASTORE obj ) { + } + + + @Override + public void visitI2D( final I2D obj ) { + } + + + @Override + public void visitDADD( final DADD obj ) { + } + + + @Override + public void visitINVOKESPECIAL( final INVOKESPECIAL obj ) { + } + + + @Override + public void visitIAND( final IAND obj ) { + } + + + @Override + public void visitPUTFIELD( final PUTFIELD obj ) { + } + + + @Override + public void visitILOAD( final ILOAD obj ) { + } + + + @Override + public void visitDLOAD( final DLOAD obj ) { + } + + + @Override + public void visitDCONST( final DCONST obj ) { + } + + + @Override + public void visitNEW( final NEW obj ) { + } + + + @Override + public void visitIFNULL( final IFNULL obj ) { + } + + + @Override + public void visitLSUB( final LSUB obj ) { + } + + + @Override + public void visitL2I( final L2I obj ) { + } + + + @Override + public void visitISHR( final ISHR obj ) { + } + + + @Override + public void visitTABLESWITCH( final TABLESWITCH obj ) { + } + + + @Override + public void visitIINC( final IINC obj ) { + } + + + @Override + public void visitDRETURN( final DRETURN obj ) { + } + + + @Override + public void visitFSTORE( final FSTORE obj ) { + } + + + @Override + public void visitDASTORE( final DASTORE obj ) { + } + + + @Override + public void visitIALOAD( final IALOAD obj ) { + } + + + @Override + public void visitDDIV( final DDIV obj ) { + } + + + @Override + public void visitIF_ICMPGE( final IF_ICMPGE obj ) { + } + + + @Override + public void visitLAND( final LAND obj ) { + } + + + @Override + public void visitIDIV( final IDIV obj ) { + } + + + @Override + public void visitLOR( final LOR obj ) { + } + + + @Override + public void visitCASTORE( final CASTORE obj ) { + } + + + @Override + public void visitFREM( final FREM obj ) { + } + + + @Override + public void visitLDC( final LDC obj ) { + } + + + @Override + public void visitBIPUSH( final BIPUSH obj ) { + } + + + @Override + public void visitDSTORE( final DSTORE obj ) { + } + + + @Override + public void visitF2L( final F2L obj ) { + } + + + @Override + public void visitFMUL( final FMUL obj ) { + } + + + @Override + public void visitLLOAD( final LLOAD obj ) { + } + + + @Override + public void visitJSR( final JSR obj ) { + } + + + @Override + public void visitFSUB( final FSUB obj ) { + } + + + @Override + public void visitSASTORE( final SASTORE obj ) { + } + + + @Override + public void visitALOAD( final ALOAD obj ) { + } + + + @Override + public void visitDUP2_X2( final DUP2_X2 obj ) { + } + + + @Override + public void visitRETURN( final RETURN obj ) { + } + + + @Override + public void visitDALOAD( final DALOAD obj ) { + } + + + @Override + public void visitSIPUSH( final SIPUSH obj ) { + } + + + @Override + public void visitDSUB( final DSUB obj ) { + } + + + @Override + public void visitL2F( final L2F obj ) { + } + + + @Override + public void visitIF_ICMPGT( final IF_ICMPGT obj ) { + } + + + @Override + public void visitF2D( final F2D obj ) { + } + + + @Override + public void visitI2L( final I2L obj ) { + } + + + @Override + public void visitIF_ACMPNE( final IF_ACMPNE obj ) { + } + + + @Override + public void visitPOP( final POP obj ) { + } + + + @Override + public void visitI2S( final I2S obj ) { + } + + + @Override + public void visitIFEQ( final IFEQ obj ) { + } + + + @Override + public void visitSWAP( final SWAP obj ) { + } + + + @Override + public void visitIOR( final IOR obj ) { + } + + + @Override + public void visitIREM( final IREM obj ) { + } + + + @Override + public void visitIASTORE( final IASTORE obj ) { + } + + + @Override + public void visitNEWARRAY( final NEWARRAY obj ) { + } + + + @Override + public void visitINVOKEINTERFACE( final INVOKEINTERFACE obj ) { + } + + + @Override + public void visitINEG( final INEG obj ) { + } + + + @Override + public void visitLCMP( final LCMP obj ) { + } + + + @Override + public void visitJSR_W( final JSR_W obj ) { + } + + + @Override + public void visitMULTIANEWARRAY( final MULTIANEWARRAY obj ) { + } + + + @Override + public void visitDUP_X2( final DUP_X2 obj ) { + } + + + @Override + public void visitSALOAD( final SALOAD obj ) { + } + + + @Override + public void visitIFNONNULL( final IFNONNULL obj ) { + } + + + @Override + public void visitDMUL( final DMUL obj ) { + } + + + @Override + public void visitIFNE( final IFNE obj ) { + } + + + @Override + public void visitIF_ICMPLE( final IF_ICMPLE obj ) { + } + + + @Override + public void visitLDC2_W( final LDC2_W obj ) { + } + + + @Override + public void visitGETFIELD( final GETFIELD obj ) { + } + + + @Override + public void visitLADD( final LADD obj ) { + } + + + @Override + public void visitNOP( final NOP obj ) { + } + + + @Override + public void visitFALOAD( final FALOAD obj ) { + } + + + @Override + public void visitINSTANCEOF( final INSTANCEOF obj ) { + } + + + @Override + public void visitIFLE( final IFLE obj ) { + } + + + @Override + public void visitLXOR( final LXOR obj ) { + } + + + @Override + public void visitLRETURN( final LRETURN obj ) { + } + + + @Override + public void visitFCONST( final FCONST obj ) { + } + + + @Override + public void visitIUSHR( final IUSHR obj ) { + } + + + @Override + public void visitBALOAD( final BALOAD obj ) { + } + + + @Override + public void visitDUP2( final DUP2 obj ) { + } + + + @Override + public void visitIF_ACMPEQ( final IF_ACMPEQ obj ) { + } + + + @Override + public void visitIMPDEP1( final IMPDEP1 obj ) { + } + + + @Override + public void visitMONITORENTER( final MONITORENTER obj ) { + } + + + @Override + public void visitLSHL( final LSHL obj ) { + } + + + @Override + public void visitDCMPG( final DCMPG obj ) { + } + + + @Override + public void visitD2L( final D2L obj ) { + } + + + @Override + public void visitIMPDEP2( final IMPDEP2 obj ) { + } + + + @Override + public void visitL2D( final L2D obj ) { + } + + + @Override + public void visitRET( final RET obj ) { + } + + + @Override + public void visitIFGT( final IFGT obj ) { + } + + + @Override + public void visitIXOR( final IXOR obj ) { + } + + + @Override + public void visitINVOKEVIRTUAL( final INVOKEVIRTUAL obj ) { + } + + + @Override + public void visitFASTORE( final FASTORE obj ) { + } + + + @Override + public void visitIRETURN( final IRETURN obj ) { + } + + + @Override + public void visitIF_ICMPNE( final IF_ICMPNE obj ) { + } + + + @Override + public void visitFLOAD( final FLOAD obj ) { + } + + + @Override + public void visitLDIV( final LDIV obj ) { + } + + + @Override + public void visitPUTSTATIC( final PUTSTATIC obj ) { + } + + + @Override + public void visitAALOAD( final AALOAD obj ) { + } + + + @Override + public void visitD2I( final D2I obj ) { + } + + + @Override + public void visitIF_ICMPEQ( final IF_ICMPEQ obj ) { + } + + + @Override + public void visitAASTORE( final AASTORE obj ) { + } + + + @Override + public void visitARETURN( final ARETURN obj ) { + } + + + @Override + public void visitDUP2_X1( final DUP2_X1 obj ) { + } + + + @Override + public void visitFNEG( final FNEG obj ) { + } + + + @Override + public void visitGOTO_W( final GOTO_W obj ) { + } + + + @Override + public void visitD2F( final D2F obj ) { + } + + + @Override + public void visitGOTO( final GOTO obj ) { + } + + + @Override + public void visitISUB( final ISUB obj ) { + } + + + @Override + public void visitF2I( final F2I obj ) { + } + + + @Override + public void visitDNEG( final DNEG obj ) { + } + + + @Override + public void visitICONST( final ICONST obj ) { + } + + + @Override + public void visitFDIV( final FDIV obj ) { + } + + + @Override + public void visitI2B( final I2B obj ) { + } + + + @Override + public void visitLNEG( final LNEG obj ) { + } + + + @Override + public void visitLREM( final LREM obj ) { + } + + + @Override + public void visitIMUL( final IMUL obj ) { + } + + + @Override + public void visitIADD( final IADD obj ) { + } + + + @Override + public void visitLSHR( final LSHR obj ) { + } + + + @Override + public void visitLOOKUPSWITCH( final LOOKUPSWITCH obj ) { + } + + + @Override + public void visitDUP_X1( final DUP_X1 obj ) { + } + + + @Override + public void visitFCMPL( final FCMPL obj ) { + } + + + @Override + public void visitI2C( final I2C obj ) { + } + + + @Override + public void visitLMUL( final LMUL obj ) { + } + + + @Override + public void visitLUSHR( final LUSHR obj ) { + } + + + @Override + public void visitISHL( final ISHL obj ) { + } + + + @Override + public void visitLALOAD( final LALOAD obj ) { + } + + + @Override + public void visitASTORE( final ASTORE obj ) { + } + + + @Override + public void visitANEWARRAY( final ANEWARRAY obj ) { + } + + + @Override + public void visitFRETURN( final FRETURN obj ) { + } + + + @Override + public void visitFADD( final FADD obj ) { + } + + + @Override + public void visitBREAKPOINT( final BREAKPOINT obj ) { + } + + /** + * @since 6.0 + */ + @Override + public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC obj) { + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java new file mode 100644 index 00000000000..ae2746e2d53 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java @@ -0,0 +1,147 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.EnumElementValue; + +/** + * @since 6.0 + */ +public class EnumElementValueGen extends ElementValueGen +{ + // 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 EnumElementValueGen(final int typeIdx, final int valueIdx, + final ConstantPoolGen cpool) + { + super(ElementValueGen.ENUM_CONSTANT, cpool); + if (super.getElementValueType() != ENUM_CONSTANT) { + throw new RuntimeException( + "Only element values of type enum can be built with this ctor - type specified: " + + super.getElementValueType()); + } + this.typeIdx = typeIdx; + this.valueIdx = valueIdx; + } + + /** + * Return immutable variant of this EnumElementValue + */ + @Override + public ElementValue getElementValue() + { + System.err.println("Duplicating value: " + getEnumTypeString() + ":" + + getEnumValueString()); + return new EnumElementValue(super.getElementValueType(), typeIdx, valueIdx, + getConstantPool().getConstantPool()); + } + + public EnumElementValueGen(final ObjectType t, final String value, final ConstantPoolGen cpool) + { + super(ElementValueGen.ENUM_CONSTANT, cpool); + typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t); + valueIdx = cpool.addUtf8(value);// was addString(value); + } + + public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen cpool, + final 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(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 type of value (ENUM_CONSTANT == 'e') + dos.writeShort(typeIdx); // u2 + dos.writeShort(valueIdx); // u2 + } + + @Override + public String stringifyValue() + { + final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(valueIdx); + return cu8.getBytes(); + // ConstantString cu8 = + // (ConstantString)getConstantPool().getConstant(valueIdx); + // return + // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); + } + + // 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)) + .getBytes(); + // return Utility.signatureToString(cu8.getBytes()); + } + + public String getEnumValueString() + { + return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getBytes(); + // 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/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java index d41af1032c8..a0947190b10 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote an instruction that may throw a run-time or a linking * exception (or both) during execution. This is not quite the truth @@ -39,8 +38,9 @@ package com.sun.org.apache.bcel.internal.generic; * "Throwable" object; so this term is equally used for "Exception" * and "Error" objects. * - * @author Enver Haase + * @version $Id: ExceptionThrower.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface ExceptionThrower { - public java.lang.Class[] getExceptions(); + + java.lang.Class[] getExceptions(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java index 417b429c682..f374a10f8a2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * F2D - Convert float to double *
      Stack: ..., value -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: F2D.java 1747278 2016-06-07 17:28:43Z britter $ */ public class F2D extends ConversionInstruction { - /** Convert float to double - */ - public F2D() { - super(com.sun.org.apache.bcel.internal.Constants.F2D); - } + + /** Convert float to double + */ + public F2D() { + super(com.sun.org.apache.bcel.internal.Const.F2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2D(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2D(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java index a8d75d1389f..c5962696a8d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * F2I - Convert float to int *
      Stack: ..., value -> ..., result
      * - * @author M. Dahm + * @version $Id: F2I.java 1747278 2016-06-07 17:28:43Z britter $ */ public class F2I extends ConversionInstruction { - /** Convert float to int - */ - public F2I() { - super(com.sun.org.apache.bcel.internal.Constants.F2I); - } + + /** Convert float to int + */ + public F2I() { + super(com.sun.org.apache.bcel.internal.Const.F2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2I(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2I(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java index 2f58b563fd5..d47b2a1c5af 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * F2L - Convert float to long *
      Stack: ..., value -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: F2L.java 1747278 2016-06-07 17:28:43Z britter $ */ public class F2L extends ConversionInstruction { - /** Convert float to long - */ - public F2L() { - super(com.sun.org.apache.bcel.internal.Constants.F2L); - } + + /** Convert float to long + */ + public F2L() { + super(com.sun.org.apache.bcel.internal.Const.F2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitF2L(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitF2L(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java index 6460c871037..f1a9a7a5b1f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FADD - Add floats *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: FADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FADD extends ArithmeticInstruction { - /** Add floats - */ - public FADD() { - super(com.sun.org.apache.bcel.internal.Constants.FADD); - } + + /** Add floats + */ + public FADD() { + super(com.sun.org.apache.bcel.internal.Const.FADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java index c3e67ab8f26..55f950a3793 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FALOAD - Load float from array *
      Stack: ..., arrayref, index -> ..., value
      * - * @author M. Dahm + * @version $Id: FALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FALOAD extends ArrayInstruction implements StackProducer { - /** Load float from array - */ - public FALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.FALOAD); - } + + /** Load float from array + */ + public FALOAD() { + super(com.sun.org.apache.bcel.internal.Const.FALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitFALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitFALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java index 231eb319684..f7e893e9273 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FASTORE - Store into float array *
      Stack: ..., arrayref, index, value -> ...
      * - * @author M. Dahm + * @version $Id: FASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FASTORE extends ArrayInstruction implements StackConsumer { - /** Store float into array - */ - public FASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.FASTORE); - } + + /** Store float into array + */ + public FASTORE() { + super(com.sun.org.apache.bcel.internal.Const.FASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitFASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitFASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java index 761df11e7e9..b950c85d102 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java @@ -21,38 +21,40 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * FCMPG - Compare floats: value1 > value2 + * FCMPG - Compare floats: value1 > value2 *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: FCMPG.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class FCMPG extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - public FCMPG() { - super(com.sun.org.apache.bcel.internal.Constants.FCMPG, (short)1); - } +public class FCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.FLOAT - */ - public Type getType(ConstantPoolGen cp) { - return Type.FLOAT; - } + public FCMPG() { + super(com.sun.org.apache.bcel.internal.Const.FCMPG, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitFCMPG(this); - } + /** @return Type.FLOAT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.FLOAT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitFCMPG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java index a6aa1780681..ddb68b08866 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java @@ -21,38 +21,40 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * FCMPL - Compare floats: value1 < value2 + * FCMPL - Compare floats: value1 < value2 *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: FCMPL.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class FCMPL extends Instruction - implements TypedInstruction, StackProducer, StackConsumer { - public FCMPL() { - super(com.sun.org.apache.bcel.internal.Constants.FCMPL, (short)1); - } +public class FCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.FLOAT - */ - public Type getType(ConstantPoolGen cp) { - return Type.FLOAT; - } + public FCMPL() { + super(com.sun.org.apache.bcel.internal.Const.FCMPL, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitFCMPL(this); - } + /** @return Type.FLOAT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.FLOAT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitFCMPL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java index 76f2b40cd06..0b29d7b7472 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java @@ -20,60 +20,69 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FCONST - Push 0.0, 1.0 or 2.0, other values cause an exception * *
      Stack: ... -> ..., 
      * - * @author M. Dahm + * @version $Id: FCONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class FCONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private float value; +public class FCONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FCONST() {} + private float value; - public FCONST(float f) { - super(com.sun.org.apache.bcel.internal.Constants.FCONST_0, (short)1); - if(f == 0.0) - opcode = com.sun.org.apache.bcel.internal.Constants.FCONST_0; - else if(f == 1.0) - opcode = com.sun.org.apache.bcel.internal.Constants.FCONST_1; - else if(f == 2.0) - opcode = com.sun.org.apache.bcel.internal.Constants.FCONST_2; - else - throw new ClassGenException("FCONST can be used only for 0.0, 1.0 and 2.0: " + f); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FCONST() { + } - value = f; - } - public Number getValue() { return Float.valueOf(value); } + public FCONST(final float f) { + super(com.sun.org.apache.bcel.internal.Const.FCONST_0, (short) 1); + if (f == 0.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.FCONST_0); + } else if (f == 1.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.FCONST_1); + } else if (f == 2.0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.FCONST_2); + } else { + throw new ClassGenException("FCONST can be used only for 0.0, 1.0 and 2.0: " + f); + } + value = f; + } - /** @return Type.FLOAT - */ - public Type getType(ConstantPoolGen cp) { - return Type.FLOAT; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitFCONST(this); - } + @Override + public Number getValue() { + return new Float(value); + } + + + /** @return Type.FLOAT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.FLOAT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitFCONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java index 8c7da046dfe..d3639219ed9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FDIV - Divide floats *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: FDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FDIV extends ArithmeticInstruction { - /** Divide floats - */ - public FDIV() { - super(com.sun.org.apache.bcel.internal.Constants.FDIV); - } + + /** Divide floats + */ + public FDIV() { + super(com.sun.org.apache.bcel.internal.Const.FDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFDIV(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java index afd730cf528..40c49d74cc3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FLOAD - Load float from local variable *
      Stack ... -> ..., result
      * - * @author M. Dahm + * @version $Id: FLOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FLOAD() { - super(com.sun.org.apache.bcel.internal.Constants.FLOAD, com.sun.org.apache.bcel.internal.Constants.FLOAD_0); - } - /** Load float from local variable - * @param n index of local variable - */ - public FLOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.FLOAD, com.sun.org.apache.bcel.internal.Constants.FLOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FLOAD() { + super(com.sun.org.apache.bcel.internal.Const.FLOAD, com.sun.org.apache.bcel.internal.Const.FLOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitFLOAD(this); - } + + /** Load float from local variable + * @param n index of local variable + */ + public FLOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.FLOAD, com.sun.org.apache.bcel.internal.Const.FLOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitFLOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java index fbba7f71f34..6af6dafc8c3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FMUL - Multiply floats *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: FMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FMUL extends ArithmeticInstruction { - /** Multiply floats - */ - public FMUL() { - super(com.sun.org.apache.bcel.internal.Constants.FMUL); - } + + /** Multiply floats + */ + public FMUL() { + super(com.sun.org.apache.bcel.internal.Const.FMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java index 33fe74faa22..586116fd439 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FNEG - Negate float *
      Stack: ..., value -> ..., result
      * - * @author M. Dahm + * @version $Id: FNEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FNEG extends ArithmeticInstruction { - public FNEG() { - super(com.sun.org.apache.bcel.internal.Constants.FNEG); - } + + public FNEG() { + super(com.sun.org.apache.bcel.internal.Const.FNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFNEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java index ad0f94de62d..e392069a5cf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FREM - Remainder of floats *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: FREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FREM extends ArithmeticInstruction { - /** Remainder of floats - */ - public FREM() { - super(com.sun.org.apache.bcel.internal.Constants.FREM); - } + + /** Remainder of floats + */ + public FREM() { + super(com.sun.org.apache.bcel.internal.Const.FREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFREM(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java index d2198f82162..80accc29613 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FRETURN - Return float from method *
      Stack: ..., value -> <empty>
      * - * @author M. Dahm + * @version $Id: FRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FRETURN extends ReturnInstruction { - /** Return float from method - */ - public FRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.FRETURN); - } + + /** Return float from method + */ + public FRETURN() { + super(com.sun.org.apache.bcel.internal.Const.FRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitFRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitFRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java index 124e8b347f1..6af475efaab 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FSTORE - Store float into local variable *
      Stack: ..., value -> ... 
      * - * @author M. Dahm + * @version $Id: FSTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FSTORE() { - super(com.sun.org.apache.bcel.internal.Constants.FSTORE, com.sun.org.apache.bcel.internal.Constants.FSTORE_0); - } - /** Store float into local variable - * @param n index of local variable - */ - public FSTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.FSTORE, com.sun.org.apache.bcel.internal.Constants.FSTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FSTORE() { + super(com.sun.org.apache.bcel.internal.Const.FSTORE, com.sun.org.apache.bcel.internal.Const.FSTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitFSTORE(this); - } + + /** Store float into local variable + * @param n index of local variable + */ + public FSTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.FSTORE, com.sun.org.apache.bcel.internal.Const.FSTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitFSTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java index 213c802a23f..71d3f726f9a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * FSUB - Substract floats *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: FSUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class FSUB extends ArithmeticInstruction { - /** Substract floats - */ - public FSUB() { - super(com.sun.org.apache.bcel.internal.Constants.FSUB); - } + + /** Substract floats + */ + public FSUB() { + super(com.sun.org.apache.bcel.internal.Const.FSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitFSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitFSUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java index 42f76abf9f3..f1c65a67e21 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java @@ -17,260 +17,345 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; -import java.util.Iterator; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Annotations; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantObject; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * Template class for building up a field. The only extraordinary thing - * one can do is to add a constant value attribute to a field (which must of - * course be compatible with to the declared type). + * Template class for building up a field. The only extraordinary thing one can + * do is to add a constant value attribute to a field (which must of course be + * compatible with to the declared type). * - * @author M. Dahm + * @version $Id: FieldGen.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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 access_flags access qualifiers - * @param type field type - * @param name field name - * @param cp constant pool - */ - public FieldGen(int access_flags, Type type, String name, ConstantPoolGen cp) { - setAccessFlags(access_flags); - setType(type); - setName(name); - setConstantPool(cp); - } + private Object value = null; + private static BCELComparator bcelComparator = new BCELComparator() { - /** - * Instantiate from existing field. - * - * @param field Field object - * @param cp constant pool (must contain the same entries as the field's constant pool) - */ - public FieldGen(Field field, ConstantPoolGen cp) { - this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp); + @Override + public boolean equals(final Object o1, final Object o2) { + final FieldGen THIS = (FieldGen) o1; + final FieldGen THAT = (FieldGen) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); + } - Attribute[] attrs = field.getAttributes(); + @Override + public int hashCode(final Object o) { + final FieldGen THIS = (FieldGen) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; - for(int i=0; i < attrs.length; i++) { - if(attrs[i] instanceof ConstantValue) - setValue(((ConstantValue)attrs[i]).getConstantValueIndex()); - else - addAttribute(attrs[i]); - } - } - - private void setValue(int index) { - ConstantPool cp = this.cp.getConstantPool(); - Constant c = cp.getConstant(index); - value = ((ConstantObject)c).getConstantValue(cp); - } - - /** - * Set (optional) initial value of field, otherwise it will be set to null/0/false - * by the JVM automatically. - */ - public void setInitValue(String str) { - checkType(new ObjectType("java.lang.String")); - - if(str != null) - value = str; - } - - public void setInitValue(long l) { - checkType(Type.LONG); - - if(l != 0L) - value = Long.valueOf(l); - } - - public void setInitValue(int i) { - checkType(Type.INT); - - if(i != 0) - value = Integer.valueOf(i); - } - - public void setInitValue(short s) { - checkType(Type.SHORT); - - if(s != 0) - value = Integer.valueOf(s); - } - - public void setInitValue(char c) { - checkType(Type.CHAR); - - if(c != 0) - value = Integer.valueOf(c); - } - - public void setInitValue(byte b) { - checkType(Type.BYTE); - - if(b != 0) - value = Integer.valueOf(b); - } - - public void setInitValue(boolean b) { - checkType(Type.BOOLEAN); - - if(b) - value = Integer.valueOf(1); - } - - public void setInitValue(float f) { - checkType(Type.FLOAT); - - if(f != 0.0) - value = Float.valueOf(f); - } - - public void setInitValue(double d) { - checkType(Type.DOUBLE); - - if(d != 0.0) - value = Double.valueOf(d); - } - - /** Remove any initial value. - */ - public void cancelInitValue() { - value = null; - } - - private void checkType(Type atype) { - if(type == null) - throw new ClassGenException("You haven't defined the type of the field yet"); - - if(!isFinal()) - throw new ClassGenException("Only final fields may have an initial value!"); - - if(!type.equals(atype)) - throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype); - } - - /** - * Get field object after having set up all necessary values. - */ - public Field getField() { - String signature = getSignature(); - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(signature); - - if(value != null) { - checkType(type); - int index = addConstant(); - addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), - 2, index, cp.getConstantPool())); + /** + * Declare a field. If it is static (isStatic() == true) and has a basic + * type like int or String it may have an initial value associated with it + * as defined by setInitValue(). + * + * @param access_flags access qualifiers + * @param type field type + * @param name field name + * @param cp constant pool + */ + public FieldGen(final int access_flags, final Type type, final String name, final ConstantPoolGen cp) { + super(access_flags); + setType(type); + setName(name); + setConstantPool(cp); } - return new Field(access_flags, name_index, signature_index, getAttributes(), - cp.getConstantPool()); - } - - private int addConstant() { - switch(type.getType()) { - case Constants.T_INT: case Constants.T_CHAR: case Constants.T_BYTE: - case Constants.T_BOOLEAN: case Constants.T_SHORT: - return cp.addInteger(((Integer)value).intValue()); - - case Constants.T_FLOAT: - return cp.addFloat(((Float)value).floatValue()); - - case Constants.T_DOUBLE: - return cp.addDouble(((Double)value).doubleValue()); - - case Constants.T_LONG: - return cp.addLong(((Long)value).longValue()); - - case Constants.T_REFERENCE: - return cp.addString(((String)value)); - - default: - throw new RuntimeException("Oops: Unhandled : " + type.getType()); + /** + * 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(final Field field, final ConstantPoolGen cp) { + this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp); + final Attribute[] attrs = field.getAttributes(); + for (final Attribute attr : attrs) { + if (attr instanceof ConstantValue) { + setValue(((ConstantValue) attr).getConstantValueIndex()); + } else if (attr instanceof Annotations) { + final Annotations runtimeAnnotations = (Annotations) attr; + final AnnotationEntry[] annotationEntries = runtimeAnnotations.getAnnotationEntries(); + for (final AnnotationEntry element : annotationEntries) { + addAnnotationEntry(new AnnotationEntryGen(element, cp, false)); + } + } else { + addAttribute(attr); + } + } } - } - public String getSignature() { return type.getSignature(); } + private void setValue(final int index) { + final ConstantPool cp = super.getConstantPool().getConstantPool(); + final Constant c = cp.getConstant(index); + value = ((ConstantObject) c).getConstantValue(cp); + } - private ArrayList observers; + /** + * Set (optional) initial value of field, otherwise it will be set to + * null/0/false by the JVM automatically. + */ + public void setInitValue(final String str) { + checkType(ObjectType.getInstance("java.lang.String")); + if (str != null) { + value = str; + } + } - /** Add observer for this object. - */ - public void addObserver(FieldObserver o) { - if(observers == null) - observers = new ArrayList(); + public void setInitValue(final long l) { + checkType(Type.LONG); + if (l != 0L) { + value = l; + } + } - observers.add(o); - } + public void setInitValue(final int i) { + checkType(Type.INT); + if (i != 0) { + value = i; + } + } - /** Remove observer for this object. - */ - public void removeObserver(FieldObserver o) { - if(observers != null) - observers.remove(o); - } + public void setInitValue(final short s) { + checkType(Type.SHORT); + if (s != 0) { + value = (int) s; + } + } - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if(observers != null) - for(Iterator e = observers.iterator(); e.hasNext(); ) - ((FieldObserver)e.next()).notify(this); - } + public void setInitValue(final char c) { + checkType(Type.CHAR); + if (c != 0) { + value = (int) c; + } + } - public String getInitValue() { - if(value != null) { - return value.toString(); - } else - return null; - } + public void setInitValue(final byte b) { + checkType(Type.BYTE); + if (b != 0) { + value = (int) b; + } + } - /** - * Return string representation close to declaration format, - * `public static final short MAX = 100', e.g.. - * - * @return String representation of field - */ - public final String toString() { - String name, signature, access; // Short cuts to constant pool + public void setInitValue(final boolean b) { + checkType(Type.BOOLEAN); + if (b) { + value = 1; + } + } - access = Utility.accessToString(access_flags); - access = access.equals("")? "" : (access + " "); - signature = type.toString(); - name = getName(); + public void setInitValue(final float f) { + checkType(Type.FLOAT); + if (f != 0.0) { + value = f; + } + } - StringBuffer buf = new StringBuffer(access + signature + " " + name); - String value = getInitValue(); + public void setInitValue(final double d) { + checkType(Type.DOUBLE); + if (d != 0.0) { + value = d; + } + } - if(value != null) - buf.append(" = " + value); + /** + * Remove any initial value. + */ + public void cancelInitValue() { + value = null; + } - return buf.toString(); - } + private void checkType(final Type atype) { + final Type superType = super.getType(); + if (superType == 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 (!superType.equals(atype)) { + throw new ClassGenException("Types are not compatible: " + superType + " vs. " + atype); + } + } - /** @return deep copy of this field - */ - public FieldGen copy(ConstantPoolGen cp) { - FieldGen fg = (FieldGen)clone(); + /** + * Get field object after having set up all necessary values. + */ + public Field getField() { + final String signature = getSignature(); + final int name_index = super.getConstantPool().addUtf8(super.getName()); + final int signature_index = super.getConstantPool().addUtf8(signature); + if (value != null) { + checkType(super.getType()); + final int index = addConstant(); + addAttribute(new ConstantValue(super.getConstantPool().addUtf8("ConstantValue"), 2, index, + super.getConstantPool().getConstantPool())); // sic + } + addAnnotationsAsAttribute(super.getConstantPool()); + return new Field(super.getAccessFlags(), name_index, signature_index, getAttributes(), + super.getConstantPool().getConstantPool()); // sic + } - fg.setConstantPool(cp); - return fg; - } + private void addAnnotationsAsAttribute(final ConstantPoolGen cp) { + final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); + for (final Attribute attr : attrs) { + addAttribute(attr); + } + } + + private int addConstant() { + switch (super.getType().getType()) { // sic + case Const.T_INT: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_BOOLEAN: + case Const.T_SHORT: + return super.getConstantPool().addInteger(((Integer) value)); + case Const.T_FLOAT: + return super.getConstantPool().addFloat(((Float) value)); + case Const.T_DOUBLE: + return super.getConstantPool().addDouble(((Double) value)); + case Const.T_LONG: + return super.getConstantPool().addLong(((Long) value)); + case Const.T_REFERENCE: + return super.getConstantPool().addString((String) value); + default: + throw new RuntimeException("Oops: Unhandled : " + super.getType().getType()); // sic + } + } + + @Override + public String getSignature() { + return super.getType().getSignature(); + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final FieldObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final FieldObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final FieldObserver observer : observers) { + observer.notify(this); + } + } + } + + public String getInitValue() { + if (value != null) { + return value.toString(); + } + return null; + } + + /** + * Return string representation close to declaration format, `public static + * final short MAX = 100', e.g.. + * + * @return String representation of field + */ + @Override + public final String toString() { + String name; + String signature; + String access; // Short cuts to constant pool + access = Utility.accessToString(super.getAccessFlags()); + access = access.isEmpty() ? "" : (access + " "); + signature = super.getType().toString(); + name = getName(); + final StringBuilder buf = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber + buf.append(access).append(signature).append(" ").append(name); + final String value = getInitValue(); + if (value != null) { + buf.append(" = ").append(value); + } + return buf.toString(); + } + + /** + * @return deep copy of this field + */ + public FieldGen copy(final ConstantPoolGen cp) { + final FieldGen fg = (FieldGen) clone(); + fg.setConstantPool(cp); + return fg; + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * FieldGen objects are said to be equal when their names and signatures are + * equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the field's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java index 677dba091df..f4aa17d9ff0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,85 +17,152 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; - -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AccessFlags; +import com.sun.org.apache.bcel.internal.classfile.Attribute; /** - * Super class for FieldGen and MethodGen objects, since they have - * some methods in common! + * Super class for FieldGen and MethodGen objects, since they have some methods + * in common! * - * @author M. Dahm + * @version $Id: FieldGenOrMethodGen.java 1749603 2016-06-21 20:50:19Z ggregory + * $ */ -public abstract class FieldGenOrMethodGen extends AccessFlags - implements NamedAndTyped, Cloneable -{ - protected String name; - protected Type type; - protected ConstantPoolGen cp; - private ArrayList attribute_vec = new ArrayList(); +public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable { - protected FieldGenOrMethodGen() {} + private String name; + private Type type; + private ConstantPoolGen cp; - public void setType(Type type) { - if(type.getType() == Constants.T_ADDRESS) - throw new IllegalArgumentException("Type can not be " + type); + private final List attribute_vec = new ArrayList<>(); - this.type = type; - } - public Type getType() { return type; } + // @since 6.0 + private final List annotation_vec = new ArrayList<>(); - /** @return name of method/field. - */ - public String getName() { return name; } - public void setName(String name) { this.name = name; } - - public ConstantPoolGen getConstantPool() { return cp; } - public void setConstantPool(ConstantPoolGen cp) { this.cp = cp; } - - /** - * Add an attribute to this method. Currently, the JVM knows about - * the `Code', `ConstantValue', `Synthetic' and `Exceptions' - * attributes. Other attributes will be ignored by the JVM but do no - * harm. - * - * @param a attribute to be added - */ - public void addAttribute(Attribute a) { attribute_vec.add(a); } - - /** - * Remove an attribute. - */ - public void removeAttribute(Attribute a) { attribute_vec.remove(a); } - - /** - * Remove all attributes. - */ - public void removeAttributes() { attribute_vec.clear(); } - - /** - * @return all attributes of this method. - */ - public Attribute[] getAttributes() { - Attribute[] attributes = new Attribute[attribute_vec.size()]; - attribute_vec.toArray(attributes); - return attributes; - } - - /** @return signature of method/field. - */ - public abstract String getSignature(); - - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + protected FieldGenOrMethodGen() { + } + + /** + * @since 6.0 + */ + protected FieldGenOrMethodGen(final int access_flags) { // TODO could this be package protected? + super(access_flags); + } + + @Override + public void setType(final Type type) { // TODO could be package-protected? + if (type.getType() == Const.T_ADDRESS) { + throw new IllegalArgumentException("Type can not be " + type); + } + this.type = type; + } + + @Override + public Type getType() { + return type; + } + + /** + * @return name of method/field. + */ + @Override + public String getName() { + return name; + } + + @Override + public void setName(final String name) { // TODO could be package-protected? + this.name = name; + } + + public ConstantPoolGen getConstantPool() { + return cp; + } + + public void setConstantPool(final ConstantPoolGen cp) { // TODO could be package-protected? + this.cp = cp; + } + + /** + * Add an attribute to this method. Currently, the JVM knows about the + * `Code', `ConstantValue', `Synthetic' and `Exceptions' attributes. Other + * attributes will be ignored by the JVM but do no harm. + * + * @param a attribute to be added + */ + public void addAttribute(final Attribute a) { + attribute_vec.add(a); + } + + /** + * @since 6.0 + */ + protected void addAnnotationEntry(final AnnotationEntryGen ag) // TODO could this be package protected? + { + annotation_vec.add(ag); + } + + /** + * Remove an attribute. + */ + public void removeAttribute(final Attribute a) { + attribute_vec.remove(a); + } + + /** + * @since 6.0 + */ + protected void removeAnnotationEntry(final AnnotationEntryGen ag) // TODO could this be package protected? + { + annotation_vec.remove(ag); + } + + /** + * Remove all attributes. + */ + public void removeAttributes() { + attribute_vec.clear(); + } + + /** + * @since 6.0 + */ + protected void removeAnnotationEntries() // TODO could this be package protected? + { + annotation_vec.clear(); + } + + /** + * @return all attributes of this method. + */ + public Attribute[] getAttributes() { + final Attribute[] attributes = new Attribute[attribute_vec.size()]; + attribute_vec.toArray(attributes); + return attributes; + } + + public AnnotationEntryGen[] getAnnotationEntries() { + final AnnotationEntryGen[] annotations = new AnnotationEntryGen[annotation_vec.size()]; + annotation_vec.toArray(annotations); + return annotations; + } + + /** + * @return signature of method/field. + */ + public abstract String getSignature(); + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java index 30224f1e20d..9848e5e905f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java @@ -21,62 +21,66 @@ package com.sun.org.apache.bcel.internal.generic; - import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; -import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; -import com.sun.org.apache.bcel.internal.classfile.ConstantCP; -import com.sun.org.apache.bcel.internal.classfile.*; /** * Super class for the GET/PUTxxx family of instructions. * - * @author M. Dahm + * @version $Id: FieldInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class FieldInstruction extends FieldOrMethod - implements TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FieldInstruction() {} +public abstract class FieldInstruction extends FieldOrMethod { - /** - * @param index to constant pool - */ - protected FieldInstruction(short opcode, int index) { - super(opcode, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FieldInstruction() { + } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - return com.sun.org.apache.bcel.internal.Constants.OPCODE_NAMES[opcode] + " " + - cp.constantToString(index, com.sun.org.apache.bcel.internal.Constants.CONSTANT_Fieldref); - } - /** @return size of field (1 or 2) - */ - protected int getFieldSize(ConstantPoolGen cpg) { - return getType(cpg).getSize(); - } + /** + * @param index to constant pool + */ + protected FieldInstruction(final short opcode, final int index) { + super(opcode, index); + } - /** @return return type of referenced field - */ - public Type getType(ConstantPoolGen cpg) { - return getFieldType(cpg); - } - /** @return type of field - */ - public Type getFieldType(ConstantPoolGen cpg) { - return Type.getType(getSignature(cpg)); - } + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + + cp.constantToString(super.getIndex(), com.sun.org.apache.bcel.internal.Const.CONSTANT_Fieldref); + } - /** @return name of referenced field. - */ - public String getFieldName(ConstantPoolGen cpg) { - return getName(cpg); - } + + /** @return size of field (1 or 2) + */ + protected int getFieldSize( final ConstantPoolGen cpg ) { + return Type.size(Type.getTypeSize(getSignature(cpg))); + } + + + /** @return return type of referenced field + */ + @Override + public Type getType( final ConstantPoolGen cpg ) { + return getFieldType(cpg); + } + + + /** @return type of field + */ + public Type getFieldType( final ConstantPoolGen cpg ) { + return Type.getType(getSignature(cpg)); + } + + + /** @return name of referenced field. + */ + public String getFieldName( final ConstantPoolGen cpg ) { + return getName(cpg); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java index b2ee9d1a957..a26ab4a2a20 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Imnplement this interface if you're interested in changes to a FieldGen object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: FieldObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface FieldObserver { - public void notify(FieldGen field); + + void notify( FieldGen field ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java index 5d32603ac5c..84f19cccf8e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java @@ -21,64 +21,123 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; /** * Super class for InvokeInstruction and FieldInstruction, since they have * some methods in common! * - * @author M. Dahm + * @version $Id: FieldOrMethod.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public abstract class FieldOrMethod extends CPInstruction implements LoadClass { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - FieldOrMethod() {} - /** - * @param index to constant pool - */ - protected FieldOrMethod(short opcode, int index) { - super(opcode, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + FieldOrMethod() { + } - /** @return signature of referenced method/field. - */ - public String getSignature(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP)cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType)cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8)cp.getConstant(cnat.getSignatureIndex())).getBytes(); - } + /** + * @param index to constant pool + */ + protected FieldOrMethod(final short opcode, final int index) { + super(opcode, index); + } - /** @return name of referenced method/field. - */ - public String getName(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP)cp.getConstant(index); - ConstantNameAndType cnat = (ConstantNameAndType)cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8)cp.getConstant(cnat.getNameIndex())).getBytes(); - } - /** @return name of the referenced class/interface - */ - public String getClassName(ConstantPoolGen cpg) { - ConstantPool cp = cpg.getConstantPool(); - ConstantCP cmr = (ConstantCP)cp.getConstant(index); - return cp.getConstantString(cmr.getClassIndex(), com.sun.org.apache.bcel.internal.Constants.CONSTANT_Class).replace('/', '.'); - } + /** @return signature of referenced method/field. + */ + public String getSignature( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); + } - /** @return type of the referenced class/interface - */ - public ObjectType getClassType(ConstantPoolGen cpg) { - return new ObjectType(getClassName(cpg)); - } - /** @return type of the referenced class/interface - */ - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - return getClassType(cpg); - } + /** @return name of referenced method/field. + */ + public String getName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } + + + /** + * @return name of the referenced class/interface + * @deprecated If the instruction references an array class, + * this method will return "java.lang.Object". + * For code generated by Java 1.5, this answer is + * sometimes wrong (e.g., if the "clone()" method is + * called on an array). A better idea is to use + * the {@link #getReferenceType(ConstantPoolGen)} method, which correctly distinguishes + * between class types and array types. + * + */ + @Deprecated + public String getClassName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class); + if (className.startsWith("[")) { + // Turn array classes into java.lang.Object. + return "java.lang.Object"; + } + return className.replace('/', '.'); + } + + + /** @return type of the referenced class/interface + * @deprecated If the instruction references an array class, + * the ObjectType returned will be invalid. Use + * getReferenceType() instead. + */ + @Deprecated + public ObjectType getClassType( final ConstantPoolGen cpg ) { + return ObjectType.getInstance(getClassName(cpg)); + } + + + /** + * Return the reference type representing the class, interface, + * or array class referenced by the instruction. + * @param cpg the ConstantPoolGen used to create the instruction + * @return an ObjectType (if the referenced class type is a class + * or interface), or an ArrayType (if the referenced class + * type is an array class) + */ + public ReferenceType getReferenceType( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class); + if (className.startsWith("[")) { + return (ArrayType) Type.getType(className); + } + className = className.replace('/', '.'); + return ObjectType.getInstance(className); + } + + + /** + * Get the ObjectType of the method return or field. + * + * @return type of the referenced class/interface + * @throws ClassGenException when the field is (or method returns) an array, + */ + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + final ReferenceType rt = getReferenceType(cpg); + if(rt instanceof ObjectType) { + return (ObjectType)rt; + } + throw new ClassGenException(rt.getSignature() + " does not represent an ObjectType"); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java index 2f2ae53ae31..ce68521a808 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java @@ -18,67 +18,62 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * GETFIELD - Fetch field from object - *
      Stack: ..., objectref -> ..., value
      - * OR + *
      Stack: ..., objectref -> ..., value
      OR *
      Stack: ..., objectref -> ..., value.word1, value.word2
      * - * @author M. Dahm + * @version $Id: GETFIELD.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class GETFIELD extends FieldInstruction - implements ExceptionThrower, StackConsumer, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GETFIELD() {} +public class GETFIELD extends FieldInstruction implements ExceptionThrower, StackConsumer, + StackProducer { - public GETFIELD(int index) { - super(Constants.GETFIELD, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GETFIELD() { + } - public int produceStack(ConstantPoolGen cpg) { return getFieldSize(cpg); } + public GETFIELD(final int index) { + super(Const.GETFIELD, index); + } - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; + @Override + public int produceStack(final ConstantPoolGen cpg) { + return getFieldSize(cpg); + } - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitGETFIELD(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitGETFIELD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java index d66b2ddef0c..40cf8a44882 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java @@ -21,9 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * GETSTATIC - Fetch static field from class @@ -31,50 +30,54 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * OR *
      Stack: ..., -> ..., value.word1, value.word2
      * - * @author M. Dahm + * @version $Id: GETSTATIC.java 1747278 2016-06-07 17:28:43Z britter $ */ public class GETSTATIC extends FieldInstruction implements PushInstruction, ExceptionThrower { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GETSTATIC() {} - public GETSTATIC(int index) { - super(Constants.GETSTATIC, index); - } - - public int produceStack(ConstantPoolGen cpg) { return getFieldSize(cpg); } - - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GETSTATIC() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitGETSTATIC(this); - } + public GETSTATIC(final int index) { + super(Const.GETSTATIC, index); + } + + + @Override + public int produceStack( final ConstantPoolGen cpg ) { + return getFieldSize(cpg); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitGETSTATIC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java index 64707b27532..ea5f59c20aa 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java @@ -21,69 +21,83 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; /** * GOTO - Branch always (to relative offset, not absolute address) * - * @author M. Dahm + * @version $Id: GOTO.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class GOTO extends GotoInstruction implements VariableLengthInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GOTO() {} - public GOTO(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.GOTO, target); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - if(opcode == com.sun.org.apache.bcel.internal.Constants.GOTO) - super.dump(out); - else { // GOTO_W - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - } - - /** Called in pass 2 of InstructionList.setPositions() in order to update - * the branch target, that may shift due to variable length instructions. - */ - protected int updatePosition(int offset, int max_offset) { - int i = getTargetOffset(); // Depending on old position value - - position += offset; // Position may be shifted by preceding expansions - - if(Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate) - opcode = com.sun.org.apache.bcel.internal.Constants.GOTO_W; - length = 5; - return 2; // 5 - 3 + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GOTO() { } - return 0; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitVariableLengthInstruction(this); - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO(this); - } + public GOTO(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.GOTO, target); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + final short _opcode = getOpcode(); + if (_opcode == com.sun.org.apache.bcel.internal.Const.GOTO) { + super.dump(out); + } else { // GOTO_W + super.setIndex(getTargetOffset()); + out.writeByte(_opcode); + out.writeInt(super.getIndex()); + } + } + + + /** + * Called in pass 2 of InstructionList.setPositions() in order to update + * the branch target, that may shift due to variable length instructions. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param max_offset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length + */ + @Override + protected int updatePosition( final int offset, final int max_offset ) { + final int i = getTargetOffset(); // Depending on old position value + setPosition(getPosition() + offset); // Position may be shifted by preceding expansions + if (Math.abs(i) >= (Short.MAX_VALUE - max_offset)) { // to large for short (estimate) + super.setOpcode(com.sun.org.apache.bcel.internal.Const.GOTO_W); + final short old_length = (short) super.getLength(); + super.setLength(5); + return super.getLength() - old_length; + } + return 0; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitVariableLengthInstruction(this); + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java index 95e1727d205..fefcd124ad7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java @@ -21,57 +21,67 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * GOTO_W - Branch always (to relative offset, not absolute address) * - * @author M. Dahm + * @version $Id: GOTO_W.java 1747278 2016-06-07 17:28:43Z britter $ */ public class GOTO_W extends GotoInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GOTO_W() {} - public GOTO_W(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.GOTO_W, target); - length = 5; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GOTO_W() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - index = bytes.readInt(); - length = 5; - } + public GOTO_W(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.GOTO_W, target); + super.setLength(5); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO_W(this); - } + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + out.writeByte(super.getOpcode()); + out.writeInt(super.getIndex()); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setIndex(bytes.readInt()); + super.setLength(5); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO_W(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java index aa5ac98971c..4d78765fa4e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java @@ -21,22 +21,22 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for GOTO * - * @author M. Dahm + * @version $Id: GotoInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class GotoInstruction extends BranchInstruction - implements UnconditionalBranch -{ - GotoInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } +public abstract class GotoInstruction extends BranchInstruction implements UnconditionalBranch { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - GotoInstruction(){} + GotoInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); + } + + + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + GotoInstruction() { + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java index 4bc35f44a9e..d634be4c8af 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2B - Convert int to byte *
      Stack: ..., value -> ..., result
      * - * @author M. Dahm + * @version $Id: I2B.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2B extends ConversionInstruction { - /** Convert int to byte - */ - public I2B() { - super(com.sun.org.apache.bcel.internal.Constants.I2B); - } + + /** Convert int to byte + */ + public I2B() { + super(com.sun.org.apache.bcel.internal.Const.I2B); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2B(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2B(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java index 704001a96f7..71dface192a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2C - Convert int to char *
      Stack: ..., value -> ..., result
      * - * @author M. Dahm + * @version $Id: I2C.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2C extends ConversionInstruction { - /** Convert int to char - */ - public I2C() { - super(com.sun.org.apache.bcel.internal.Constants.I2C); - } + + /** Convert int to char + */ + public I2C() { + super(com.sun.org.apache.bcel.internal.Const.I2C); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2C(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2C(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java index c35511dc17d..cf8a47b0127 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2D - Convert int to double *
      Stack: ..., value -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: I2D.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2D extends ConversionInstruction { - /** Convert int to double - */ - public I2D() { - super(com.sun.org.apache.bcel.internal.Constants.I2D); - } + + /** Convert int to double + */ + public I2D() { + super(com.sun.org.apache.bcel.internal.Const.I2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2D(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2D(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java index 567e4b08cd3..b1bdda855ff 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2F - Convert int to float *
      Stack: ..., value -> ..., result
      * - * @author M. Dahm + * @version $Id: I2F.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2F extends ConversionInstruction { - /** Convert int to float - */ - public I2F() { - super(com.sun.org.apache.bcel.internal.Constants.I2F); - } + + /** Convert int to float + */ + public I2F() { + super(com.sun.org.apache.bcel.internal.Const.I2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2F(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2F(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java index f087d4507e7..e9f14a34ae9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2L - Convert int to long *
      Stack: ..., value -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: I2L.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2L extends ConversionInstruction { - /** Convert int to long - */ - public I2L() { - super(com.sun.org.apache.bcel.internal.Constants.I2L); - } + + /** Convert int to long + */ + public I2L() { + super(com.sun.org.apache.bcel.internal.Const.I2L); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2L(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2L(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java index e917e3e6a70..fa4c72b647f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * I2S - Convert int to short *
      Stack: ..., value -> ..., result
      * - * @author M. Dahm + * @version $Id: I2S.java 1747278 2016-06-07 17:28:43Z britter $ */ public class I2S extends ConversionInstruction { - public I2S() { - super(com.sun.org.apache.bcel.internal.Constants.I2S); - } + + public I2S() { + super(com.sun.org.apache.bcel.internal.Const.I2S); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitI2S(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitI2S(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java index 71127939b4d..4e709dbc370 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IADD - Add ints *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: IADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IADD extends ArithmeticInstruction { - /** Add ints - */ - public IADD() { - super(com.sun.org.apache.bcel.internal.Constants.IADD); - } + + /** Add ints + */ + public IADD() { + super(com.sun.org.apache.bcel.internal.Const.IADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java index e957e6c19b8..222424a5261 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IALOAD - Load int from array *
      Stack: ..., arrayref, index -> ..., value
      * - * @author M. Dahm + * @version $Id: IALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IALOAD extends ArrayInstruction implements StackProducer { - /** - * Load int from array - */ - public IALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.IALOAD); - } + + /** + * Load int from array + */ + public IALOAD() { + super(com.sun.org.apache.bcel.internal.Const.IALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitIALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitIALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java index f62d301c2a5..5e47267aef4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IAND - Bitwise AND int *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: IAND.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IAND extends ArithmeticInstruction { - public IAND() { - super(com.sun.org.apache.bcel.internal.Constants.IAND); - } + + public IAND() { + super(com.sun.org.apache.bcel.internal.Const.IAND); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIAND(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIAND(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java index a5f0aa2499d..1170a35bcd4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java @@ -21,35 +21,36 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IASTORE - Store into int array *
      Stack: ..., arrayref, index, value -> ...
      * - * @author M. Dahm + * @version $Id: IASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IASTORE extends ArrayInstruction implements StackConsumer { - /** - * Store into int array - */ - public IASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.IASTORE); - } + + /** + * Store into int array + */ + public IASTORE() { + super(com.sun.org.apache.bcel.internal.Const.IASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitIASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitIASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java index 41345d82864..71a592ec550 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java @@ -17,59 +17,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - /** * ICONST - Push value between -1, ..., 5, other values cause an exception * *
      Stack: ... -> ..., 
      * - * @author M. Dahm + * @version $Id: ICONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class ICONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private int value; +public class ICONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ICONST() {} + private int value; - public ICONST(int i) { - super(com.sun.org.apache.bcel.internal.Constants.ICONST_0, (short)1); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ICONST() { + } - if((i >= -1) && (i <= 5)) - opcode = (short)(com.sun.org.apache.bcel.internal.Constants.ICONST_0 + i); // Even works for i == -1 - else - throw new ClassGenException("ICONST can be used only for value between -1 and 5: " + - i); - value = i; - } + public ICONST(final int i) { + super(com.sun.org.apache.bcel.internal.Const.ICONST_0, (short) 1); + if ((i >= -1) && (i <= 5)) { + super.setOpcode((short) (com.sun.org.apache.bcel.internal.Const.ICONST_0 + i)); // Even works for i == -1 + } else { + throw new ClassGenException("ICONST can be used only for value between -1 and 5: " + i); + } + value = i; + } - public Number getValue() { return Integer.valueOf(value); } + @Override + public Number getValue() { + return Integer.valueOf(value); + } - /** @return Type.INT - */ - public Type getType(ConstantPoolGen cp) { - return Type.INT; - } + /** + * @return Type.INT + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.INT; + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitICONST(this); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitICONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java index 7043f0408a3..97793944713 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java @@ -21,41 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * IDIV - Divide ints *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: IDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IDIV extends ArithmeticInstruction implements ExceptionThrower { - /** Divide ints - */ - public IDIV() { - super(com.sun.org.apache.bcel.internal.Constants.IDIV); - } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; - } + /** Divide ints + */ + public IDIV() { + super(com.sun.org.apache.bcel.internal.Const.IDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIDIV(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java index 87c2bb61e2a..188cdd17eba 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFEQ - Branch if int comparison with zero succeeds * *
      Stack: ..., value -> ...
      * - * @author M. Dahm + * @version $Id: IFEQ.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFEQ() {} - public IFEQ(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFEQ, target); - } - - /** - * @return negation of instruction, e.g. IFEQ.negate() == IFNE - */ - public IfInstruction negate() { - return new IFNE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFEQ() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFEQ(this); - } + public IFEQ(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFEQ, target); + } + + + /** + * @return negation of instruction, e.g. IFEQ.negate() == IFNE + */ + @Override + public IfInstruction negate() { + return new IFNE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFEQ(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java index 90636622e7f..8488b7610c5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFGE - Branch if int comparison with zero succeeds * *
      Stack: ..., value -> ...
      * - * @author M. Dahm + * @version $Id: IFGE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFGE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFGE() {} - public IFGE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFGE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFLT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFGE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFGE(this); - } + public IFGE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFGE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFGE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java index 0195733021f..b9a53779057 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFGT - Branch if int comparison with zero succeeds * *
      Stack: ..., value -> ...
      * - * @author M. Dahm + * @version $Id: IFGT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFGT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFGT() {} - public IFGT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFGT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFLE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFGT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFGT(this); - } + public IFGT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFGT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFGT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java index b5fd9fec1c8..38c69d60555 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFLE - Branch if int comparison with zero succeeds * *
      Stack: ..., value -> ...
      * - * @author M. Dahm + * @version $Id: IFLE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFLE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFLE() {} - public IFLE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFLE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFGT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFLE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFLE(this); - } + public IFLE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFLE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFLE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java index 124e874bbfb..c74ae9edba4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFLT - Branch if int comparison with zero succeeds * *
      Stack: ..., value -> ...
      * - * @author M. Dahm + * @version $Id: IFLT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFLT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFLT() {} - public IFLT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFLT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFGE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFLT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFLT(this); - } + public IFLT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFLT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFLT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java index 1d99492a6d0..104c2ed24eb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFNE - Branch if int comparison with zero succeeds * *
      Stack: ..., value -> ...
      * - * @author M. Dahm + * @version $Id: IFNE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNE() {} - public IFNE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFNE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFEQ(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNE(this); - } + public IFNE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFNE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFEQ(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java index 9b519f5e129..77c8be6a451 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java @@ -21,44 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFNONNULL - Branch if reference is not null * *
      Stack: ..., reference -> ...
      * - * @author M. Dahm + * @version $Id: IFNONNULL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFNONNULL extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNONNULL() {} - public IFNONNULL(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFNONNULL, target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNONNULL() { + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFNULL(target); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNONNULL(this); - } + public IFNONNULL(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFNONNULL, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNULL(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNONNULL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java index 45b15c22b4f..bf8e4346745 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IFNULL - Branch if reference is not null * *
      Stack: ..., reference -> ...
      * - * @author M. Dahm + * @version $Id: IFNULL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IFNULL extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IFNULL() {} - public IFNULL(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IFNULL, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IFNONNULL(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IFNULL() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIFNULL(this); - } + public IFNULL(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IFNULL, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNONNULL(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIFNULL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java index c18b9c84329..cb9979709eb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java @@ -21,44 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ACMPEQ - Branch if reference comparison succeeds * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ACMPEQ.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ACMPEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ACMPEQ() {} - public IF_ACMPEQ(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ACMPEQ, target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ACMPEQ() { + } - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ACMPNE(target); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ACMPEQ(this); - } + public IF_ACMPEQ(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ACMPEQ, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPNE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ACMPEQ(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java index 5a3df6d8a43..50f1a17fd82 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ACMPNE - Branch if reference comparison doesn't succeed * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ACMPNE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ACMPNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ACMPNE() {} - public IF_ACMPNE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ACMPNE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ACMPEQ(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ACMPNE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ACMPNE(this); - } + public IF_ACMPNE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ACMPNE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPEQ(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ACMPNE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java index f14a5b88217..0d3666c99bc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPEQ - Branch if int comparison succeeds * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ICMPEQ.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPEQ extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPEQ() {} - public IF_ICMPEQ(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPEQ, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPNE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPEQ() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPEQ(this); - } + public IF_ICMPEQ(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPEQ, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPNE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPEQ(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java index 9b978416da1..abb0d21c03a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPGE - Branch if int comparison succeeds * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ICMPGE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPGE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPGE() {} - public IF_ICMPGE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPGE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPLT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPGE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPGE(this); - } + public IF_ICMPGE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPGE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPGE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java index f0de3fc407d..da1749604f3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPGT - Branch if int comparison succeeds * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ICMPGT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPGT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPGT() {} - public IF_ICMPGT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPGT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPLE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPGT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPGT(this); - } + public IF_ICMPGT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPGT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPGT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java index 3c13250cafb..b816ab0e863 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPLE - Branch if int comparison succeeds * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ICMPLE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPLE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPLE() {} - public IF_ICMPLE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPLE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPGT(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPLE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPLE(this); - } + public IF_ICMPLE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPLE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGT(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPLE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java index 849951cf548..58eee78d9bf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPLT - Branch if int comparison succeeds * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ICMPLT.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPLT extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPLT() {} - public IF_ICMPLT(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPLT, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPGE(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPLT() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPLT(this); - } + public IF_ICMPLT(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPLT, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGE(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPLT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java index f1de6f641a3..78e7d341250 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java @@ -21,45 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IF_ICMPNE - Branch if int comparison doesn't succeed * *
      Stack: ..., value1, value2 -> ...
      * - * @author M. Dahm + * @version $Id: IF_ICMPNE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IF_ICMPNE extends IfInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IF_ICMPNE() {} - public IF_ICMPNE(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.IF_ICMPNE, target); - } - - /** - * @return negation of instruction - */ - public IfInstruction negate() { - return new IF_ICMPEQ(target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IF_ICMPNE() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitIfInstruction(this); - v.visitIF_ICMPNE(this); - } + public IF_ICMPNE(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.IF_ICMPNE, target); + } + + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPEQ(super.getTarget()); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitIfInstruction(this); + v.visitIF_ICMPNE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java index 897d426a549..1067443d66b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java @@ -21,130 +21,149 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * IINC - Increment local variable by constant * - * @author M. Dahm + * @version $Id: IINC.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IINC extends LocalVariableInstruction { - private boolean wide; - private int c; - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IINC() {} + private boolean wide; + private int c; - /** - * @param n index of local variable - * @param c increment factor - */ - public IINC(int n, int c) { - super(); // Default behaviour of LocalVariableInstruction causes error - this.opcode = com.sun.org.apache.bcel.internal.Constants.IINC; - this.length = (short)3; - - setIndex(n); // May set wide as side effect - setIncrement(c); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - if(wide) // Need WIDE prefix ? - out.writeByte(com.sun.org.apache.bcel.internal.Constants.WIDE); - - out.writeByte(opcode); - - if(wide) { - out.writeShort(n); - out.writeShort(c); - } else { - out.writeByte(n); - out.writeByte(c); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IINC() { } - } - private final void setWide() { - if(wide = ((n > com.sun.org.apache.bcel.internal.Constants.MAX_SHORT) || - (Math.abs(c) > Byte.MAX_VALUE))) - length = 6; // wide byte included - else - length = 3; - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - this.wide = wide; - - if(wide) { - length = 6; - n = bytes.readUnsignedShort(); - c = bytes.readShort(); - } else { - length = 3; - n = bytes.readUnsignedByte(); - c = bytes.readByte(); + /** + * @param n index of local variable + * @param c increment factor + */ + public IINC(final int n, final int c) { + super(); // Default behaviour of LocalVariableInstruction causes error + super.setOpcode(com.sun.org.apache.bcel.internal.Const.IINC); + super.setLength((short) 3); + setIndex(n); // May set wide as side effect + setIncrement(c); } - } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + c; - } - /** - * Set index of local variable. - */ - public final void setIndex(int n) { - if(n < 0) - throw new ClassGenException("Negative index value: " + n); + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + if (wide) { + out.writeByte(com.sun.org.apache.bcel.internal.Const.WIDE); + } + out.writeByte(super.getOpcode()); + if (wide) { + out.writeShort(super.getIndex()); + out.writeShort(c); + } else { + out.writeByte(super.getIndex()); + out.writeByte(c); + } + } - this.n = n; - setWide(); - } - /** - * @return increment factor - */ - public final int getIncrement() { return c; } + private void setWide() { + wide = (super.getIndex() > com.sun.org.apache.bcel.internal.Const.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE); + if (wide) { + super.setLength(6); // wide byte included + } else { + super.setLength(3); + } + } - /** - * Set increment factor. - */ - public final void setIncrement(int c) { - this.c = c; - setWide(); - } - /** @return int type - */ - public Type getType(ConstantPoolGen cp) { - return Type.INT; - } + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + this.wide = wide; + if (wide) { + super.setLength(6); + super.setIndexOnly(bytes.readUnsignedShort()); + c = bytes.readShort(); + } else { + super.setLength(3); + super.setIndexOnly(bytes.readUnsignedByte()); + c = bytes.readByte(); + } + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLocalVariableInstruction(this); - v.visitIINC(this); - } + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + c; + } + + + /** + * Set index of local variable. + */ + @Override + public final void setIndex( final int n ) { + if (n < 0) { + throw new ClassGenException("Negative index value: " + n); + } + super.setIndexOnly(n); + setWide(); + } + + + /** + * @return increment factor + */ + public final int getIncrement() { + return c; + } + + + /** + * Set increment factor. + */ + public final void setIncrement( final int c ) { + this.c = c; + setWide(); + } + + + /** @return int type + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.INT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLocalVariableInstruction(this); + v.visitIINC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java index 748da0b860f..cf63d872b34 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ILOAD - Load int from local variable onto stack *
      Stack: ... -> ..., result
      * - * @author M. Dahm + * @version $Id: ILOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ILOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ILOAD() { - super(com.sun.org.apache.bcel.internal.Constants.ILOAD, com.sun.org.apache.bcel.internal.Constants.ILOAD_0); - } - /** Load int from local variable - * @param n index of local variable - */ - public ILOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ILOAD, com.sun.org.apache.bcel.internal.Constants.ILOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ILOAD() { + super(com.sun.org.apache.bcel.internal.Const.ILOAD, com.sun.org.apache.bcel.internal.Const.ILOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitILOAD(this); - } + + /** Load int from local variable + * @param n index of local variable + */ + public ILOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.ILOAD, com.sun.org.apache.bcel.internal.Const.ILOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitILOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java index 20555243e3d..a1603214864 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java @@ -21,27 +21,28 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IMPDEP1 - Implementation dependent * - * @author M. Dahm + * @version $Id: IMPDEP1.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IMPDEP1 extends Instruction { - public IMPDEP1() { - super(com.sun.org.apache.bcel.internal.Constants.IMPDEP1, (short)1); - } + + public IMPDEP1() { + super(com.sun.org.apache.bcel.internal.Const.IMPDEP1, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitIMPDEP1(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitIMPDEP1(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java index 9caa3523bde..e7d9dd8f03f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java @@ -21,27 +21,28 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IMPDEP2 - Implementation dependent * - * @author M. Dahm + * @version $Id: IMPDEP2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IMPDEP2 extends Instruction { - public IMPDEP2() { - super(com.sun.org.apache.bcel.internal.Constants.IMPDEP2, (short)1); - } + + public IMPDEP2() { + super(com.sun.org.apache.bcel.internal.Const.IMPDEP2, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitIMPDEP2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitIMPDEP2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java index 8c8e150c725..7bf4cf98ed5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IMUL - Multiply ints *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: IMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IMUL extends ArithmeticInstruction { - /** Multiply ints - */ - public IMUL() { - super(com.sun.org.apache.bcel.internal.Constants.IMUL); - } + + /** Multiply ints + */ + public IMUL() { + super(com.sun.org.apache.bcel.internal.Const.IMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java index c874e95c440..87e0356daf4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * INEG - Negate int *
      Stack: ..., value -> ..., result
      * - * @author M. Dahm + * @version $Id: INEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class INEG extends ArithmeticInstruction { - public INEG() { - super(com.sun.org.apache.bcel.internal.Constants.INEG); - } + + public INEG() { + super(com.sun.org.apache.bcel.internal.Const.INEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitINEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitINEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java index c67ffeb3fd9..15b48b85068 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java @@ -21,53 +21,62 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INSTANCEOF - Determine if object is of given type *
      Stack: ..., objectref -> ..., result
      * - * @author M. Dahm + * @version $Id: INSTANCEOF.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class INSTANCEOF extends CPInstruction - implements LoadClass, ExceptionThrower, StackProducer, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INSTANCEOF() {} +public class INSTANCEOF extends CPInstruction implements LoadClass, ExceptionThrower, + StackProducer, StackConsumer { - public INSTANCEOF(int index) { - super(com.sun.org.apache.bcel.internal.Constants.INSTANCEOF, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INSTANCEOF() { + } - public Class[] getExceptions() { - return com.sun.org.apache.bcel.internal.ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION; - } - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); + public INSTANCEOF(final int index) { + super(com.sun.org.apache.bcel.internal.Const.INSTANCEOF, index); + } - if(t instanceof ArrayType) - t = ((ArrayType) t).getBasicType(); - return (t instanceof ObjectType)? (ObjectType) t : null; - } + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitINSTANCEOF(this); - } + + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitINSTANCEOF(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java new file mode 100644 index 00000000000..a41ffdcb1f5 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java @@ -0,0 +1,134 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; +import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.util.ByteSequence; + +/** + * Class for INVOKEDYNAMIC. Not an instance of InvokeInstruction, since that class + * expects to be able to get the class of the method. Ignores the bootstrap + * mechanism entirely. + * + * @version $Id: InvokeInstruction.java 1152072 2011-07-29 01:54:05Z dbrosius $ + * @see + * + * The invokedynamic instruction in The Java Virtual Machine Specification + * @since 6.0 + */ +public class INVOKEDYNAMIC extends InvokeInstruction { + + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEDYNAMIC() { + } + + + public INVOKEDYNAMIC(final int index) { + super(Const.INVOKEDYNAMIC, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(0); + out.writeByte(0); + } + + + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + super.setLength(5); + bytes.readByte(); // Skip 0 byte + bytes.readByte(); // Skip 0 byte + } + + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + return super.toString(cp); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, + ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEDYNAMIC(this); + } + + /** + * Override the parent method because our classname is held elsewhere. + */ + @Override + public String getClassName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic); + return ((ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex())).getName(cp); + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java index bda3a357a46..a47afc06cd2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java @@ -21,110 +21,123 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * INVOKEINTERFACE - Invoke interface method *
      Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
      * - * @author M. Dahm + * @version $Id: INVOKEINTERFACE.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokeinterface instruction in The Java Virtual Machine Specification */ public final class INVOKEINTERFACE extends InvokeInstruction { - private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKEINTERFACE() {} + private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 - public INVOKEINTERFACE(int index, int nargs) { - super(Constants.INVOKEINTERFACE, index); - length = 5; - if(nargs < 1) - throw new ClassGenException("Number of arguments must be > 0 " + nargs); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEINTERFACE() { + } - 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); - } + public INVOKEINTERFACE(final int index, final int nargs) { + super(Const.INVOKEINTERFACE, index); + super.setLength(5); + if (nargs < 1) { + throw new ClassGenException("Number of arguments must be > 0 " + nargs); + } + this.nargs = nargs; + } - /** - * The count argument according to the Java Language Specification, - * Second Edition. - */ - public int getCount() { return nargs; } - /** - * Read needed data (i.e., index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - super.initFromFile(bytes, wide); + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(nargs); + out.writeByte(0); + } - length = 5; - nargs = bytes.readUnsignedByte(); - bytes.readByte(); // Skip 0 byte - } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - public String toString(ConstantPool cp) { - return super.toString(cp) + " " + nargs; - } + /** + * The count argument according to the Java Language Specification, + * Second Edition. + */ + public int getCount() { + return nargs; + } - public int consumeStack(ConstantPoolGen cpg) { // nargs is given in byte-code - return nargs; // nargs includes this reference - } - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length]; + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + super.setLength(5); + nargs = bytes.readUnsignedByte(); + bytes.readByte(); // Skip 0 byte + } - System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length+3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length+2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length+1] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + return super.toString(cp) + " " + nargs; + } - return cs; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKEINTERFACE(this); - } + @Override + public int consumeStack( final ConstantPoolGen cpg ) { // nargs is given in byte-code + return nargs; // nargs includes this reference + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, + ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEINTERFACE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java index 566f58e2112..387b39ca59f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java @@ -21,8 +21,11 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INVOKESPECIAL - Invoke instance method; special handling for superclass, private @@ -30,51 +33,64 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * *
      Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
      * - * @author M. Dahm + * @version $Id: INVOKESPECIAL.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokespecial instruction in The Java Virtual Machine Specification */ public class INVOKESPECIAL extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKESPECIAL() {} - public INVOKESPECIAL(int index) { - super(Constants.INVOKESPECIAL, index); - } - - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKESPECIAL() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKESPECIAL(this); - } + public INVOKESPECIAL(final int index) { + super(Const.INVOKESPECIAL, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.UNSATISFIED_LINK_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKESPECIAL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java index 2946d477a73..415527faf95 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java @@ -21,57 +21,73 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INVOKESTATIC - Invoke a class (static) method * *
      Stack: ..., [arg1, [arg2 ...]] -> ...
      * - * @author M. Dahm + * @version $Id: INVOKESTATIC.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokestatic instruction in The Java Virtual Machine Specification */ public class INVOKESTATIC extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKESTATIC() {} - public INVOKESTATIC(int index) { - super(Constants.INVOKESTATIC, index); - } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKESTATIC() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKESTATIC(this); - } + public INVOKESTATIC(final int index) { + super(Const.INVOKESTATIC, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKESTATIC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java index 9e7d7e2622a..eb814d4889a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java @@ -21,59 +21,75 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * INVOKEVIRTUAL - Invoke instance method; dispatch based on class * *
      Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
      * - * @author M. Dahm + * @version $Id: INVOKEVIRTUAL.java 1747278 2016-06-07 17:28:43Z britter $ + * @see + * + * The invokevirtual instruction in The Java Virtual Machine Specification */ public class INVOKEVIRTUAL extends InvokeInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - INVOKEVIRTUAL() {} - public INVOKEVIRTUAL(int index) { - super(Constants.INVOKEVIRTUAL, index); - } - - public Class[] getExceptions() { - Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+3] = ExceptionConstants.UNSATISFIED_LINK_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+2] = ExceptionConstants.ABSTRACT_METHOD_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + INVOKEVIRTUAL() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKEVIRTUAL(this); - } + public INVOKEVIRTUAL(final int index) { + super(Const.INVOKEVIRTUAL, index); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, + ExceptionConst.UNSATISFIED_LINK_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEVIRTUAL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java index 3b030d9f34d..7bf38937e35 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IOR - Bitwise OR int *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: IOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IOR extends ArithmeticInstruction { - public IOR() { - super(com.sun.org.apache.bcel.internal.Constants.IOR); - } + + public IOR() { + super(com.sun.org.apache.bcel.internal.Const.IOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java index 472ce73bde8..85810f5ff36 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java @@ -21,41 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * IREM - Remainder of int *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: IREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IREM extends ArithmeticInstruction implements ExceptionThrower { - /** Remainder of ints - */ - public IREM() { - super(com.sun.org.apache.bcel.internal.Constants.IREM); - } - /** @return exceptions this instruction may cause - */ - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; - } + /** Remainder of ints + */ + public IREM() { + super(com.sun.org.apache.bcel.internal.Const.IREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIREM(this); - } + /** @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java index 53d9384a1aa..f2f1fdbcccd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IRETURN - Return int from method *
      Stack: ..., value -> <empty>
      * - * @author M. Dahm + * @version $Id: IRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IRETURN extends ReturnInstruction { - /** Return int from method - */ - public IRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.IRETURN); - } + + /** Return int from method + */ + public IRETURN() { + super(com.sun.org.apache.bcel.internal.Const.IRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitIRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitIRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java index 577e3b204a7..e4848f897bd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISHL - Arithmetic shift left int *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: ISHL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISHL extends ArithmeticInstruction { - public ISHL() { - super(com.sun.org.apache.bcel.internal.Constants.ISHL); - } + + public ISHL() { + super(com.sun.org.apache.bcel.internal.Const.ISHL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISHL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISHL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java index e9b121f00c3..92a06e07d12 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISHR - Arithmetic shift right int *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: ISHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISHR extends ArithmeticInstruction { - public ISHR() { - super(com.sun.org.apache.bcel.internal.Constants.ISHR); - } + + public ISHR() { + super(com.sun.org.apache.bcel.internal.Const.ISHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java index fd270fd4d65..6e42ea0c578 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java @@ -21,39 +21,42 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISTORE - Store int from stack into local variable *
      Stack: ..., value -> ... 
      * - * @author M. Dahm + * @version $Id: ISTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ISTORE() { - super(com.sun.org.apache.bcel.internal.Constants.ISTORE, com.sun.org.apache.bcel.internal.Constants.ISTORE_0); - } - /** Store int into local variable - * @param n index of local variable - */ - public ISTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.ISTORE, com.sun.org.apache.bcel.internal.Constants.ISTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ISTORE() { + super(com.sun.org.apache.bcel.internal.Const.ISTORE, com.sun.org.apache.bcel.internal.Const.ISTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitISTORE(this); - } + + /** Store int into local variable + * @param n index of local variable + */ + public ISTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.ISTORE, com.sun.org.apache.bcel.internal.Const.ISTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitISTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java index 824b0e3bc60..e3415486ed0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * ISUB - Substract ints *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: ISUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class ISUB extends ArithmeticInstruction { - /** Substract ints - */ - public ISUB() { - super(com.sun.org.apache.bcel.internal.Constants.ISUB); - } + + /** Substract ints + */ + public ISUB() { + super(com.sun.org.apache.bcel.internal.Const.ISUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitISUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitISUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java index b9fe7308803..6c0d46d545e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IUSHR - Logical shift right int *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: IUSHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IUSHR extends ArithmeticInstruction { - public IUSHR() { - super(com.sun.org.apache.bcel.internal.Constants.IUSHR); - } + + public IUSHR() { + super(com.sun.org.apache.bcel.internal.Const.IUSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIUSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIUSHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java index 27545563dc2..3cd49158dc2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * IXOR - Bitwise XOR int *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: IXOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class IXOR extends ArithmeticInstruction { - public IXOR() { - super(com.sun.org.apache.bcel.internal.Constants.IXOR); - } + + public IXOR() { + super(com.sun.org.apache.bcel.internal.Const.IXOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitIXOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitIXOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java index d677f220b66..64b3381f83f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java @@ -21,28 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for the IFxxx family of instructions. * - * @author M. Dahm + * @version $Id: IfInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public abstract class IfInstruction extends BranchInstruction implements StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - IfInstruction() {} - /** - * @param instruction Target instruction to branch to - */ - protected IfInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + IfInstruction() { + } - /** - * @return negation of instruction, e.g. IFEQ.negate() == IFNE - */ - public abstract IfInstruction negate(); + + /** + * @param opcode opcode of instruction + * @param target Target instruction to branch to + */ + protected IfInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); + } + + + /** + * @return negation of instruction, e.g. IFEQ.negate() == IFNE + */ + public abstract IfInstruction negate(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java index 5c6fb7bc618..0202c82fe38 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java @@ -21,14 +21,16 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote entity that refers to an index, e.g. local variable instructions, * RET, CPInstruction, etc. * - * @author M. Dahm + * @version $Id: IndexedInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface IndexedInstruction { - public int getIndex(); - public void setIndex(int index); + + int getIndex(); + + + void setIndex( int index ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java index 7b2753e2d68..463875fb27d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java @@ -17,254 +17,583 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; +import java.io.DataOutputStream; +import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import java.io.*; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * Abstract super class for all Java byte codes. * - * @author M. Dahm + * @version $Id: Instruction.java 1750029 2016-06-23 22:14:38Z sebb $ */ -public abstract class Instruction implements Cloneable, Serializable { - protected short length = 1; // Length of instruction in bytes - protected short opcode = -1; // Opcode number +public abstract class Instruction implements Cloneable { - private static InstructionComparator cmp = InstructionComparator.DEFAULT; + private short length = 1; // Length of instruction in bytes + private short opcode = -1; // Opcode number - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - Instruction() {} + private static InstructionComparator cmp = InstructionComparator.DEFAULT; - public Instruction(short opcode, short length) { - this.length = length; - this.opcode = opcode; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); // Common for all instructions - } - - /** @return name of instruction, i.e., opcode name - */ - public String getName() { - return Constants.OPCODE_NAMES[opcode]; - } - - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - if(verbose) - return getName() + "[" + opcode + "](" + length + ")"; - else - return getName(); - } - - /** - * @return mnemonic for instruction in verbose format - */ - public String toString() { - return toString(true); - } - - /** - * @return mnemonic for instruction with sumbolic references resolved - */ - public String toString(ConstantPool cp) { - return toString(false); - } - - /** - * Use with caution, since `BranchInstruction's have a `target' reference which - * is not copied correctly (only basic types are). This also applies for - * `Select' instructions with their multiple branch targets. - * - * @see BranchInstruction - * @return (shallow) copy of an instruction - */ - public Instruction copy() { - Instruction i = null; - - // "Constant" instruction, no need to duplicate - if(InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null) - i = this; - else { - try { - i = (Instruction)clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - } - } - - return i; - } - - /** - * Read needed data (e.g. index) from file. - * - * @param bytes byte sequence to read from - * @param wide "wide" instruction flag - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - {} - - /** - * Read an instruction from (byte code) input stream and return the - * appropiate 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(); - Instruction obj = null; - - if(opcode == Constants.WIDE) { // Read next opcode after wide byte - wide = true; - opcode = (short)bytes.readUnsignedByte(); - } - - if(InstructionConstants.INSTRUCTIONS[opcode] != null) - return InstructionConstants.INSTRUCTIONS[opcode]; // Used predefined immutable object, if available - - /* Find appropiate class, instantiate an (empty) instruction object - * and initialize it by hand. + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. */ - Class clazz; - - try { - clazz = Class.forName(className(opcode)); - } catch (ClassNotFoundException cnfe){ - // If a class by that name does not exist, the opcode is illegal. - // Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a sense. - throw new ClassGenException("Illegal opcode detected."); + Instruction() { } - try { - obj = (Instruction)clazz.getConstructor().newInstance(); + public Instruction(final short opcode, final short length) { + this.length = length; + this.opcode = opcode; + } - if(wide && !((obj instanceof LocalVariableInstruction) || - (obj instanceof IINC) || - (obj instanceof RET))) - throw new Exception("Illegal opcode after wide: " + opcode); - - obj.setOpcode(opcode); - obj.initFromFile(bytes, wide); // Do further initializations, if any - // Byte code offset set in InstructionList - } catch(Exception e) { throw new ClassGenException(e.toString()); } - - return obj; - } - - private static final String className(short opcode) { - String name = Constants.OPCODE_NAMES[opcode].toUpperCase(); - - /* ICONST_0, etc. will be shortened to ICONST, etc., since ICONST_0 and the like - * are not implemented (directly). + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream */ - try { - int len = name.length(); - char ch1 = name.charAt(len - 2), ch2 = name.charAt(len - 1); + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(opcode); // Common for all instructions + } - if((ch1 == '_') && (ch2 >= '0') && (ch2 <= '5')) - name = name.substring(0, len - 2); + /** + * @return name of instruction, i.e., opcode name + */ + public String getName() { + return Const.getOpcodeName(opcode); + } - if(name.equals("ICONST_M1")) // Special case - name = "ICONST"; - } catch(StringIndexOutOfBoundsException e) { System.err.println(e); } + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + public String toString(final boolean verbose) { + if (verbose) { + return getName() + "[" + opcode + "](" + length + ")"; + } + return getName(); + } - return "com.sun.org.apache.bcel.internal.generic." + name; - } + /** + * @return mnemonic for instruction in verbose format + */ + @Override + public String toString() { + return toString(true); + } - /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words consumed from stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically - */ - public int consumeStack(ConstantPoolGen cpg) { - return Constants.CONSUME_STACK[opcode]; - } + /** + * @return mnemonic for instruction with sumbolic references resolved + */ + public String toString(final ConstantPool cp) { + return toString(false); + } - /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words produced onto stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically - */ - public int produceStack(ConstantPoolGen cpg) { - return Constants.PRODUCE_STACK[opcode]; - } + /** + * Use with caution, since `BranchInstruction's have a `target' reference + * which is not copied correctly (only basic types are). This also applies + * for `Select' instructions with their multiple branch targets. + * + * @see BranchInstruction + * @return (shallow) copy of an instruction + */ + public Instruction copy() { + Instruction i = null; + // "Constant" instruction, no need to duplicate + if (InstructionConst.getInstruction(this.getOpcode()) != null) { + i = this; + } else { + try { + i = (Instruction) clone(); + } catch (final CloneNotSupportedException e) { + System.err.println(e); + } + } + return i; + } - /** - * @return this instructions opcode - */ - public short getOpcode() { return opcode; } + /** + * Read needed data (e.g. index) from file. + * + * @param bytes byte sequence to read from + * @param wide "wide" instruction flag + * @throws IOException may be thrown if the implementation needs to read + * data from the file + */ + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + } - /** - * @return length (in bytes) of instruction - */ - public int getLength() { return length; } + /** + * Read an instruction from (byte code) input stream and return the + * appropiate object. + *

      + * If the Instruction is defined in {@link InstructionConst}, then the + * singleton instance is returned. + * + * @param bytes input stream bytes + * @return instruction object being read + * @see InstructionConst#getInstruction(int) + */ + // @since 6.0 no longer final + public static Instruction readInstruction(final ByteSequence bytes) throws IOException { + boolean wide = false; + short opcode = (short) bytes.readUnsignedByte(); + Instruction obj = null; + if (opcode == Const.WIDE) { // Read next opcode after wide byte + wide = true; + opcode = (short) bytes.readUnsignedByte(); + } + final Instruction instruction = InstructionConst.getInstruction(opcode); + if (instruction != null) { + return instruction; // Used predefined immutable object, if available + } - /** - * Needed in readInstruction. - */ - private void setOpcode(short opcode) { this.opcode = opcode; } + switch (opcode) { + case Const.BIPUSH: + obj = new BIPUSH(); + break; + case Const.SIPUSH: + obj = new SIPUSH(); + break; + case Const.LDC: + obj = new LDC(); + break; + case Const.LDC_W: + obj = new LDC_W(); + break; + case Const.LDC2_W: + obj = new LDC2_W(); + break; + case Const.ILOAD: + obj = new ILOAD(); + break; + case Const.LLOAD: + obj = new LLOAD(); + break; + case Const.FLOAD: + obj = new FLOAD(); + break; + case Const.DLOAD: + obj = new DLOAD(); + break; + case Const.ALOAD: + obj = new ALOAD(); + break; + case Const.ILOAD_0: + obj = new ILOAD(0); + break; + case Const.ILOAD_1: + obj = new ILOAD(1); + break; + case Const.ILOAD_2: + obj = new ILOAD(2); + break; + case Const.ILOAD_3: + obj = new ILOAD(3); + break; + case Const.LLOAD_0: + obj = new LLOAD(0); + break; + case Const.LLOAD_1: + obj = new LLOAD(1); + break; + case Const.LLOAD_2: + obj = new LLOAD(2); + break; + case Const.LLOAD_3: + obj = new LLOAD(3); + break; + case Const.FLOAD_0: + obj = new FLOAD(0); + break; + case Const.FLOAD_1: + obj = new FLOAD(1); + break; + case Const.FLOAD_2: + obj = new FLOAD(2); + break; + case Const.FLOAD_3: + obj = new FLOAD(3); + break; + case Const.DLOAD_0: + obj = new DLOAD(0); + break; + case Const.DLOAD_1: + obj = new DLOAD(1); + break; + case Const.DLOAD_2: + obj = new DLOAD(2); + break; + case Const.DLOAD_3: + obj = new DLOAD(3); + break; + case Const.ALOAD_0: + obj = new ALOAD(0); + break; + case Const.ALOAD_1: + obj = new ALOAD(1); + break; + case Const.ALOAD_2: + obj = new ALOAD(2); + break; + case Const.ALOAD_3: + obj = new ALOAD(3); + break; + case Const.ISTORE: + obj = new ISTORE(); + break; + case Const.LSTORE: + obj = new LSTORE(); + break; + case Const.FSTORE: + obj = new FSTORE(); + break; + case Const.DSTORE: + obj = new DSTORE(); + break; + case Const.ASTORE: + obj = new ASTORE(); + break; + case Const.ISTORE_0: + obj = new ISTORE(0); + break; + case Const.ISTORE_1: + obj = new ISTORE(1); + break; + case Const.ISTORE_2: + obj = new ISTORE(2); + break; + case Const.ISTORE_3: + obj = new ISTORE(3); + break; + case Const.LSTORE_0: + obj = new LSTORE(0); + break; + case Const.LSTORE_1: + obj = new LSTORE(1); + break; + case Const.LSTORE_2: + obj = new LSTORE(2); + break; + case Const.LSTORE_3: + obj = new LSTORE(3); + break; + case Const.FSTORE_0: + obj = new FSTORE(0); + break; + case Const.FSTORE_1: + obj = new FSTORE(1); + break; + case Const.FSTORE_2: + obj = new FSTORE(2); + break; + case Const.FSTORE_3: + obj = new FSTORE(3); + break; + case Const.DSTORE_0: + obj = new DSTORE(0); + break; + case Const.DSTORE_1: + obj = new DSTORE(1); + break; + case Const.DSTORE_2: + obj = new DSTORE(2); + break; + case Const.DSTORE_3: + obj = new DSTORE(3); + break; + case Const.ASTORE_0: + obj = new ASTORE(0); + break; + case Const.ASTORE_1: + obj = new ASTORE(1); + break; + case Const.ASTORE_2: + obj = new ASTORE(2); + break; + case Const.ASTORE_3: + obj = new ASTORE(3); + break; + case Const.IINC: + obj = new IINC(); + break; + case Const.IFEQ: + obj = new IFEQ(); + break; + case Const.IFNE: + obj = new IFNE(); + break; + case Const.IFLT: + obj = new IFLT(); + break; + case Const.IFGE: + obj = new IFGE(); + break; + case Const.IFGT: + obj = new IFGT(); + break; + case Const.IFLE: + obj = new IFLE(); + break; + case Const.IF_ICMPEQ: + obj = new IF_ICMPEQ(); + break; + case Const.IF_ICMPNE: + obj = new IF_ICMPNE(); + break; + case Const.IF_ICMPLT: + obj = new IF_ICMPLT(); + break; + case Const.IF_ICMPGE: + obj = new IF_ICMPGE(); + break; + case Const.IF_ICMPGT: + obj = new IF_ICMPGT(); + break; + case Const.IF_ICMPLE: + obj = new IF_ICMPLE(); + break; + case Const.IF_ACMPEQ: + obj = new IF_ACMPEQ(); + break; + case Const.IF_ACMPNE: + obj = new IF_ACMPNE(); + break; + case Const.GOTO: + obj = new GOTO(); + break; + case Const.JSR: + obj = new JSR(); + break; + case Const.RET: + obj = new RET(); + break; + case Const.TABLESWITCH: + obj = new TABLESWITCH(); + break; + case Const.LOOKUPSWITCH: + obj = new LOOKUPSWITCH(); + break; + case Const.GETSTATIC: + obj = new GETSTATIC(); + break; + case Const.PUTSTATIC: + obj = new PUTSTATIC(); + break; + case Const.GETFIELD: + obj = new GETFIELD(); + break; + case Const.PUTFIELD: + obj = new PUTFIELD(); + break; + case Const.INVOKEVIRTUAL: + obj = new INVOKEVIRTUAL(); + break; + case Const.INVOKESPECIAL: + obj = new INVOKESPECIAL(); + break; + case Const.INVOKESTATIC: + obj = new INVOKESTATIC(); + break; + case Const.INVOKEINTERFACE: + obj = new INVOKEINTERFACE(); + break; + case Const.INVOKEDYNAMIC: + obj = new INVOKEDYNAMIC(); + break; + case Const.NEW: + obj = new NEW(); + break; + case Const.NEWARRAY: + obj = new NEWARRAY(); + break; + case Const.ANEWARRAY: + obj = new ANEWARRAY(); + break; + case Const.CHECKCAST: + obj = new CHECKCAST(); + break; + case Const.INSTANCEOF: + obj = new INSTANCEOF(); + break; + case Const.MULTIANEWARRAY: + obj = new MULTIANEWARRAY(); + break; + case Const.IFNULL: + obj = new IFNULL(); + break; + case Const.IFNONNULL: + obj = new IFNONNULL(); + break; + case Const.GOTO_W: + obj = new GOTO_W(); + break; + case Const.JSR_W: + obj = new JSR_W(); + break; + case Const.BREAKPOINT: + obj = new BREAKPOINT(); + break; + case Const.IMPDEP1: + obj = new IMPDEP1(); + break; + case Const.IMPDEP2: + obj = new IMPDEP2(); + break; + default: + throw new ClassGenException("Illegal opcode detected: " + opcode); - /** Some instructions may be reused, so don't do anything by default. - */ - void dispose() {} + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public abstract void accept(Visitor v); + if (wide + && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) { + throw new ClassGenException("Illegal opcode after wide: " + opcode); + } + obj.setOpcode(opcode); + obj.initFromFile(bytes, wide); // Do further initializations, if any + return obj; + } - /** Get Comparator object used in the equals() method to determine - * equality of instructions. - * - * @return currently used comparator for equals() - */ - public static InstructionComparator getComparator() { return cmp; } + /** + * This method also gives right results for instructions whose effect on the + * stack depends on the constant pool entry they reference. + * + * @return Number of words consumed from stack by this instruction, or + * Constants.UNPREDICTABLE, if this can not be computed statically + */ + public int consumeStack(final ConstantPoolGen cpg) { + return Const.getConsumeStack(opcode); + } - /** Set comparator to be used for equals(). - */ - public static void setComparator(InstructionComparator c) { cmp = c; } + /** + * This method also gives right results for instructions whose effect on the + * stack depends on the constant pool entry they reference. + * + * @return Number of words produced onto stack by this instruction, or + * Constants.UNPREDICTABLE, if this can not be computed statically + */ + public int produceStack(final ConstantPoolGen cpg) { + return Const.getProduceStack(opcode); + } - /** Check for equality, delegated to comparator - * @return true if that is an Instruction and has the same opcode - */ - public boolean equals(Object that) { - return (that instanceof Instruction)? - cmp.equals(this, (Instruction)that) : false; - } + /** + * @return this instructions opcode + */ + public short getOpcode() { + return opcode; + } + + /** + * @return length (in bytes) of instruction + */ + public int getLength() { + return length; + } + + /** + * Needed in readInstruction and subclasses in this package + */ + final void setOpcode(final short opcode) { + this.opcode = opcode; + } + + /** + * Needed in readInstruction and subclasses in this package + * + * @since 6.0 + */ + final void setLength(final int length) { + this.length = (short) length; // TODO check range? + } + + /** + * Some instructions may be reused, so don't do anything by default. + */ + void dispose() { + } + + /** + * Call corresponding visitor method(s). The order is: Call visitor methods + * of implemented interfaces first, then call methods according to the class + * hierarchy in descending order, i.e., the most specific visitXXX() call + * comes last. + * + * @param v Visitor object + */ + public abstract void accept(Visitor v); + + /** + * Get Comparator object used in the equals() method to determine equality + * of instructions. + * + * @return currently used comparator for equals() + * @deprecated (6.0) use the built in comparator, or wrap this class in + * another object that implements these methods + */ + @Deprecated + public static InstructionComparator getComparator() { + return cmp; + } + + /** + * Set comparator to be used for equals(). + * + * @deprecated (6.0) use the built in comparator, or wrap this class in + * another object that implements these methods + */ + @Deprecated + public static void setComparator(final InstructionComparator c) { + cmp = c; + } + + /** + * Check for equality, delegated to comparator + * + * @return true if that is an Instruction and has the same opcode + */ + @Override + public boolean equals(final Object that) { + return (that instanceof Instruction) ? cmp.equals(this, (Instruction) that) : false; + } + + /** + * calculate the hashCode of this object + * + * @return the hashCode + * @since 6.0 + */ + @Override + public int hashCode() { + return opcode; + } + + /** + * Check if the value can fit in a byte (signed) + * + * @param value the value to check + * @return true if the value is in range + * @since 6.0 + */ + public static boolean isValidByte(final int value) { + return value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE; + } + + /** + * Check if the value can fit in a short (signed) + * + * @param value the value to check + * @return true if the value is in range + * @since 6.0 + */ + public static boolean isValidShort(final int value) { + return value >= Short.MIN_VALUE && value <= Short.MAX_VALUE; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java index 03589cb2dbc..a1a17370674 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Equality of instructions isn't clearly to be defined. You might * wish, for example, to compare whether instructions have the same @@ -32,45 +31,36 @@ package com.sun.org.apache.bcel.internal.generic; * instructions must have the same target. * * @see Instruction - * @author M. Dahm + * @version $Id: InstructionComparator.java 1749597 2016-06-21 20:28:51Z ggregory $ */ public interface InstructionComparator { - public static final InstructionComparator DEFAULT = - new InstructionComparator() { - public boolean equals(Instruction i1, Instruction i2) { - if(i1.opcode == i2.opcode) { - if(i1 instanceof Select) { - InstructionHandle[] t1 = ((Select)i1).getTargets(); - InstructionHandle[] t2 = ((Select)i2).getTargets(); - if(t1.length == t2.length) { - for(int i = 0; i < t1.length; i++) { - if(t1[i] != t2[i]) { + InstructionComparator DEFAULT = new InstructionComparator() { + + @Override + public boolean equals( final Instruction i1, final Instruction i2 ) { + if (i1.getOpcode() == i2.getOpcode()) { + if (i1 instanceof BranchInstruction) { + // BIs are never equal to make targeters work correctly (BCEL-195) return false; - } +// } else if (i1 == i2) { TODO consider adding this shortcut +// return true; // this must be AFTER the BI test + } else if (i1 instanceof ConstantPushInstruction) { + return ((ConstantPushInstruction) i1).getValue().equals( + ((ConstantPushInstruction) i2).getValue()); + } else if (i1 instanceof IndexedInstruction) { + return ((IndexedInstruction) i1).getIndex() == ((IndexedInstruction) i2) + .getIndex(); + } else if (i1 instanceof NEWARRAY) { + return ((NEWARRAY) i1).getTypecode() == ((NEWARRAY) i2).getTypecode(); + } else { + return true; } - - return true; - } - } else if(i1 instanceof BranchInstruction) { - return ((BranchInstruction)i1).target == - ((BranchInstruction)i2).target; - } else if(i1 instanceof ConstantPushInstruction) { - return ((ConstantPushInstruction)i1).getValue(). - equals(((ConstantPushInstruction)i2).getValue()); - } else if(i1 instanceof IndexedInstruction) { - return ((IndexedInstruction)i1).getIndex() == - ((IndexedInstruction)i2).getIndex(); - } else if(i1 instanceof NEWARRAY) { - return ((NEWARRAY)i1).getTypecode() == ((NEWARRAY)i2).getTypecode(); - } else { - return true; } - } - - return false; + return false; } - }; + }; - public boolean equals(Instruction i1, Instruction i2); + + boolean equals( Instruction i1, Instruction i2 ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java new file mode 100644 index 00000000000..5e33ab3dd9e --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java @@ -0,0 +1,301 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import com.sun.org.apache.bcel.internal.Const; + +/** + * 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: InstructionConst.java 1695415 2015-08-12 01:02:39Z chas $ + */ +public final class InstructionConst { + + /** + * Predefined instruction objects + */ + /* + * NOTE these are not currently immutable, because Instruction + * has mutable protected fields opcode and length. + */ + public static final Instruction NOP = new NOP(); + public static final Instruction ACONST_NULL = new ACONST_NULL(); + public static final Instruction ICONST_M1 = new ICONST(-1); + public static final Instruction ICONST_0 = new ICONST(0); + public static final Instruction ICONST_1 = new ICONST(1); + public static final Instruction ICONST_2 = new ICONST(2); + public static final Instruction ICONST_3 = new ICONST(3); + public static final Instruction ICONST_4 = new ICONST(4); + public static final Instruction ICONST_5 = new ICONST(5); + public static final Instruction LCONST_0 = new LCONST(0); + public static final Instruction LCONST_1 = new LCONST(1); + public static final Instruction FCONST_0 = new FCONST(0); + public static final Instruction FCONST_1 = new FCONST(1); + public static final Instruction FCONST_2 = new FCONST(2); + public static final Instruction DCONST_0 = new DCONST(0); + public static final Instruction DCONST_1 = new DCONST(1); + public static final ArrayInstruction IALOAD = new IALOAD(); + public static final ArrayInstruction LALOAD = new LALOAD(); + public static final ArrayInstruction FALOAD = new FALOAD(); + public static final ArrayInstruction DALOAD = new DALOAD(); + public static final ArrayInstruction AALOAD = new AALOAD(); + public static final ArrayInstruction BALOAD = new BALOAD(); + public static final ArrayInstruction CALOAD = new CALOAD(); + public static final ArrayInstruction SALOAD = new SALOAD(); + public static final ArrayInstruction IASTORE = new IASTORE(); + public static final ArrayInstruction LASTORE = new LASTORE(); + public static final ArrayInstruction FASTORE = new FASTORE(); + public static final ArrayInstruction DASTORE = new DASTORE(); + public static final ArrayInstruction AASTORE = new AASTORE(); + public static final ArrayInstruction BASTORE = new BASTORE(); + public static final ArrayInstruction CASTORE = new CASTORE(); + public static final ArrayInstruction SASTORE = new SASTORE(); + public static final StackInstruction POP = new POP(); + public static final StackInstruction POP2 = new POP2(); + public static final StackInstruction DUP = new DUP(); + public static final StackInstruction DUP_X1 = new DUP_X1(); + public static final StackInstruction DUP_X2 = new DUP_X2(); + public static final StackInstruction DUP2 = new DUP2(); + public static final StackInstruction DUP2_X1 = new DUP2_X1(); + public static final StackInstruction DUP2_X2 = new DUP2_X2(); + public static final StackInstruction SWAP = new SWAP(); + public static final ArithmeticInstruction IADD = new IADD(); + public static final ArithmeticInstruction LADD = new LADD(); + public static final ArithmeticInstruction FADD = new FADD(); + public static final ArithmeticInstruction DADD = new DADD(); + public static final ArithmeticInstruction ISUB = new ISUB(); + public static final ArithmeticInstruction LSUB = new LSUB(); + public static final ArithmeticInstruction FSUB = new FSUB(); + public static final ArithmeticInstruction DSUB = new DSUB(); + public static final ArithmeticInstruction IMUL = new IMUL(); + public static final ArithmeticInstruction LMUL = new LMUL(); + public static final ArithmeticInstruction FMUL = new FMUL(); + public static final ArithmeticInstruction DMUL = new DMUL(); + public static final ArithmeticInstruction IDIV = new IDIV(); + public static final ArithmeticInstruction LDIV = new LDIV(); + public static final ArithmeticInstruction FDIV = new FDIV(); + public static final ArithmeticInstruction DDIV = new DDIV(); + public static final ArithmeticInstruction IREM = new IREM(); + public static final ArithmeticInstruction LREM = new LREM(); + public static final ArithmeticInstruction FREM = new FREM(); + public static final ArithmeticInstruction DREM = new DREM(); + public static final ArithmeticInstruction INEG = new INEG(); + public static final ArithmeticInstruction LNEG = new LNEG(); + public static final ArithmeticInstruction FNEG = new FNEG(); + public static final ArithmeticInstruction DNEG = new DNEG(); + public static final ArithmeticInstruction ISHL = new ISHL(); + public static final ArithmeticInstruction LSHL = new LSHL(); + public static final ArithmeticInstruction ISHR = new ISHR(); + public static final ArithmeticInstruction LSHR = new LSHR(); + public static final ArithmeticInstruction IUSHR = new IUSHR(); + public static final ArithmeticInstruction LUSHR = new LUSHR(); + public static final ArithmeticInstruction IAND = new IAND(); + public static final ArithmeticInstruction LAND = new LAND(); + public static final ArithmeticInstruction IOR = new IOR(); + public static final ArithmeticInstruction LOR = new LOR(); + public static final ArithmeticInstruction IXOR = new IXOR(); + public static final ArithmeticInstruction LXOR = new LXOR(); + public static final ConversionInstruction I2L = new I2L(); + public static final ConversionInstruction I2F = new I2F(); + public static final ConversionInstruction I2D = new I2D(); + public static final ConversionInstruction L2I = new L2I(); + public static final ConversionInstruction L2F = new L2F(); + public static final ConversionInstruction L2D = new L2D(); + public static final ConversionInstruction F2I = new F2I(); + public static final ConversionInstruction F2L = new F2L(); + public static final ConversionInstruction F2D = new F2D(); + public static final ConversionInstruction D2I = new D2I(); + public static final ConversionInstruction D2L = new D2L(); + public static final ConversionInstruction D2F = new D2F(); + public static final ConversionInstruction I2B = new I2B(); + public static final ConversionInstruction I2C = new I2C(); + public static final ConversionInstruction I2S = new I2S(); + public static final Instruction LCMP = new LCMP(); + public static final Instruction FCMPL = new FCMPL(); + public static final Instruction FCMPG = new FCMPG(); + public static final Instruction DCMPL = new DCMPL(); + public static final Instruction DCMPG = new DCMPG(); + public static final ReturnInstruction IRETURN = new IRETURN(); + public static final ReturnInstruction LRETURN = new LRETURN(); + public static final ReturnInstruction FRETURN = new FRETURN(); + public static final ReturnInstruction DRETURN = new DRETURN(); + public static final ReturnInstruction ARETURN = new ARETURN(); + public static final ReturnInstruction RETURN = new RETURN(); + public static final Instruction ARRAYLENGTH = new ARRAYLENGTH(); + public static final Instruction ATHROW = new ATHROW(); + public static final Instruction MONITORENTER = new MONITORENTER(); + public static final Instruction MONITOREXIT = new MONITOREXIT(); + + /** You can use these constants in multiple places safely, if you can guarantee + * that you will never alter their internal values, e.g. call setIndex(). + */ + public static final LocalVariableInstruction THIS = new ALOAD(0); + public static final LocalVariableInstruction ALOAD_0 = THIS; + public static final LocalVariableInstruction ALOAD_1 = new ALOAD(1); + public static final LocalVariableInstruction ALOAD_2 = new ALOAD(2); + public static final LocalVariableInstruction ILOAD_0 = new ILOAD(0); + public static final LocalVariableInstruction ILOAD_1 = new ILOAD(1); + public static final LocalVariableInstruction ILOAD_2 = new ILOAD(2); + public static final LocalVariableInstruction ASTORE_0 = new ASTORE(0); + public static final LocalVariableInstruction ASTORE_1 = new ASTORE(1); + public static final LocalVariableInstruction ASTORE_2 = new ASTORE(2); + public static final LocalVariableInstruction ISTORE_0 = new ISTORE(0); + public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1); + public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2); + + /** Get object via its opcode, for immutable instructions like + * branch instructions entries are set to null. + */ + private static final Instruction[] INSTRUCTIONS = new Instruction[256]; + + static { + INSTRUCTIONS[Const.NOP] = NOP; + INSTRUCTIONS[Const.ACONST_NULL] = ACONST_NULL; + INSTRUCTIONS[Const.ICONST_M1] = ICONST_M1; + INSTRUCTIONS[Const.ICONST_0] = ICONST_0; + INSTRUCTIONS[Const.ICONST_1] = ICONST_1; + INSTRUCTIONS[Const.ICONST_2] = ICONST_2; + INSTRUCTIONS[Const.ICONST_3] = ICONST_3; + INSTRUCTIONS[Const.ICONST_4] = ICONST_4; + INSTRUCTIONS[Const.ICONST_5] = ICONST_5; + INSTRUCTIONS[Const.LCONST_0] = LCONST_0; + INSTRUCTIONS[Const.LCONST_1] = LCONST_1; + INSTRUCTIONS[Const.FCONST_0] = FCONST_0; + INSTRUCTIONS[Const.FCONST_1] = FCONST_1; + INSTRUCTIONS[Const.FCONST_2] = FCONST_2; + INSTRUCTIONS[Const.DCONST_0] = DCONST_0; + INSTRUCTIONS[Const.DCONST_1] = DCONST_1; + INSTRUCTIONS[Const.IALOAD] = IALOAD; + INSTRUCTIONS[Const.LALOAD] = LALOAD; + INSTRUCTIONS[Const.FALOAD] = FALOAD; + INSTRUCTIONS[Const.DALOAD] = DALOAD; + INSTRUCTIONS[Const.AALOAD] = AALOAD; + INSTRUCTIONS[Const.BALOAD] = BALOAD; + INSTRUCTIONS[Const.CALOAD] = CALOAD; + INSTRUCTIONS[Const.SALOAD] = SALOAD; + INSTRUCTIONS[Const.IASTORE] = IASTORE; + INSTRUCTIONS[Const.LASTORE] = LASTORE; + INSTRUCTIONS[Const.FASTORE] = FASTORE; + INSTRUCTIONS[Const.DASTORE] = DASTORE; + INSTRUCTIONS[Const.AASTORE] = AASTORE; + INSTRUCTIONS[Const.BASTORE] = BASTORE; + INSTRUCTIONS[Const.CASTORE] = CASTORE; + INSTRUCTIONS[Const.SASTORE] = SASTORE; + INSTRUCTIONS[Const.POP] = POP; + INSTRUCTIONS[Const.POP2] = POP2; + INSTRUCTIONS[Const.DUP] = DUP; + INSTRUCTIONS[Const.DUP_X1] = DUP_X1; + INSTRUCTIONS[Const.DUP_X2] = DUP_X2; + INSTRUCTIONS[Const.DUP2] = DUP2; + INSTRUCTIONS[Const.DUP2_X1] = DUP2_X1; + INSTRUCTIONS[Const.DUP2_X2] = DUP2_X2; + INSTRUCTIONS[Const.SWAP] = SWAP; + INSTRUCTIONS[Const.IADD] = IADD; + INSTRUCTIONS[Const.LADD] = LADD; + INSTRUCTIONS[Const.FADD] = FADD; + INSTRUCTIONS[Const.DADD] = DADD; + INSTRUCTIONS[Const.ISUB] = ISUB; + INSTRUCTIONS[Const.LSUB] = LSUB; + INSTRUCTIONS[Const.FSUB] = FSUB; + INSTRUCTIONS[Const.DSUB] = DSUB; + INSTRUCTIONS[Const.IMUL] = IMUL; + INSTRUCTIONS[Const.LMUL] = LMUL; + INSTRUCTIONS[Const.FMUL] = FMUL; + INSTRUCTIONS[Const.DMUL] = DMUL; + INSTRUCTIONS[Const.IDIV] = IDIV; + INSTRUCTIONS[Const.LDIV] = LDIV; + INSTRUCTIONS[Const.FDIV] = FDIV; + INSTRUCTIONS[Const.DDIV] = DDIV; + INSTRUCTIONS[Const.IREM] = IREM; + INSTRUCTIONS[Const.LREM] = LREM; + INSTRUCTIONS[Const.FREM] = FREM; + INSTRUCTIONS[Const.DREM] = DREM; + INSTRUCTIONS[Const.INEG] = INEG; + INSTRUCTIONS[Const.LNEG] = LNEG; + INSTRUCTIONS[Const.FNEG] = FNEG; + INSTRUCTIONS[Const.DNEG] = DNEG; + INSTRUCTIONS[Const.ISHL] = ISHL; + INSTRUCTIONS[Const.LSHL] = LSHL; + INSTRUCTIONS[Const.ISHR] = ISHR; + INSTRUCTIONS[Const.LSHR] = LSHR; + INSTRUCTIONS[Const.IUSHR] = IUSHR; + INSTRUCTIONS[Const.LUSHR] = LUSHR; + INSTRUCTIONS[Const.IAND] = IAND; + INSTRUCTIONS[Const.LAND] = LAND; + INSTRUCTIONS[Const.IOR] = IOR; + INSTRUCTIONS[Const.LOR] = LOR; + INSTRUCTIONS[Const.IXOR] = IXOR; + INSTRUCTIONS[Const.LXOR] = LXOR; + INSTRUCTIONS[Const.I2L] = I2L; + INSTRUCTIONS[Const.I2F] = I2F; + INSTRUCTIONS[Const.I2D] = I2D; + INSTRUCTIONS[Const.L2I] = L2I; + INSTRUCTIONS[Const.L2F] = L2F; + INSTRUCTIONS[Const.L2D] = L2D; + INSTRUCTIONS[Const.F2I] = F2I; + INSTRUCTIONS[Const.F2L] = F2L; + INSTRUCTIONS[Const.F2D] = F2D; + INSTRUCTIONS[Const.D2I] = D2I; + INSTRUCTIONS[Const.D2L] = D2L; + INSTRUCTIONS[Const.D2F] = D2F; + INSTRUCTIONS[Const.I2B] = I2B; + INSTRUCTIONS[Const.I2C] = I2C; + INSTRUCTIONS[Const.I2S] = I2S; + INSTRUCTIONS[Const.LCMP] = LCMP; + INSTRUCTIONS[Const.FCMPL] = FCMPL; + INSTRUCTIONS[Const.FCMPG] = FCMPG; + INSTRUCTIONS[Const.DCMPL] = DCMPL; + INSTRUCTIONS[Const.DCMPG] = DCMPG; + INSTRUCTIONS[Const.IRETURN] = IRETURN; + INSTRUCTIONS[Const.LRETURN] = LRETURN; + INSTRUCTIONS[Const.FRETURN] = FRETURN; + INSTRUCTIONS[Const.DRETURN] = DRETURN; + INSTRUCTIONS[Const.ARETURN] = ARETURN; + INSTRUCTIONS[Const.RETURN] = RETURN; + INSTRUCTIONS[Const.ARRAYLENGTH] = ARRAYLENGTH; + INSTRUCTIONS[Const.ATHROW] = ATHROW; + INSTRUCTIONS[Const.MONITORENTER] = MONITORENTER; + INSTRUCTIONS[Const.MONITOREXIT] = MONITOREXIT; + } + + private InstructionConst() { } // non-instantiable + + /** + * Gets the Instruction. + * @param index the index, e.g. {@link Const#RETURN} + * @return the entry from the private INSTRUCTIONS table + */ + public static Instruction getInstruction(final int index) { + return INSTRUCTIONS[index]; + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConstants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConstants.java deleted file mode 100644 index 4b624d7cf0a..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConstants.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.generic; - - -import com.sun.org.apache.bcel.internal.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); - * - * @author M. Dahm - */ -public interface InstructionConstants { - /** Predefined instruction objects - */ - public static final Instruction NOP = new NOP(); - public static final Instruction ACONST_NULL = new ACONST_NULL(); - public static final Instruction ICONST_M1 = new ICONST(-1); - public static final Instruction ICONST_0 = new ICONST(0); - public static final Instruction ICONST_1 = new ICONST(1); - public static final Instruction ICONST_2 = new ICONST(2); - public static final Instruction ICONST_3 = new ICONST(3); - public static final Instruction ICONST_4 = new ICONST(4); - public static final Instruction ICONST_5 = new ICONST(5); - public static final Instruction LCONST_0 = new LCONST(0); - public static final Instruction LCONST_1 = new LCONST(1); - public static final Instruction FCONST_0 = new FCONST(0); - public static final Instruction FCONST_1 = new FCONST(1); - public static final Instruction FCONST_2 = new FCONST(2); - public static final Instruction DCONST_0 = new DCONST(0); - public static final Instruction DCONST_1 = new DCONST(1); - public static final ArrayInstruction IALOAD = new IALOAD(); - public static final ArrayInstruction LALOAD = new LALOAD(); - public static final ArrayInstruction FALOAD = new FALOAD(); - public static final ArrayInstruction DALOAD = new DALOAD(); - public static final ArrayInstruction AALOAD = new AALOAD(); - public static final ArrayInstruction BALOAD = new BALOAD(); - public static final ArrayInstruction CALOAD = new CALOAD(); - public static final ArrayInstruction SALOAD = new SALOAD(); - public static final ArrayInstruction IASTORE = new IASTORE(); - public static final ArrayInstruction LASTORE = new LASTORE(); - public static final ArrayInstruction FASTORE = new FASTORE(); - public static final ArrayInstruction DASTORE = new DASTORE(); - public static final ArrayInstruction AASTORE = new AASTORE(); - public static final ArrayInstruction BASTORE = new BASTORE(); - public static final ArrayInstruction CASTORE = new CASTORE(); - public static final ArrayInstruction SASTORE = new SASTORE(); - public static final StackInstruction POP = new POP(); - public static final StackInstruction POP2 = new POP2(); - public static final StackInstruction DUP = new DUP(); - public static final StackInstruction DUP_X1 = new DUP_X1(); - public static final StackInstruction DUP_X2 = new DUP_X2(); - public static final StackInstruction DUP2 = new DUP2(); - public static final StackInstruction DUP2_X1 = new DUP2_X1(); - public static final StackInstruction DUP2_X2 = new DUP2_X2(); - public static final StackInstruction SWAP = new SWAP(); - public static final ArithmeticInstruction IADD = new IADD(); - public static final ArithmeticInstruction LADD = new LADD(); - public static final ArithmeticInstruction FADD = new FADD(); - public static final ArithmeticInstruction DADD = new DADD(); - public static final ArithmeticInstruction ISUB = new ISUB(); - public static final ArithmeticInstruction LSUB = new LSUB(); - public static final ArithmeticInstruction FSUB = new FSUB(); - public static final ArithmeticInstruction DSUB = new DSUB(); - public static final ArithmeticInstruction IMUL = new IMUL(); - public static final ArithmeticInstruction LMUL = new LMUL(); - public static final ArithmeticInstruction FMUL = new FMUL(); - public static final ArithmeticInstruction DMUL = new DMUL(); - public static final ArithmeticInstruction IDIV = new IDIV(); - public static final ArithmeticInstruction LDIV = new LDIV(); - public static final ArithmeticInstruction FDIV = new FDIV(); - public static final ArithmeticInstruction DDIV = new DDIV(); - public static final ArithmeticInstruction IREM = new IREM(); - public static final ArithmeticInstruction LREM = new LREM(); - public static final ArithmeticInstruction FREM = new FREM(); - public static final ArithmeticInstruction DREM = new DREM(); - public static final ArithmeticInstruction INEG = new INEG(); - public static final ArithmeticInstruction LNEG = new LNEG(); - public static final ArithmeticInstruction FNEG = new FNEG(); - public static final ArithmeticInstruction DNEG = new DNEG(); - public static final ArithmeticInstruction ISHL = new ISHL(); - public static final ArithmeticInstruction LSHL = new LSHL(); - public static final ArithmeticInstruction ISHR = new ISHR(); - public static final ArithmeticInstruction LSHR = new LSHR(); - public static final ArithmeticInstruction IUSHR = new IUSHR(); - public static final ArithmeticInstruction LUSHR = new LUSHR(); - public static final ArithmeticInstruction IAND = new IAND(); - public static final ArithmeticInstruction LAND = new LAND(); - public static final ArithmeticInstruction IOR = new IOR(); - public static final ArithmeticInstruction LOR = new LOR(); - public static final ArithmeticInstruction IXOR = new IXOR(); - public static final ArithmeticInstruction LXOR = new LXOR(); - public static final ConversionInstruction I2L = new I2L(); - public static final ConversionInstruction I2F = new I2F(); - public static final ConversionInstruction I2D = new I2D(); - public static final ConversionInstruction L2I = new L2I(); - public static final ConversionInstruction L2F = new L2F(); - public static final ConversionInstruction L2D = new L2D(); - public static final ConversionInstruction F2I = new F2I(); - public static final ConversionInstruction F2L = new F2L(); - public static final ConversionInstruction F2D = new F2D(); - public static final ConversionInstruction D2I = new D2I(); - public static final ConversionInstruction D2L = new D2L(); - public static final ConversionInstruction D2F = new D2F(); - public static final ConversionInstruction I2B = new I2B(); - public static final ConversionInstruction I2C = new I2C(); - public static final ConversionInstruction I2S = new I2S(); - public static final Instruction LCMP = new LCMP(); - public static final Instruction FCMPL = new FCMPL(); - public static final Instruction FCMPG = new FCMPG(); - public static final Instruction DCMPL = new DCMPL(); - public static final Instruction DCMPG = new DCMPG(); - public static final ReturnInstruction IRETURN = new IRETURN(); - public static final ReturnInstruction LRETURN = new LRETURN(); - public static final ReturnInstruction FRETURN = new FRETURN(); - public static final ReturnInstruction DRETURN = new DRETURN(); - public static final ReturnInstruction ARETURN = new ARETURN(); - public static final ReturnInstruction RETURN = new RETURN(); - public static final Instruction ARRAYLENGTH = new ARRAYLENGTH(); - public static final Instruction ATHROW = new ATHROW(); - public static final Instruction MONITORENTER = new MONITORENTER(); - public static final Instruction MONITOREXIT = new MONITOREXIT(); - - /** You can use these constants in multiple places safely, if you can guarantee - * that you will never alter their internal values, e.g. call setIndex(). - */ - public static final LocalVariableInstruction THIS = new ALOAD(0); - public static final LocalVariableInstruction ALOAD_0 = THIS; - public static final LocalVariableInstruction ALOAD_1 = new ALOAD(1); - public static final LocalVariableInstruction ALOAD_2 = new ALOAD(2); - public static final LocalVariableInstruction ILOAD_0 = new ILOAD(0); - public static final LocalVariableInstruction ILOAD_1 = new ILOAD(1); - public static final LocalVariableInstruction ILOAD_2 = new ILOAD(2); - public static final LocalVariableInstruction ASTORE_0 = new ASTORE(0); - public static final LocalVariableInstruction ASTORE_1 = new ASTORE(1); - public static final LocalVariableInstruction ASTORE_2 = new ASTORE(2); - public static final LocalVariableInstruction ISTORE_0 = new ISTORE(0); - public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1); - public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2); - - - /** Get object via its opcode, for immutable instructions like - * branch instructions entries are set to null. - */ - public static final Instruction[] INSTRUCTIONS = new Instruction[256]; - - /** Interfaces may have no static initializers, so we simulate this - * with an inner class. - */ - static final Clinit bla = new Clinit(); - - 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; - } - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java index 7deb0eceaa3..f108e79cca4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java @@ -17,573 +17,731 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; /** - * Instances of this class may be used, e.g., to generate typed - * versions of instructions. Its main purpose is to be used as the - * byte code generating backend of a compiler. You can subclass it to - * add your own create methods. + * Instances of this class may be used, e.g., to generate typed versions of + * instructions. Its main purpose is to be used as the byte code generating + * backend of a compiler. You can subclass it to add your own create methods. + *

      + * Note: The static createXXX methods return singleton instances from the + * {@link InstructionConst} class. * - * @author M. Dahm - * @see Constants + * @version $Id: InstructionFactory.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see Const + * @see InstructionConst */ -public class InstructionFactory - implements InstructionConstants, java.io.Serializable -{ - protected ClassGen cg; - protected ConstantPoolGen cp; +public class InstructionFactory { - public InstructionFactory(ClassGen cg, ConstantPoolGen cp) { - this.cg = cg; - this.cp = cp; - } + // N.N. These must agree with the order of Constants.T_CHAR through T_LONG + private static final String[] short_names = { + "C", "F", "D", "B", "S", "I", "L" + }; - /** Initialize with ClassGen object - */ - public InstructionFactory(ClassGen cg) { - this(cg, cg.getConstantPool()); - } + private ClassGen cg; + private ConstantPoolGen cp; - /** Initialize just with ConstantPoolGen object - */ - public InstructionFactory(ConstantPoolGen cp) { - this(null, cp); - } - - /** Create an invoke instruction. - * - * @param class_name name of the called class - * @param name name of the called method - * @param ret_type return type of method - * @param arg_types argument types of method - * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, - * or INVOKESPECIAL - * @see Constants - */ - public InvokeInstruction createInvoke(String class_name, String name, Type ret_type, - Type[] arg_types, short kind) { - int index; - int nargs = 0; - String signature = Type.getMethodSignature(ret_type, arg_types); - - for(int i=0; i < arg_types.length; i++) // Count size of arguments - nargs += arg_types[i].getSize(); - - if(kind == Constants.INVOKEINTERFACE) - index = cp.addInterfaceMethodref(class_name, name, signature); - else - index = cp.addMethodref(class_name, name, signature); - - switch(kind) { - case Constants.INVOKESPECIAL: return new INVOKESPECIAL(index); - case Constants.INVOKEVIRTUAL: return new INVOKEVIRTUAL(index); - case Constants.INVOKESTATIC: return new INVOKESTATIC(index); - case Constants.INVOKEINTERFACE: return new INVOKEINTERFACE(index, nargs + 1); - default: - throw new RuntimeException("Oops: Unknown invoke kind:" + kind); + public InstructionFactory(final ClassGen cg, final ConstantPoolGen cp) { + this.cg = cg; + this.cp = cp; } - } - /** Create a call to the most popular System.out.println() method. - * - * @param s the string to print - */ - public InstructionList createPrintln(String s) { - InstructionList il = new InstructionList(); - int out = cp.addFieldref("java.lang.System", "out", - "Ljava/io/PrintStream;"); - int println = cp.addMethodref("java.io.PrintStream", "println", - "(Ljava/lang/String;)V"); - - il.append(new GETSTATIC(out)); - il.append(new PUSH(cp, s)); - il.append(new INVOKEVIRTUAL(println)); - - return il; - } - - /** Uses PUSH to push a constant value onto the stack. - * @param value must be of type Number, Boolean, Character or String - */ - public Instruction createConstant(Object value) { - PUSH push; - - if(value instanceof Number) - push = new PUSH(cp, (Number)value); - else if(value instanceof String) - push = new PUSH(cp, (String)value); - else if(value instanceof Boolean) - push = new PUSH(cp, (Boolean)value); - else if(value instanceof Character) - push = new PUSH(cp, (Character)value); - else - throw new ClassGenException("Illegal type: " + value.getClass()); - - return push.getInstruction(); - } - - private static class MethodObject { - Type[] arg_types; - Type result_type; - String[] arg_names; - String class_name; - String name; - int access; - - MethodObject(String c, String n, Type r, Type[] a, int acc) { - class_name = c; - name = n; - result_type = r; - arg_types = a; - access = acc; + /** + * Initialize with ClassGen object + */ + public InstructionFactory(final ClassGen cg) { + this(cg, cg.getConstantPool()); } - } - private InvokeInstruction createInvoke(MethodObject m, short kind) { - return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind); - } - - private static MethodObject[] append_mos = { - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.STRING }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.OBJECT }, Constants.ACC_PUBLIC), - null, null, // indices 2, 3 - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.BOOLEAN }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.CHAR }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.FLOAT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.DOUBLE }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.INT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte) - new Type[] { Type.INT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short) - new Type[] { Type.INT }, Constants.ACC_PUBLIC), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, - new Type[] { Type.LONG }, Constants.ACC_PUBLIC) - }; - - private static final boolean isString(Type type) { - return ((type instanceof ObjectType) && - ((ObjectType)type).getClassName().equals("java.lang.String")); - } - - public Instruction createAppend(Type type) { - byte t = type.getType(); - - if(isString(type)) - return createInvoke(append_mos[0], Constants.INVOKEVIRTUAL); - - switch(t) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_FLOAT: - case Constants.T_DOUBLE: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - case Constants.T_LONG - : return createInvoke(append_mos[t], Constants.INVOKEVIRTUAL); - case Constants.T_ARRAY: - case Constants.T_OBJECT: - return createInvoke(append_mos[1], Constants.INVOKEVIRTUAL); - default: - throw new RuntimeException("Oops: No append for this type? " + type); + /** + * Initialize just with ConstantPoolGen object + */ + public InstructionFactory(final ConstantPoolGen cp) { + this(null, cp); } - } - /** Create a field instruction. - * - * @param class_name name of the accessed class - * @param name name of the referenced field - * @param type type of field - * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC - * @see Constants - */ - public FieldInstruction createFieldAccess(String class_name, String name, Type type, short kind) { - int index; - String signature = type.getSignature(); - - index = cp.addFieldref(class_name, name, signature); - - switch(kind) { - case Constants.GETFIELD: return new GETFIELD(index); - case Constants.PUTFIELD: return new PUTFIELD(index); - case Constants.GETSTATIC: return new GETSTATIC(index); - case Constants.PUTSTATIC: return new PUTSTATIC(index); - - default: - throw new RuntimeException("Oops: Unknown getfield kind:" + kind); + /** + * Create an invoke instruction. (Except for invokedynamic.) + * + * @param class_name name of the called class + * @param name name of the called method + * @param ret_type return type of method + * @param arg_types argument types of method + * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, + * INVOKEVIRTUAL, or INVOKESPECIAL + * @see Const + */ + public InvokeInstruction createInvoke(final String class_name, final String name, final Type ret_type, + final Type[] arg_types, final short kind) { + int index; + int nargs = 0; + final String signature = Type.getMethodSignature(ret_type, arg_types); + for (final Type arg_type : arg_types) { + nargs += arg_type.getSize(); + } + if (kind == Const.INVOKEINTERFACE) { + index = cp.addInterfaceMethodref(class_name, name, signature); + } else { + index = cp.addMethodref(class_name, name, signature); + } + switch (kind) { + case Const.INVOKESPECIAL: + return new INVOKESPECIAL(index); + case Const.INVOKEVIRTUAL: + return new INVOKEVIRTUAL(index); + case Const.INVOKESTATIC: + return new INVOKESTATIC(index); + case Const.INVOKEINTERFACE: + return new INVOKEINTERFACE(index, nargs + 1); + case Const.INVOKEDYNAMIC: + return new INVOKEDYNAMIC(index); + default: + throw new RuntimeException("Oops: Unknown invoke kind: " + kind); + } } - } - /** Create reference to `this' - */ - public static Instruction createThis() { - return new ALOAD(0); - } - - /** Create typed return - */ - public static ReturnInstruction createReturn(Type type) { - switch(type.getType()) { - case Constants.T_ARRAY: - case Constants.T_OBJECT: return ARETURN; - case Constants.T_INT: - case Constants.T_SHORT: - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: return IRETURN; - case Constants.T_FLOAT: return FRETURN; - case Constants.T_DOUBLE: return DRETURN; - case Constants.T_LONG: return LRETURN; - case Constants.T_VOID: return RETURN; - - default: - throw new RuntimeException("Invalid type: " + type); + /** + * Create an invokedynamic instruction. + * + * @param bootstrap_index index into the bootstrap_methods array + * @param name name of the called method + * @param ret_type return type of method + * @param arg_types argument types of method + * @see Constants + */ + /* + * createInvokeDynamic only needed if instrumention code wants to generate + * a new invokedynamic instruction. I don't think we need. (markro) + * + public InvokeInstruction createInvokeDynamic( int bootstrap_index, String name, Type ret_type, + Type[] arg_types) { + int index; + int nargs = 0; + String signature = Type.getMethodSignature(ret_type, arg_types); + for (int i = 0; i < arg_types.length; i++) { + nargs += arg_types[i].getSize(); + } + // UNDONE - needs to be added to ConstantPoolGen + //index = cp.addInvokeDynamic(bootstrap_index, name, signature); + index = 0; + return new INVOKEDYNAMIC(index); + } + */ + /** + * Create a call to the most popular System.out.println() method. + * + * @param s the string to print + */ + public InstructionList createPrintln(final String s) { + final InstructionList il = new InstructionList(); + final int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;"); + final int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V"); + il.append(new GETSTATIC(out)); + il.append(new PUSH(cp, s)); + il.append(new INVOKEVIRTUAL(println)); + return il; } - } - private static final ArithmeticInstruction createBinaryIntOp(char first, String op) { - switch(first) { - case '-' : return ISUB; - case '+' : return IADD; - case '%' : return IREM; - case '*' : return IMUL; - case '/' : return IDIV; - case '&' : return IAND; - case '|' : return IOR; - case '^' : return IXOR; - case '<' : return ISHL; - case '>' : return op.equals(">>>")? (ArithmeticInstruction)IUSHR : - (ArithmeticInstruction)ISHR; - default: throw new RuntimeException("Invalid operand " + op); + /** + * Uses PUSH to push a constant value onto the stack. + * + * @param value must be of type Number, Boolean, Character or String + */ + public Instruction createConstant(final Object value) { + PUSH push; + if (value instanceof Number) { + push = new PUSH(cp, (Number) value); + } else if (value instanceof String) { + push = new PUSH(cp, (String) value); + } else if (value instanceof Boolean) { + push = new PUSH(cp, (Boolean) value); + } else if (value instanceof Character) { + push = new PUSH(cp, (Character) value); + } else { + throw new ClassGenException("Illegal type: " + value.getClass()); + } + return push.getInstruction(); } - } - private static final ArithmeticInstruction createBinaryLongOp(char first, String op) { - switch(first) { - case '-' : return LSUB; - case '+' : return LADD; - case '%' : return LREM; - case '*' : return LMUL; - case '/' : return LDIV; - case '&' : return LAND; - case '|' : return LOR; - case '^' : return LXOR; - case '<' : return LSHL; - case '>' : return op.equals(">>>")? (ArithmeticInstruction)LUSHR : - (ArithmeticInstruction)LSHR; - default: throw new RuntimeException("Invalid operand " + op); + private static class MethodObject { + + final Type[] arg_types; + final Type result_type; + final String class_name; + final String name; + + MethodObject(final String c, final String n, final Type r, final Type[] a) { + class_name = c; + name = n; + result_type = r; + arg_types = a; + } } - } - private static final ArithmeticInstruction createBinaryFloatOp(char op) { - switch(op) { - case '-' : return FSUB; - case '+' : return FADD; - case '*' : return FMUL; - case '/' : return FDIV; - default: throw new RuntimeException("Invalid operand " + op); + private InvokeInstruction createInvoke(final MethodObject m, final short kind) { + return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind); } - } - private static final ArithmeticInstruction createBinaryDoubleOp(char op) { - switch(op) { - case '-' : return DSUB; - case '+' : return DADD; - case '*' : return DMUL; - case '/' : return DDIV; - default: throw new RuntimeException("Invalid operand " + op); + private static final MethodObject[] append_mos = { + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.STRING + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.OBJECT + }), + null, + null, // indices 2, 3 + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.BOOLEAN + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.CHAR + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.FLOAT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.DOUBLE + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.INT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte) + new Type[]{ + Type.INT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short) + new Type[]{ + Type.INT + }), + new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{ + Type.LONG + }) + }; + + private static boolean isString(final Type type) { + return (type instanceof ObjectType) + && ((ObjectType) type).getClassName().equals("java.lang.String"); } - } - /** - * Create binary operation for simple basic types, such as int and float. - * - * @param op operation, such as "+", "*", "<<", etc. - */ - public static ArithmeticInstruction createBinaryOperation(String op, Type type) { - char first = op.toCharArray()[0]; - - switch(type.getType()) { - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: - case Constants.T_CHAR: return createBinaryIntOp(first, op); - case Constants.T_LONG: return createBinaryLongOp(first, op); - case Constants.T_FLOAT: return createBinaryFloatOp(first); - case Constants.T_DOUBLE: return createBinaryDoubleOp(first); - default: throw new RuntimeException("Invalid type " + type); + public Instruction createAppend(final Type type) { + final byte t = type.getType(); + if (isString(type)) { + return createInvoke(append_mos[0], Const.INVOKEVIRTUAL); + } + switch (t) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_FLOAT: + case Const.T_DOUBLE: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + case Const.T_LONG: + return createInvoke(append_mos[t], Const.INVOKEVIRTUAL); + case Const.T_ARRAY: + case Const.T_OBJECT: + return createInvoke(append_mos[1], Const.INVOKEVIRTUAL); + default: + throw new RuntimeException("Oops: No append for this type? " + type); + } } - } - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createPop(int size) { - return (size == 2)? (StackInstruction)POP2 : - (StackInstruction)POP; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup(int size) { - return (size == 2)? (StackInstruction)DUP2 : - (StackInstruction)DUP; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup_2(int size) { - return (size == 2)? (StackInstruction)DUP2_X2 : - (StackInstruction)DUP_X2; - } - - /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) - */ - public static StackInstruction createDup_1(int size) { - return (size == 2)? (StackInstruction)DUP2_X1 : - (StackInstruction)DUP_X1; - } - - /** - * @param index index of local variable - */ - public static LocalVariableInstruction createStore(Type type, int index) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: return new ISTORE(index); - case Constants.T_FLOAT: return new FSTORE(index); - case Constants.T_DOUBLE: return new DSTORE(index); - case Constants.T_LONG: return new LSTORE(index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: return new ASTORE(index); - default: throw new RuntimeException("Invalid type " + type); + /** + * 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 Const + */ + public FieldInstruction createFieldAccess(final String class_name, final String name, final Type type, final short kind) { + int index; + final String signature = type.getSignature(); + index = cp.addFieldref(class_name, name, signature); + switch (kind) { + case Const.GETFIELD: + return new GETFIELD(index); + case Const.PUTFIELD: + return new PUTFIELD(index); + case Const.GETSTATIC: + return new GETSTATIC(index); + case Const.PUTSTATIC: + return new PUTSTATIC(index); + default: + throw new RuntimeException("Oops: Unknown getfield kind:" + kind); + } } - } - /** - * @param index index of local variable - */ - public static LocalVariableInstruction createLoad(Type type, int index) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_CHAR: - case Constants.T_BYTE: - case Constants.T_SHORT: - case Constants.T_INT: return new ILOAD(index); - case Constants.T_FLOAT: return new FLOAD(index); - case Constants.T_DOUBLE: return new DLOAD(index); - case Constants.T_LONG: return new LLOAD(index); - case Constants.T_ARRAY: - case Constants.T_OBJECT: return new ALOAD(index); - default: throw new RuntimeException("Invalid type " + type); + /** + * Create reference to `this' + */ + public static Instruction createThis() { + return new ALOAD(0); } - } - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static ArrayInstruction createArrayLoad(Type type) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: return BALOAD; - case Constants.T_CHAR: return CALOAD; - case Constants.T_SHORT: return SALOAD; - case Constants.T_INT: return IALOAD; - case Constants.T_FLOAT: return FALOAD; - case Constants.T_DOUBLE: return DALOAD; - case Constants.T_LONG: return LALOAD; - case Constants.T_ARRAY: - case Constants.T_OBJECT: return AALOAD; - default: throw new RuntimeException("Invalid type " + type); + /** + * Create typed return + */ + public static ReturnInstruction createReturn(final Type type) { + switch (type.getType()) { + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.ARETURN; + case Const.T_INT: + case Const.T_SHORT: + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + return InstructionConst.IRETURN; + case Const.T_FLOAT: + return InstructionConst.FRETURN; + case Const.T_DOUBLE: + return InstructionConst.DRETURN; + case Const.T_LONG: + return InstructionConst.LRETURN; + case Const.T_VOID: + return InstructionConst.RETURN; + default: + throw new RuntimeException("Invalid type: " + type); + } } - } - /** - * @param type type of elements of array, i.e., array.getElementType() - */ - public static ArrayInstruction createArrayStore(Type type) { - switch(type.getType()) { - case Constants.T_BOOLEAN: - case Constants.T_BYTE: return BASTORE; - case Constants.T_CHAR: return CASTORE; - case Constants.T_SHORT: return SASTORE; - case Constants.T_INT: return IASTORE; - case Constants.T_FLOAT: return FASTORE; - case Constants.T_DOUBLE: return DASTORE; - case Constants.T_LONG: return LASTORE; - case Constants.T_ARRAY: - case Constants.T_OBJECT: return AASTORE; - default: throw new RuntimeException("Invalid type " + type); + private static ArithmeticInstruction createBinaryIntOp(final char first, final String op) { + switch (first) { + case '-': + return InstructionConst.ISUB; + case '+': + return InstructionConst.IADD; + case '%': + return InstructionConst.IREM; + case '*': + return InstructionConst.IMUL; + case '/': + return InstructionConst.IDIV; + case '&': + return InstructionConst.IAND; + case '|': + return InstructionConst.IOR; + case '^': + return InstructionConst.IXOR; + case '<': + return InstructionConst.ISHL; + case '>': + return op.equals(">>>") ? InstructionConst.IUSHR : InstructionConst.ISHR; + default: + throw new RuntimeException("Invalid operand " + op); + } } - } - - /** Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., - * if the operands are basic types and CHECKCAST if they are reference types. - */ - public Instruction createCast(Type src_type, Type dest_type) { - if((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { - byte dest = dest_type.getType(); - byte src = src_type.getType(); - - if(dest == Constants.T_LONG && (src == Constants.T_CHAR || src == Constants.T_BYTE || - src == Constants.T_SHORT)) - src = Constants.T_INT; - - String[] short_names = { "C", "F", "D", "B", "S", "I", "L" }; - - String name = "com.sun.org.apache.bcel.internal.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).getConstructor().newInstance(); - } catch(Exception e) { - throw new RuntimeException("Could not find instruction: " + name); - } - - return i; - } else if((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { - if(dest_type instanceof ArrayType) - return new CHECKCAST(cp.addArrayClass((ArrayType)dest_type)); - else - return new CHECKCAST(cp.addClass(((ObjectType)dest_type).getClassName())); + private static ArithmeticInstruction createBinaryLongOp(final char first, final String op) { + switch (first) { + case '-': + return InstructionConst.LSUB; + case '+': + return InstructionConst.LADD; + case '%': + return InstructionConst.LREM; + case '*': + return InstructionConst.LMUL; + case '/': + return InstructionConst.LDIV; + case '&': + return InstructionConst.LAND; + case '|': + return InstructionConst.LOR; + case '^': + return InstructionConst.LXOR; + case '<': + return InstructionConst.LSHL; + case '>': + return op.equals(">>>") ? InstructionConst.LUSHR : InstructionConst.LSHR; + default: + throw new RuntimeException("Invalid operand " + op); + } } - else - throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); - } - public GETFIELD createGetField(String class_name, String name, Type t) { - return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); - } - - public GETSTATIC createGetStatic(String class_name, String name, Type t) { - return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); - } - - public PUTFIELD createPutField(String class_name, String name, Type t) { - return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); - } - - public PUTSTATIC createPutStatic(String class_name, String name, Type t) { - return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); - } - - public CHECKCAST createCheckCast(ReferenceType t) { - if(t instanceof ArrayType) - return new CHECKCAST(cp.addArrayClass((ArrayType)t)); - else - return new CHECKCAST(cp.addClass((ObjectType)t)); - } - - public INSTANCEOF createInstanceOf(ReferenceType t) { - if(t instanceof ArrayType) - return new INSTANCEOF(cp.addArrayClass((ArrayType)t)); - else - return new INSTANCEOF(cp.addClass((ObjectType)t)); - } - - public NEW createNew(ObjectType t) { - return new NEW(cp.addClass(t)); - } - - public NEW createNew(String s) { - return createNew(new ObjectType(s)); - } - - /** Create new array of given size and type. - * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction - */ - public Instruction createNewArray(Type t, short dim) { - if(dim == 1) { - if(t instanceof ObjectType) - return new ANEWARRAY(cp.addClass((ObjectType)t)); - else if(t instanceof ArrayType) - return new ANEWARRAY(cp.addArrayClass((ArrayType)t)); - else - return new NEWARRAY(((BasicType)t).getType()); - } else { - ArrayType at; - - if(t instanceof ArrayType) - at = (ArrayType)t; - else - at = new ArrayType(t, dim); - - return new MULTIANEWARRAY(cp.addArrayClass(at), dim); + private static ArithmeticInstruction createBinaryFloatOp(final char op) { + switch (op) { + case '-': + return InstructionConst.FSUB; + case '+': + return InstructionConst.FADD; + case '*': + return InstructionConst.FMUL; + case '/': + return InstructionConst.FDIV; + case '%': + return InstructionConst.FREM; + default: + throw new RuntimeException("Invalid operand " + op); + } } - } - /** 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); + private static ArithmeticInstruction createBinaryDoubleOp(final char op) { + switch (op) { + case '-': + return InstructionConst.DSUB; + case '+': + return InstructionConst.DADD; + case '*': + return InstructionConst.DMUL; + case '/': + return InstructionConst.DDIV; + case '%': + return InstructionConst.DREM; + default: + throw new RuntimeException("Invalid operand " + op); + } } - } - /** Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. - * For those you should use the SWITCH compound instruction. - */ - public static BranchInstruction createBranchInstruction(short opcode, InstructionHandle target) { - switch(opcode) { - case Constants.IFEQ: return new IFEQ(target); - case Constants.IFNE: return new IFNE(target); - case Constants.IFLT: return new IFLT(target); - case Constants.IFGE: return new IFGE(target); - case Constants.IFGT: return new IFGT(target); - case Constants.IFLE: return new IFLE(target); - case Constants.IF_ICMPEQ: return new IF_ICMPEQ(target); - case Constants.IF_ICMPNE: return new IF_ICMPNE(target); - case Constants.IF_ICMPLT: return new IF_ICMPLT(target); - case Constants.IF_ICMPGE: return new IF_ICMPGE(target); - case Constants.IF_ICMPGT: return new IF_ICMPGT(target); - case Constants.IF_ICMPLE: return new IF_ICMPLE(target); - case Constants.IF_ACMPEQ: return new IF_ACMPEQ(target); - case Constants.IF_ACMPNE: return new IF_ACMPNE(target); - case Constants.GOTO: return new GOTO(target); - case Constants.JSR: return new JSR(target); - case Constants.IFNULL: return new IFNULL(target); - case Constants.IFNONNULL: return new IFNONNULL(target); - case Constants.GOTO_W: return new GOTO_W(target); - case Constants.JSR_W: return new JSR_W(target); - default: - throw new RuntimeException("Invalid opcode: " + opcode); + /** + * Create binary operation for simple basic types, such as int and float. + * + * @param op operation, such as "+", "*", "<<", etc. + */ + public static ArithmeticInstruction createBinaryOperation(final String op, final Type type) { + final char first = op.charAt(0); + switch (type.getType()) { + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + case Const.T_CHAR: + return createBinaryIntOp(first, op); + case Const.T_LONG: + return createBinaryLongOp(first, op); + case Const.T_FLOAT: + return createBinaryFloatOp(first); + case Const.T_DOUBLE: + return createBinaryDoubleOp(first); + default: + throw new RuntimeException("Invalid type " + type); + } } - } - public void setClassGen(ClassGen c) { cg = c; } - public ClassGen getClassGen() { return cg; } - public void setConstantPool(ConstantPoolGen c) { cp = c; } - public ConstantPoolGen getConstantPool() { return cp; } + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createPop(final int size) { + return (size == 2) ? InstructionConst.POP2 : InstructionConst.POP; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup(final int size) { + return (size == 2) ? InstructionConst.DUP2 : InstructionConst.DUP; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup_2(final int size) { + return (size == 2) ? InstructionConst.DUP2_X2 : InstructionConst.DUP_X2; + } + + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createDup_1(final int size) { + return (size == 2) ? InstructionConst.DUP2_X1 : InstructionConst.DUP_X1; + } + + /** + * @param index index of local variable + */ + public static LocalVariableInstruction createStore(final Type type, final int index) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + return new ISTORE(index); + case Const.T_FLOAT: + return new FSTORE(index); + case Const.T_DOUBLE: + return new DSTORE(index); + case Const.T_LONG: + return new LSTORE(index); + case Const.T_ARRAY: + case Const.T_OBJECT: + return new ASTORE(index); + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param index index of local variable + */ + public static LocalVariableInstruction createLoad(final Type type, final int index) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + return new ILOAD(index); + case Const.T_FLOAT: + return new FLOAD(index); + case Const.T_DOUBLE: + return new DLOAD(index); + case Const.T_LONG: + return new LLOAD(index); + case Const.T_ARRAY: + case Const.T_OBJECT: + return new ALOAD(index); + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param type type of elements of array, i.e., array.getElementType() + */ + public static ArrayInstruction createArrayLoad(final Type type) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_BYTE: + return InstructionConst.BALOAD; + case Const.T_CHAR: + return InstructionConst.CALOAD; + case Const.T_SHORT: + return InstructionConst.SALOAD; + case Const.T_INT: + return InstructionConst.IALOAD; + case Const.T_FLOAT: + return InstructionConst.FALOAD; + case Const.T_DOUBLE: + return InstructionConst.DALOAD; + case Const.T_LONG: + return InstructionConst.LALOAD; + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.AALOAD; + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * @param type type of elements of array, i.e., array.getElementType() + */ + public static ArrayInstruction createArrayStore(final Type type) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_BYTE: + return InstructionConst.BASTORE; + case Const.T_CHAR: + return InstructionConst.CASTORE; + case Const.T_SHORT: + return InstructionConst.SASTORE; + case Const.T_INT: + return InstructionConst.IASTORE; + case Const.T_FLOAT: + return InstructionConst.FASTORE; + case Const.T_DOUBLE: + return InstructionConst.DASTORE; + case Const.T_LONG: + return InstructionConst.LASTORE; + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.AASTORE; + default: + throw new RuntimeException("Invalid type " + type); + } + } + + /** + * Create conversion operation for two stack operands, this may be an I2C, + * instruction, e.g., if the operands are basic types and CHECKCAST if they + * are reference types. + */ + public Instruction createCast(final Type src_type, final Type dest_type) { + if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { + final byte dest = dest_type.getType(); + byte src = src_type.getType(); + if (dest == Const.T_LONG + && (src == Const.T_CHAR || src == Const.T_BYTE || src == Const.T_SHORT)) { + src = Const.T_INT; + } + final String name = "com.sun.org.apache.bcel.internal.generic." + short_names[src - Const.T_CHAR] + "2" + + short_names[dest - Const.T_CHAR]; + Instruction i = null; + try { + i = (Instruction) java.lang.Class.forName(name).newInstance(); + } catch (final Exception e) { + throw new RuntimeException("Could not find instruction: " + name, e); + } + return i; + } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { + if (dest_type instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) dest_type)); + } + return new CHECKCAST(cp.addClass(((ObjectType) dest_type).getClassName())); + } else { + throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); + } + } + + public GETFIELD createGetField(final String class_name, final String name, final Type t) { + return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); + } + + public GETSTATIC createGetStatic(final String class_name, final String name, final Type t) { + return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + } + + public PUTFIELD createPutField(final String class_name, final String name, final Type t) { + return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); + } + + public PUTSTATIC createPutStatic(final String class_name, final String name, final Type t) { + return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + } + + public CHECKCAST createCheckCast(final ReferenceType t) { + if (t instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) t)); + } + return new CHECKCAST(cp.addClass((ObjectType) t)); + } + + public INSTANCEOF createInstanceOf(final ReferenceType t) { + if (t instanceof ArrayType) { + return new INSTANCEOF(cp.addArrayClass((ArrayType) t)); + } + return new INSTANCEOF(cp.addClass((ObjectType) t)); + } + + public NEW createNew(final ObjectType t) { + return new NEW(cp.addClass(t)); + } + + public NEW createNew(final String s) { + return createNew(ObjectType.getInstance(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(final Type t, final short dim) { + if (dim == 1) { + if (t instanceof ObjectType) { + return new ANEWARRAY(cp.addClass((ObjectType) t)); + } else if (t instanceof ArrayType) { + return new ANEWARRAY(cp.addArrayClass((ArrayType) t)); + } else { + return new NEWARRAY(t.getType()); + } + } + 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(final Type type) { + switch (type.getType()) { + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.ACONST_NULL; + case Const.T_INT: + case Const.T_SHORT: + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + return InstructionConst.ICONST_0; + case Const.T_FLOAT: + return InstructionConst.FCONST_0; + case Const.T_DOUBLE: + return InstructionConst.DCONST_0; + case Const.T_LONG: + return InstructionConst.LCONST_0; + case Const.T_VOID: + return InstructionConst.NOP; + default: + throw new RuntimeException("Invalid type: " + type); + } + } + + /** + * Create branch instruction by given opcode, except LOOKUPSWITCH and + * TABLESWITCH. For those you should use the SWITCH compound instruction. + */ + public static BranchInstruction createBranchInstruction(final short opcode, final InstructionHandle target) { + switch (opcode) { + case Const.IFEQ: + return new IFEQ(target); + case Const.IFNE: + return new IFNE(target); + case Const.IFLT: + return new IFLT(target); + case Const.IFGE: + return new IFGE(target); + case Const.IFGT: + return new IFGT(target); + case Const.IFLE: + return new IFLE(target); + case Const.IF_ICMPEQ: + return new IF_ICMPEQ(target); + case Const.IF_ICMPNE: + return new IF_ICMPNE(target); + case Const.IF_ICMPLT: + return new IF_ICMPLT(target); + case Const.IF_ICMPGE: + return new IF_ICMPGE(target); + case Const.IF_ICMPGT: + return new IF_ICMPGT(target); + case Const.IF_ICMPLE: + return new IF_ICMPLE(target); + case Const.IF_ACMPEQ: + return new IF_ACMPEQ(target); + case Const.IF_ACMPNE: + return new IF_ACMPNE(target); + case Const.GOTO: + return new GOTO(target); + case Const.JSR: + return new JSR(target); + case Const.IFNULL: + return new IFNULL(target); + case Const.IFNONNULL: + return new IFNONNULL(target); + case Const.GOTO_W: + return new GOTO_W(target); + case Const.JSR_W: + return new JSR_W(target); + default: + throw new RuntimeException("Invalid opcode: " + opcode); + } + } + + public void setClassGen(final ClassGen c) { + cg = c; + } + + public ClassGen getClassGen() { + return cg; + } + + public void setConstantPool(final ConstantPoolGen c) { + cp = c; + } + + public ConstantPoolGen getConstantPool() { + return cp; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java index c490f3550f3..85a7dadcb84 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,234 +17,298 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.classfile.Utility; -import java.util.HashSet; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Instances of this class give users a handle to the instructions contained in * an InstructionList. Instruction objects may be used more than once within a * list, this is useful because it saves memory and may be much faster. * - * Within an InstructionList an InstructionHandle object is wrapped - * around all instructions, i.e., it implements a cell in a - * doubly-linked list. From the outside only the next and the - * previous instruction (handle) are accessible. One - * can traverse the list via an Enumeration returned by + * Within an InstructionList an InstructionHandle object is wrapped around all + * instructions, i.e., it implements a cell in a doubly-linked list. From the + * outside only the next and the previous instruction (handle) are accessible. + * One can traverse the list via an Enumeration returned by * InstructionList.elements(). * - * @author M. Dahm + * @version $Id: InstructionHandle.java 1749603 2016-06-21 20:50:19Z ggregory $ * @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 i_position = -1; // byte code offset of instruction - private HashSet targeters; - private HashMap attributes; +public class InstructionHandle { - public final InstructionHandle getNext() { return next; } - public final InstructionHandle getPrev() { return prev; } - public final Instruction getInstruction() { return instruction; } + private InstructionHandle next; + private InstructionHandle prev; + private Instruction instruction; - /** - * Replace current instruction contained in this handle. - * Old instruction is disposed using Instruction.dispose(). - */ - public void setInstruction(Instruction i) { // Overridden in BranchHandle - if(i == null) - throw new ClassGenException("Assigning null to handle"); + private int i_position = -1; // byte code offset of instruction - if((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) - throw new ClassGenException("Assigning branch instruction " + i + " to plain handle"); + private Set targeters; + private Map attributes; - if(instruction != null) - instruction.dispose(); - - instruction = i; - } - - /** - * Temporarily swap the current instruction, without disturbing - * anything. Meant to be used by a debugger, implementing - * breakpoints. Current instruction is returned. - */ - public Instruction swapInstruction(Instruction i) { - Instruction oldInstruction = instruction; - instruction = i; - return oldInstruction; - } - - /*private*/ protected InstructionHandle(Instruction i) { - setInstruction(i); - } - - private static InstructionHandle ih_list = null; // List of reusable handles - - /** Factory method. - */ - static final InstructionHandle getInstructionHandle(Instruction i) { - if(ih_list == null) - return new InstructionHandle(i); - else { - InstructionHandle ih = ih_list; - ih_list = ih.next; - - ih.setInstruction(i); - - return ih; + public final InstructionHandle getNext() { + return next; } - } - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions()' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - protected int updatePosition(int offset, int max_offset) { - i_position += offset; - return 0; - } + public final InstructionHandle getPrev() { + return prev; + } - /** @return the position, i.e., the byte code offset of the contained - * instruction. This is accurate only after - * InstructionList.setPositions() has been called. - */ - public int getPosition() { return i_position; } + public final Instruction getInstruction() { + return instruction; + } - /** Set the position, i.e., the byte code offset of the contained - * instruction. - */ - void setPosition(int pos) { i_position = pos; } + /** + * Replace current instruction contained in this handle. Old instruction is + * disposed using Instruction.dispose(). + */ + public void setInstruction(final Instruction i) { // Overridden in BranchHandle TODO could be package-protected? + if (i == null) { + throw new ClassGenException("Assigning null to handle"); + } + if ((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) { + throw new ClassGenException("Assigning branch instruction " + i + " to plain handle"); + } + if (instruction != null) { + instruction.dispose(); + } + instruction = i; + } - /** Overridden in BranchHandle - */ - protected void addHandle() { - next = ih_list; - ih_list = this; - } + /** + * Temporarily swap the current instruction, without disturbing anything. + * Meant to be used by a debugger, implementing breakpoints. Current + * instruction is returned. + *

      + * Warning: if this is used on a BranchHandle then some methods such as + * getPosition() will still refer to the original cached instruction, + * whereas other BH methods may affect the cache and the replacement + * instruction. + */ + // See BCEL-273 + // TODO remove this method in any redesign of BCEL + public Instruction swapInstruction(final Instruction i) { + final Instruction oldInstruction = instruction; + instruction = i; + return oldInstruction; + } - /** - * Delete contents, i.e., remove user access and make handle reusable. - */ - void dispose() { - next = prev = null; - instruction.dispose(); - instruction = null; - i_position = -1; - attributes = null; - removeAllTargeters(); - addHandle(); - } - /** Remove all targeters, if any. - */ - public void removeAllTargeters() { - if(targeters != null) - targeters.clear(); - } + /*private*/ + protected InstructionHandle(final Instruction i) { + setInstruction(i); + } - /** - * Denote this handle isn't referenced anymore by t. - */ - public void removeTargeter(InstructionTargeter t) { - targeters.remove(t); - } + private static InstructionHandle ih_list = null; // List of reusable handles - /** - * Denote this handle is being referenced by t. - */ - public void addTargeter(InstructionTargeter t) { - if(targeters == null) - targeters = new HashSet(); + /** + * Factory method. + */ + static InstructionHandle getInstructionHandle(final Instruction i) { + if (ih_list == null) { + return new InstructionHandle(i); + } + final InstructionHandle ih = ih_list; + ih_list = ih.next; + ih.setInstruction(i); + return ih; + } - //if(!targeters.contains(t)) - targeters.add(t); - } + /** + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions()' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset additional offset caused by preceding (variable length) + * instructions + * @param max_offset the maximum offset that may be caused by these + * instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + protected int updatePosition(final int offset, final int max_offset) { + i_position += offset; + return 0; + } - public boolean hasTargeters() { - return (targeters != null) && (targeters.size() > 0); - } + /** + * @return the position, i.e., the byte code offset of the contained + * instruction. This is accurate only after InstructionList.setPositions() + * has been called. + */ + public int getPosition() { + return i_position; + } - /** - * @return null, if there are no targeters - */ - public InstructionTargeter[] getTargeters() { - if(!hasTargeters()) - return null; + /** + * Set the position, i.e., the byte code offset of the contained + * instruction. + */ + void setPosition(final int pos) { + i_position = pos; + } - InstructionTargeter[] t = new InstructionTargeter[targeters.size()]; - targeters.toArray(t); - return t; - } + /** + * Overridden in BranchHandle + */ + protected void addHandle() { + next = ih_list; + ih_list = this; + } - /** @return a (verbose) string representation of the contained instruction. - */ - public String toString(boolean verbose) { - return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose); - } + /** + * Delete contents, i.e., remove user access and make handle reusable. + */ + void dispose() { + next = prev = null; + instruction.dispose(); + instruction = null; + i_position = -1; + attributes = null; + removeAllTargeters(); + addHandle(); + } - /** @return a string representation of the contained instruction. - */ - public String toString() { - return toString(true); - } + /** + * Remove all targeters, if any. + */ + public void removeAllTargeters() { + if (targeters != null) { + targeters.clear(); + } + } - /** Add an attribute to an instruction handle. - * - * @param key the key object to store/retrieve the attribute - * @param attr the attribute to associate with this handle - */ - public void addAttribute(Object key, Object attr) { - if(attributes == null) - attributes = new HashMap(3); + /** + * Denote this handle isn't referenced anymore by t. + */ + public void removeTargeter(final InstructionTargeter t) { + if (targeters != null) { + targeters.remove(t); + } + } - attributes.put(key, attr); - } + /** + * Denote this handle is being referenced by t. + */ + public void addTargeter(final InstructionTargeter t) { + if (targeters == null) { + targeters = new HashSet<>(); + } + //if(!targeters.contains(t)) + targeters.add(t); + } - /** Delete an attribute of an instruction handle. - * - * @param key the key object to retrieve the attribute - */ - public void removeAttribute(Object key) { - if(attributes != null) - attributes.remove(key); - } + public boolean hasTargeters() { + return (targeters != null) && (targeters.size() > 0); + } - /** Get attribute of an instruction handle. - * - * @param key the key object to store/retrieve the attribute - */ - public Object getAttribute(Object key) { - if(attributes != null) - return attributes.get(key); + /** + * @return null, if there are no targeters + */ + public InstructionTargeter[] getTargeters() { + if (!hasTargeters()) { + return new InstructionTargeter[0]; + } + final InstructionTargeter[] t = new InstructionTargeter[targeters.size()]; + targeters.toArray(t); + return t; + } - return null; - } + /** + * @return a (verbose) string representation of the contained instruction. + */ + public String toString(final boolean verbose) { + return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose); + } - /** @return all attributes associated with this handle - */ - public Collection getAttributes() { - return attributes.values(); - } + /** + * @return a string representation of the contained instruction. + */ + @Override + public String toString() { + return toString(true); + } - /** Convenience method, simply calls accept() on the contained instruction. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - instruction.accept(v); - } + /** + * Add an attribute to an instruction handle. + * + * @param key the key object to store/retrieve the attribute + * @param attr the attribute to associate with this handle + */ + public void addAttribute(final Object key, final Object attr) { + if (attributes == null) { + attributes = new HashMap<>(3); + } + attributes.put(key, attr); + } + + /** + * Delete an attribute of an instruction handle. + * + * @param key the key object to retrieve the attribute + */ + public void removeAttribute(final Object key) { + if (attributes != null) { + attributes.remove(key); + } + } + + /** + * Get attribute of an instruction handle. + * + * @param key the key object to store/retrieve the attribute + */ + public Object getAttribute(final Object key) { + if (attributes != null) { + return attributes.get(key); + } + return null; + } + + /** + * @return all attributes associated with this handle + */ + public Collection getAttributes() { + if (attributes == null) { + attributes = new HashMap<>(3); + } + return attributes.values(); + } + + /** + * Convenience method, simply calls accept() on the contained instruction. + * + * @param v Visitor object + */ + public void accept(final Visitor v) { + instruction.accept(v); + } + + /** + * @param next the next to set + * @ since 6.0 + */ + final InstructionHandle setNext(final InstructionHandle next) { + this.next = next; + return next; + } + + /** + * @param prev the prev to set + * @ since 6.0 + */ + final InstructionHandle setPrev(final InstructionHandle prev) { + this.prev = prev; + return prev; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java index c5bf9b46555..1e5fa2f5771 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,1236 +17,1239 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.Constant; import com.sun.org.apache.bcel.internal.util.ByteSequence; -import java.io.*; -import java.util.Iterator; -import java.util.HashMap; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; /** * This class is a container for a list of Instruction objects. Instructions can - * be appended, inserted, moved, deleted, etc.. Instructions are being - * wrapped into InstructionHandles objects that - * are returned upon append/insert operations. They give the user - * (read only) access to the list structure, such that it can be traversed and - * manipulated in a controlled way. + * href="Instruction.html">Instruction objects. Instructions can be + * appended, inserted, moved, deleted, etc.. Instructions are being wrapped into + * InstructionHandles objects that are + * returned upon append/insert operations. They give the user (read only) access + * to the list structure, such that it can be traversed and manipulated in a + * controlled way. * * A list is finally dumped to a byte code array with getByteCode. * - * @author M. Dahm - * @see Instruction - * @see InstructionHandle + * @version $Id: InstructionList.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see Instruction + * @see InstructionHandle * @see BranchHandle */ -public class InstructionList implements Serializable { - private InstructionHandle start = null, end = null; - private int length = 0; // number of elements in list - private int[] byte_positions; // byte code offsets corresponding to instructions +public class InstructionList implements Iterable { + private InstructionHandle start = null; + private InstructionHandle end = null; + private int length = 0; // number of elements in list + private int[] byte_positions; // byte code offsets corresponding to instructions - /** - * Create (empty) instruction list. - */ - public InstructionList() {} - - /** - * Create instruction list containing one instruction. - * @param i initial instruction - */ - public InstructionList(Instruction i) { - append(i); - } - - /** - * Create instruction list containing one instruction. - * @param i initial instruction - */ - public InstructionList(BranchInstruction i) { - append(i); - } - - /** - * Initialize list with (nonnull) compound instruction. Consumes argument - * list, i.e., it becomes empty. - * - * @param c compound instruction (list) - */ - public InstructionList(CompoundInstruction c) { - append(c.getInstructionList()); - } - - /** - * Test for empty list. - */ - public boolean isEmpty() { return start == null; } // && end == null - - /** - * Find the target instruction (handle) that corresponds to the given target - * position (byte code offset). - * - * @param ihs array of instruction handles, i.e. il.getInstructionHandles() - * @param pos array of positions corresponding to ihs, i.e. il.getInstructionPositions() - * @param count length of arrays - * @param target target position to search for - * @return target position's instruction handle if available - */ - public static InstructionHandle findHandle(InstructionHandle[] ihs, - int[] pos, int count, - int target) { - int l=0, r = count - 1; - - /* Do a binary search since the pos array is orderd. + /** + * Create (empty) instruction list. */ - do { - int i = (l + r) / 2; - int j = pos[i]; + public InstructionList() { + } - if(j == target) // target found - return ihs[i]; - else if(target < j) // else constrain search area - r = i - 1; - else // target > j - l = i + 1; - } while(l <= r); - - return null; - } - - /** - * Get instruction handle for instruction at byte code position pos. - * This only works properly, if the list is freshly initialized from a byte array or - * setPositions() has been called before this method. - * - * @param pos byte code position to search for - * @return target position's instruction handle if available - */ - public InstructionHandle findHandle(int pos) { - InstructionHandle[] ihs = getInstructionHandles(); - return findHandle(ihs, byte_positions, length, pos); - } - - /** - * Initialize instruction list from byte array. - * - * @param code byte array containing the instructions - */ - public InstructionList(byte[] code) { - ByteSequence bytes = new ByteSequence(code); - InstructionHandle[] ihs = new InstructionHandle[code.length]; - int[] pos = new int[code.length]; // Can't be more than that - int count = 0; // Contains actual length - - /* Pass 1: Create an object for each byte code and append them - * to the list. + /** + * Create instruction list containing one instruction. + * + * @param i initial instruction */ - try { - while(bytes.available() > 0) { - // Remember byte offset and associate it with the instruction - int off = bytes.getIndex(); - pos[count] = off; + public InstructionList(final Instruction i) { + append(i); + } - /* Read one instruction from the byte stream, the byte position is set - * accordingly. + /** + * Create instruction list containing one instruction. + * + * @param i initial instruction + */ + public InstructionList(final BranchInstruction i) { + append(i); + } + + /** + * Initialize list with (nonnull) compound instruction. Consumes argument + * list, i.e., it becomes empty. + * + * @param c compound instruction (list) + */ + public InstructionList(final CompoundInstruction c) { + append(c.getInstructionList()); + } + + /** + * Test for empty list. + */ + public boolean isEmpty() { + return start == null; + } // && end == null + + /** + * Find the target instruction (handle) that corresponds to the given target + * position (byte code offset). + * + * @param ihs array of instruction handles, i.e. il.getInstructionHandles() + * @param pos array of positions corresponding to ihs, i.e. + * il.getInstructionPositions() + * @param count length of arrays + * @param target target position to search for + * @return target position's instruction handle if available + */ + public static InstructionHandle findHandle(final InstructionHandle[] ihs, final int[] pos, final int count, final int target) { + int l = 0; + int r = count - 1; + /* + * Do a binary search since the pos array is orderd. */ - Instruction i = Instruction.readInstruction(bytes); - InstructionHandle ih; - if(i instanceof BranchInstruction) // Use proper append() method - ih = append((BranchInstruction)i); - else - ih = append(i); - - ih.setPosition(off); - ihs[count] = ih; - - count++; - } - } catch(IOException e) { throw new ClassGenException(e.toString()); } - - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); - - /* Pass 2: Look for BranchInstruction and update their targets, i.e., - * convert offsets to instruction handles. - */ - for(int i=0; i < count; i++) { - if(ihs[i] instanceof BranchHandle) { - BranchInstruction bi = (BranchInstruction)ihs[i].instruction; - int target = bi.position + bi.getIndex(); /* Byte code position: - * relative -> absolute. */ - // Search for target position - InstructionHandle ih = findHandle(ihs, pos, count, target); - - if(ih == null) // Search failed - throw new ClassGenException("Couldn't find target for branch: " + bi); - - bi.setTarget(ih); // Update target - - // If it is a Select instruction, update all branch targets - if(bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - Select s = (Select)bi; - int[] indices = s.getIndices(); - - for(int j=0; j < indices.length; j++) { - target = bi.position + indices[j]; - ih = findHandle(ihs, pos, count, target); - - if(ih == null) // Search failed - throw new ClassGenException("Couldn't find target for switch: " + bi); - - s.setTarget(j, ih); // Update target - } - } - } - } - } - - /** - * Append another list after instruction (handle) ih contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param ih where to append the instruction list - * @param il Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(InstructionHandle ih, InstructionList il) { - if(il == null) - throw new ClassGenException("Appending null InstructionList"); - - if(il.isEmpty()) // Nothing to do - return ih; - - InstructionHandle next = ih.next, ret = il.start; - - ih.next = il.start; - il.start.prev = ih; - - il.end.next = next; - - if(next != null) // i == end ? - next.prev = il.end; - else - end = il.end; // Update end ... - - length += il.length; // Update length - - il.clear(); - - return ret; - } - - /** - * Append another list after instruction i contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(Instruction i, InstructionList il) { - InstructionHandle ih; - - if((ih = findInstruction2(i)) == null) // Also applies for empty list - throw new ClassGenException("Instruction " + i + - " is not contained in this list."); - - return append(ih, il); - } - - /** - * Append another list to this one. - * Consumes argument list, i.e., it becomes empty. - * - * @param il list to append to end of this list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(InstructionList il) { - if(il == null) - throw new ClassGenException("Appending null InstructionList"); - - if(il.isEmpty()) // Nothing to do - return null; - - if(isEmpty()) { - start = il.start; - end = il.end; - length = il.length; - - il.clear(); - - return start; - } else - return append(end, il); // was end.instruction - } - - /** - * Append an instruction to the end of this list. - * - * @param ih instruction to append - */ - private void append(InstructionHandle ih) { - if(isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } - else { - end.next = ih; - ih.prev = end; - ih.next = null; - end = ih; - } - - length++; // Update length - } - - /** - * Append an instruction to the end of this list. - * - * @param i instruction to append - * @return instruction handle of the appended instruction - */ - public InstructionHandle append(Instruction i) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - append(ih); - - return ih; - } - - /** - * Append a branch instruction to the end of this list. - * - * @param i branch instruction to append - * @return branch instruction handle of the appended instruction - */ - public BranchHandle append(BranchInstruction i) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - append(ih); - - return ih; - } - - /** - * Append a single instruction j after another instruction i, which - * must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to append after i in list - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(Instruction i, Instruction j) { - return append(i, new InstructionList(j)); - } - - /** - * Append a compound instruction, after instruction i. - * - * @param i Instruction in list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(Instruction i, CompoundInstruction c) { - return append(i, c.getInstructionList()); - } - - /** - * Append a compound instruction. - * - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(CompoundInstruction c) { - return append(c.getInstructionList()); - } - - /** - * Append a compound instruction. - * - * @param ih where to append the instruction list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction - */ - public InstructionHandle append(InstructionHandle ih, CompoundInstruction c) { - return append(ih, c.getInstructionList()); - } - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public InstructionHandle append(InstructionHandle ih, Instruction i) { - return append(ih, new InstructionList(i)); - } - - /** - * Append an instruction after instruction (handle) ih contained in this list. - * - * @param ih where to append the instruction list - * @param i Instruction to append - * @return instruction handle pointing to the first appended instruction - */ - public BranchHandle append(InstructionHandle ih, BranchInstruction i) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - - append(ih, il); - - return bh; - } - - /** - * Insert another list before Instruction handle ih contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param 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()) // Nothing to do - return ih; - - InstructionHandle prev = ih.prev, ret = il.start; - - ih.prev = il.end; - il.end.next = ih; - - il.start.prev = prev; - - if(prev != null) // ih == start ? - prev.next = il.start; - else - start = il.start; // Update start ... - - length += il.length; // Update length - - il.clear(); - - return ret; - } - - /** - * Insert another list. - * - * @param il list to insert before start of this list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionList il) { - if(isEmpty()) { - append(il); // Code is identical for this case - return start; - } - else - return insert(start, il); - } - - /** - * Insert an instruction at start of this list. - * - * @param ih instruction to insert - */ - private void insert(InstructionHandle ih) { - if(isEmpty()) { - start = end = ih; - ih.next = ih.prev = null; - } else { - start.prev = ih; - ih.next = start; - ih.prev = null; - start = ih; - } - - length++; - } - - /** - * Insert another list before Instruction i contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param i where to append the instruction list - * @param il Instruction list to insert - * @return instruction handle pointing to the first inserted instruction, - * i.e., il.getStart() - */ - public InstructionHandle insert(Instruction i, InstructionList il) { - InstructionHandle ih; - - if((ih = findInstruction1(i)) == null) - throw new ClassGenException("Instruction " + i + - " is not contained in this list."); - - return insert(ih, il); - } - - /** - * Insert an instruction at start of this list. - * - * @param i instruction to insert - * @return instruction handle of the inserted instruction - */ - public InstructionHandle insert(Instruction i) { - InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - insert(ih); - - return ih; - } - - /** - * Insert a branch instruction at start of this list. - * - * @param i branch instruction to insert - * @return branch instruction handle of the appended instruction - */ - public BranchHandle insert(BranchInstruction i) { - BranchHandle ih = BranchHandle.getBranchHandle(i); - insert(ih); - return ih; - } - - /** - * Insert a single instruction j before another instruction i, which - * must be in this list of course! - * - * @param i Instruction in list - * @param j Instruction to insert before i in list - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(Instruction i, Instruction j) { - return insert(i, new InstructionList(j)); - } - - /** - * Insert a compound instruction before instruction i. - * - * @param i Instruction in list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(Instruction i, CompoundInstruction c) { - return insert(i, c.getInstructionList()); - } - - /** - * Insert a compound instruction. - * - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(CompoundInstruction c) { - return insert(c.getInstructionList()); - } - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionHandle ih, Instruction i) { - return insert(ih, new InstructionList(i)); - } - - /** - * Insert a compound instruction. - * - * @param ih where to insert the instruction list - * @param c The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(InstructionHandle ih, CompoundInstruction c) { - return insert(ih, c.getInstructionList()); - } - - /** - * Insert an instruction before instruction (handle) ih contained in this list. - * - * @param ih where to insert to the instruction list - * @param i Instruction to insert - * @return instruction handle of the first inserted instruction - */ - public BranchHandle insert(InstructionHandle ih, BranchInstruction i) { - BranchHandle bh = BranchHandle.getBranchHandle(i); - InstructionList il = new InstructionList(); - il.append(bh); - - insert(ih, il); - - return bh; - } - - /** - * Take all instructions (handles) from "start" to "end" and append them after the - * new location "target". Of course, "end" must be after "start" and target must - * not be located withing this range. If you want to move something to the start of - * the list use null as value for target.
      - * Any instruction targeters pointing to handles within the block, keep their targets. - * - * @param start of moved block - * @param end of moved block - * @param target of moved block - */ - public void move(InstructionHandle start, InstructionHandle end, InstructionHandle target) { - // Step 1: Check constraints - - if((start == null) || (end == null)) - throw new ClassGenException("Invalid null handle: From " + start + " to " + end); - - if((target == start) || (target == end)) - throw new ClassGenException("Invalid range: From " + start + " to " + end + - " contains target " + target); - - for(InstructionHandle ih = start; ih != end.next; ih = ih.next) { - if(ih == null) // At end of list, end not found yet - throw new ClassGenException("Invalid range: From " + start + " to " + end); - else if(ih == target) // target may be null - 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 // start == this.start! - this.start = next; - - if(next != null) - next.prev = prev; - else // end == this.end! - 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. Throws TargetLostException when one of the removed instruction handles - * is still being targeted. - * - * @param prev where to start deleting (predecessor, exclusive) - * @param next where to end deleting (successor, exclusive) - */ - private void remove(InstructionHandle prev, InstructionHandle next) - throws TargetLostException - { - InstructionHandle first, last; // First and last deleted instruction - - if((prev == null) && (next == null)) { // singleton list - first = last = start; - start = end = null; - } else { - if(prev == null) { // At start of list - first = start; - start = next; - } else { - first = prev.next; - prev.next = next; - } - - if(next == null) { // At end of list - last = end; - end = prev; - } else { - last = next.prev; - next.prev = prev; - } - } - - first.prev = null; // Completely separated from rest of list - last.next = null; - - ArrayList target_vec = new ArrayList(); - - for(InstructionHandle ih=first; ih != null; ih = ih.next) - ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets - - StringBuffer buf = new StringBuffer("{ "); - for(InstructionHandle ih=first; ih != null; ih = next) { - next = ih.next; - length--; - - if(ih.hasTargeters()) { // Still got targeters? - target_vec.add(ih); - buf.append(ih.toString(true) + " "); - ih.next = ih.prev = null; - } else - ih.dispose(); - } - - buf.append("}"); - - if(!target_vec.isEmpty()) { - InstructionHandle[] targeted = new InstructionHandle[target_vec.size()]; - target_vec.toArray(targeted); - throw new TargetLostException(targeted, buf.toString()); - } - } - - /** - * Remove instruction from this list. The corresponding Instruction - * handles must not be reused! - * - * @param ih instruction (handle) to remove - */ - public void delete(InstructionHandle ih) throws TargetLostException { - remove(ih.prev, ih.next); - } - - /** - * Remove instruction from this list. The corresponding Instruction - * handles must not be reused! - * - * @param i instruction to remove - */ - public void delete(Instruction i) throws TargetLostException { - InstructionHandle ih; - - if((ih = findInstruction1(i)) == null) - throw new ClassGenException("Instruction " + i + - " is not contained in this list."); - delete(ih); - } - - /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete(InstructionHandle from, InstructionHandle to) - throws TargetLostException - { - remove(from.prev, to.next); - } - - /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from where to start deleting (inclusive) - * @param to where to end deleting (inclusive) - */ - public void delete(Instruction from, Instruction to) throws TargetLostException { - InstructionHandle from_ih, to_ih; - - if((from_ih = findInstruction1(from)) == null) - throw new ClassGenException("Instruction " + from + - " is not contained in this list."); - - if((to_ih = findInstruction2(to)) == null) - throw new ClassGenException("Instruction " + to + - " is not contained in this list."); - delete(from_ih, to_ih); - } - - /** - * Search for given Instruction reference, start at beginning of list. - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction1(Instruction i) { - for(InstructionHandle ih=start; ih != null; ih = ih.next) - if(ih.instruction == i) - return ih; - - return null; - } - - /** - * Search for given Instruction reference, start at end of list - * - * @param i instruction to search for - * @return instruction found on success, null otherwise - */ - private InstructionHandle findInstruction2(Instruction i) { - for(InstructionHandle ih=end; ih != null; ih = ih.prev) - if(ih.instruction == i) - return ih; - - return null; - } - - public boolean contains(InstructionHandle i) { - if(i == null) - return false; - - for(InstructionHandle ih=start; ih != null; ih = ih.next) - if(ih == i) - return true; - - return false; - } - - public boolean contains(Instruction i) { - return findInstruction1(i) != null; - } - - public void setPositions() { - setPositions(false); - } - - /** - * Give all instructions their position number (offset in byte stream), i.e., - * make the list ready to be dumped. - * - * @param check Perform sanity checks, e.g. if all targeted instructions really belong - * to this list - */ - public void setPositions(boolean check) { - int max_additional_bytes = 0, additional_bytes = 0; - int index = 0, count = 0; - int[] pos = new int[length]; - - /* Pass 0: Sanity checks - */ - if(check) { - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - - if(i instanceof BranchInstruction) { // target instruction within list? - Instruction inst = ((BranchInstruction)i).getTarget().instruction; - if(!contains(inst)) - throw new ClassGenException("Branch target of " + - Constants.OPCODE_NAMES[i.opcode] + ":" + - inst + " not in instruction list"); - - if(i instanceof Select) { - InstructionHandle[] targets = ((Select)i).getTargets(); - - for(int j=0; j < targets.length; j++) { - inst = targets[j].instruction; - if(!contains(inst)) - throw new ClassGenException("Branch target of " + - Constants.OPCODE_NAMES[i.opcode] + ":" + - inst + " not in instruction list"); + do { + final int i = (l + r) / 2; + final int j = pos[i]; + if (j == target) { + return ihs[i]; + } else if (target < j) { + r = i - 1; + } else { + l = i + 1; } - } + } while (l <= r); + return null; + } - if(!(ih instanceof BranchHandle)) - throw new ClassGenException("Branch instruction " + - Constants.OPCODE_NAMES[i.opcode] + ":" + + /** + * 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(final int pos) { + final int[] positions = byte_positions; + InstructionHandle ih = start; + for (int i = 0; i < length; i++) { + if (positions[i] == pos) { + return ih; + } + ih = ih.getNext(); + } + return null; + } + + /** + * Initialize instruction list from byte array. + * + * @param code byte array containing the instructions + */ + public InstructionList(final byte[] code) { + int count = 0; // Contains actual length + int[] pos; + InstructionHandle[] ihs; + try (ByteSequence bytes = new ByteSequence(code)) { + ihs = new InstructionHandle[code.length]; + pos = new int[code.length]; // Can't be more than that + /* + * Pass 1: Create an object for each byte code and append them to the list. + */ + while (bytes.available() > 0) { + // Remember byte offset and associate it with the instruction + final int off = bytes.getIndex(); + pos[count] = off; + /* + * Read one instruction from the byte stream, the byte position is set accordingly. + */ + final Instruction i = Instruction.readInstruction(bytes); + InstructionHandle ih; + if (i instanceof BranchInstruction) { + ih = append((BranchInstruction) i); + } else { + ih = append(i); + } + ih.setPosition(off); + ihs[count] = ih; + count++; + } + } catch (final IOException e) { + throw new ClassGenException(e.toString(), e); + } + byte_positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, byte_positions, 0, count); + /* + * Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles. + */ + for (int i = 0; i < count; i++) { + if (ihs[i] instanceof BranchHandle) { + final BranchInstruction bi = (BranchInstruction) ihs[i].getInstruction(); + int target = bi.getPosition() + bi.getIndex(); /* + * Byte code position: relative -> absolute. + */ + + // Search for target position + + InstructionHandle ih = findHandle(ihs, pos, count, target); + if (ih == null) { + throw new ClassGenException("Couldn't find target for branch: " + bi); + } + bi.setTarget(ih); // Update target + // If it is a Select instruction, update all branch targets + if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final Select s = (Select) bi; + final int[] indices = s.getIndices(); + for (int j = 0; j < indices.length; j++) { + target = bi.getPosition() + indices[j]; + ih = findHandle(ihs, pos, count, target); + if (ih == null) { + throw new ClassGenException("Couldn't find target for switch: " + bi); + } + s.setTarget(j, ih); // Update target + } + } + } + } + } + + /** + * Append another list after instruction (handle) ih contained in this list. + * Consumes argument list, i.e., it becomes empty. + * + * @param ih where to append the instruction list + * @param il Instruction list to append to this one + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(final InstructionHandle ih, final InstructionList il) { + if (il == null) { + throw new ClassGenException("Appending null InstructionList"); + } + if (il.isEmpty()) { + return ih; + } + final InstructionHandle next = ih.getNext(); + final InstructionHandle ret = il.start; + ih.setNext(il.start); + il.start.setPrev(ih); + il.end.setNext(next); + if (next != null) { + next.setPrev(il.end); + } else { + end = il.end; // Update end ... + } + length += il.length; // Update length + il.clear(); + return ret; + } + + /** + * Append another list after instruction i contained in this list. Consumes + * argument list, i.e., it becomes empty. + * + * @param i where to append the instruction list + * @param il Instruction list to append to this one + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(final Instruction i, final InstructionList il) { + InstructionHandle ih; + if ((ih = findInstruction2(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + return append(ih, il); + } + + /** + * Append another list to this one. Consumes argument list, i.e., it becomes + * empty. + * + * @param il list to append to end of this list + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final InstructionList il) { + if (il == null) { + throw new ClassGenException("Appending null InstructionList"); + } + if (il.isEmpty()) { + return null; + } + if (isEmpty()) { + start = il.start; + end = il.end; + length = il.length; + il.clear(); + return start; + } + return append(end, il); // was end.instruction + } + + /** + * Append an instruction to the end of this list. + * + * @param ih instruction to append + */ + private void append(final InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.setNext(ih.setPrev(null)); + } else { + end.setNext(ih); + ih.setPrev(end); + ih.setNext(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(final Instruction i) { + final InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + append(ih); + return ih; + } + + /** + * Append a branch instruction to the end of this list. + * + * @param i branch instruction to append + * @return branch instruction handle of the appended instruction + */ + public BranchHandle append(final BranchInstruction i) { + final 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(final Instruction i, final Instruction j) { + return append(i, new InstructionList(j)); + } + + /** + * Append a compound instruction, after instruction i. + * + * @param i Instruction in list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final Instruction i, final CompoundInstruction c) { + return append(i, c.getInstructionList()); + } + + /** + * Append a compound instruction. + * + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final CompoundInstruction c) { + return append(c.getInstructionList()); + } + + /** + * Append a compound instruction. + * + * @param ih where to append the instruction list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction + */ + public InstructionHandle append(final InstructionHandle ih, final CompoundInstruction c) { + return append(ih, c.getInstructionList()); + } + + /** + * Append an instruction after instruction (handle) ih contained in this + * list. + * + * @param ih where to append the instruction list + * @param i Instruction to append + * @return instruction handle pointing to the first appended + * instruction + */ + public InstructionHandle append(final InstructionHandle ih, final Instruction i) { + return append(ih, new InstructionList(i)); + } + + /** + * Append an instruction after instruction (handle) ih contained in this + * list. + * + * @param ih where to append the instruction list + * @param i Instruction to append + * @return instruction handle pointing to the first appended + * instruction + */ + public BranchHandle append(final InstructionHandle ih, final BranchInstruction i) { + final BranchHandle bh = BranchHandle.getBranchHandle(i); + final InstructionList il = new InstructionList(); + il.append(bh); + append(ih, il); + return bh; + } + + /** + * Insert another list before Instruction handle ih contained in this list. + * Consumes argument list, i.e., it becomes empty. + * + * @param ih where to append the instruction list + * @param il Instruction list to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final InstructionList il) { + if (il == null) { + throw new ClassGenException("Inserting null InstructionList"); + } + if (il.isEmpty()) { + return ih; + } + final InstructionHandle prev = ih.getPrev(); + final InstructionHandle ret = il.start; + ih.setPrev(il.end); + il.end.setNext(ih); + il.start.setPrev(prev); + if (prev != null) { + prev.setNext(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(final InstructionList il) { + if (isEmpty()) { + append(il); // Code is identical for this case + return start; + } + return insert(start, il); + } + + /** + * Insert an instruction at start of this list. + * + * @param ih instruction to insert + */ + private void insert(final InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.setNext(ih.setPrev(null)); + } else { + start.setPrev(ih); + ih.setNext(start); + ih.setPrev(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(final Instruction i, final 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(final Instruction i) { + final 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(final BranchInstruction i) { + final 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(final Instruction i, final Instruction j) { + return insert(i, new InstructionList(j)); + } + + /** + * Insert a compound instruction before instruction i. + * + * @param i Instruction in list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final Instruction i, final CompoundInstruction c) { + return insert(i, c.getInstructionList()); + } + + /** + * Insert a compound instruction. + * + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final CompoundInstruction c) { + return insert(c.getInstructionList()); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this + * list. + * + * @param ih where to insert to the instruction list + * @param i Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final Instruction i) { + return insert(ih, new InstructionList(i)); + } + + /** + * Insert a compound instruction. + * + * @param ih where to insert the instruction list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final CompoundInstruction c) { + return insert(ih, c.getInstructionList()); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this + * list. + * + * @param ih where to insert to the instruction list + * @param i Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public BranchHandle insert(final InstructionHandle ih, final BranchInstruction i) { + final BranchHandle bh = BranchHandle.getBranchHandle(i); + final InstructionList il = new InstructionList(); + il.append(bh); + insert(ih, il); + return bh; + } + + /** + * Take all instructions (handles) from "start" to "end" and append them + * after the new location "target". Of course, "end" must be after "start" + * and target must not be located withing this range. If you want to move + * something to the start of the list use null as value for target.
      + * Any instruction targeters pointing to handles within the block, keep + * their targets. + * + * @param start of moved block + * @param end of moved block + * @param target of moved block + */ + public void move(final InstructionHandle start, final InstructionHandle end, final 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.getNext(); ih = ih.getNext()) { + 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 + final InstructionHandle prev = start.getPrev(); + InstructionHandle next = end.getNext(); + if (prev != null) { + prev.setNext(next); + } else { + this.start = next; + } + if (next != null) { + next.setPrev(prev); + } else { + this.end = prev; + } + start.setPrev(end.setNext(null)); + // Step 3: append after target + if (target == null) { // append to start of list + if (this.start != null) { + this.start.setPrev(end); + } + end.setNext(this.start); + this.start = start; + } else { + next = target.getNext(); + target.setNext(start); + start.setPrev(target); + end.setNext(next); + if (next != null) { + next.setPrev(end); + } else { + this.end = end; + } + } + } + + /** + * Move a single instruction (handle) to a new location. + * + * @param ih moved instruction + * @param target new location of moved instruction + */ + public void move(final InstructionHandle ih, final InstructionHandle target) { + move(ih, ih, target); + } + + /** + * Remove from instruction `prev' to instruction `next' both contained in + * this list. Throws TargetLostException when one of the removed instruction + * handles is still being targeted. + * + * @param prev where to start deleting (predecessor, exclusive) + * @param next where to end deleting (successor, exclusive) + */ + private void remove(final InstructionHandle prev, InstructionHandle next) throws TargetLostException { + InstructionHandle first; + InstructionHandle last; // First and last deleted instruction + if ((prev == null) && (next == null)) { + first = start; + last = end; + start = end = null; + } else { + if (prev == null) { // At start of list + first = start; + start = next; + } else { + first = prev.getNext(); + prev.setNext(next); + } + if (next == null) { // At end of list + last = end; + end = prev; + } else { + last = next.getPrev(); + next.setPrev(prev); + } + } + first.setPrev(null); // Completely separated from rest of list + last.setNext(null); + final List target_vec = new ArrayList<>(); + for (InstructionHandle ih = first; ih != null; ih = ih.getNext()) { + ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets + } + final StringBuilder buf = new StringBuilder("{ "); + for (InstructionHandle ih = first; ih != null; ih = next) { + next = ih.getNext(); + length--; + if (ih.hasTargeters()) { // Still got targeters? + target_vec.add(ih); + buf.append(ih.toString(true)).append(" "); + ih.setNext(ih.setPrev(null)); + } else { + ih.dispose(); + } + } + buf.append("}"); + if (!target_vec.isEmpty()) { + final 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(final InstructionHandle ih) throws TargetLostException { + remove(ih.getPrev(), ih.getNext()); + } + + /** + * Remove instruction from this list. The corresponding Instruction handles + * must not be reused! + * + * @param i instruction to remove + */ + public void delete(final 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(final InstructionHandle from, final InstructionHandle to) throws TargetLostException { + remove(from.getPrev(), to.getNext()); + } + + /** + * 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(final Instruction from, final Instruction to) throws TargetLostException { + InstructionHandle from_ih; + InstructionHandle 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(final Instruction i) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + if (ih.getInstruction() == 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(final Instruction i) { + for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { + if (ih.getInstruction() == i) { + return ih; + } + } + return null; + } + + public boolean contains(final InstructionHandle i) { + if (i == null) { + return false; + } + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + if (ih == i) { + return true; + } + } + return false; + } + + public boolean contains(final Instruction i) { + return findInstruction1(i) != null; + } + + public void setPositions() { // TODO could be package-protected? (some test code would need to be repackaged) + 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(final boolean check) { // called by code in other packages + int max_additional_bytes = 0; + int additional_bytes = 0; + int index = 0; + int count = 0; + final int[] pos = new int[length]; + /* + * Pass 0: Sanity checks + */ + if (check) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { // target instruction within list? + Instruction inst = ((BranchInstruction) i).getTarget().getInstruction(); + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + + Const.getOpcodeName(i.getOpcode()) + ":" + + inst + " not in instruction list"); + } + if (i instanceof Select) { + final InstructionHandle[] targets = ((Select) i).getTargets(); + for (final InstructionHandle target : targets) { + inst = target.getInstruction(); + if (!contains(inst)) { + throw new ClassGenException("Branch target of " + + Const.getOpcodeName(i.getOpcode()) + ":" + + inst + " not in instruction list"); + } + } + } + if (!(ih instanceof BranchHandle)) { + throw new ClassGenException( + "Branch instruction " + + Const.getOpcodeName(i.getOpcode()) + ":" + inst + " not contained in BranchHandle."); - + } + } + } } - } - } + /* + * Pass 1: Set position numbers and sum up the maximum number of bytes an instruction may be shifted. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - /* 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; + final Instruction i = ih.getInstruction(); + ih.setPosition(index); + pos[count++] = index; - ih.setPosition(index); - pos[count++] = index; - - /* Get an estimate about how many additional bytes may be added, because - * BranchInstructions may have variable length depending on the target - * offset (short vs. int) or alignment issues (TABLESWITCH and - * LOOKUPSWITCH). - */ - switch(i.getOpcode()) { - case Constants.JSR: case Constants.GOTO: - max_additional_bytes += 2; - break; - - case Constants.TABLESWITCH: case Constants.LOOKUPSWITCH: - max_additional_bytes += 3; - break; - } - - index += i.getLength(); - } - - /* Pass 2: Expand the variable-length (Branch)Instructions depending on - * the target offset (short or int) and ensure that branch targets are - * within this list. - */ - for(InstructionHandle ih=start; ih != null; ih = ih.next) - additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes); - - /* Pass 3: Update position numbers (which may have changed due to the - * preceding expansions), like pass 1. - */ - index=count=0; - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - - ih.setPosition(index); - pos[count++] = index; - index += i.getLength(); - } - - byte_positions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, byte_positions, 0, count); - } - - /** - * When everything is finished, use this method to convert the instruction - * list into an array of bytes. - * - * @return the byte code ready to be dumped - */ - public byte[] getByteCode() { - // Update position indices of instructions - setPositions(); - - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(b); - - try { - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - i.dump(out); // Traverse list - } - } catch(IOException e) { - System.err.println(e); - return null; - } - - return b.toByteArray(); - } - - /** - * @return an array of instructions without target information for branch instructions. - */ - public Instruction[] getInstructions() { - ByteSequence bytes = new ByteSequence(getByteCode()); - ArrayList instructions = new ArrayList(); - - 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; - } - - 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 byte_positions; } - - /** - * @return complete, i.e., deep copy of this list - */ - public InstructionList copy() { - HashMap map = new HashMap(); - InstructionList il = new InstructionList(); - - /* Pass 1: Make copies of all instructions, append them to the new list - * and associate old instruction references with the new ones, i.e., - * a 1:1 mapping. - */ - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - Instruction c = i.copy(); // Use clone for shallow copy - - if(c instanceof BranchInstruction) - map.put(ih, il.append((BranchInstruction)c)); - else - map.put(ih, il.append(c)); - } - - /* Pass 2: Update branch targets. - */ - InstructionHandle ih=start; - InstructionHandle ch=il.start; - - while(ih != null) { - Instruction i = ih.instruction; - Instruction c = ch.instruction; - - if(i instanceof BranchInstruction) { - BranchInstruction bi = (BranchInstruction)i; - BranchInstruction bc = (BranchInstruction)c; - InstructionHandle itarget = bi.getTarget(); // old target - - // New target is in hash map - bc.setTarget((InstructionHandle)map.get(itarget)); - - if(bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] itargets = ((Select)bi).getTargets(); - InstructionHandle[] ctargets = ((Select)bc).getTargets(); - - for(int j=0; j < itargets.length; j++) { // Update all targets - ctargets[j] = (InstructionHandle)map.get(itargets[j]); - } + /* + * Get an estimate about how many additional bytes may be added, + * because BranchInstructions may have variable length depending on the target offset + * (short vs. int) or alignment issues (TABLESWITCH and LOOKUPSWITCH). + */ + switch (i.getOpcode()) { + case Const.JSR: + case Const.GOTO: + max_additional_bytes += 2; + break; + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: + max_additional_bytes += 3; + break; + } + index += i.getLength(); } - } - ih = ih.next; - ch = ch.next; - } - - return il; - } - - /** Replace all references to the old constant pool with references to the new - * constant pool - */ - public void replaceConstantPool(ConstantPoolGen old_cp, ConstantPoolGen new_cp) { - for(InstructionHandle ih=start; ih != null; ih = ih.next) { - Instruction i = ih.instruction; - - if(i instanceof CPInstruction) { - CPInstruction ci = (CPInstruction)i; - Constant c = old_cp.getConstant(ci.getIndex()); - ci.setIndex(new_cp.addConstant(c, old_cp)); - } - } - } - - private void clear() { - start = end = null; - length = 0; - } - - /** - * Delete contents of list. Provides besser memory utilization, - * because the system then may reuse the instruction handles. This - * method is typically called right after - * MethodGen.getMethod(). - */ - public void dispose() { - // Traverse in reverse order, because ih.next is overwritten - for(InstructionHandle ih=end; ih != null; ih = ih.prev) - /* Causes BranchInstructions to release target and targeters, because it - * calls dispose() on the contained instruction. - */ - ih.dispose(); - - clear(); - } - - /** - * @return start of list - */ - public InstructionHandle getStart() { return start; } - - /** - * @return end of list - */ - public InstructionHandle getEnd() { return end; } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int getLength() { return length; } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int size() { return length; } - - /** - * Redirect all references from old_target to new_target, i.e., update targets - * of branch instructions. - * - * @param old_target the old target instruction handle - * @param new_target the new target instruction handle - */ - public void redirectBranches(InstructionHandle old_target, - InstructionHandle new_target) { - for(InstructionHandle ih = start; ih != null; ih = ih.next) { - Instruction i = ih.getInstruction(); - - if(i instanceof BranchInstruction) { - BranchInstruction b = (BranchInstruction)i; - InstructionHandle target = b.getTarget(); - - if(target == old_target) - b.setTarget(new_target); - - if(b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - InstructionHandle[] targets = ((Select)b).getTargets(); - - for(int j=0; j < targets.length; j++) // Update targets - if(targets[j] == old_target) - ((Select)b).setTarget(j, new_target); + /* Pass 2: Expand the variable-length (Branch)Instructions depending on + * the target offset (short or int) and ensure that branch targets are + * within this list. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes); + } + /* + * Pass 3: Update position numbers (which may have changed due to the + * preceding expansions), like pass 1. + */ + index = count = 0; + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + + ih.setPosition(index); + pos[count++] = index; + index += i.getLength(); + } + if (length == count) { + byte_positions = pos; + } else { + byte_positions = new int[count]; // Trim to proper size + System.arraycopy(pos, 0, byte_positions, 0, count); } - } } - } - /** - * 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); + /** + * 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(); + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + final DataOutputStream out = new DataOutputStream(b); + try { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + i.dump(out); // Traverse list + } + out.flush(); + } catch (final IOException e) { + System.err.println(e); + return new byte[0]; + } + return b.toByteArray(); } - } - /** - * 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); + /** + * @return an array of instructions without target information for branch + * instructions. + */ + public Instruction[] getInstructions() { + final List instructions = new ArrayList<>(); + try (ByteSequence bytes = new ByteSequence(getByteCode())) { + while (bytes.available() > 0) { + instructions.add(Instruction.readInstruction(bytes)); + } + } catch (final IOException e) { + throw new ClassGenException(e.toString(), e); + } + return instructions.toArray(new Instruction[instructions.size()]); } - } - private ArrayList observers; + @Override + public String toString() { + return toString(true); + } - /** Add observer for this object. - */ - public void addObserver(InstructionListObserver o) { - if(observers == null) - observers = new ArrayList(); + /** + * @param verbose toggle output format + * @return String containing all instructions in this list. + */ + public String toString(final boolean verbose) { + final StringBuilder buf = new StringBuilder(); + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + buf.append(ih.toString(verbose)).append("\n"); + } + return buf.toString(); + } - observers.add(o); - } + /** + * @return iterator that lists all instructions (handles) + */ + @Override + public Iterator iterator() { + return new Iterator() { - /** Remove observer for this object. - */ - public void removeObserver(InstructionListObserver o) { - if(observers != null) - observers.remove(o); - } + private InstructionHandle ih = start; - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if(observers != null) - for(Iterator e = observers.iterator(); e.hasNext(); ) - ((InstructionListObserver)e.next()).notify(this); - } + @Override + public InstructionHandle next() throws NoSuchElementException { + if (ih == null) { + throw new NoSuchElementException(); + } + final InstructionHandle i = ih; + ih = ih.getNext(); + return i; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + return ih != null; + } + }; + } + + /** + * @return array containing all instructions (handles) + */ + public InstructionHandle[] getInstructionHandles() { + final InstructionHandle[] ihs = new InstructionHandle[length]; + InstructionHandle ih = start; + for (int i = 0; i < length; i++) { + ihs[i] = ih; + ih = ih.getNext(); + } + return ihs; + } + + /** + * Get positions (offsets) of all instructions in the list. This relies on + * that the list has been freshly created from an byte code array, or that + * setPositions() has been called. Otherwise this may be inaccurate. + * + * @return array containing all instruction's offset in byte code + */ + public int[] getInstructionPositions() { + return byte_positions; + } + + /** + * @return complete, i.e., deep copy of this list + */ + public InstructionList copy() { + final Map map = new HashMap<>(); + final 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.getNext()) { + final Instruction i = ih.getInstruction(); + final Instruction c = i.copy(); // Use clone for shallow copy + if (c instanceof BranchInstruction) { + map.put(ih, il.append((BranchInstruction) c)); + } else { + map.put(ih, il.append(c)); + } + } + /* + * Pass 2: Update branch targets. + */ + InstructionHandle ih = start; + InstructionHandle ch = il.start; + while (ih != null) { + final Instruction i = ih.getInstruction(); + final Instruction c = ch.getInstruction(); + if (i instanceof BranchInstruction) { + final BranchInstruction bi = (BranchInstruction) i; + final BranchInstruction bc = (BranchInstruction) c; + final InstructionHandle itarget = bi.getTarget(); // old target + // New target is in hash map + bc.setTarget(map.get(itarget)); + if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final InstructionHandle[] itargets = ((Select) bi).getTargets(); + final InstructionHandle[] ctargets = ((Select) bc).getTargets(); + for (int j = 0; j < itargets.length; j++) { // Update all targets + ctargets[j] = map.get(itargets[j]); + } + } + } + ih = ih.getNext(); + ch = ch.getNext(); + } + return il; + } + + /** + * Replace all references to the old constant pool with references to the + * new constant pool + */ + public void replaceConstantPool(final ConstantPoolGen old_cp, final ConstantPoolGen new_cp) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof CPInstruction) { + final CPInstruction ci = (CPInstruction) i; + final 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 {@link MethodGen#getMethod()}. + */ + public void dispose() { + // Traverse in reverse order, because ih.next is overwritten + for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { + /* + * 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(final InstructionHandle old_target, + final InstructionHandle new_target) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { + final BranchInstruction b = (BranchInstruction) i; + final InstructionHandle target = b.getTarget(); + if (target == old_target) { + b.setTarget(new_target); + } + if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final InstructionHandle[] targets = ((Select) b).getTargets(); + for (int j = 0; j < targets.length; j++) { + if (targets[j] == old_target) { + ((Select) b).setTarget(j, new_target); + } + } + } + } + } + } + + /** + * Redirect all references of local variables from old_target to new_target. + * + * @param lg array of local variables + * @param old_target the old target instruction handle + * @param new_target the new target instruction handle + * @see MethodGen + */ + public void redirectLocalVariables(final LocalVariableGen[] lg, + final InstructionHandle old_target, final InstructionHandle new_target) { + for (final LocalVariableGen element : lg) { + final InstructionHandle start = element.getStart(); + final InstructionHandle end = element.getEnd(); + if (start == old_target) { + element.setStart(new_target); + } + if (end == old_target) { + element.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(final CodeExceptionGen[] exceptions, + final InstructionHandle old_target, final InstructionHandle new_target) { + for (final CodeExceptionGen exception : exceptions) { + if (exception.getStartPC() == old_target) { + exception.setStartPC(new_target); + } + if (exception.getEndPC() == old_target) { + exception.setEndPC(new_target); + } + if (exception.getHandlerPC() == old_target) { + exception.setHandlerPC(new_target); + } + } + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final InstructionListObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final InstructionListObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final InstructionListObserver observer : observers) { + observer.notify(this); + } + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java index e9721ed6c42..3038ba5a8d5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Implement this interface if you're interested in changes to an InstructionList object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: InstructionListObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface InstructionListObserver { - public void notify(InstructionList list); + + void notify( InstructionList list ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java index 1d8d25a6a68..6ff6aef3cab 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java @@ -21,7 +21,6 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote that a class targets InstructionHandles within an InstructionList. Namely * the following implementers: @@ -29,9 +28,21 @@ package com.sun.org.apache.bcel.internal.generic; * @see BranchHandle * @see LocalVariableGen * @see CodeExceptionGen - * @author M. Dahm + * @version $Id: InstructionTargeter.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface InstructionTargeter { - public boolean containsTarget(InstructionHandle ih); - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih); + + /** + * Checks whether this targeter targets the specified instruction handle. + */ + boolean containsTarget(InstructionHandle ih); + + /** + * Replaces the target of this targeter from this old handle to the new handle. + * + * @param old_ih the old handle + * @param new_ih the new handle + * @throws ClassGenException if old_ih is not targeted by this object + */ + void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) throws ClassGenException; } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java index 592d11d6ecc..57fc9204d51 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java @@ -21,93 +21,124 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.StringTokenizer; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; + /** * Super class for the INVOKExxx family of instructions. * - * @author M. Dahm + * @version $Id: InvokeInstruction.java 1752106 2016-07-10 20:02:39Z britter $ */ -public abstract class InvokeInstruction extends FieldOrMethod - implements ExceptionThrower, TypedInstruction, StackConsumer, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - InvokeInstruction() {} +public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower, + StackConsumer, StackProducer { - /** - * @param index to constant pool - */ - protected InvokeInstruction(short opcode, int index) { - super(opcode, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + InvokeInstruction() { + } - /** - * @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(); - } + /** + * @param index to constant pool + */ + protected InvokeInstruction(final short opcode, final int index) { + super(opcode, index); + } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words consumed from stack by this instruction - */ - public int consumeStack(ConstantPoolGen cpg) { - String signature = getSignature(cpg); - Type[] args = Type.getArgumentTypes(signature); - int sum; - if(opcode == Constants.INVOKESTATIC) - sum = 0; - else - sum = 1; // this reference + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final ConstantPool cp ) { + final Constant c = cp.getConstant(super.getIndex()); + final StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); + return Const.getOpcodeName(super.getOpcode()) + " " + tok.nextToken().replace('.', '/') + + tok.nextToken(); + } - int n = args.length; - for (int i = 0; i < n; i++) - sum += args[i].getSize(); - return sum; - } + /** + * Also works for instructions whose stack effect depends on the + * constant pool entry they reference. + * @return Number of words consumed from stack by this instruction + */ + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + int sum; + if ((super.getOpcode() == Const.INVOKESTATIC) || (super.getOpcode() == Const.INVOKEDYNAMIC)) { + sum = 0; + } else { + sum = 1; // this reference + } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words produced onto stack by this instruction - */ - public int produceStack(ConstantPoolGen cpg) { - return getReturnType(cpg).getSize(); - } + final String signature = getSignature(cpg); + sum += Type.getArgumentTypesSize(signature); + return sum; + } - /** @return return type of referenced method. - */ - public Type getType(ConstantPoolGen cpg) { - return getReturnType(cpg); - } - /** @return name of referenced method. - */ - public String getMethodName(ConstantPoolGen cpg) { - return getName(cpg); - } + /** + * Also works for instructions whose stack effect depends on the + * constant pool entry they reference. + * @return Number of words produced onto stack by this instruction + */ + @Override + public int produceStack( final ConstantPoolGen cpg ) { + final String signature = getSignature(cpg); + return Type.getReturnTypeSize(signature); + } - /** @return return type of referenced method. - */ - public Type getReturnType(ConstantPoolGen cpg) { - return Type.getReturnType(getSignature(cpg)); - } + /** + * This overrides the deprecated version as we know here that the referenced class + * may legally be an array. + * + * @deprecated in FieldOrMethod + * + * @return name of the referenced class/interface + * @throws IllegalArgumentException if the referenced class is an array (this should not happen) + */ + @Override + @Deprecated + public String getClassName( final ConstantPoolGen cpg ) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class); + return className.replace('/', '.'); + } + + /** @return return type of referenced method. + */ + @Override + public Type getType( final ConstantPoolGen cpg ) { + return getReturnType(cpg); + } + + + /** @return name of referenced method. + */ + public String getMethodName( final ConstantPoolGen cpg ) { + return getName(cpg); + } + + + /** @return return type of referenced method. + */ + public Type getReturnType( final ConstantPoolGen cpg ) { + return Type.getReturnType(getSignature(cpg)); + } + + + /** @return argument types of referenced method. + */ + public Type[] getArgumentTypes( final ConstantPoolGen cpg ) { + return Type.getArgumentTypes(getSignature(cpg)); + } - /** @return argument types of referenced method. - */ - public Type[] getArgumentTypes(ConstantPoolGen cpg) { - return Type.getArgumentTypes(getSignature(cpg)); - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java index babfc422dba..fa32244b4b1 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java @@ -21,66 +21,74 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; /** * JSR - Jump to subroutine * - * @author M. Dahm + * @version $Id: JSR.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class JSR extends JsrInstruction implements VariableLengthInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JSR() {} - public JSR(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.JSR, target); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - if(opcode == com.sun.org.apache.bcel.internal.Constants.JSR) - super.dump(out); - else { // JSR_W - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - } - - protected int updatePosition(int offset, int max_offset) { - int i = getTargetOffset(); // Depending on old position value - - position += offset; // Position may be shifted by preceding expansions - - if(Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate) - opcode = com.sun.org.apache.bcel.internal.Constants.JSR_W; - length = 5; - return 2; // 5 - 3 + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JSR() { } - return 0; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitVariableLengthInstruction(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR(this); - } + public JSR(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.JSR, target); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + if (super.getOpcode() == com.sun.org.apache.bcel.internal.Const.JSR) { + super.dump(out); + } else { // JSR_W + super.setIndex(getTargetOffset()); + out.writeByte(super.getOpcode()); + out.writeInt(super.getIndex()); + } + } + + + @Override + protected int updatePosition( final int offset, final int max_offset ) { + final int i = getTargetOffset(); // Depending on old position value + setPosition(getPosition() + offset); // Position may be shifted by preceding expansions + if (Math.abs(i) >= (Short.MAX_VALUE - max_offset)) { // to large for short (estimate) + super.setOpcode(com.sun.org.apache.bcel.internal.Const.JSR_W); + final short old_length = (short) super.getLength(); + super.setLength(5); + return super.getLength() - old_length; + } + return 0; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitVariableLengthInstruction(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java index 2776c513e5f..69fd91afaf2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java @@ -21,57 +21,67 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * JSR_W - Jump to subroutine * - * @author M. Dahm + * @version $Id: JSR_W.java 1747278 2016-06-07 17:28:43Z britter $ */ public class JSR_W extends JsrInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JSR_W() {} - public JSR_W(InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.JSR_W, target); - length = 5; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JSR_W() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - index = getTargetOffset(); - out.writeByte(opcode); - out.writeInt(index); - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - index = bytes.readInt(); - length = 5; - } + public JSR_W(final InstructionHandle target) { + super(com.sun.org.apache.bcel.internal.Const.JSR_W, target); + super.setLength(5); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR_W(this); - } + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.setIndex(getTargetOffset()); + out.writeByte(super.getOpcode()); + out.writeInt(super.getIndex()); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setIndex(bytes.readInt()); + super.setLength(5); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR_W(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java index a67702e7aa0..39228c4afeb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java @@ -21,62 +21,64 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for JSR - Jump to subroutine * - * @author M. Dahm + * @version $Id: JsrInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public abstract class JsrInstruction extends BranchInstruction - implements UnconditionalBranch, TypedInstruction, StackProducer -{ - JsrInstruction(short opcode, InstructionHandle target) { - super(opcode, target); - } +public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch, + TypedInstruction, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - JsrInstruction(){} - - /** @return return address type - */ - public Type getType(ConstantPoolGen cp) { - return new ReturnaddressType(physicalSuccessor()); - } - - /** - * Returns an InstructionHandle to the physical successor - * of this JsrInstruction. For this method to work, - * this JsrInstruction object must not be shared between - * multiple InstructionHandle objects! - * Formally, there must not be InstructionHandle objects - * i, j where i != j and i.getInstruction() == this == - * j.getInstruction(). - * @return an InstructionHandle to the "next" instruction that - * will be executed when RETurned from a subroutine. - */ - public InstructionHandle physicalSuccessor(){ - InstructionHandle ih = this.target; - - // Rewind! - while(ih.getPrev() != null) - ih = ih.getPrev(); - - // Find the handle for "this" JsrInstruction object. - while(ih.getInstruction() != this) - ih = ih.getNext(); - - InstructionHandle toThis = ih; - - while(ih != null){ - ih = ih.getNext(); - if ((ih != null) && (ih.getInstruction() == this)) - throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); + JsrInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); } - // Return the physical successor - return toThis.getNext(); - } + + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + JsrInstruction() { + } + + + /** @return return address type + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return new ReturnaddressType(physicalSuccessor()); + } + + + /** + * Returns an InstructionHandle to the physical successor + * of this JsrInstruction. For this method to work, + * this JsrInstruction object must not be shared between + * multiple InstructionHandle objects! + * Formally, there must not be InstructionHandle objects + * i, j where i != j and i.getInstruction() == this == + * j.getInstruction(). + * @return an InstructionHandle to the "next" instruction that + * will be executed when RETurned from a subroutine. + */ + public InstructionHandle physicalSuccessor() { + InstructionHandle ih = super.getTarget(); + // Rewind! + while (ih.getPrev() != null) { + ih = ih.getPrev(); + } + // Find the handle for "this" JsrInstruction object. + while (ih.getInstruction() != this) { + ih = ih.getNext(); + } + final InstructionHandle toThis = ih; + while (ih != null) { + ih = ih.getNext(); + if ((ih != null) && (ih.getInstruction() == this)) { + throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction."); + } + } + // Return the physical successor + return toThis.getNext(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java index fb0926faa9f..93894dc7741 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * L2D - Convert long to double *
      Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: L2D.java 1747278 2016-06-07 17:28:43Z britter $ */ public class L2D extends ConversionInstruction { - public L2D() { - super(com.sun.org.apache.bcel.internal.Constants.L2D); - } + + public L2D() { + super(com.sun.org.apache.bcel.internal.Const.L2D); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2D(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2D(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java index afc5b0016b5..0ce9f52285d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * L2F - Convert long to float *
      Stack: ..., value.word1, value.word2 -> ..., result
      * - * @author M. Dahm + * @version $Id: L2F.java 1747278 2016-06-07 17:28:43Z britter $ */ public class L2F extends ConversionInstruction { - public L2F() { - super(com.sun.org.apache.bcel.internal.Constants.L2F); - } + + public L2F() { + super(com.sun.org.apache.bcel.internal.Const.L2F); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2F(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2F(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java index be9615f20dd..a1bc7cc2397 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * L2I - Convert long to int *
      Stack: ..., value.word1, value.word2 -> ..., result
      * - * @author M. Dahm + * @version $Id: L2I.java 1747278 2016-06-07 17:28:43Z britter $ */ public class L2I extends ConversionInstruction { - public L2I() { - super(com.sun.org.apache.bcel.internal.Constants.L2I); - } + + public L2I() { + super(com.sun.org.apache.bcel.internal.Const.L2I); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitConversionInstruction(this); - v.visitL2I(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitConversionInstruction(this); + v.visitL2I(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java index 999c39c77f8..e3176d3eac3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LADD - Add longs *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LADD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LADD extends ArithmeticInstruction { - public LADD() { - super(com.sun.org.apache.bcel.internal.Constants.LADD); - } + + public LADD() { + super(com.sun.org.apache.bcel.internal.Const.LADD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLADD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLADD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java index 7068be8f28e..0c7750506bd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LALOAD - Load long from array *
      Stack: ..., arrayref, index -> ..., value1, value2
      * - * @author M. Dahm + * @version $Id: LALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LALOAD extends ArrayInstruction implements StackProducer { - /** Load long from array - */ - public LALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.LALOAD); - } + + /** Load long from array + */ + public LALOAD() { + super(com.sun.org.apache.bcel.internal.Const.LALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitLALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitLALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java index a5fa96c1b17..62af531f524 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LAND - Bitwise AND longs *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LAND.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LAND extends ArithmeticInstruction { - public LAND() { - super(com.sun.org.apache.bcel.internal.Constants.LAND); - } + + public LAND() { + super(com.sun.org.apache.bcel.internal.Const.LAND); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLAND(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLAND(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java index 04d25d20181..cbb9a992c71 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java @@ -21,34 +21,35 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LASTORE - Store into long array *
      Stack: ..., arrayref, index, value.word1, value.word2 -> ...
      * - * @author M. Dahm + * @version $Id: LASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LASTORE extends ArrayInstruction implements StackConsumer { - /** Store long into array - */ - public LASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.LASTORE); - } + + /** Store long into array + */ + public LASTORE() { + super(com.sun.org.apache.bcel.internal.Const.LASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitLASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitLASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java index cb2fb4f8404..b46ed10f4dd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java @@ -21,39 +21,41 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LCMP - Compare longs: - *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      - * ..., result <= -1, 0, 1> + *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result <= -1, 0, 1>
      * - * @author M. Dahm + * + * @version $Id: LCMP.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class LCMP extends Instruction - implements TypedInstruction, StackProducer, StackConsumer -{ - public LCMP() { - super(com.sun.org.apache.bcel.internal.Constants.LCMP, (short)1); - } +public class LCMP extends Instruction implements TypedInstruction, StackProducer, StackConsumer { - /** @return Type.LONG - */ - public Type getType(ConstantPoolGen cp) { - return Type.LONG; - } + public LCMP() { + super(com.sun.org.apache.bcel.internal.Const.LCMP, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitLCMP(this); - } + + /** @return Type.LONG + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.LONG; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitLCMP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java index dcc2383877c..3c278c40c70 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java @@ -20,58 +20,67 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LCONST - Push 0 or 1, other values cause an exception * *
      Stack: ... -> ..., 
      * - * @author M. Dahm + * @version $Id: LCONST.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class LCONST extends Instruction - implements ConstantPushInstruction, TypedInstruction { - private long value; +public class LCONST extends Instruction implements ConstantPushInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LCONST() {} + private long value; - public LCONST(long l) { - super(com.sun.org.apache.bcel.internal.Constants.LCONST_0, (short)1); - if(l == 0) - opcode = com.sun.org.apache.bcel.internal.Constants.LCONST_0; - else if(l == 1) - opcode = com.sun.org.apache.bcel.internal.Constants.LCONST_1; - else - throw new ClassGenException("LCONST can be used only for 0 and 1: " + l); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LCONST() { + } - value = l; - } - public Number getValue() { return Long.valueOf(value); } + public LCONST(final long l) { + super(com.sun.org.apache.bcel.internal.Const.LCONST_0, (short) 1); + if (l == 0) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LCONST_0); + } else if (l == 1) { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LCONST_1); + } else { + throw new ClassGenException("LCONST can be used only for 0 and 1: " + l); + } + value = l; + } - /** @return Type.LONG - */ - public Type getType(ConstantPoolGen cp) { - return Type.LONG; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitLCONST(this); - } + @Override + public Number getValue() { + return Long.valueOf(value); + } + + + /** @return Type.LONG + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.LONG; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitLCONST(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java index 80899e77d95..3803fe85fb2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java @@ -20,7 +20,10 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.ExceptionConst; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -28,111 +31,130 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
      Stack: ... -> ..., item
      * - * @author M. Dahm + * @version $Id: LDC.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public class LDC extends CPInstruction - implements PushInstruction, ExceptionThrower, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC() {} +public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower { - public LDC(int index) { - super(com.sun.org.apache.bcel.internal.Constants.LDC_W, index); - setSize(); - } - - // Adjust to proper size - protected final void setSize() { - if(index <= com.sun.org.apache.bcel.internal.Constants.MAX_BYTE) { // Fits in one byte? - opcode = com.sun.org.apache.bcel.internal.Constants.LDC; - length = 2; - } else { - opcode = com.sun.org.apache.bcel.internal.Constants.LDC_W; - length = 3; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC() { } - } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - if(length == 2) - out.writeByte(index); - else // Applies for LDC_W - out.writeShort(index); - } - - /** - * Set the index to constant pool and adjust size. - */ - public final void setIndex(int index) { - super.setIndex(index); - setSize(); - } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - length = 2; - index = bytes.readUnsignedByte(); - } - - public Object getValue(ConstantPoolGen cpg) { - com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(index); - - switch(c.getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_String: - int i = ((com.sun.org.apache.bcel.internal.classfile.ConstantString)c).getStringIndex(); - c = cpg.getConstantPool().getConstant(i); - return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8)c).getBytes(); - - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Float: - return Float.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat)c).getBytes()); - - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Integer: - return Integer.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger)c).getBytes()); - - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } - - public Type getType(ConstantPoolGen cpg) { - switch(cpg.getConstantPool().getConstant(index).getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_String: return Type.STRING; - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Float: return Type.FLOAT; - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Integer: return Type.INT; - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); + public LDC(final int index) { + super(com.sun.org.apache.bcel.internal.Const.LDC_W, index); + setSize(); } - } - public Class[] getExceptions() { - return com.sun.org.apache.bcel.internal.ExceptionConstants.EXCS_STRING_RESOLUTION; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitLDC(this); - } + // Adjust to proper size + protected final void setSize() { + if (super.getIndex() <= com.sun.org.apache.bcel.internal.Const.MAX_BYTE) { // Fits in one byte? + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC); + super.setLength(2); + } else { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC_W); + super.setLength(3); + } + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + if (super.getLength() == 2) { // TODO useless check? + out.writeByte(super.getIndex()); + } else { + out.writeShort(super.getIndex()); + } + } + + + /** + * Set the index to constant pool and adjust size. + */ + @Override + public final void setIndex( final int index ) { + super.setIndex(index); + setSize(); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setLength(2); + super.setIndex(bytes.readUnsignedByte()); + } + + + public Object getValue( final ConstantPoolGen cpg ) { + com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); + switch (c.getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: + final int i = ((com.sun.org.apache.bcel.internal.classfile.ConstantString) c).getStringIndex(); + c = cpg.getConstantPool().getConstant(i); + return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes(); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: + return new Float(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: + return Integer.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: + final int nameIndex = ((com.sun.org.apache.bcel.internal.classfile.ConstantClass) c).getNameIndex(); + c = cpg.getConstantPool().getConstant(nameIndex); + return new ObjectType(((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes()); + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + } + } + + + @Override + public Type getType( final ConstantPoolGen cpg ) { + switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: + return Type.STRING; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: + return Type.FLOAT; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: + return Type.INT; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: + return Type.CLASS; + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + } + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_STRING_RESOLUTION); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitLDC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java index 2279676c61a..561176c0d81 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java @@ -20,63 +20,68 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LDC2_W - Push long or double from constant pool * *
      Stack: ... -> ..., item.word1, item.word2
      * - * @author M. Dahm + * @version $Id: LDC2_W.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public class LDC2_W extends CPInstruction - implements PushInstruction, TypedInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC2_W() {} +public class LDC2_W extends CPInstruction implements PushInstruction { - public LDC2_W(int index) { - super(com.sun.org.apache.bcel.internal.Constants.LDC2_W, index); - } - - public Type getType(ConstantPoolGen cpg) { - switch(cpg.getConstantPool().getConstant(index).getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Long: return Type.LONG; - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Double: return Type.DOUBLE; - default: // Never reached - throw new RuntimeException("Unknown constant type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC2_W() { } - } - public Number getValue(ConstantPoolGen cpg) { - com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(index); - switch(c.getTag()) { - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Long: - return Long.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantLong)c).getBytes()); + public LDC2_W(final int index) { + super(com.sun.org.apache.bcel.internal.Const.LDC2_W, index); + } - case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Double: - return Double.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantDouble)c).getBytes()); - default: // Never reached - throw new RuntimeException("Unknown or invalid constant type at " + index); - } - } + @Override + public Type getType( final ConstantPoolGen cpg ) { + switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: + return Type.LONG; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: + return Type.DOUBLE; + default: // Never reached + throw new RuntimeException("Unknown constant type " + super.getOpcode()); + } + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitLDC2_W(this); - } + + public Number getValue( final ConstantPoolGen cpg ) { + final com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); + switch (c.getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: + return Long.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: + return new Double(((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes()); + default: // Never reached + throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex()); + } + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitLDC2_W(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java index be3f5693f0e..9651aaa09b4 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java @@ -22,6 +22,7 @@ package com.sun.org.apache.bcel.internal.generic; import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -29,27 +30,31 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
      Stack: ... -> ..., item.word1, item.word2
      * - * @author M. Dahm + * @version $Id: LDC_W.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LDC_W extends LDC { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LDC_W() {} - public LDC_W(int index) { - super(index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LDC_W() { + } - /** - * Read needed data (i.e., index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - setIndex(bytes.readUnsignedShort()); - // Override just in case it has been changed - opcode = com.sun.org.apache.bcel.internal.Constants.LDC_W; - } + + public LDC_W(final int index) { + super(index); + } + + + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + setIndex(bytes.readUnsignedShort()); + // Override just in case it has been changed + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC_W); + super.setLength(3); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java index 55f82cab10e..f3d104e8872 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java @@ -21,38 +21,45 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * LDIV - Divide longs *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LDIV.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class LDIV extends ArithmeticInstruction implements ExceptionThrower { - public LDIV() { - super(com.sun.org.apache.bcel.internal.Constants.LDIV); - } +public class LDIV extends ArithmeticInstruction implements ExceptionThrower { - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; - } + public LDIV() { + super(com.sun.org.apache.bcel.internal.Const.LDIV); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLDIV(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLDIV(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java index b36e57549e2..0e5deec7dfa 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java @@ -21,36 +21,39 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LLOAD - Load long from local variable - *
      Stack ... -> ..., result.word1, result.word2
      + *
      Stack ... -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: LLOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LLOAD extends LoadInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LLOAD() { - super(com.sun.org.apache.bcel.internal.Constants.LLOAD, com.sun.org.apache.bcel.internal.Constants.LLOAD_0); - } - public LLOAD(int n) { - super(com.sun.org.apache.bcel.internal.Constants.LLOAD, com.sun.org.apache.bcel.internal.Constants.LLOAD_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LLOAD() { + super(com.sun.org.apache.bcel.internal.Const.LLOAD, com.sun.org.apache.bcel.internal.Const.LLOAD_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitLLOAD(this); - } + + public LLOAD(final int n) { + super(com.sun.org.apache.bcel.internal.Const.LLOAD, com.sun.org.apache.bcel.internal.Const.LLOAD_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitLLOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java index aa746fb623a..3290f093592 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LMUL - Multiply longs *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LMUL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LMUL extends ArithmeticInstruction { - public LMUL() { - super(com.sun.org.apache.bcel.internal.Constants.LMUL); - } + + public LMUL() { + super(com.sun.org.apache.bcel.internal.Const.LMUL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLMUL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLMUL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java index b08f303bf55..698b52c486d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LNEG - Negate long *
      Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: LNEG.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LNEG extends ArithmeticInstruction { - public LNEG() { - super(com.sun.org.apache.bcel.internal.Constants.LNEG); - } + + public LNEG() { + super(com.sun.org.apache.bcel.internal.Const.LNEG); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLNEG(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLNEG(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java index 1b026df5289..b403ddebb54 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java @@ -21,80 +21,89 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * LOOKUPSWITCH - Switch with unordered set of values * - * @author M. Dahm + * @version $Id: LOOKUPSWITCH.java 1747278 2016-06-07 17:28:43Z britter $ * @see SWITCH */ public class LOOKUPSWITCH extends Select { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LOOKUPSWITCH() {} - public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.LOOKUPSWITCH, match, targets, target); - - length = (short)(9 + match_length * 8); /* alignment remainder assumed - * 0 here, until dump time. */ - fixed_length = length; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - out.writeInt(match_length); // npairs - - for(int i=0; i < match_length; i++) { - out.writeInt(match[i]); // match-offset pairs - out.writeInt(indices[i] = getTargetOffset(targets[i])); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LOOKUPSWITCH() { } - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - super.initFromFile(bytes, wide); // reads padding - match_length = bytes.readInt(); - fixed_length = (short)(9 + match_length * 8); - length = (short)(fixed_length + padding); - - match = new int[match_length]; - indices = new int[match_length]; - targets = new InstructionHandle[match_length]; - - for(int i=0; i < match_length; i++) { - match[i] = bytes.readInt(); - indices[i] = bytes.readInt(); + public LOOKUPSWITCH(final int[] match, final InstructionHandle[] targets, + final InstructionHandle defaultTarget) { + super(com.sun.org.apache.bcel.internal.Const.LOOKUPSWITCH, match, targets, defaultTarget); + /* alignment remainder assumed 0 here, until dump time. */ + final short _length = (short) (9 + getMatch_length() * 8); + super.setLength(_length); + setFixed_length(_length); } - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitVariableLengthInstruction(this); - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitLOOKUPSWITCH(this); - } + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.dump(out); + final int _match_length = getMatch_length(); + out.writeInt(_match_length); // npairs + for (int i = 0; i < _match_length; i++) { + out.writeInt(super.getMatch(i)); // match-offset pairs + out.writeInt(setIndices(i, getTargetOffset(super.getTarget(i)))); + } + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); // reads padding + final int _match_length = bytes.readInt(); + setMatch_length(_match_length); + final short _fixed_length = (short) (9 + _match_length * 8); + setFixed_length(_fixed_length); + final short _length = (short) (_match_length + super.getPadding()); + super.setLength(_length); + super.setMatches(new int[_match_length]); + super.setIndices(new int[_match_length]); + super.setTargets(new InstructionHandle[_match_length]); + for (int i = 0; i < _match_length; i++) { + super.setMatch(i, bytes.readInt()); + super.setIndices(i, bytes.readInt()); + } + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitVariableLengthInstruction(this); + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitLOOKUPSWITCH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java index 19a25deaf8c..e5dbf97a80e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LOR - Bitwise OR long *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: LOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LOR extends ArithmeticInstruction { - public LOR() { - super(com.sun.org.apache.bcel.internal.Constants.LOR); - } + + public LOR() { + super(com.sun.org.apache.bcel.internal.Const.LOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java index 7f2892d25e7..4f485c1cf73 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java @@ -21,35 +21,44 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * LREM - Remainder of long *
      Stack: ..., value1, value2 -> result
      * - * @author M. Dahm + * @version $Id: LREM.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LREM extends ArithmeticInstruction implements ExceptionThrower { - public LREM() { - super(com.sun.org.apache.bcel.internal.Constants.LREM); - } - public Class[] getExceptions() { return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.ARITHMETIC_EXCEPTION }; } + public LREM() { + super(com.sun.org.apache.bcel.internal.Const.LREM); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLREM(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ARITHMETIC_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLREM(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java index b09344aee5d..b84c0ca0333 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LRETURN - Return long from method *
      Stack: ..., value.word1, value.word2 -> <empty>
      * - * @author M. Dahm + * @version $Id: LRETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LRETURN extends ReturnInstruction { - public LRETURN() { - super(com.sun.org.apache.bcel.internal.Constants.LRETURN); - } + + public LRETURN() { + super(com.sun.org.apache.bcel.internal.Const.LRETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitLRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitLRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java index ae677302842..4eaa5a77dd6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSHL - Arithmetic shift left long *
      Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: LSHL.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSHL extends ArithmeticInstruction { - public LSHL() { - super(com.sun.org.apache.bcel.internal.Constants.LSHL); - } + + public LSHL() { + super(com.sun.org.apache.bcel.internal.Const.LSHL); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSHL(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSHL(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java index f6a520b2831..d5df3027aa6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSHR - Arithmetic shift right long *
      Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
      * - * @author M. Dahm + * @version $Id: LSHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSHR extends ArithmeticInstruction { - public LSHR() { - super(com.sun.org.apache.bcel.internal.Constants.LSHR); - } + + public LSHR() { + super(com.sun.org.apache.bcel.internal.Const.LSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java index 3b560d28b03..1919c561c6a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java @@ -21,36 +21,39 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSTORE - Store long into local variable *
      Stack: ..., value.word1, value.word2 -> ... 
      * - * @author M. Dahm + * @version $Id: LSTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSTORE extends StoreInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - LSTORE() { - super(com.sun.org.apache.bcel.internal.Constants.LSTORE, com.sun.org.apache.bcel.internal.Constants.LSTORE_0); - } - public LSTORE(int n) { - super(com.sun.org.apache.bcel.internal.Constants.LSTORE, com.sun.org.apache.bcel.internal.Constants.LSTORE_0, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + LSTORE() { + super(com.sun.org.apache.bcel.internal.Const.LSTORE, com.sun.org.apache.bcel.internal.Const.LSTORE_0); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - super.accept(v); - v.visitLSTORE(this); - } + + public LSTORE(final int n) { + super(com.sun.org.apache.bcel.internal.Const.LSTORE, com.sun.org.apache.bcel.internal.Const.LSTORE_0, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + super.accept(v); + v.visitLSTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java index 789c47fe143..2f0bcb3aedd 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LSUB - Substract longs *
      Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
      * ..., result.word1, result.word2 * - * @author M. Dahm + * @version $Id: LSUB.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LSUB extends ArithmeticInstruction { - public LSUB() { - super(com.sun.org.apache.bcel.internal.Constants.LSUB); - } + + public LSUB() { + super(com.sun.org.apache.bcel.internal.Const.LSUB); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLSUB(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLSUB(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java index 19d83c8f7b7..5852db50e02 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LUSHR - Logical shift right long *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: LUSHR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LUSHR extends ArithmeticInstruction { - public LUSHR() { - super(com.sun.org.apache.bcel.internal.Constants.LUSHR); - } + + public LUSHR() { + super(com.sun.org.apache.bcel.internal.Const.LUSHR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLUSHR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLUSHR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java index 56f680125f6..5156d7d319e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * LXOR - Bitwise XOR long *
      Stack: ..., value1, value2 -> ..., result
      * - * @author M. Dahm + * @version $Id: LXOR.java 1747278 2016-06-07 17:28:43Z britter $ */ public class LXOR extends ArithmeticInstruction { - public LXOR() { - super(com.sun.org.apache.bcel.internal.Constants.LXOR); - } + + public LXOR() { + super(com.sun.org.apache.bcel.internal.Const.LXOR); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitTypedInstruction(this); - v.visitStackProducer(this); - v.visitStackConsumer(this); - v.visitArithmeticInstruction(this); - v.visitLXOR(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitTypedInstruction(this); + v.visitStackProducer(this); + v.visitStackConsumer(this); + v.visitArithmeticInstruction(this); + v.visitLXOR(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java index ebda36320c0..e5e6d59875e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java @@ -21,80 +21,96 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.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. * - * @author M. Dahm + * @version $Id: LineNumberGen.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see LineNumber * @see MethodGen */ -public class LineNumberGen - implements InstructionTargeter, Cloneable, java.io.Serializable -{ - private InstructionHandle ih; - private int src_line; +public class LineNumberGen implements InstructionTargeter, Cloneable { - /** - * Create a line number. - * - * @param ih instruction handle to reference - */ - public LineNumberGen(InstructionHandle ih, int src_line) { - setInstruction(ih); - setSourceLine(src_line); - } + private InstructionHandle ih; + private int src_line; - /** - * @return true, if ih is target of this line number - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return this.ih == ih; - } - /** - * @param old_ih old target - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - if(old_ih != ih) - throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); - else - setInstruction(new_ih); - } - - /** - * 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 final void setInstruction(InstructionHandle ih) { - BranchInstruction.notifyTargetChanging(this.ih, this); - this.ih = ih; - BranchInstruction.notifyTargetChanged(this.ih, this); - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + /** + * Create a line number. + * + * @param ih instruction handle to reference + */ + public LineNumberGen(final InstructionHandle ih, final int src_line) { + setInstruction(ih); + setSourceLine(src_line); } - } - public InstructionHandle getInstruction() { return ih; } - public void setSourceLine(int src_line) { this.src_line = src_line; } - public int getSourceLine() { return src_line; } + + /** + * @return true, if ih is target of this line number + */ + @Override + public boolean containsTarget( final InstructionHandle ih ) { + return this.ih == ih; + } + + + /** + * @param old_ih old target + * @param new_ih new target + */ + @Override + public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { + if (old_ih != ih) { + throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); + } + 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( final InstructionHandle ih ) { // TODO could be package-protected? + if (ih == null) { + throw new NullPointerException("InstructionHandle may not be null"); + } + BranchInstruction.notifyTarget(this.ih, ih, this); + this.ih = ih; + } + + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } + + + public InstructionHandle getInstruction() { + return ih; + } + + + public void setSourceLine( final int src_line ) { // TODO could be package-protected? + this.src_line = src_line; + } + + + public int getSourceLine() { + return src_line; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java index 0cf2b23509c..819b24a1cf9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java @@ -21,33 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes that an instruction may start the process of loading and resolving * the referenced class in the Virtual Machine. * - * @author M. Dahm + * @version $Id: LoadClass.java 1749597 2016-06-21 20:28:51Z ggregory $ */ public interface LoadClass { - /** - * Returns the ObjectType of the referenced class or interface - * that may be loaded and resolved. - * @return object type that may be loaded or null if a primitive is - * referenced - */ - public ObjectType getLoadClassType(ConstantPoolGen cpg); - /** - * Returns the type associated with this instruction. - * LoadClass instances are always typed, but this type - * does not always refer to the type of the class or interface - * that it possibly forces to load. For example, GETFIELD would - * return the type of the field and not the type of the class - * where the field is defined. - * If no class is forced to be loaded, null is returned. - * An example for this is an ANEWARRAY instruction that creates - * an int[][]. - * @see #getLoadClassType(ConstantPoolGen) - */ - public Type getType(ConstantPoolGen cpg); + /** + * Returns the ObjectType of the referenced class or interface + * that may be loaded and resolved. + * @return object type that may be loaded or null if a primitive is + * referenced + */ + ObjectType getLoadClassType( ConstantPoolGen cpg ); + + + /** + * Returns the type associated with this instruction. + * LoadClass instances are always typed, but this type + * does not always refer to the type of the class or interface + * that it possibly forces to load. For example, GETFIELD would + * return the type of the field and not the type of the class + * where the field is defined. + * If no class is forced to be loaded, null is returned. + * An example for this is an ANEWARRAY instruction that creates + * an int[][]. + * @see #getLoadClassType(ConstantPoolGen) + */ + Type getType( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java index 6d663263e58..b125d245a09 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java @@ -21,47 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to load a value from a local * variable, e.g. ILOAD. * - * @author M. Dahm + * @version $Id: LoadInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class LoadInstruction extends LocalVariableInstruction - implements PushInstruction -{ - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - LoadInstruction(short canon_tag, short c_tag) { - super(canon_tag, c_tag); - } +public abstract class LoadInstruction extends LocalVariableInstruction implements PushInstruction { - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. - * @param n local variable index (unsigned short) - */ - protected LoadInstruction(short opcode, short c_tag, int n) { - super(opcode, c_tag, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + * tag and length are defined in readInstruction and initFromFile, respectively. + */ + LoadInstruction(final short canon_tag, final short c_tag) { + super(canon_tag, c_tag); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitTypedInstruction(this); - v.visitLocalVariableInstruction(this); - v.visitLoadInstruction(this); - } + + /** + * @param opcode Instruction opcode + * @param c_tag Instruction number for compact version, ALOAD_0, e.g. + * @param n local variable index (unsigned short) + */ + protected LoadInstruction(final short opcode, final short c_tag, final int n) { + super(opcode, c_tag, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitTypedInstruction(this); + v.visitLocalVariableInstruction(this); + v.visitLoadInstruction(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java index 92ae424b8cc..1e2dcbf3d89 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java @@ -18,237 +18,197 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.util.Objects; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; /** * This class represents a local variable within a method. It contains its - * scope, name and type. The generated LocalVariable object can be obtained - * with getLocalVariable which needs the instruction list and the constant - * pool as parameters. + * scope, name and type. The generated LocalVariable object can be obtained with + * getLocalVariable which needs the instruction list and the constant pool as + * parameters. * - * @author M. Dahm - * @see LocalVariable - * @see MethodGen + * @version $Id: LocalVariableGen.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see LocalVariable + * @see MethodGen */ -public class LocalVariableGen - implements InstructionTargeter, NamedAndTyped, Cloneable, - java.io.Serializable -{ - private final int index; - private String name; - private Type type; - private InstructionHandle start, end; +public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable { - /** - * 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); + private int index; + private String name; + private Type type; + private InstructionHandle start; + private InstructionHandle end; - 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(ConstantPoolGen cp) { - int start_pc = start.getPosition(); - int length = end.getPosition() - start_pc; - - if(length > 0) - length += end.getInstruction().getLength(); - - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(type.getSignature()); - - return new LocalVariable(start_pc, length, name_index, - signature_index, index, cp.getConstantPool()); - } - - public int getIndex() { return index; } - @Override - public void setName(String name) { this.name = name; } - @Override - public String getName() { return name; } - @Override - public void setType(Type type) { this.type = type; } - @Override - public Type getType() { return type; } - - public InstructionHandle getStart() { return start; } - public InstructionHandle getEnd() { return end; } - - /** - * Remove this from any known HashSet in which it might be registered. - */ - void notifyTargetChanging() { - // hashCode depends on 'index', 'start', and 'end'. - // Therefore before changing any of these values we - // need to unregister 'this' from any HashSet where - // this is registered, and then we need to add it - // back... - - // Unregister 'this' from the HashSet held by 'start'. - BranchInstruction.notifyTargetChanging(this.start, this); - if (this.end != this.start) { - // Since hashCode() is going to change we need to unregister - // 'this' both form 'start' and 'end'. - // Unregister 'this' from the HashSet held by 'end'. - BranchInstruction.notifyTargetChanging(this.end, this); - } - } - - /** - * Add back 'this' in all HashSet in which it should be registered. - **/ - void notifyTargetChanged() { - // hashCode depends on 'index', 'start', and 'end'. - // Therefore before changing any of these values we - // need to unregister 'this' from any HashSet where - // this is registered, and then we need to add it - // back... - - // Register 'this' in the HashSet held by start. - BranchInstruction.notifyTargetChanged(this.start, this); - if (this.end != this.start) { - // Since hashCode() has changed we need to register - // 'this' again in 'end'. - // Add back 'this' in the HashSet held by 'end'. - BranchInstruction.notifyTargetChanged(this.end, this); - } - } - - public final void setStart(InstructionHandle start) { - - // Call notifyTargetChanging *before* modifying this, - // as the code triggered by notifyTargetChanging - // depends on this pointing to the 'old' start. - notifyTargetChanging(); - - this.start = start; - - // call notifyTargetChanged *after* modifying this, - // as the code triggered by notifyTargetChanged - // depends on this pointing to the 'new' start. - notifyTargetChanged(); - } - - public final void setEnd(InstructionHandle end) { - // call notifyTargetChanging *before* modifying this, - // as the code triggered by notifyTargetChanging - // depends on this pointing to the 'old' end. - // Unregister 'this' from the HashSet held by the 'old' end. - notifyTargetChanging(); - - this.end = end; - - // call notifyTargetChanged *after* modifying this, - // as the code triggered by notifyTargetChanged - // depends on this pointing to the 'new' end. - // Register 'this' in the HashSet held by the 'new' end. - notifyTargetChanged(); - - } - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if(start == old_ih) { - targeted = true; - setStart(new_ih); + /** + * 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(final int index, final String name, final Type type, + final InstructionHandle start, final InstructionHandle end) { + if ((index < 0) || (index > Const.MAX_SHORT)) { + throw new ClassGenException("Invalid index index: " + index); + } + this.name = name; + this.type = type; + this.index = index; + setStart(start); + setEnd(end); } - if(end == old_ih) { - targeted = true; - setEnd(new_ih); + /** + * Get LocalVariable object. + * + * This relies on that the instruction list has already been dumped to byte + * code or or that the `setPositions' methods has been called for the + * instruction list. + * + * Note that for local variables whose scope end at the last instruction of + * the method's code, the JVM specification is ambiguous: both a + * start_pc+length ending at the last instruction and start_pc+length ending + * at first index beyond the end of the code are valid. + * + * @param cp constant pool + */ + public LocalVariable getLocalVariable(final ConstantPoolGen cp) { + int start_pc = 0; + int length = 0; + if ((start != null) && (end != null)) { + start_pc = start.getPosition(); + length = end.getPosition() - start_pc; + if (end.getNext() == null) { + length += end.getInstruction().getLength(); + } + } + final int name_index = cp.addUtf8(name); + final int signature_index = cp.addUtf8(type.getSignature()); + return new LocalVariable(start_pc, length, name_index, signature_index, index, cp + .getConstantPool()); } - if(!targeted) - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + - end + "}"); - } - - /** - * @return true, if ih is target of this variable - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - return (start == ih) || (end == ih); - } - - /** - * We consider two local variables to be equal, if they use the same index and - * are valid in the same range. - */ - @Override - public boolean equals(Object o) { - if (o==this) - return true; - - if(!(o instanceof LocalVariableGen)) - return false; - - LocalVariableGen l = (LocalVariableGen)o; - return (l.index == index) && (l.start == start) && (l.end == end); - } - - @Override - public int hashCode() { - int hash = 7; - hash = 59 * hash + this.index; - hash = 59 * hash + Objects.hashCode(this.start); - hash = 59 * hash + Objects.hashCode(this.end); - return hash; - } - - @Override - public String toString() { - return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch(CloneNotSupportedException e) { - System.err.println(e); - return null; + public void setIndex(final int index) { + this.index = index; + } + + public int getIndex() { + return index; + } + + @Override + public void setName(final String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setType(final Type type) { + this.type = type; + } + + @Override + public Type getType() { + return type; + } + + public InstructionHandle getStart() { + return start; + } + + public InstructionHandle getEnd() { + return end; + } + + public void setStart(final InstructionHandle start) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.start, start, this); + this.start = start; + } + + public void setEnd(final InstructionHandle end) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.end, end, this); + this.end = end; + } + + /** + * @param old_ih old target, either start or end + * @param new_ih new target + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final 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 + + "}"); + } + } + + /** + * Clear the references from and to this variable when it's removed. + */ + void dispose() { + setStart(null); + setEnd(null); + } + + /** + * @return true, if ih is target of this variable + */ + @Override + public boolean containsTarget(final InstructionHandle ih) { + return (start == ih) || (end == ih); + } + + @Override + public int hashCode() { + // If the user changes the name or type, problems with the targeter hashmap will occur. + // Note: index cannot be part of hash as it may be changed by the user. + return name.hashCode() ^ type.hashCode(); + } + + /** + * We consider to local variables to be equal, if the use the same index and + * are valid in the same range. + */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof LocalVariableGen)) { + return false; + } + final LocalVariableGen l = (LocalVariableGen) o; + return (l.index == index) && (l.start == start) && (l.end == end); + } + + @Override + public String toString() { + return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java index 26e14a3787f..87eb80da82d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,176 +17,205 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.util.ByteSequence; -import com.sun.org.apache.bcel.internal.classfile.Utility; -import com.sun.org.apache.bcel.internal.Constants; /** * Abstract super class for instructions dealing with local variables. * - * @author M. Dahm + * @version $Id: LocalVariableInstruction.java 1747278 2016-06-07 17:28:43Z + * britter $ */ -public abstract class LocalVariableInstruction extends Instruction - implements TypedInstruction, IndexedInstruction { - protected int n = -1; // index of referenced variable - private short c_tag = -1; // compact version, such as ILOAD_0 - private short canon_tag = -1; // canonical tag such as ILOAD +public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction, + IndexedInstruction { - private final boolean wide() { return n > Constants.MAX_BYTE; } + private int n = -1; // index of referenced variable + private short c_tag = -1; // compact version, such as ILOAD_0 + private short canon_tag = -1; // canonical tag such as ILOAD - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - LocalVariableInstruction(short canon_tag, short c_tag) { - super(); - this.canon_tag = canon_tag; - this.c_tag = c_tag; - } - - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Also used by IINC()! - */ - LocalVariableInstruction() { - } - - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. - * @param n local variable index (unsigned short) - */ - protected LocalVariableInstruction(short opcode, short c_tag, int n) { - super(opcode, (short)2); - - this.c_tag = c_tag; - canon_tag = opcode; - - setIndex(n); - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - if(wide()) // Need WIDE prefix ? - out.writeByte(Constants.WIDE); - - out.writeByte(opcode); - - if(length > 1) { // Otherwise ILOAD_n, instruction, e.g. - if(wide()) - out.writeShort(n); - else - out.writeByte(n); + private boolean wide() { + return n > Const.MAX_BYTE; } - } - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< local variable index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - if(((opcode >= Constants.ILOAD_0) && - (opcode <= Constants.ALOAD_3)) || - ((opcode >= Constants.ISTORE_0) && - (opcode <= Constants.ASTORE_3))) - return super.toString(verbose); - else - return super.toString(verbose) + " " + n; - } - - /** - * Read needed data (e.g. index) from file. - * PRE: (ILOAD <= tag <= ALOAD_3) || (ISTORE <= tag <= ASTORE_3) - */ - protected void initFromFile(ByteSequence bytes, boolean wide) - throws IOException - { - if(wide) { - n = bytes.readUnsignedShort(); - length = 4; - } else if(((opcode >= Constants.ILOAD) && - (opcode <= Constants.ALOAD)) || - ((opcode >= Constants.ISTORE) && - (opcode <= Constants.ASTORE))) { - n = bytes.readUnsignedByte(); - length = 2; - } else if(opcode <= Constants.ALOAD_3) { // compact load instruction such as ILOAD_2 - n = (opcode - Constants.ILOAD_0) % 4; - length = 1; - } else { // Assert ISTORE_0 <= tag <= ASTORE_3 - n = (opcode - Constants.ISTORE_0) % 4; - length = 1; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. tag and length + * are defined in readInstruction and initFromFile, respectively. + */ + LocalVariableInstruction(final short canon_tag, final short c_tag) { + super(); + this.canon_tag = canon_tag; + this.c_tag = c_tag; } - } - /** - * @return local variable index referred by this instruction. - */ - public final int getIndex() { return n; } - - /** - * Set the local variable index - */ - public void setIndex(int n) { - if((n < 0) || (n > Constants.MAX_SHORT)) - throw new ClassGenException("Illegal value: " + n); - - this.n = n; - - if(n >= 0 && n <= 3) { // Use more compact instruction xLOAD_n - opcode = (short)(c_tag + n); - length = 1; - } else { - opcode = canon_tag; - - if(wide()) // Need WIDE prefix ? - length = 4; - else - length = 2; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Also used by IINC()! + */ + LocalVariableInstruction() { } - } - /** @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 - */ - public short getCanonicalTag() { - return canon_tag; - } - - /** - * Returns the type associated with the instruction - - * in case of ALOAD or ASTORE Type.OBJECT is returned. - * This is just a bit incorrect, because ALOAD and ASTORE - * may work on every ReferenceType (including Type.NULL) and - * ASTORE may even work on a ReturnaddressType . - * @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - switch(canon_tag) { - case Constants.ILOAD: case Constants.ISTORE: - return Type.INT; - case Constants.LLOAD: case Constants.LSTORE: - return Type.LONG; - case Constants.DLOAD: case Constants.DSTORE: - return Type.DOUBLE; - case Constants.FLOAD: case Constants.FSTORE: - return Type.FLOAT; - case Constants.ALOAD: case Constants.ASTORE: - return Type.OBJECT; - - default: throw new ClassGenException("Oops: unknown case in switch" + canon_tag); + /** + * @param opcode Instruction opcode + * @param c_tag Instruction number for compact version, ALOAD_0, e.g. + * @param n local variable index (unsigned short) + */ + protected LocalVariableInstruction(final short opcode, final short c_tag, final int n) { + super(opcode, (short) 2); + this.c_tag = c_tag; + canon_tag = opcode; + setIndex(n); + } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + if (wide()) { + out.writeByte(Const.WIDE); + } + out.writeByte(super.getOpcode()); + if (super.getLength() > 1) { // Otherwise ILOAD_n, instruction, e.g. + if (wide()) { + out.writeShort(n); + } else { + out.writeByte(n); + } + } + } + + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of + * instruction>")" "<"< local variable index>">" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + final short _opcode = super.getOpcode(); + if (((_opcode >= Const.ILOAD_0) && (_opcode <= Const.ALOAD_3)) + || ((_opcode >= Const.ISTORE_0) && (_opcode <= Const.ASTORE_3))) { + return super.toString(verbose); + } + return super.toString(verbose) + " " + n; + } + + /** + * Read needed data (e.g. index) from file. + *
      +     * (ILOAD <= tag <= ALOAD_3) || (ISTORE <= tag <= ASTORE_3)
      +     * 
      + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + if (wide) { + n = bytes.readUnsignedShort(); + super.setLength(4); + } else { + final short _opcode = super.getOpcode(); + if (((_opcode >= Const.ILOAD) && (_opcode <= Const.ALOAD)) + || ((_opcode >= Const.ISTORE) && (_opcode <= Const.ASTORE))) { + n = bytes.readUnsignedByte(); + super.setLength(2); + } else if (_opcode <= Const.ALOAD_3) { // compact load instruction such as ILOAD_2 + n = (_opcode - Const.ILOAD_0) % 4; + super.setLength(1); + } else { // Assert ISTORE_0 <= tag <= ASTORE_3 + n = (_opcode - Const.ISTORE_0) % 4; + super.setLength(1); + } + } + } + + /** + * @return local variable index (n) referred by this instruction. + */ + @Override + public final int getIndex() { + return n; + } + + /** + * Set the local variable index. also updates opcode and length TODO Why? + * + * @see #setIndexOnly(int) + */ + @Override + public void setIndex(final int n) { // TODO could be package-protected? + if ((n < 0) || (n > Const.MAX_SHORT)) { + throw new ClassGenException("Illegal value: " + n); + } + this.n = n; + // Cannot be < 0 as this is checked above + if (n <= 3) { // Use more compact instruction xLOAD_n + super.setOpcode((short) (c_tag + n)); + super.setLength(1); + } else { + super.setOpcode(canon_tag); + if (wide()) { + super.setLength(4); + } else { + super.setLength(2); + } + } + } + + /** + * @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 + */ + public short getCanonicalTag() { + return canon_tag; + } + + /** + * Returns the type associated with the instruction - in case of ALOAD or + * ASTORE Type.OBJECT is returned. This is just a bit incorrect, because + * ALOAD and ASTORE may work on every ReferenceType (including Type.NULL) + * and ASTORE may even work on a ReturnaddressType . + * + * @return type associated with the instruction + */ + @Override + public Type getType(final ConstantPoolGen cp) { + switch (canon_tag) { + case Const.ILOAD: + case Const.ISTORE: + return Type.INT; + case Const.LLOAD: + case Const.LSTORE: + return Type.LONG; + case Const.DLOAD: + case Const.DSTORE: + return Type.DOUBLE; + case Const.FLOAD: + case Const.FSTORE: + return Type.FLOAT; + case Const.ALOAD: + case Const.ASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Oops: unknown case in switch" + canon_tag); + } + } + + /** + * Sets the index of the referenced variable (n) only + * + * @since 6.0 + * @see #setIndex(int) + */ + final void setIndexOnly(final int n) { + this.n = n; } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java index 5fd6d61692c..7d5267ef471 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java @@ -21,35 +21,41 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * MONITORENTER - Enter monitor for object *
      Stack: ..., objectref -> ...
      * - * @author M. Dahm + * @version $Id: MONITORENTER.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class MONITORENTER extends Instruction - implements ExceptionThrower, StackConsumer { - public MONITORENTER() { - super(com.sun.org.apache.bcel.internal.Constants.MONITORENTER, (short)1); - } +public class MONITORENTER extends Instruction implements ExceptionThrower, StackConsumer { - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NULL_POINTER_EXCEPTION }; - } + public MONITORENTER() { + super(com.sun.org.apache.bcel.internal.Const.MONITORENTER, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitMONITORENTER(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NULL_POINTER_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitMONITORENTER(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java index d6a87fd64b5..c1ec802c759 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java @@ -21,35 +21,41 @@ package com.sun.org.apache.bcel.internal.generic; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * MONITOREXIT - Exit monitor for object *
      Stack: ..., objectref -> ...
      * - * @author M. Dahm + * @version $Id: MONITOREXIT.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class MONITOREXIT extends Instruction - implements ExceptionThrower, StackConsumer { - public MONITOREXIT() { - super(com.sun.org.apache.bcel.internal.Constants.MONITOREXIT, (short)1); - } +public class MONITOREXIT extends Instruction implements ExceptionThrower, StackConsumer { - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NULL_POINTER_EXCEPTION }; - } + public MONITOREXIT() { + super(com.sun.org.apache.bcel.internal.Const.MONITOREXIT, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitMONITOREXIT(this); - } + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NULL_POINTER_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitMONITOREXIT(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java index 54c9d8b11df..cc941ae7ae2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java @@ -21,119 +21,136 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; -import com.sun.org.apache.bcel.internal.util.ByteSequence; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.ExceptionConst; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * MULTIANEWARRAY - Create new mutidimensional array of references *
      Stack: ..., count1, [count2, ...] -> ..., arrayref
      * - * @author M. Dahm + * @version $Id: MULTIANEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, ExceptionThrower { - private short dimensions; +public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, + ExceptionThrower { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - MULTIANEWARRAY() {} + private short dimensions; - public MULTIANEWARRAY(int index, short dimensions) { - super(com.sun.org.apache.bcel.internal.Constants.MULTIANEWARRAY, index); - if(dimensions < 1) - throw new ClassGenException("Invalid dimensions value: " + dimensions); - - this.dimensions = dimensions; - length = 4; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - 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(ConstantPoolGen cpg) { return dimensions; } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length+1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - - return cs; - } - - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - Type t = getType(cpg); - - if (t instanceof ArrayType){ - t = ((ArrayType) t).getBasicType(); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + MULTIANEWARRAY() { } - 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 MULTIANEWARRAY(final int index, final short dimensions) { + super(com.sun.org.apache.bcel.internal.Const.MULTIANEWARRAY, index); + if (dimensions < 1) { + throw new ClassGenException("Invalid dimensions value: " + dimensions); + } + this.dimensions = dimensions; + super.setLength(4); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(dimensions); + } + + + /** + * Read needed data (i.e., no. dimension) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + dimensions = bytes.readByte(); + super.setLength(4); + } + + + /** + * @return number of dimensions to be created + */ + public final short getDimensions() { + return dimensions; + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + super.getIndex() + " " + dimensions; + } + + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString( final 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 + */ + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + return dimensions; + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); + } + + + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return (t instanceof ObjectType) ? (ObjectType) t : null; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitMULTIANEWARRAY(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java index 61a3daf61ea..81ed1c07f69 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,13 +17,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.util.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.Annotations; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.CodeException; +import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; +import com.sun.org.apache.bcel.internal.classfile.LineNumber; +import com.sun.org.apache.bcel.internal.classfile.LineNumberTable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTypeTable; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotationEntry; +import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotations; +import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleParameterAnnotations; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.util.BCELComparator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; /** * Template class for building up a method. This is done by defining exception @@ -33,1021 +52,1216 @@ import java.util.*; * automatically for the code. Use stripAttributes() if you don't like this. * * While generating code it may be necessary to insert NOP operations. You can - * use the `removeNOPs' method to get rid off them. - * The resulting method object can be obtained via the `getMethod()' method. + * use the `removeNOPs' method to get rid off them. The resulting method object + * can be obtained via the `getMethod()' method. * - * @author M. Dahm - * @author Patrick C. Beard [setMaxStack()] - * @see InstructionList - * @see Method + * @version $Id: MethodGen.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see InstructionList + * @see Method */ public class MethodGen extends FieldGenOrMethodGen { - private String class_name; - private Type[] arg_types; - private String[] arg_names; - private int max_locals; - private int max_stack; - private InstructionList il; - private boolean strip_attributes; - private ArrayList variable_vec = new ArrayList(); - private ArrayList type_vec = new ArrayList(); - private ArrayList line_number_vec = new ArrayList(); - private ArrayList exception_vec = new ArrayList(); - private ArrayList throws_vec = new ArrayList(); - private ArrayList code_attrs_vec = new ArrayList(); + private String class_name; + private Type[] arg_types; + private String[] arg_names; + private int max_locals; + private int max_stack; + private InstructionList il; + private boolean strip_attributes; + private final List variable_vec = new ArrayList<>(); + private final List type_vec = new ArrayList<>(); + private final List line_number_vec = new ArrayList<>(); + private final List exception_vec = new ArrayList<>(); + private final List throws_vec = new ArrayList<>(); + private final List code_attrs_vec = new ArrayList<>(); - /** - * Declare method. If the method is non-static the constructor - * automatically declares a local variable `$this' in slot 0. The - * actual code is contained in the `il' parameter, which may further - * manipulated by the user. But he must take care not to remove any - * instruction (handles) that are still referenced from this object. - * - * For example one may not add a local variable and later remove the - * instructions it refers to without causing havoc. It is safe - * however if you remove that local variable, too. - * - * @param access_flags access qualifiers - * @param return_type method type - * @param arg_types argument types - * @param arg_names argument names (if this is null, default names will be provided - * for them) - * @param method_name name of method - * @param class_name class name containing this method (may be null, if you don't care) - * @param il instruction list associated with this method, may be null only for - * abstract or native methods - * @param cp constant pool - */ - public MethodGen(int access_flags, Type return_type, Type[] arg_types, - String[] arg_names, String method_name, String class_name, - InstructionList il, ConstantPoolGen cp) { - setAccessFlags(access_flags); - setType(return_type); - setArgumentTypes(arg_types); - setArgumentNames(arg_names); - setName(method_name); - setClassName(class_name); - setInstructionList(il); - setConstantPool(cp); + private List[] param_annotations; // Array of lists containing AnnotationGen objects + private boolean hasParameterAnnotations = false; + private boolean haveUnpackedParameterAnnotations = false; - boolean abstract_ = isAbstract() || isNative(); - InstructionHandle start = null; - InstructionHandle end = null; + private static BCELComparator bcelComparator = new BCELComparator() { - 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"); + @Override + public boolean equals(final Object o1, final Object o2) { + final MethodGen THIS = (MethodGen) o1; + final MethodGen THAT = (MethodGen) o2; + return THIS.getName().equals(THAT.getName()) + && THIS.getSignature().equals(THAT.getSignature()); } - } - 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; + @Override + public int hashCode(final Object o) { + final MethodGen THIS = (MethodGen) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; + /** + * Declare method. If the method is non-static the constructor automatically + * declares a local variable `$this' in slot 0. The actual code is contained + * in the `il' parameter, which may further manipulated by the user. But he + * must take care not to remove any instruction (handles) that are still + * referenced from this object. + * + * For example one may not add a local variable and later remove the + * instructions it refers to without causing havoc. It is safe however if + * you remove that local variable, too. + * + * @param access_flags access qualifiers + * @param return_type method type + * @param arg_types argument types + * @param arg_names argument names (if this is null, default names will be + * provided for them) + * @param method_name name of method + * @param class_name class name containing this method (may be null, if you + * don't care) + * @param il instruction list associated with this method, may be null only + * for abstract or native methods + * @param cp constant pool + */ + public MethodGen(final int access_flags, final Type return_type, final Type[] arg_types, String[] arg_names, + final String method_name, final String class_name, final InstructionList il, final ConstantPoolGen cp) { + super(access_flags); + setType(return_type); + setArgumentTypes(arg_types); setArgumentNames(arg_names); - } - - if(!abstract_) { - for(int i=0; i < size; i++) { - addLocalVariable(arg_names[i], arg_types[i], start, end); - } - } - } - } - - /** - * Instantiate from existing method. - * - * @param m method - * @param class_name class name containing this method - * @param cp constant pool - */ - public MethodGen(Method m, String class_name, ConstantPoolGen cp) { - this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), - Type.getArgumentTypes(m.getSignature()), null /* may be overridden anyway */, - m.getName(), class_name, - ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0)? - new InstructionList(m.getCode().getCode()) : null, - cp); - - Attribute[] attributes = m.getAttributes(); - for(int i=0; i < attributes.length; i++) { - Attribute a = attributes[i]; - - if(a instanceof Code) { - Code c = (Code)a; - setMaxStack(c.getMaxStack()); - setMaxLocals(c.getMaxLocals()); - - CodeException[] ces = c.getExceptionTable(); - - if(ces != null) { - for(int j=0; j < ces.length; j++) { - CodeException ce = ces[j]; - int type = ce.getCatchType(); - ObjectType c_type = null; - - if(type > 0) { - String cen = m.getConstantPool().getConstantString(type, Constants.CONSTANT_Class); - c_type = new ObjectType(cen); + setName(method_name); + setClassName(class_name); + setInstructionList(il); + setConstantPool(cp); + final 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", ObjectType.getInstance(class_name), start, end); } + } + if (arg_types != null) { + final int size = arg_types.length; + for (final Type arg_type : arg_types) { + if (Type.VOID == arg_type) { + 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); + } + } + } + } - 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(); + /** + * Instantiate from existing method. + * + * @param m method + * @param class_name class name containing this method + * @param cp constant pool + */ + public MethodGen(final Method m, final String class_name, final ConstantPoolGen cp) { + this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), Type.getArgumentTypes(m + .getSignature()), null /* may be overridden anyway */, m.getName(), class_name, + ((m.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0) + ? new InstructionList(m.getCode().getCode()) + : null, cp); + final Attribute[] attributes = m.getAttributes(); + for (final Attribute attribute : attributes) { + Attribute a = attribute; + if (a instanceof Code) { + final Code c = (Code) a; + setMaxStack(c.getMaxStack()); + setMaxLocals(c.getMaxLocals()); + final CodeException[] ces = c.getExceptionTable(); + if (ces != null) { + for (final CodeException ce : ces) { + final int type = ce.getCatchType(); + ObjectType c_type = null; + if (type > 0) { + final String cen = m.getConstantPool().getConstantString(type, + Const.CONSTANT_Class); + c_type = ObjectType.getInstance(cen); + } + final int end_pc = ce.getEndPC(); + final int length = m.getCode().getCode().length; + InstructionHandle end; + if (length == end_pc) { // May happen, because end_pc is exclusive + end = il.getEnd(); + } else { + end = il.findHandle(end_pc); + end = end.getPrev(); // Make it inclusive + } + addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce + .getHandlerPC()), c_type); + } + } + final Attribute[] c_attributes = c.getAttributes(); + for (final Attribute c_attribute : c_attributes) { + a = c_attribute; + if (a instanceof LineNumberTable) { + final LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable(); + for (final LineNumber l : ln) { + final InstructionHandle ih = il.findHandle(l.getStartPC()); + if (ih != null) { + addLineNumber(ih, l.getLineNumber()); + } + } + } else if (a instanceof LocalVariableTable) { + final LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable(); + removeLocalVariables(); + repairHandles(lv, false); + } else if (a instanceof LocalVariableTypeTable) { + LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable(); + removeLocalVariableTypes(); + repairHandles(lv, true); + } else { + addCodeAttribute(a); + } + } + } else if (a instanceof ExceptionTable) { + final String[] names = ((ExceptionTable) a).getExceptionNames(); + for (final String name2 : names) { + addException(name2); + } + } else if (a instanceof Annotations) { + final Annotations runtimeAnnotations = (Annotations) a; + final AnnotationEntry[] aes = runtimeAnnotations.getAnnotationEntries(); + for (final AnnotationEntry element : aes) { + addAnnotationEntry(new AnnotationEntryGen(element, cp, false)); + } } else { - end = il.findHandle(end_pc); - end = end.getPrev(); // Make it inclusive + addAttribute(a); } - - addExceptionHandler(il.findHandle(ce.getStartPC()), end, - il.findHandle(ce.getHandlerPC()), c_type); - } } + } - Attribute[] c_attributes = c.getAttributes(); - for(int j=0; j < c_attributes.length; j++) { - a = c_attributes[j]; - - if(a instanceof LineNumberTable) { - LineNumber[] ln = ((LineNumberTable)a).getLineNumberTable(); - - for(int k=0; k < ln.length; k++) { - LineNumber l = ln[k]; - addLineNumber(il.findHandle(l.getStartPC()), l.getLineNumber()); - } - } else if(a instanceof LocalVariableTable) { - LocalVariable[] lv = ((LocalVariableTable)a).getLocalVariableTable(); - - removeLocalVariables(); - - for(int k=0; k < lv.length; k++) { - LocalVariable l = lv[k]; - InstructionHandle start = il.findHandle(l.getStartPC()); - InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); - - // Repair malformed handles - if(null == start) { + private void repairHandles(final LocalVariable[] lv, boolean isLVT) { + for (int k = 0; k < lv.length; k++) { + LocalVariable l = lv[k]; + InstructionHandle start = il.findHandle(l.getStartPC()); + InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); + // Repair malformed handles + if (null == start) { start = il.getStart(); - } - - if(null == end) { + } + if (null == end) { end = il.getEnd(); - } - - addLocalVariable(l.getName(), Type.getType(l.getSignature()), - l.getIndex(), start, end); } - } else if (a instanceof LocalVariableTypeTable) { - LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable(); - removeLocalVariableTypes(); - for (int k = 0; k < lv.length; k++) { - LocalVariable l = lv[k]; - InstructionHandle start = il.findHandle(l.getStartPC()); - InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); - // Repair malformed handles - if (null == start) { - start = il.getStart(); - } - if (null == end) { - end = il.getEnd(); - } - addLocalVariableType(l.getName(), Type.getType(l.getSignature()), l - .getIndex(), start, end); - } - } else - addCodeAttribute(a); - } - } else if(a instanceof ExceptionTable) { - String[] names = ((ExceptionTable)a).getExceptionNames(); - for(int j=0; j < names.length; j++) - addException(names[j]); - } else - addAttribute(a); - } - } - - /** - * Adds a local variable to this method. - * - * @param name variable name - * @param type variable type - * @param slot the index of the local variable, if type is long or double, the next available - * index is slot+2 - * @param start from where the variable is valid - * @param end until where the variable is valid - * @return new local variable object - * @see LocalVariable - */ - public LocalVariableGen addLocalVariable(String name, Type type, int slot, - InstructionHandle start, - InstructionHandle end) { - byte t = type.getType(); - - if(t != Constants.T_ADDRESS) { - int add = type.getSize(); - - if(slot + add > max_locals) - max_locals = slot + add; - - LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); - int i; - - if((i = variable_vec.indexOf(l)) >= 0) // Overwrite if necessary - variable_vec.set(i, l); - else - variable_vec.add(l); - - return l; - } else { - throw new IllegalArgumentException("Can not use " + type + - " as type for local variable"); - - } - } - - /** - * Adds a local variable to this method and assigns an index automatically. - * - * @param name variable name - * @param type variable type - * @param start from where the variable is valid, if this is null, - * it is valid from the start - * @param end until where the variable is valid, if this is null, - * it is valid to the end - * @return new local variable object - * @see LocalVariable - */ - public LocalVariableGen addLocalVariable(String name, Type type, - InstructionHandle start, - InstructionHandle end) { - return addLocalVariable(name, type, max_locals, start, end); - } - - /** - * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable - * with an explicit index argument. - */ - public void removeLocalVariable(LocalVariableGen l) { - variable_vec.remove(l); - } - - /** - * Remove all local variables. - */ - public void removeLocalVariables() { - variable_vec.clear(); - } - - /** - * Sort local variables by index - */ - private static final void sort(LocalVariableGen[] vars, int l, int r) { - int i = l, j = r; - int m = vars[(l + r) / 2].getIndex(); - LocalVariableGen h; - - do { - while(vars[i].getIndex() < m) i++; - while(m < vars[j].getIndex()) j--; - - if(i <= j) { - h=vars[i]; vars[i]=vars[j]; vars[j]=h; // Swap elements - i++; j--; - } - } while(i <= j); - - if(l < j) sort(vars, l, j); - if(i < r) sort(vars, i, r); - } - - /* - * If the range of the variable has not been set yet, it will be set to be valid from - * the start to the end of the instruction list. - * - * @return array of declared local variables sorted by index - */ - public LocalVariableGen[] getLocalVariables() { - int size = variable_vec.size(); - LocalVariableGen[] lg = new LocalVariableGen[size]; - variable_vec.toArray(lg); - - for(int i=0; i < size; i++) { - if(lg[i].getStart() == null) - lg[i].setStart(il.getStart()); - - if(lg[i].getEnd() == null) - lg[i].setEnd(il.getEnd()); - } - - if(size > 1) - sort(lg, 0, size - 1); - - return lg; - } - - /* - * If the range of the variable has not been set yet, it will be set to be - * val id from the start to the end of the instruction list. - * - * @return array of declared local variable types sorted by index - */ - private LocalVariableGen[] getLocalVariableTypes() { - int size = type_vec.size(); - LocalVariableGen[] lg = new LocalVariableGen[size]; - type_vec.toArray(lg); - - for(int i=0; i < size; i++) { - if(lg[i].getStart() == null) - lg[i].setStart(il.getStart()); - - if(lg[i].getEnd() == null) - lg[i].setEnd(il.getEnd()); - } - - if(size > 1) - sort(lg, 0, size - 1); - - return lg; - } - - /** - * @return `LocalVariableTable' attribute of all the local variables of this method. - */ - public LocalVariableTable getLocalVariableTable(ConstantPoolGen cp) { - LocalVariableGen[] lg = getLocalVariables(); - int size = lg.length; - LocalVariable[] lv = new LocalVariable[size]; - - for(int i=0; i < size; i++) - lv[i] = lg[i].getLocalVariable(cp); - - return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), - 2 + lv.length * 10, lv, cp.getConstantPool()); - } - - /** - * @return `LocalVariableTypeTable' attribute of all the local variable - * types of this method. - */ - public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) { - LocalVariableGen[] lg = getLocalVariableTypes(); - int size = lg.length; - LocalVariable[] lv = new LocalVariable[size]; - - for(int i=0; i < size; i++) - lv[i] = lg[i].getLocalVariable(cp); - - return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"), - 2 + lv.length * 10, lv, cp.getConstantPool()); - } - - /** - * Adds a local variable type to this method. - * - * @param name variable name - * @param type variable type - * @param slot the index of the local variable, if type is long or double, the next available - * index is slot+2 - * @param start from where the variable is valid - * @param end until where the variable is valid - * @return new local variable object - * @see LocalVariable - */ - private LocalVariableGen addLocalVariableType(String name, Type type, int slot, - InstructionHandle start, - InstructionHandle end) { - byte t = type.getType(); - - if(t != Constants.T_ADDRESS) { - int add = type.getSize(); - - if(slot + add > max_locals) - max_locals = slot + add; - - LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); - int i; - - if((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary - type_vec.set(i, l); - else - type_vec.add(l); - - return l; - } else { - throw new IllegalArgumentException("Can not use " + type + - " as type for local variable"); - - } - } - - /** - * Remove all local variable types. - */ - private void removeLocalVariableTypes() { - type_vec.clear(); - } - - /** - * Give an instruction a line number corresponding to the source code line. - * - * @param ih instruction to tag - * @return new line number object - * @see LineNumber - */ - public LineNumberGen addLineNumber(InstructionHandle ih, int src_line) { - LineNumberGen l = new LineNumberGen(ih, src_line); - line_number_vec.add(l); - return l; - } - - /** - * Remove a line number. - */ - public void removeLineNumber(LineNumberGen l) { - line_number_vec.remove(l); - } - - /** - * Remove all line numbers. - */ - public void removeLineNumbers() { - line_number_vec.clear(); - } - - /* - * @return array of line numbers - */ - public LineNumberGen[] getLineNumbers() { - LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()]; - line_number_vec.toArray(lg); - return lg; - } - - /** - * @return `LineNumberTable' attribute of all the local variables of this method. - */ - public LineNumberTable getLineNumberTable(ConstantPoolGen cp) { - int size = line_number_vec.size(); - LineNumber[] ln = new LineNumber[size]; - - try { - for(int i=0; i < size; i++) - ln[i] = ((LineNumberGen)line_number_vec.get(i)).getLineNumber(); - } catch(ArrayIndexOutOfBoundsException e) {} // Never occurs - - return new LineNumberTable(cp.addUtf8("LineNumberTable"), - 2 + ln.length * 4, ln, cp.getConstantPool()); - } - - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. - * - * @param start_pc Start of region (inclusive) - * @param end_pc End of region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type class type of handled exception or null if any - * exception is handled - * @return new exception handler object - */ - public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc, - InstructionHandle end_pc, - InstructionHandle handler_pc, - ObjectType catch_type) { - if((start_pc == null) || (end_pc == null) || (handler_pc == null)) - throw new ClassGenException("Exception handler target is null instruction"); - - CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, - handler_pc, catch_type); - exception_vec.add(c); - return c; - } - - /** - * Remove an exception handler. - */ - public void removeExceptionHandler(CodeExceptionGen c) { - exception_vec.remove(c); - } - - /** - * Remove all line numbers. - */ - public void removeExceptionHandlers() { - exception_vec.clear(); - } - - /* - * @return array of declared exception handlers - */ - public CodeExceptionGen[] getExceptionHandlers() { - CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()]; - exception_vec.toArray(cg); - return cg; - } - - /** - * @return code exceptions for `Code' attribute - */ - private CodeException[] getCodeExceptions() { - int size = exception_vec.size(); - CodeException[] c_exc = new CodeException[size]; - - try { - for(int i=0; i < size; i++) { - CodeExceptionGen c = (CodeExceptionGen)exception_vec.get(i); - c_exc[i] = c.getCodeException(cp); - } - } catch(ArrayIndexOutOfBoundsException e) {} - - return c_exc; - } - - /** - * Add an exception possibly thrown by this method. - * - * @param class_name (fully qualified) name of exception - */ - public void addException(String class_name) { - throws_vec.add(class_name); - } - - /** - * Remove an exception. - */ - public void removeException(String c) { - throws_vec.remove(c); - } - - /** - * Remove all exceptions. - */ - public void removeExceptions() { - throws_vec.clear(); - } - - /* - * @return array of thrown exceptions - */ - public String[] getExceptions() { - String[] e = new String[throws_vec.size()]; - throws_vec.toArray(e); - return e; - } - - /** - * @return `Exceptions' attribute of all the exceptions thrown by this method. - */ - private ExceptionTable getExceptionTable(ConstantPoolGen cp) { - int size = throws_vec.size(); - int[] ex = new int[size]; - - try { - for(int i=0; i < size; i++) - ex[i] = cp.addClass((String)throws_vec.get(i)); - } catch(ArrayIndexOutOfBoundsException e) {} - - return new ExceptionTable(cp.addUtf8("Exceptions"), - 2 + 2 * size, ex, cp.getConstantPool()); - } - - /** - * Add an attribute to the code. Currently, the JVM knows about the - * LineNumberTable, LocalVariableTable and StackMap attributes, - * where the former two will be generated automatically and the - * latter is used for the MIDP only. Other attributes will be - * ignored by the JVM but do no harm. - * - * @param a attribute to be added - */ - public void addCodeAttribute(Attribute a) { code_attrs_vec.add(a); } - - /** - * Remove a code attribute. - */ - public void removeCodeAttribute(Attribute a) { code_attrs_vec.remove(a); } - - /** - * Remove all code attributes. - */ - public void removeCodeAttributes() { - code_attrs_vec.clear(); - } - - /** - * @return all attributes of this method. - */ - public Attribute[] getCodeAttributes() { - Attribute[] attributes = new Attribute[code_attrs_vec.size()]; - code_attrs_vec.toArray(attributes); - return attributes; - } - - /** - * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively, - * before calling this method (the same applies for max locals). - * - * @return method object - */ - public Method getMethod() { - String signature = getSignature(); - int name_index = cp.addUtf8(name); - int signature_index = cp.addUtf8(signature); - - /* Also updates positions of instructions, i.e., their indices - */ - byte[] byte_code = null; - - if(il != null) - byte_code = il.getByteCode(); - - LineNumberTable lnt = null; - LocalVariableTable lvt = null; - LocalVariableTypeTable lvtt = null; - - /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable - * attributes (for debuggers, e.g.) - */ - if((variable_vec.size() > 0) && !strip_attributes) - addCodeAttribute(lvt = getLocalVariableTable(cp)); - - if((type_vec.size() > 0) && !strip_attributes) - addCodeAttribute(lvtt = getLocalVariableTypeTable(cp)); - - if((line_number_vec.size() > 0) && !strip_attributes) - addCodeAttribute(lnt = getLineNumberTable(cp)); - - Attribute[] code_attrs = getCodeAttributes(); - - /* Each attribute causes 6 additional header bytes - */ - int attrs_len = 0; - for(int i=0; i < code_attrs.length; i++) - attrs_len += (code_attrs[i].getLength() + 6); - - CodeException[] c_exc = getCodeExceptions(); - int exc_len = c_exc.length * 8; // Every entry takes 8 bytes - - Code code = null; - - if((il != null) && !isAbstract()) { - // Remove any stale code attribute - Attribute[] attributes = getAttributes(); - for(int i=0; i < attributes.length; i++) { - Attribute a = attributes[i]; - - if(a instanceof Code) - removeAttribute(a); - } - - code = new Code(cp.addUtf8("Code"), - 8 + byte_code.length + // prologue byte code - 2 + exc_len + // exceptions - 2 + attrs_len, // attributes - max_stack, max_locals, - byte_code, c_exc, - code_attrs, - cp.getConstantPool()); - - addAttribute(code); - } - - ExceptionTable et = null; - - if(throws_vec.size() > 0) - addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses - - Method m = new Method(access_flags, name_index, signature_index, - getAttributes(), cp.getConstantPool()); - - // Undo effects of adding attributes - if(lvt != null) removeCodeAttribute(lvt); - if(lvtt != null) removeCodeAttribute(lvtt); - if(lnt != null) removeCodeAttribute(lnt); - if(code != null) removeAttribute(code); - if(et != null) removeAttribute(et); - - return m; - } - - /** - * Remove all NOPs from the instruction list (if possible) and update every - * object refering to them, i.e., branch instructions, local variables and - * exception handlers. - */ - public void removeNOPs() { - if(il != null) { - InstructionHandle next; - /* Check branch instructions. - */ - for(InstructionHandle ih = il.getStart(); ih != null; ih = next) { - next = ih.next; - - if((next != null) && (ih.getInstruction() instanceof NOP)) { - try { - il.delete(ih); - } catch(TargetLostException e) { - InstructionHandle[] targets = e.getTargets(); - - for(int i=0; i < targets.length; i++) { - InstructionTargeter[] targeters = targets[i].getTargeters(); - - for(int j=0; j < targeters.length; j++) - targeters[j].updateTarget(targets[i], next); + if (isLVT) { + addLocalVariableType(l.getName(), Type.getType(l.getSignature()), + l.getIndex(), start, end); + } else { + addLocalVariable(l.getName(), Type.getType(l.getSignature()), + l.getIndex(), start, end); } - } } - } - } - } - - /** - * Set maximum number of local variables. - */ - public void setMaxLocals(int m) { max_locals = m; } - public int getMaxLocals() { return max_locals; } - - /** - * Set maximum stack size for this method. - */ - public void setMaxStack(int m) { max_stack = m; } - public int getMaxStack() { return max_stack; } - - /** @return class that contains this method - */ - public String getClassName() { return class_name; } - public void setClassName(String class_name) { this.class_name = class_name; } - - public void setReturnType(Type return_type) { setType(return_type); } - public Type getReturnType() { return getType(); } - - public void setArgumentTypes(Type[] arg_types) { this.arg_types = arg_types; } - public Type[] getArgumentTypes() { return (Type[])arg_types.clone(); } - public void setArgumentType(int i, Type type) { arg_types[i] = type; } - public Type getArgumentType(int i) { return arg_types[i]; } - - public void setArgumentNames(String[] arg_names) { this.arg_names = arg_names; } - public String[] getArgumentNames() { return (String[])arg_names.clone(); } - public void setArgumentName(int i, String name) { arg_names[i] = name; } - public String getArgumentName(int i) { return arg_names[i]; } - - public InstructionList getInstructionList() { return il; } - public void setInstructionList(InstructionList il) { this.il = il; } - - public String getSignature() { - return Type.getMethodSignature(type, arg_types); - } - - /** - * Computes max. stack size by performing control flow analysis. - */ - public void setMaxStack() { - if(il != null) - max_stack = getMaxStack(cp, il, getExceptionHandlers()); - else - max_stack = 0; - } - - /** - * Compute maximum number of local variables. - */ - public void setMaxLocals() { - if(il != null) { - int max = isStatic()? 0 : 1; - - if(arg_types != null) - for(int i=0; i < arg_types.length; i++) - max += arg_types[i].getSize(); - - for(InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { - Instruction ins = ih.getInstruction(); - - if((ins instanceof LocalVariableInstruction) || - (ins instanceof RET) || (ins instanceof IINC)) - { - int index = ((IndexedInstruction)ins).getIndex() + - ((TypedInstruction)ins).getType(cp).getSize(); - - if(index > max) - max = index; - } - } - - max_locals = max; - } else - max_locals = 0; - } - - /** Do not/Do produce attributes code attributesLineNumberTable and - * LocalVariableTable, like javac -O - */ - public void stripAttributes(boolean flag) { strip_attributes = flag; } - - static final class BranchTarget { - InstructionHandle target; - int stackDepth; - - BranchTarget(InstructionHandle target, int stackDepth) { - this.target = target; - this.stackDepth = stackDepth; - } - } - - static final class BranchStack { - Stack branchTargets = new Stack(); - Hashtable visitedTargets = new Hashtable(); - - public void push(InstructionHandle target, int stackDepth) { - if(visited(target)) - return; - - branchTargets.push(visit(target, stackDepth)); } - public BranchTarget pop() { - if(!branchTargets.empty()) { - BranchTarget bt = (BranchTarget) branchTargets.pop(); - return bt; - } - - return null; - } - - private final BranchTarget visit(InstructionHandle target, int stackDepth) { - BranchTarget bt = new BranchTarget(target, stackDepth); - visitedTargets.put(target, bt); - - return bt; - } - - private final boolean visited(InstructionHandle target) { - return (visitedTargets.get(target) != null); - } - } - - /** - * Computes stack usage of an instruction list by performing control flow analysis. - * - * @return maximum stack depth used by method - */ - public static int getMaxStack(ConstantPoolGen cp, InstructionList il, CodeExceptionGen[] et) { - BranchStack branchTargets = new BranchStack(); - - /* Initially, populate the branch stack with the exception - * handlers, because these aren't (necessarily) branched to - * explicitly. in each case, the stack will have depth 1, - * containing the exception object. + /** + * Adds a local variable to this method. + * + * @param name variable name + * @param type variable type + * @param slot the index of the local variable, if type is long or double, + * the next available index is slot+2 + * @param start from where the variable is valid + * @param end until where the variable is valid + * @return new local variable object + * @see LocalVariable */ - for (int i = 0; i < et.length; i++) { - InstructionHandle handler_pc = et[i].getHandlerPC(); - if (handler_pc != null) - branchTargets.push(handler_pc, 1); - } + public LocalVariableGen addLocalVariable(final String name, final Type type, final int slot, + final InstructionHandle start, final InstructionHandle end) { - int stackDepth = 0, maxStackDepth = 0; - InstructionHandle ih = il.getStart(); - - while(ih != null) { - Instruction instruction = ih.getInstruction(); - short opcode = instruction.getOpcode(); - int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); - - stackDepth += delta; - if(stackDepth > maxStackDepth) - maxStackDepth = stackDepth; - - // choose the next instruction based on whether current is a branch. - if(instruction instanceof BranchInstruction) { - BranchInstruction branch = (BranchInstruction) instruction; - if(instruction instanceof Select) { - // explore all of the select's targets. the default target is handled below. - Select select = (Select) branch; - InstructionHandle[] targets = select.getTargets(); - for (int i = 0; i < targets.length; i++) - branchTargets.push(targets[i], stackDepth); - // nothing to fall through to. - ih = null; - } else if(!(branch instanceof IfInstruction)) { - // if an instruction that comes back to following PC, - // push next instruction, with stack depth reduced by 1. - if(opcode == Constants.JSR || opcode == Constants.JSR_W) - branchTargets.push(ih.getNext(), stackDepth - 1); - ih = null; + final byte t = type.getType(); + if (t != Const.T_ADDRESS) { + final int add = type.getSize(); + if (slot + add > max_locals) { + max_locals = slot + add; + } + final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); + int i; + if ((i = variable_vec.indexOf(l)) >= 0) { + variable_vec.set(i, l); + } else { + variable_vec.add(l); + } + return l; } - // 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; + throw new IllegalArgumentException("Can not use " + type + + " as type for local variable"); + } + + /** + * Adds a local variable to this method and assigns an index automatically. + * + * @param name variable name + * @param type variable type + * @param start from where the variable is valid, if this is null, it is + * valid from the start + * @param end until where the variable is valid, if this is null, it is + * valid to the end + * @return new local variable object + * @see LocalVariable + */ + public LocalVariableGen addLocalVariable(final String name, final Type type, + final InstructionHandle start, final InstructionHandle end) { + return addLocalVariable(name, type, max_locals, start, end); + } + + /** + * Remove a local variable, its slot will not be reused, if you do not use + * addLocalVariable with an explicit index argument. + */ + public void removeLocalVariable(final LocalVariableGen l) { + variable_vec.remove(l); + } + + /** + * Remove all local variables. + */ + public void removeLocalVariables() { + variable_vec.clear(); + } + + /* + * 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() { + return getLocalVariableOrTypes(false); + } + + /* + * 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 variable types sorted by index + */ + private LocalVariableGen[] getLocalVariableTypes() { + return getLocalVariableOrTypes(true); + } + + /* + * If the range of the variable or type 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 or types sorted by index + */ + private LocalVariableGen[] getLocalVariableOrTypes(boolean isLVT) { + int size = (isLVT) ? type_vec.size() : variable_vec.size(); + LocalVariableGen[] lg = new LocalVariableGen[size]; + if (isLVT) { + type_vec.toArray(lg); + } else { + variable_vec.toArray(lg); } - } + + for (int i = 0; i < size; i++) { + if (lg[i].getStart() == null) { + lg[i].setStart(il.getStart()); + } + + if (lg[i].getEnd() == null) { + lg[i].setEnd(il.getEnd()); + } + } + + if (size > 1) { + Arrays.sort(lg, new Comparator() { + @Override + public int compare(final LocalVariableGen o1, final LocalVariableGen o2) { + return o1.getIndex() - o2.getIndex(); + } + }); + } + + return lg; } - return maxStackDepth; - } - - private ArrayList observers; - - /** Add observer for this object. - */ - public void addObserver(MethodObserver o) { - if(observers == null) - observers = new ArrayList(); - - observers.add(o); - } - - /** Remove observer for this object. - */ - public void removeObserver(MethodObserver o) { - if(observers != null) - observers.remove(o); - } - - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if(observers != null) - for(Iterator e = observers.iterator(); e.hasNext(); ) - ((MethodObserver)e.next()).notify(this); - } - - /** - * Return string representation close to declaration format, - * `public static void _main(String[]) throws IOException', e.g. - * - * @return String representation of the method. - */ - public final String toString() { - String access = Utility.accessToString(access_flags); - String signature = Type.getMethodSignature(type, arg_types); - - signature = Utility.methodSignatureToString(signature, name, access, - true, getLocalVariableTable(cp)); - - StringBuffer buf = new StringBuffer(signature); - - if(throws_vec.size() > 0) { - for(Iterator e = throws_vec.iterator(); e.hasNext(); ) - buf.append("\n\t\tthrows " + e.next()); + /** + * @return `LocalVariableTable' attribute of all the local variables of this + * method. + */ + public LocalVariableTable getLocalVariableTable(final ConstantPoolGen cp) { + final LocalVariableGen[] lg = getLocalVariables(); + final int size = lg.length; + final LocalVariable[] lv = new LocalVariable[size]; + for (int i = 0; i < size; i++) { + lv[i] = lg[i].getLocalVariable(cp); + } + return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp + .getConstantPool()); } - return buf.toString(); - } + /** + * @return `LocalVariableTypeTable' attribute of all the local variable + * types of this method. + */ + public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) { + LocalVariableGen[] lg = getLocalVariableTypes(); + int size = lg.length; + LocalVariable[] lv = new LocalVariable[size]; - /** @return deep copy of this method - */ - public MethodGen copy(String class_name, ConstantPoolGen cp) { - Method m = ((MethodGen)clone()).getMethod(); - MethodGen mg = new MethodGen(m, class_name, this.cp); + for (int i = 0; i < size; i++) { + lv[i] = lg[i].getLocalVariable(cp); + } - if(this.cp != cp) { - mg.setConstantPool(cp); - mg.getInstructionList().replaceConstantPool(this.cp, cp); + return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"), + 2 + lv.length * 10, lv, cp.getConstantPool()); } - return mg; - } + /** + * Adds a local variable type to this method. + * + * @param name variable name + * @param type variable type + * @param slot the index of the local variable, if type is long or double, + * the next available index is slot+2 + * @param start from where the variable is valid + * @param end until where the variable is valid + * @return new local variable object + * @see LocalVariable + */ + private LocalVariableGen addLocalVariableType(String name, Type type, int slot, + InstructionHandle start, + InstructionHandle end) { + byte t = type.getType(); + + if (t != Const.T_ADDRESS) { + int add = type.getSize(); + + if (slot + add > max_locals) { + max_locals = slot + add; + } + + LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end); + int i; + + if ((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary + { + type_vec.set(i, l); + } else { + type_vec.add(l); + } + + return l; + } else { + throw new IllegalArgumentException("Can not use " + type + + " as type for local variable"); + } + } + + /** + * Remove all local variable types. + */ + private void removeLocalVariableTypes() { + type_vec.clear(); + } + + /** + * 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(final InstructionHandle ih, final int src_line) { + final LineNumberGen l = new LineNumberGen(ih, src_line); + line_number_vec.add(l); + return l; + } + + /** + * Remove a line number. + */ + public void removeLineNumber(final LineNumberGen l) { + line_number_vec.remove(l); + } + + /** + * Remove all line numbers. + */ + public void removeLineNumbers() { + line_number_vec.clear(); + } + + /* + * @return array of line numbers + */ + public LineNumberGen[] getLineNumbers() { + final LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()]; + line_number_vec.toArray(lg); + return lg; + } + + /** + * @return `LineNumberTable' attribute of all the local variables of this + * method. + */ + public LineNumberTable getLineNumberTable(final ConstantPoolGen cp) { + final int size = line_number_vec.size(); + final LineNumber[] ln = new LineNumber[size]; + for (int i = 0; i < size; i++) { + ln[i] = line_number_vec.get(i).getLineNumber(); + } + return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp + .getConstantPool()); + } + + /** + * Add an exception handler, i.e., specify region where a handler is active + * and an instruction where the actual handling is done. + * + * @param start_pc Start of region (inclusive) + * @param end_pc End of region (inclusive) + * @param handler_pc Where handling is done + * @param catch_type class type of handled exception or null if any + * exception is handled + * @return new exception handler object + */ + public CodeExceptionGen addExceptionHandler(final InstructionHandle start_pc, + final InstructionHandle end_pc, final InstructionHandle handler_pc, final ObjectType catch_type) { + if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) { + throw new ClassGenException("Exception handler target is null instruction"); + } + final CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type); + exception_vec.add(c); + return c; + } + + /** + * Remove an exception handler. + */ + public void removeExceptionHandler(final CodeExceptionGen c) { + exception_vec.remove(c); + } + + /** + * Remove all line numbers. + */ + public void removeExceptionHandlers() { + exception_vec.clear(); + } + + /* + * @return array of declared exception handlers + */ + public CodeExceptionGen[] getExceptionHandlers() { + final CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()]; + exception_vec.toArray(cg); + return cg; + } + + /** + * @return code exceptions for `Code' attribute + */ + private CodeException[] getCodeExceptions() { + final int size = exception_vec.size(); + final CodeException[] c_exc = new CodeException[size]; + for (int i = 0; i < size; i++) { + final CodeExceptionGen c = exception_vec.get(i); + c_exc[i] = c.getCodeException(super.getConstantPool()); + } + return c_exc; + } + + /** + * Add an exception possibly thrown by this method. + * + * @param class_name (fully qualified) name of exception + */ + public void addException(final String class_name) { + throws_vec.add(class_name); + } + + /** + * Remove an exception. + */ + public void removeException(final String c) { + throws_vec.remove(c); + } + + /** + * Remove all exceptions. + */ + public void removeExceptions() { + throws_vec.clear(); + } + + /* + * @return array of thrown exceptions + */ + public String[] getExceptions() { + final String[] e = new String[throws_vec.size()]; + throws_vec.toArray(e); + return e; + } + + /** + * @return `Exceptions' attribute of all the exceptions thrown by this + * method. + */ + private ExceptionTable getExceptionTable(final ConstantPoolGen cp) { + final int size = throws_vec.size(); + final int[] ex = new int[size]; + for (int i = 0; i < size; i++) { + ex[i] = cp.addClass(throws_vec.get(i)); + } + return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp.getConstantPool()); + } + + /** + * Add an attribute to the code. Currently, the JVM knows about the + * LineNumberTable, LocalVariableTable and StackMap attributes, where the + * former two will be generated automatically and the latter is used for the + * MIDP only. Other attributes will be ignored by the JVM but do no harm. + * + * @param a attribute to be added + */ + public void addCodeAttribute(final Attribute a) { + code_attrs_vec.add(a); + } + + /** + * Remove a code attribute. + */ + public void removeCodeAttribute(final Attribute a) { + code_attrs_vec.remove(a); + } + + /** + * Remove all code attributes. + */ + public void removeCodeAttributes() { + code_attrs_vec.clear(); + } + + /** + * @return all attributes of this method. + */ + public Attribute[] getCodeAttributes() { + final Attribute[] attributes = new Attribute[code_attrs_vec.size()]; + code_attrs_vec.toArray(attributes); + return attributes; + } + + /** + * @since 6.0 + */ + public void addAnnotationsAsAttribute(final ConstantPoolGen cp) { + final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); + for (final Attribute attr : attrs) { + addAttribute(attr); + } + } + + /** + * @since 6.0 + */ + public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { + if (!hasParameterAnnotations) { + return; + } + final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, param_annotations); + if (attrs != null) { + for (final Attribute attr : attrs) { + addAttribute(attr); + } + } + } + + /** + * 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() { + final String signature = getSignature(); + final ConstantPoolGen _cp = super.getConstantPool(); + final int name_index = _cp.addUtf8(super.getName()); + final int signature_index = _cp.addUtf8(signature); + /* Also updates positions of instructions, i.e., their indices + */ + byte[] byte_code = null; + if (il != null) { + byte_code = il.getByteCode(); + } + LineNumberTable lnt = null; + LocalVariableTable lvt = null; + LocalVariableTypeTable lvtt = null; + + /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable + * attributes (for debuggers, e.g.) + */ + if ((variable_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lvt = getLocalVariableTable(_cp)); + } + + if ((type_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lvtt = getLocalVariableTypeTable(_cp)); + } + + if ((line_number_vec.size() > 0) && !strip_attributes) { + addCodeAttribute(lnt = getLineNumberTable(_cp)); + } + final Attribute[] code_attrs = getCodeAttributes(); + /* Each attribute causes 6 additional header bytes + */ + int attrs_len = 0; + for (final Attribute code_attr : code_attrs) { + attrs_len += code_attr.getLength() + 6; + } + final CodeException[] c_exc = getCodeExceptions(); + final int exc_len = c_exc.length * 8; // Every entry takes 8 bytes + Code code = null; + if ((il != null) && !isAbstract() && !isNative()) { + // Remove any stale code attribute + final Attribute[] attributes = getAttributes(); + for (final Attribute a : attributes) { + if (a instanceof Code) { + removeAttribute(a); + } + } + code = new Code(_cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code + 2 + exc_len + // exceptions + 2 + attrs_len, // attributes + max_stack, max_locals, byte_code, c_exc, code_attrs, _cp.getConstantPool()); + addAttribute(code); + } + addAnnotationsAsAttribute(_cp); + addParameterAnnotationsAsAttribute(_cp); + ExceptionTable et = null; + if (throws_vec.size() > 0) { + addAttribute(et = getExceptionTable(_cp)); + // Add `Exceptions' if there are "throws" clauses + } + final Method m = new Method(super.getAccessFlags(), name_index, signature_index, getAttributes(), _cp + .getConstantPool()); + // Undo effects of adding attributes + if (lvt != null) { + removeCodeAttribute(lvt); + } + if (lvtt != null) { + removeCodeAttribute(lvtt); + } + if (lnt != null) { + removeCodeAttribute(lnt); + } + if (code != null) { + removeAttribute(code); + } + if (et != null) { + removeAttribute(et); + } + return m; + } + + /** + * Remove all NOPs from the instruction list (if possible) and update every + * object referring to them, i.e., branch instructions, local variables and + * exception handlers. + */ + public void removeNOPs() { + if (il != null) { + InstructionHandle next; + /* Check branch instructions. + */ + for (InstructionHandle ih = il.getStart(); ih != null; ih = next) { + next = ih.getNext(); + if ((next != null) && (ih.getInstruction() instanceof NOP)) { + try { + il.delete(ih); + } catch (final TargetLostException e) { + for (final InstructionHandle target : e.getTargets()) { + for (final InstructionTargeter targeter : target.getTargeters()) { + targeter.updateTarget(target, next); + } + } + } + } + } + } + } + + /** + * Set maximum number of local variables. + */ + public void setMaxLocals(final int m) { + max_locals = m; + } + + public int getMaxLocals() { + return max_locals; + } + + /** + * Set maximum stack size for this method. + */ + public void setMaxStack(final int m) { // TODO could be package-protected? + max_stack = m; + } + + public int getMaxStack() { + return max_stack; + } + + /** + * @return class that contains this method + */ + public String getClassName() { + return class_name; + } + + public void setClassName(final String class_name) { // TODO could be package-protected? + this.class_name = class_name; + } + + public void setReturnType(final Type return_type) { + setType(return_type); + } + + public Type getReturnType() { + return getType(); + } + + public void setArgumentTypes(final Type[] arg_types) { + this.arg_types = arg_types; + } + + public Type[] getArgumentTypes() { + return arg_types.clone(); + } + + public void setArgumentType(final int i, final Type type) { + arg_types[i] = type; + } + + public Type getArgumentType(final int i) { + return arg_types[i]; + } + + public void setArgumentNames(final String[] arg_names) { + this.arg_names = arg_names; + } + + public String[] getArgumentNames() { + return arg_names.clone(); + } + + public void setArgumentName(final int i, final String name) { + arg_names[i] = name; + } + + public String getArgumentName(final int i) { + return arg_names[i]; + } + + public InstructionList getInstructionList() { + return il; + } + + public void setInstructionList(final InstructionList il) { // TODO could be package-protected? + this.il = il; + } + + @Override + public String getSignature() { + return Type.getMethodSignature(super.getType(), arg_types); + } + + /** + * Computes max. stack size by performing control flow analysis. + */ + public void setMaxStack() { // TODO could be package-protected? (some tests would need repackaging) + if (il != null) { + max_stack = getMaxStack(super.getConstantPool(), il, getExceptionHandlers()); + } else { + max_stack = 0; + } + } + + /** + * Compute maximum number of local variables. + */ + public void setMaxLocals() { // TODO could be package-protected? (some tests would need repackaging) + if (il != null) { + int max = isStatic() ? 0 : 1; + if (arg_types != null) { + for (final Type arg_type : arg_types) { + max += arg_type.getSize(); + } + } + for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { + final Instruction ins = ih.getInstruction(); + if ((ins instanceof LocalVariableInstruction) || (ins instanceof RET) + || (ins instanceof IINC)) { + final int index = ((IndexedInstruction) ins).getIndex() + + ((TypedInstruction) ins).getType(super.getConstantPool()).getSize(); + if (index > max) { + max = index; + } + } + } + max_locals = max; + } else { + max_locals = 0; + } + } + + /** + * Do not/Do produce attributes code attributesLineNumberTable and + * LocalVariableTable, like javac -O + */ + public void stripAttributes(final boolean flag) { + strip_attributes = flag; + } + + static final class BranchTarget { + + final InstructionHandle target; + final int stackDepth; + + BranchTarget(final InstructionHandle target, final int stackDepth) { + this.target = target; + this.stackDepth = stackDepth; + } + } + + static final class BranchStack { + + private final Stack branchTargets = new Stack<>(); + private final Map visitedTargets = new HashMap<>(); + + public void push(final InstructionHandle target, final int stackDepth) { + if (visited(target)) { + return; + } + branchTargets.push(visit(target, stackDepth)); + } + + public BranchTarget pop() { + if (!branchTargets.empty()) { + final BranchTarget bt = branchTargets.pop(); + return bt; + } + return null; + } + + private BranchTarget visit(final InstructionHandle target, final int stackDepth) { + final BranchTarget bt = new BranchTarget(target, stackDepth); + visitedTargets.put(target, bt); + return bt; + } + + private boolean visited(final 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(final ConstantPoolGen cp, final InstructionList il, + final CodeExceptionGen[] et) { + final BranchStack branchTargets = new BranchStack(); + /* Initially, populate the branch stack with the exception + * handlers, because these aren't (necessarily) branched to + * explicitly. in each case, the stack will have depth 1, + * containing the exception object. + */ + for (final CodeExceptionGen element : et) { + final InstructionHandle handler_pc = element.getHandlerPC(); + if (handler_pc != null) { + branchTargets.push(handler_pc, 1); + } + } + int stackDepth = 0; + int maxStackDepth = 0; + InstructionHandle ih = il.getStart(); + while (ih != null) { + final Instruction instruction = ih.getInstruction(); + final short opcode = instruction.getOpcode(); + final int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); + stackDepth += delta; + if (stackDepth > maxStackDepth) { + maxStackDepth = stackDepth; + } + // choose the next instruction based on whether current is a branch. + if (instruction instanceof BranchInstruction) { + final BranchInstruction branch = (BranchInstruction) instruction; + if (instruction instanceof Select) { + // explore all of the select's targets. the default target is handled below. + final Select select = (Select) branch; + final InstructionHandle[] targets = select.getTargets(); + for (final InstructionHandle target : targets) { + branchTargets.push(target, stackDepth); + } + // nothing to fall through to. + ih = null; + } else if (!(branch instanceof IfInstruction)) { + // if an instruction that comes back to following PC, + // push next instruction, with stack depth reduced by 1. + if (opcode == Const.JSR || opcode == Const.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 == Const.ATHROW || opcode == Const.RET + || (opcode >= Const.IRETURN && opcode <= Const.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) { + final BranchTarget bt = branchTargets.pop(); + if (bt != null) { + ih = bt.target; + stackDepth = bt.stackDepth; + } + } + } + return maxStackDepth; + } + + private List observers; + + /** + * Add observer for this object. + */ + public void addObserver(final MethodObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); + } + + /** + * Remove observer for this object. + */ + public void removeObserver(final MethodObserver o) { + if (observers != null) { + observers.remove(o); + } + } + + /** + * Call notify() method on all observers. This method is not called + * automatically whenever the state has changed, but has to be called by the + * user after he has finished editing the object. + */ + public void update() { + if (observers != null) { + for (final MethodObserver observer : observers) { + observer.notify(this); + } + } + } + + /** + * Return string representation close to declaration format, e.g. public + * static void main(String[]) throws IOException' + * + * @return String representation of the method. + */ + @Override + public final String toString() { + final String access = Utility.accessToString(super.getAccessFlags()); + String signature = Type.getMethodSignature(super.getType(), arg_types); + signature = Utility.methodSignatureToString(signature, super.getName(), access, true, + getLocalVariableTable(super.getConstantPool())); + final StringBuilder buf = new StringBuilder(signature); + for (final Attribute a : getAttributes()) { + if (!((a instanceof Code) || (a instanceof ExceptionTable))) { + buf.append(" [").append(a).append("]"); + } + } + + if (throws_vec.size() > 0) { + for (final String throwsDescriptor : throws_vec) { + buf.append("\n\t\tthrows ").append(throwsDescriptor); + } + } + return buf.toString(); + } + + /** + * @return deep copy of this method + */ + public MethodGen copy(final String class_name, final ConstantPoolGen cp) { + final Method m = ((MethodGen) clone()).getMethod(); + final MethodGen mg = new MethodGen(m, class_name, super.getConstantPool()); + if (super.getConstantPool() != cp) { + mg.setConstantPool(cp); + mg.getInstructionList().replaceConstantPool(super.getConstantPool(), cp); + } + return mg; + } + + //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 + * + * @since 6.0 + */ + public List getAnnotationsOnParameter(final int i) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations || i > arg_types.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 + final Attribute[] attrs = getAttributes(); + ParameterAnnotations paramAnnVisAttr = null; + ParameterAnnotations paramAnnInvisAttr = null; + for (final Attribute attribute : attrs) { + if (attribute instanceof ParameterAnnotations) { + // Initialize param_annotations + if (!hasParameterAnnotations) { + @SuppressWarnings("unchecked") // OK + final List[] parmList = new List[arg_types.length]; + param_annotations = parmList; + for (int j = 0; j < arg_types.length; j++) { + param_annotations[j] = new ArrayList<>(); + } + } + hasParameterAnnotations = true; + final ParameterAnnotations rpa = (ParameterAnnotations) attribute; + if (rpa instanceof RuntimeVisibleParameterAnnotations) { + paramAnnVisAttr = rpa; + } else { + paramAnnInvisAttr = rpa; + } + for (int j = 0; j < arg_types.length; j++) { + // This returns Annotation[] ... + final ParameterAnnotationEntry immutableArray = rpa + .getParameterAnnotationEntries()[j]; + // ... which needs transforming into an AnnotationGen[] ... + final List mutable + = makeMutableVersion(immutableArray.getAnnotationEntries()); + // ... then add these to any we already know about + param_annotations[j].addAll(mutable); + } + } + } + if (paramAnnVisAttr != null) { + removeAttribute(paramAnnVisAttr); + } + if (paramAnnInvisAttr != null) { + removeAttribute(paramAnnInvisAttr); + } + haveUnpackedParameterAnnotations = true; + } + + private List makeMutableVersion(final AnnotationEntry[] mutableArray) { + final List result = new ArrayList<>(); + for (final AnnotationEntry element : mutableArray) { + result.add(new AnnotationEntryGen(element, getConstantPool(), + false)); + } + return result; + } + + public void addParameterAnnotation(final int parameterIndex, + final AnnotationEntryGen annotation) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations) { + @SuppressWarnings("unchecked") // OK + final List[] parmList = new List[arg_types.length]; + param_annotations = parmList; + hasParameterAnnotations = true; + } + final List existingAnnotations = param_annotations[parameterIndex]; + if (existingAnnotations != null) { + existingAnnotations.add(annotation); + } else { + final List l = new ArrayList<>(); + l.add(annotation); + param_annotations[parameterIndex] = l; + } + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two + * MethodGen objects are said to be equal when their names and signatures + * are equal. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Return value as defined by given BCELComparator strategy. By default + * return the hashcode of the method's name XOR signature. + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java index c50acc69558..ac22de9153c 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Implement this interface if you're interested in changes to a MethodGen object * and register yourself with addObserver(). * - * @author M. Dahm + * @version $Id: MethodObserver.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface MethodObserver { - public void notify(MethodGen method); + + void notify( MethodGen method ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java index 9fd3014caa1..c30cdba6012 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java @@ -21,58 +21,60 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * NEW - Create new object *
      Stack: ... -> ..., objectref
      * - * @author M. Dahm + * @version $Id: NEW.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class NEW extends CPInstruction - implements LoadClass, AllocationInstruction, ExceptionThrower, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - NEW() {} +public class NEW extends CPInstruction implements LoadClass, AllocationInstruction, + ExceptionThrower, StackProducer { - public NEW(int index) { - super(com.sun.org.apache.bcel.internal.Constants.NEW, index); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + NEW() { + } - 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); + public NEW(final int index) { + super(com.sun.org.apache.bcel.internal.Const.NEW, index); + } - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length+1] = ExceptionConstants.INSTANTIATION_ERROR; - cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR; - return cs; - } + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, + ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.INSTANTIATION_ERROR); + } - public ObjectType getLoadClassType(ConstantPoolGen cpg) { - return (ObjectType)getType(cpg); - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitNEW(this); - } + @Override + public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + return (ObjectType) getType(cpg); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitNEW(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java index dbf157d847a..8e26d2efed3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java @@ -21,7 +21,10 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.ExceptionConst; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -29,79 +32,100 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; *
      Stack: ..., count -> ..., arrayref
      * type must be one of T_INT, T_SHORT, ... * - * @author M. Dahm + * @version $Id: NEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class NEWARRAY extends Instruction - implements AllocationInstruction, ExceptionThrower, StackProducer { - private byte type; +public class NEWARRAY extends Instruction implements AllocationInstruction, ExceptionThrower, + StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - NEWARRAY() {} + private byte type; - public NEWARRAY(byte type) { - super(com.sun.org.apache.bcel.internal.Constants.NEWARRAY, (short)2); - this.type = type; - } - public NEWARRAY(BasicType type) { - this(type.getType()); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + NEWARRAY() { + } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - out.writeByte(type); - } - /** - * @return numeric code for basic element type - */ - public final byte getTypecode() { return type; } + public NEWARRAY(final byte type) { + super(com.sun.org.apache.bcel.internal.Const.NEWARRAY, (short) 2); + this.type = type; + } - /** - * @return type of constructed array - */ - public final Type getType() { - return new ArrayType(BasicType.getType(type), 1); - } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + com.sun.org.apache.bcel.internal.Constants.TYPE_NAMES[type]; - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - type = bytes.readByte(); - length = 2; - } + public NEWARRAY(final BasicType type) { + this(type.getType()); + } - public Class[] getExceptions() { - return new Class[] { com.sun.org.apache.bcel.internal.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION }; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitNEWARRAY(this); - } + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + out.writeByte(super.getOpcode()); + out.writeByte(type); + } + + + /** + * @return numeric code for basic element type + */ + public final byte getTypecode() { + return type; + } + + + /** + * @return type of constructed array + */ + public final Type getType() { + return new ArrayType(BasicType.getType(type), 1); + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + com.sun.org.apache.bcel.internal.Const.getTypeName(type); + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + type = bytes.readByte(); + super.setLength(2); + } + + + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION + }; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitNEWARRAY(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java index 8dec0dafbff..785e4e67575 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java @@ -21,27 +21,28 @@ package com.sun.org.apache.bcel.internal.generic; - /** * NOP - Do nothing * - * @author M. Dahm + * @version $Id: NOP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class NOP extends Instruction { - public NOP() { - super(com.sun.org.apache.bcel.internal.Constants.NOP, (short)1); - } + + public NOP() { + super(com.sun.org.apache.bcel.internal.Const.NOP, (short) 1); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitNOP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitNOP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java new file mode 100644 index 00000000000..1e8398f7437 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java @@ -0,0 +1,67 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import com.sun.org.apache.bcel.internal.classfile.ConstantCP; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; + +/** + * Super class for FieldOrMethod and INVOKEDYNAMIC, since they both have + * names and signatures + * + * @version $Id: FieldOrMethod.java 1481383 2013-05-11 17:34:32Z dbrosius $ + * @since 6.0 + */ +public abstract class NameSignatureInstruction extends CPInstruction { + + public NameSignatureInstruction() { + super(); + } + + public NameSignatureInstruction(final short opcode, final int index) { + super(opcode, index); + } + + public ConstantNameAndType getNameAndType(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + return (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + } + /** @return signature of referenced method/field. + */ + public String getSignature(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantNameAndType cnat = getNameAndType(cpg); + return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); + } + + /** @return name of referenced method/field. + */ + public String getName(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantNameAndType cnat = getNameAndType(cpg); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } + +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java index 006d6dffd70..14f5d3cbd77 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java @@ -21,17 +21,22 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote entity that has both name and type. This is true for local variables, * methods and fields. * - * @author M. Dahm + * @version $Id: NamedAndTyped.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface NamedAndTyped { - public String getName(); - public Type getType(); - public void setName(String name); - public void setType(Type type); + String getName(); + + + Type getType(); + + + void setName( String name ); + + + void setType( Type type ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java index d3af662a1fc..76cc31eb8f0 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java @@ -21,83 +21,148 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** * Denotes reference such as java.lang.String. * - * @author M. Dahm + * @version $Id: ObjectType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public final class ObjectType extends ReferenceType { - private String class_name; // Class name of type +public class ObjectType extends ReferenceType { - /** - * @param class_name fully qualified class name, e.g. java.lang.String - */ - public ObjectType(String class_name) { - super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); - this.class_name = class_name.replace('/', '.'); - } + private final String class_name; // Class name of type - /** @return name of referenced class - */ - public String getClassName() { return class_name; } - - /** @return a hash code value for the object. - */ - public int hashCode() { return class_name.hashCode(); } - - /** @return true if both type objects refer to the same class. - */ - public boolean equals(Object type) { - return (type instanceof ObjectType)? - ((ObjectType)type).class_name.equals(class_name) : false; - } - - /** - * If "this" doesn't reference a class, it references an interface - * or a non-existant entity. - */ - public boolean referencesClass(){ - JavaClass jc = Repository.lookupClass(class_name); - 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(class_name); - 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.class_name, superclass.class_name); - } - - /** - * Java Virtual Machine Specification edition 2, 5.4.4 Access Control - */ - public boolean accessibleTo(ObjectType accessor) { - JavaClass jc = Repository.lookupClass(class_name); - - if(jc.isPublic()) { - return true; - } else { - JavaClass acc = Repository.lookupClass(accessor.class_name); - return acc.getPackageName().equals(jc.getPackageName()); + /** + * @since 6.0 + */ + public static ObjectType getInstance(final String class_name) { + return new ObjectType(class_name); + } + + /** + * @param class_name fully qualified class name, e.g. java.lang.String + */ + public ObjectType(final String class_name) { + super(Const.T_REFERENCE, "L" + class_name.replace('.', '/') + ";"); + this.class_name = class_name.replace('/', '.'); + } + + + /** @return name of referenced class + */ + public String getClassName() { + return class_name; + } + + + /** @return a hash code value for the object. + */ + @Override + public int hashCode() { + return class_name.hashCode(); + } + + + /** @return true if both type objects refer to the same class. + */ + @Override + public boolean equals( final Object type ) { + return (type instanceof ObjectType) + ? ((ObjectType) type).class_name.equals(class_name) + : false; + } + + + /** + * If "this" doesn't reference a class, it references an interface + * or a non-existant entity. + * @deprecated (since 6.0) this method returns an inaccurate result + * if the class or interface referenced cannot + * be found: use referencesClassExact() instead + */ + @Deprecated + public boolean referencesClass() { + try { + final JavaClass jc = Repository.lookupClass(class_name); + return jc.isClass(); + } catch (final ClassNotFoundException e) { + return false; + } + } + + + /** + * If "this" doesn't reference an interface, it references a class + * or a non-existant entity. + * @deprecated (since 6.0) this method returns an inaccurate result + * if the class or interface referenced cannot + * be found: use referencesInterfaceExact() instead + */ + @Deprecated + public boolean referencesInterface() { + try { + final JavaClass jc = Repository.lookupClass(class_name); + return !jc.isClass(); + } catch (final ClassNotFoundException e) { + return false; + } + } + + + /** + * Return true if this type references a class, + * false if it references an interface. + * @return true if the type references a class, false if + * it references an interface + * @throws ClassNotFoundException if the class or interface + * referenced by this type can't be found + */ + public boolean referencesClassExact() throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(class_name); + return jc.isClass(); + } + + + /** + * Return true if this type references an interface, + * false if it references a class. + * @return true if the type references an interface, false if + * it references a class + * @throws ClassNotFoundException if the class or interface + * referenced by this type can't be found + */ + public boolean referencesInterfaceExact() throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(class_name); + return !jc.isClass(); + } + + + /** + * Return true if this type is a subclass of given ObjectType. + * @throws ClassNotFoundException if any of this class's superclasses + * can't be found + */ + public boolean subclassOf( final ObjectType superclass ) throws ClassNotFoundException { + if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) { + return false; + } + return Repository.instanceOf(this.class_name, superclass.class_name); + } + + + /** + * Java Virtual Machine Specification edition 2, 5.4.4 Access Control + * @throws ClassNotFoundException if the class referenced by this type + * can't be found + */ + public boolean accessibleTo( final ObjectType accessor ) throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(class_name); + if (jc.isPublic()) { + return true; + } + final JavaClass acc = Repository.lookupClass(accessor.class_name); + return acc.getPackageName().equals(jc.getPackageName()); } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java index 76c460a21d5..16cd4ccdf1a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * POP - Pop top operand stack word * *
      Stack: ..., word -> ...
      * - * @author M. Dahm + * @version $Id: POP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class POP extends StackInstruction implements PopInstruction { - public POP() { - super(com.sun.org.apache.bcel.internal.Constants.POP); - } + + public POP() { + super(com.sun.org.apache.bcel.internal.Const.POP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitStackInstruction(this); - v.visitPOP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitStackInstruction(this); + v.visitPOP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java index f63925841f6..40de6f75467 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * POP2 - Pop two top operand stack words * *
      Stack: ..., word2, word1 -> ...
      * - * @author M. Dahm + * @version $Id: POP2.java 1747278 2016-06-07 17:28:43Z britter $ */ public class POP2 extends StackInstruction implements PopInstruction { - public POP2() { - super(com.sun.org.apache.bcel.internal.Constants.POP2); - } + + public POP2() { + super(com.sun.org.apache.bcel.internal.Const.POP2); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitStackInstruction(this); - v.visitPOP2(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitStackInstruction(this); + v.visitPOP2(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java index da73c7fd6af..7ab8ebfeccc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,142 +20,176 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; /** * Wrapper class for push operations, which are implemented either as BIPUSH, * LDC or xCONST_n instructions. * - * @author M. Dahm + * @version $Id: PUSH.java 1749598 2016-06-21 20:36:33Z ggregory $ */ -public final class PUSH - implements CompoundInstruction, VariableLengthInstruction, InstructionConstants -{ - private Instruction instruction; +public final class PUSH implements CompoundInstruction, VariableLengthInstruction { - /** - * This constructor also applies for values of type short, char, byte - * - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, int value) { - if((value >= -1) && (value <= 5)) // Use ICONST_n - instruction = INSTRUCTIONS[Constants.ICONST_0 + value]; - else if((value >= -128) && (value <= 127)) // Use BIPUSH - instruction = new BIPUSH((byte)value); - else if((value >= -32768) && (value <= 32767)) // Use SIPUSH - instruction = new SIPUSH((short)value); - else // If everything fails create a Constant pool entry - instruction = new LDC(cp.addInteger(value)); - } + private Instruction instruction; - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, boolean value) { - instruction = INSTRUCTIONS[Constants.ICONST_0 + (value? 1 : 0)]; - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, float value) { - if(value == 0.0) - instruction = FCONST_0; - else if(value == 1.0) - instruction = FCONST_1; - else if(value == 2.0) - instruction = FCONST_2; - else // Create a Constant pool entry - instruction = new LDC(cp.addFloat(value)); - } + /** + * This constructor also applies for values of type short, char, byte + * + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final int value) { + if ((value >= -1) && (value <= 5)) { + instruction = InstructionConst.getInstruction(Const.ICONST_0 + value); + } else if (Instruction.isValidByte(value)) { + instruction = new BIPUSH((byte) value); + } else if (Instruction.isValidShort(value)) { + instruction = new SIPUSH((short) value); + } else { + instruction = new LDC(cp.addInteger(value)); + } + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, long value) { - if(value == 0) - instruction = LCONST_0; - else if(value == 1) - instruction = LCONST_1; - else // Create a Constant pool entry - instruction = new LDC2_W(cp.addLong(value)); - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, double value) { - if(value == 0.0) - instruction = DCONST_0; - else if(value == 1.0) - instruction = DCONST_1; - else // Create a Constant pool entry - instruction = new LDC2_W(cp.addDouble(value)); - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final boolean value) { + instruction = InstructionConst.getInstruction(Const.ICONST_0 + (value ? 1 : 0)); + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, String value) { - if(value == null) - instruction = ACONST_NULL; - else // Create a Constant pool entry - instruction = new LDC(cp.addString(value)); - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Number value) { - if((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) - instruction = new PUSH(cp, value.intValue()).instruction; - else if(value instanceof Double) - instruction = new PUSH(cp, value.doubleValue()).instruction; - else if(value instanceof Float) - instruction = new PUSH(cp, value.floatValue()).instruction; - else if(value instanceof Long) - instruction = new PUSH(cp, value.longValue()).instruction; - else - throw new ClassGenException("What's this: " + value); - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final float value) { + if (value == 0.0) { + instruction = InstructionConst.FCONST_0; + } else if (value == 1.0) { + instruction = InstructionConst.FCONST_1; + } else if (value == 2.0) { + instruction = InstructionConst.FCONST_2; + } else { + instruction = new LDC(cp.addFloat(value)); + } + } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Character value) { - this(cp, (int)value.charValue()); - } - /** - * @param cp Constant pool - * @param value to be pushed - */ - public PUSH(ConstantPoolGen cp, Boolean value) { - this(cp, value.booleanValue()); - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final long value) { + if (value == 0) { + instruction = InstructionConst.LCONST_0; + } else if (value == 1) { + instruction = InstructionConst.LCONST_1; + } else { + instruction = new LDC2_W(cp.addLong(value)); + } + } - public final InstructionList getInstructionList() { - return new InstructionList(instruction); - } - public final Instruction getInstruction() { - return instruction; - } + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final double value) { + if (value == 0.0) { + instruction = InstructionConst.DCONST_0; + } else if (value == 1.0) { + instruction = InstructionConst.DCONST_1; + } else { + instruction = new LDC2_W(cp.addDouble(value)); + } + } - /** - * @return mnemonic for instruction - */ - public String toString() { - return instruction.toString() + " (PUSH)"; - } + + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final String value) { + if (value == null) { + instruction = InstructionConst.ACONST_NULL; + } else { + instruction = new LDC(cp.addString(value)); + } + } + + /** + * + * @param cp + * @param value + * @since 6.0 + */ + public PUSH(final ConstantPoolGen cp, final ObjectType value) { + if (value == null) { + instruction = InstructionConst.ACONST_NULL; + } else { + instruction = new LDC(cp.addClass(value)); + } + } + + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final Number value) { + if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) { + instruction = new PUSH(cp, value.intValue()).instruction; + } else if (value instanceof Double) { + instruction = new PUSH(cp, value.doubleValue()).instruction; + } else if (value instanceof Float) { + instruction = new PUSH(cp, value.floatValue()).instruction; + } else if (value instanceof Long) { + instruction = new PUSH(cp, value.longValue()).instruction; + } else { + throw new ClassGenException("What's this: " + value); + } + } + + + /** + * creates a push object from a Character value. Warning: Make sure not to attempt to allow + * autoboxing to create this value parameter, as an alternative constructor will be called + * + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final Character value) { + this(cp, value.charValue()); + } + + + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final Boolean value) { + this(cp, value.booleanValue()); + } + + + @Override + public final InstructionList getInstructionList() { + return new InstructionList(instruction); + } + + + public final Instruction getInstruction() { + return instruction; + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString() { + return instruction + " (PUSH)"; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java index 9f7b42f108c..56a81740e1b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java @@ -21,9 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * PUTFIELD - Put field in object @@ -31,55 +30,55 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * OR *
      Stack: ..., objectref, value.word1, value.word2 -> ...
      * - * @author M. Dahm + * @version $Id: PUTFIELD.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class PUTFIELD - extends FieldInstruction - implements PopInstruction,ExceptionThrower{ - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - PUTFIELD() {} +public class PUTFIELD extends FieldInstruction implements PopInstruction, ExceptionThrower { - public PUTFIELD(int index) { - super(Constants.PUTFIELD, index); - } - - public int consumeStack(ConstantPoolGen cpg) { return getFieldSize(cpg) + 1; } - - public Class[] getExceptions() { - Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length+1] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.NULL_POINTER_EXCEPTION; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + PUTFIELD() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitPUTFIELD(this); - } + public PUTFIELD(final int index) { + super(Const.PUTFIELD, index); + } + + + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + return getFieldSize(cpg) + 1; + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitPUTFIELD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java index ffb7a626bc2..d7816175eb6 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java @@ -21,9 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * PUTSTATIC - Put static field in class @@ -31,51 +30,54 @@ import com.sun.org.apache.bcel.internal.ExceptionConstants; * OR *
      Stack: ..., value.word1, value.word2 -> ...
      * - * @author M. Dahm + * @version $Id: PUTSTATIC.java 1747278 2016-06-07 17:28:43Z britter $ */ -public class PUTSTATIC extends FieldInstruction - implements ExceptionThrower, PopInstruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - PUTSTATIC() {} +public class PUTSTATIC extends FieldInstruction implements ExceptionThrower, PopInstruction { - public PUTSTATIC(int index) { - super(Constants.PUTSTATIC, index); - } - - public int consumeStack(ConstantPoolGen cpg) { return getFieldSize(cpg); } - - public Class[] getExceptions() { - Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length]; - - System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, - cs, 0, ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length); - cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = - ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR; - - return cs; - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + PUTSTATIC() { + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitFieldInstruction(this); - v.visitPUTSTATIC(this); - } + public PUTSTATIC(final int index) { + super(Const.PUTSTATIC, index); + } + + + @Override + public int consumeStack( final ConstantPoolGen cpg ) { + return getFieldSize(cpg); + } + + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitFieldInstruction(this); + v.visitPUTSTATIC(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java index f195a83477d..750640b3631 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java @@ -21,12 +21,11 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to pop a value on top from the stack, * such as ISTORE, POP, PUTSTATIC. * - * @author M. Dahm + * @version $Id: PopInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see ISTORE * @see POP */ diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java index bb702276412..c03a2871e5e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java @@ -21,12 +21,11 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to produce a value on top of the stack, * such as ILOAD, LDC, SIPUSH, DUP, ICONST, etc. * - * @author M. Dahm + * @version $Id: PushInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see ILOAD * @see ICONST diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java index 093a870d27f..c1c60a563a5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java @@ -21,108 +21,131 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * RET - Return from subroutine * - *
      Stack: ..., -> ..., address
      + *
      Stack: ... -> ...
      * - * @author M. Dahm + * @version $Id: RET.java 1747278 2016-06-07 17:28:43Z britter $ */ public class RET extends Instruction implements IndexedInstruction, TypedInstruction { - private boolean wide; - private int index; // index to local variable containg the return address - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - RET() {} + private boolean wide; + private int index; // index to local variable containg the return address - public RET(int index) { - super(com.sun.org.apache.bcel.internal.Constants.RET, (short)2); - setIndex(index); // May set wide as side effect - } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - if(wide) - out.writeByte(com.sun.org.apache.bcel.internal.Constants.WIDE); - - out.writeByte(opcode); - - if(wide) - out.writeShort(index); - else - out.writeByte(index); - } - - private final void setWide() { - if(wide = index > com.sun.org.apache.bcel.internal.Constants.MAX_BYTE) - length = 4; // Including the wide byte - else - length = 2; - } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - this.wide = wide; - - if(wide) { - index = bytes.readUnsignedShort(); - length = 4; - } else { - index = bytes.readUnsignedByte(); - length = 2; + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + RET() { } - } - /** - * @return index of local variable containg the return address - */ - public final int getIndex() { return index; } - /** - * Set index of local variable containg the return address - */ - public final void setIndex(int n) { - if(n < 0) - throw new ClassGenException("Negative index value: " + n); + public RET(final int index) { + super(com.sun.org.apache.bcel.internal.Const.RET, (short) 2); + setIndex(index); // May set wide as side effect + } - index = n; - setWide(); - } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + index; - } + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + if (wide) { + out.writeByte(com.sun.org.apache.bcel.internal.Const.WIDE); + } + out.writeByte(super.getOpcode()); + if (wide) { + out.writeShort(index); + } else { + out.writeByte(index); + } + } - /** @return return address type - */ - public Type getType(ConstantPoolGen cp) { - return ReturnaddressType.NO_TARGET; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitRET(this); - } + private void setWide() { + wide = index > com.sun.org.apache.bcel.internal.Const.MAX_BYTE; + if (wide) { + super.setLength(4); // Including the wide byte + } else { + super.setLength(2); + } + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + this.wide = wide; + if (wide) { + index = bytes.readUnsignedShort(); + super.setLength(4); + } else { + index = bytes.readUnsignedByte(); + super.setLength(2); + } + } + + + /** + * @return index of local variable containg the return address + */ + @Override + public final int getIndex() { + return index; + } + + + /** + * Set index of local variable containg the return address + */ + @Override + public final void setIndex( final int n ) { + if (n < 0) { + throw new ClassGenException("Negative index value: " + n); + } + index = n; + setWide(); + } + + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + index; + } + + + /** @return return address type + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return ReturnaddressType.NO_TARGET; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitRET(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java index c9b6621152d..7d414c6eef2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * RETURN - Return from void method *
      Stack: ... -> <empty>
      * - * @author M. Dahm + * @version $Id: RETURN.java 1747278 2016-06-07 17:28:43Z britter $ */ public class RETURN extends ReturnInstruction { - public RETURN() { - super(com.sun.org.apache.bcel.internal.Constants.RETURN); - } + + public RETURN() { + super(com.sun.org.apache.bcel.internal.Const.RETURN); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitReturnInstruction(this); - v.visitRETURN(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitReturnInstruction(this); + v.visitRETURN(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java index 0513c1c76de..300a7171a02 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java @@ -20,297 +20,314 @@ package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** * Super class for object and array types. * - * @author M. Dahm + * @version $Id: ReferenceType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public abstract class ReferenceType extends Type { - protected ReferenceType(byte t, String s) { - super(t, s); - } - /** Class is non-abstract but not instantiable from the outside - */ - ReferenceType() { - super(Constants.T_OBJECT, ""); - } - - /** - * Return true iff this type is castable to another type t as defined in - * the JVM specification. The case where this is Type.NULL is not - * defined (see the CHECKCAST definition in the JVM specification). - * However, because e.g. CHECKCAST doesn't throw a - * ClassCastException when casting a null reference to any Object, - * true is returned in this case. - */ - 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; - } + protected ReferenceType(final byte t, final String s) { + super(t, s); } - /* 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; - } + /** Class is non-abstract but not instantiable from the outside + */ + ReferenceType() { + super(Const.T_OBJECT, ""); } - /* If this is an array type, namely, the type SC[], that is, an - * array of components of type SC, then: + + /** + * Return true iff this type is castable to another type t as defined in + * the JVM specification. The case where this is Type.NULL is not + * defined (see the CHECKCAST definition in the JVM specification). + * However, because e.g. CHECKCAST doesn't throw a + * ClassCastException when casting a null reference to any Object, + * true is returned in this case. + * + * @throws ClassNotFoundException if any classes or interfaces required + * to determine assignment compatibility can't be found */ - 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((ReferenceType) 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; + public boolean isCastableTo( final Type t ) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t instanceof ReferenceType; // 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 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 :) + + /** + * Return true iff this is assignment compatible with another type t + * as defined in the JVM specification; see the AASTORE definition + * there. + * @throws ClassNotFoundException if any classes or interfaces required + * to determine assignment compatibility can't be found */ - - /* This code is from a bug report by Konstantin Shagin */ - - if ((this instanceof ArrayType) && (t instanceof ArrayType)) { - ArrayType arrType1 = (ArrayType) this; - ArrayType arrType2 = (ArrayType) t; - if ( - (arrType1.getDimensions() == arrType2.getDimensions()) && - arrType1.getBasicType() instanceof ObjectType && - arrType2.getBasicType() instanceof ObjectType) { - return new ArrayType( - ((ObjectType) arrType1.getBasicType()).getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), - arrType1.getDimensions() - ); - - } + public boolean isAssignmentCompatibleWith( final Type t ) throws ClassNotFoundException { + if (!(t instanceof ReferenceType)) { + return false; + } + final ReferenceType T = (ReferenceType) t; + if (this.equals(Type.NULL)) { + return true; // This is not explicitely stated, but clear. Isn't it? + } + /* If this is a class type then + */ + if ((this instanceof ObjectType) && (((ObjectType) this).referencesClassExact())) { + /* If T is a class type, then this must be the same class as T, + or this must be a subclass of T; + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { + if (this.equals(T)) { + return true; + } + if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T) + .getClassName())) { + return true; + } + } + /* If T is an interface type, this must implement interface T. + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { + if (Repository.implementationOf(((ObjectType) this).getClassName(), + ((ObjectType) T).getClassName())) { + return true; + } + } + } + /* If this is an interface type, then: + */ + if ((this instanceof ObjectType) && (((ObjectType) this).referencesInterfaceExact())) { + /* If T is a class type, then T must be Object (2.4.7). + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + /* If T is an interface type, then T must be the same interface + * as this or a superinterface of this (2.13.2). + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { + if (this.equals(T)) { + return true; + } + if (Repository.implementationOf(((ObjectType) this).getClassName(), + ((ObjectType) T).getClassName())) { + return true; + } + } + } + /* If this is an array type, namely, the type SC[], that is, an + * array of components of type SC, then: + */ + if (this instanceof ArrayType) { + /* If T is a class type, then T must be Object (2.4.7). + */ + if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { + if (T.equals(Type.OBJECT)) { + return true; + } + } + /* If T is an array type TC[], that is, an array of components + * of type TC, then one of the following must be true: + */ + if (T instanceof ArrayType) { + /* TC and SC are the same primitive type (2.4.1). + */ + final Type sc = ((ArrayType) this).getElementType(); + final Type tc = ((ArrayType) T).getElementType(); + if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) { + return true; + } + /* TC and SC are reference types (2.4.6), and type SC is + * assignable to TC by these runtime rules. + */ + if (tc instanceof ReferenceType && sc instanceof ReferenceType + && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { + return true; + } + } + /* If T is an interface type, T must be one of the interfaces implemented by arrays (2.15). */ + // TODO: Check if this is still valid or find a way to dynamically find out which + // interfaces arrays implement. However, as of the JVM specification edition 2, there + // are at least two different pages where assignment compatibility is defined and + // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or + // 'java.io.Serializable'" + if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { + for (final String element : Const.getInterfacesImplementedByArrays()) { + if (T.equals(ObjectType.getInstance(element))) { + return true; + } + } + } + } + return false; // default. } - if ((this instanceof ArrayType) || (t instanceof ArrayType)) - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) || - ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - - - // this and t are ObjectTypes, see above. - ObjectType thiz = (ObjectType) this; - ObjectType other = (ObjectType) t; - JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - - if ((thiz_sups == null) || (other_sups == null)) { - return null; - } - - // Waaahh... - JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - - for (int i = 0; i < t_sups.length; i++) { - for (int j = 0; j < this_sups.length; j++) { - if (this_sups[j].equals(t_sups[i])) return new ObjectType(this_sups[j].getClassName()); - } - } - - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } - - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType - * referencing a class, not an interface). - * If one of the types is a superclass of the other, the former is returned. - * If "this" is Type.NULL, then t is returned. - * If t is Type.NULL, then "this" is returned. - * If "this" equals t ['this.equals(t)'] "this" is returned. - * If "this" or t is an ArrayType, then Type.OBJECT is returned. - * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. - * If not all of the two classes' superclasses cannot be found, "null" is returned. - * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". - * - * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has - * slightly changed semantics. - */ - @Deprecated - 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 :) + /** + * This commutative operation returns the first common superclass (narrowest ReferenceType + * referencing a class, not an interface). + * If one of the types is a superclass of the other, the former is returned. + * If "this" is Type.NULL, then t is returned. + * If t is Type.NULL, then "this" is returned. + * If "this" equals t ['this.equals(t)'] "this" is returned. + * If "this" or t is an ArrayType, then Type.OBJECT is returned; + * unless their dimensions match. Then an ArrayType of the same + * number of dimensions is returned, with its basic type being the + * first common super class of the basic types of "this" and t. + * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. + * If not all of the two classes' superclasses cannot be found, "null" is returned. + * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". + * + * @throws ClassNotFoundException on failure to find superclasses of this + * type, or the type passed as a parameter */ - - 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; + public ReferenceType getFirstCommonSuperclass( final ReferenceType t ) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL)) { + return this; + } + if (this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there is + * no object referenced by Type.NULL so we can also say all the objects + * referenced by Type.NULL were derived from java.lang.Object. + * However, the Java Language's "instanceof" operator proves us wrong: + * "null" is not referring to an instance of java.lang.Object :) + */ + } + /* This code is from a bug report by Konstantin Shagin */ + if ((this instanceof ArrayType) && (t instanceof ArrayType)) { + final ArrayType arrType1 = (ArrayType) this; + final 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).referencesInterfaceExact()) + || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterfaceExact())) { + 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. + final ObjectType thiz = (ObjectType) this; + final ObjectType other = (ObjectType) t; + final JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); + final JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); + if ((thiz_sups == null) || (other_sups == null)) { + return null; + } + // Waaahh... + final JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + final 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 (final JavaClass t_sup : t_sups) { + for (final JavaClass this_sup : this_sups) { + if (this_sup.equals(t_sup)) { + return ObjectType.getInstance(this_sup.getClassName()); + } + } + } + // Huh? Did you ask for Type.OBJECT's superclass?? + 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()); - } + /** + * This commutative operation returns the first common superclass (narrowest ReferenceType + * referencing a class, not an interface). + * If one of the types is a superclass of the other, the former is returned. + * If "this" is Type.NULL, then t is returned. + * If t is Type.NULL, then "this" is returned. + * If "this" equals t ['this.equals(t)'] "this" is returned. + * If "this" or t is an ArrayType, then Type.OBJECT is returned. + * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. + * If not all of the two classes' superclasses cannot be found, "null" is returned. + * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". + * + * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has + * slightly changed semantics. + * @throws ClassNotFoundException on failure to find superclasses of this + * type, or the type passed as a parameter + */ + @Deprecated + public ReferenceType firstCommonSuperclass( final ReferenceType t ) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL)) { + return this; + } + if (this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there is + * no object referenced by Type.NULL so we can also say all the objects + * referenced by Type.NULL were derived from java.lang.Object. + * However, the Java Language's "instanceof" operator proves us wrong: + * "null" is not referring to an instance of java.lang.Object :) + */ + } + if ((this instanceof ArrayType) || (t instanceof ArrayType)) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + } + if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) + || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) { + return Type.OBJECT; + // TODO: The above line is correct comparing to the vmspec2. But one could + // make class file verification a bit stronger here by using the notion of + // superinterfaces or even castability or assignment compatibility. + } + // this and t are ObjectTypes, see above. + final ObjectType thiz = (ObjectType) this; + final ObjectType other = (ObjectType) t; + final JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); + final JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); + if ((thiz_sups == null) || (other_sups == null)) { + return null; + } + // Waaahh... + final JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; + final 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 (final JavaClass t_sup : t_sups) { + for (final JavaClass this_sup : this_sups) { + if (this_sup.equals(t_sup)) { + return ObjectType.getInstance(this_sup.getClassName()); + } + } + } + // Huh? Did you ask for Type.OBJECT's superclass?? + return null; } - - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java index 12906a06391..47c5b300c9e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java @@ -21,50 +21,66 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.ExceptionConstants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.ExceptionConst; /** * Super class for the xRETURN family of instructions. * - * @author M. Dahm + * @version $Id: ReturnInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class ReturnInstruction extends Instruction - implements ExceptionThrower, TypedInstruction, StackConsumer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - ReturnInstruction() {} +public abstract class ReturnInstruction extends Instruction implements ExceptionThrower, + TypedInstruction, StackConsumer { - /** - * @param opcode of instruction - */ - protected ReturnInstruction(short opcode) { - super(opcode, (short)1); - } - - public Type getType() { - switch(opcode) { - case Constants.IRETURN: return Type.INT; - case Constants.LRETURN: return Type.LONG; - case Constants.FRETURN: return Type.FLOAT; - case Constants.DRETURN: return Type.DOUBLE; - case Constants.ARETURN: return Type.OBJECT; - case Constants.RETURN: return Type.VOID; - - default: // Never reached - throw new ClassGenException("Unknown type " + opcode); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + ReturnInstruction() { } - } - public Class[] getExceptions() { - return new Class[] { ExceptionConstants.ILLEGAL_MONITOR_STATE }; - } - /** @return type associated with the instruction - */ - public Type getType(ConstantPoolGen cp) { - return getType(); - } + /** + * @param opcode of instruction + */ + protected ReturnInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + public Type getType() { + final short _opcode = super.getOpcode(); + switch (_opcode) { + case Const.IRETURN: + return Type.INT; + case Const.LRETURN: + return Type.LONG; + case Const.FRETURN: + return Type.FLOAT; + case Const.DRETURN: + return Type.DOUBLE; + case Const.ARETURN: + return Type.OBJECT; + case Const.RETURN: + return Type.VOID; + default: // Never reached + throw new ClassGenException("Unknown type " + _opcode); + } + } + + + @Override + public Class[] getExceptions() { + return new Class[] { + ExceptionConst.ILLEGAL_MONITOR_STATE + }; + } + + + /** @return type associated with the instruction + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return getType(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java index f62f6db9ccf..a2422242cd3 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java @@ -21,55 +21,68 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Constants; -import java.util.Objects; +import com.sun.org.apache.bcel.internal.Const; /** * Returnaddress, the type JSR or JSR_W instructions push upon the stack. * * see vmspec2 3.3.3 - * @author Enver Haase + * @version $Id: ReturnaddressType.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public class ReturnaddressType extends Type { - public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); - private InstructionHandle returnTarget; + 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, ""); - } - /** - * Creates a ReturnaddressType object with a target. - */ - public ReturnaddressType(InstructionHandle returnTarget) { - super(Constants.T_ADDRESS, ""); + /** + * A Returnaddress [that doesn't know where to return to]. + */ + private ReturnaddressType() { + super(Const.T_ADDRESS, ""); + } + + + /** + * Creates a ReturnaddressType object with a target. + */ + public ReturnaddressType(final InstructionHandle returnTarget) { + super(Const.T_ADDRESS, ""); this.returnTarget = returnTarget; - } + } - @Override - public int hashCode() { - return Objects.hashCode(this.returnTarget); - } - /** - * Returns if the two Returnaddresses refer to the same target. - */ - @Override - public boolean equals(Object rat){ - if(!(rat instanceof ReturnaddressType)) - return false; + /** @return a hash code value for the object. + */ + @Override + public int hashCode() { + if (returnTarget == null) { + return 0; + } + return returnTarget.hashCode(); + } - return ((ReturnaddressType)rat).returnTarget.equals(this.returnTarget); - } - /** - * @return the target of this ReturnaddressType - */ - public InstructionHandle getTarget(){ - return returnTarget; - } + /** + * Returns if the two Returnaddresses refer to the same target. + */ + @Override + public boolean equals( final Object rat ) { + if (!(rat instanceof ReturnaddressType)) { + return false; + } + final ReturnaddressType that = (ReturnaddressType) rat; + if (this.returnTarget == null || that.returnTarget == null) { + return that.returnTarget == this.returnTarget; + } + return that.returnTarget.equals(this.returnTarget); + } + + + /** + * @return the target of this ReturnaddressType + */ + public InstructionHandle getTarget() { + return returnTarget; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java index 126f599a38d..56ce69e91ed 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SALOAD - Load short from array *
      Stack: ..., arrayref, index -> ..., value
      * - * @author M. Dahm + * @version $Id: SALOAD.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SALOAD extends ArrayInstruction implements StackProducer { - public SALOAD() { - super(com.sun.org.apache.bcel.internal.Constants.SALOAD); - } + + public SALOAD() { + super(com.sun.org.apache.bcel.internal.Const.SALOAD); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackProducer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitSALOAD(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackProducer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitSALOAD(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java index 10e4f215abf..b84e4385edf 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java @@ -21,32 +21,33 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SASTORE - Store into short array *
      Stack: ..., arrayref, index, value -> ...
      * - * @author M. Dahm + * @version $Id: SASTORE.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SASTORE extends ArrayInstruction implements StackConsumer { - public SASTORE() { - super(com.sun.org.apache.bcel.internal.Constants.SASTORE); - } + + public SASTORE() { + super(com.sun.org.apache.bcel.internal.Const.SASTORE); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitArrayInstruction(this); - v.visitSASTORE(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitArrayInstruction(this); + v.visitSASTORE(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java index 74a30454bd2..ec7cd472196 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java @@ -20,7 +20,9 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** @@ -28,67 +30,84 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; * *
      Stack: ... -> ..., value
      * - * @author M. Dahm + * @version $Id: SIPUSH.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SIPUSH extends Instruction implements ConstantPushInstruction { - private short b; - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - SIPUSH() {} + private short b; - public SIPUSH(short b) { - super(com.sun.org.apache.bcel.internal.Constants.SIPUSH, (short)3); - this.b = b; - } - /** - * Dump instruction as short code to stream out. - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - out.writeShort(b); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + SIPUSH() { + } - /** - * @return mnemonic for instruction - */ - public String toString(boolean verbose) { - return super.toString(verbose) + " " + b; - } - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - length = 3; - b = bytes.readShort(); - } + public SIPUSH(final short b) { + super(com.sun.org.apache.bcel.internal.Const.SIPUSH, (short) 3); + this.b = b; + } - public Number getValue() { return Integer.valueOf(b); } - /** @return Type.SHORT - */ - public Type getType(ConstantPoolGen cp) { - return Type.SHORT; - } + /** + * Dump instruction as short code to stream out. + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.dump(out); + out.writeShort(b); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitSIPUSH(this); - } + + /** + * @return mnemonic for instruction + */ + @Override + public String toString( final boolean verbose ) { + return super.toString(verbose) + " " + b; + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.setLength(3); + b = bytes.readShort(); + } + + + @Override + public Number getValue() { + return Integer.valueOf(b); + } + + + /** @return Type.SHORT + */ + @Override + public Type getType( final ConstantPoolGen cp ) { + return Type.SHORT; + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitSIPUSH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java index a85e91da980..e88fbed0468 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java @@ -21,31 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SWAP - Swa top operand stack word *
      Stack: ..., word2, word1 -> ..., word1, word2
      * - * @author M. Dahm + * @version $Id: SWAP.java 1747278 2016-06-07 17:28:43Z britter $ */ public class SWAP extends StackInstruction implements StackConsumer, StackProducer { - public SWAP() { - super(com.sun.org.apache.bcel.internal.Constants.SWAP); - } + + public SWAP() { + super(com.sun.org.apache.bcel.internal.Const.SWAP); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitStackInstruction(this); - v.visitSWAP(this); - } + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitStackInstruction(this); + v.visitSWAP(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java index fb4dce327ea..e75ea3c7564 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java @@ -21,130 +21,140 @@ package com.sun.org.apache.bcel.internal.generic; - /** * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or * TABLESWITCH instruction, depending on whether the match values (int[]) can be * sorted with no gaps between the numbers. * - * @author M. Dahm + * @version $Id: SWITCH.java 1749603 2016-06-21 20:50:19Z ggregory $ */ public final class SWITCH implements CompoundInstruction { - private int[] match; - private InstructionHandle[] targets; - private Select instruction; - private int match_length; - /** - * Template for switch() constructs. If the match array can be - * sorted in ascending order with gaps no larger than max_gap - * between the numbers, a TABLESWITCH instruction is generated, and - * a LOOKUPSWITCH otherwise. The former may be more efficient, but - * needs more space. - * - * Note, that the key array always will be sorted, though we leave - * the original arrays unaltered. - * - * @param match array of match values (case 2: ... case 7: ..., etc.) - * @param targets the instructions to be branched to for each case - * @param target the default target - * @param max_gap maximum gap that may between case branches - */ - public SWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target, int max_gap) { - this.match = (int[])match.clone(); - this.targets = (InstructionHandle[])targets.clone(); + private int[] match; + private InstructionHandle[] targets; + private Select instruction; + private int match_length; - if((match_length = match.length) < 2) // (almost) empty switch, or just default - instruction = new TABLESWITCH(match, targets, target); - else { - sort(0, match_length - 1); - if(matchIsOrdered(max_gap)) { - fillup(max_gap, target); - - instruction = new TABLESWITCH(this.match, this.targets, target); - } - else - instruction = new LOOKUPSWITCH(this.match, this.targets, target); - } - } - - public SWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target) { - this(match, targets, target, 1); - } - - private final void fillup(int max_gap, InstructionHandle target) { - int max_size = match_length + match_length * max_gap; - int[] m_vec = new int[max_size]; - InstructionHandle[] t_vec = new InstructionHandle[max_size]; - int count = 1; - - m_vec[0] = match[0]; - t_vec[0] = targets[0]; - - for(int i=1; i < match_length; i++) { - int prev = match[i-1]; - int gap = match[i] - prev; - - for(int j=1; j < gap; j++) { - m_vec[count] = prev + j; - t_vec[count] = target; - count++; - } - - m_vec[count] = match[i]; - t_vec[count] = targets[i]; - count++; + /** + * Template for switch() constructs. If the match array can be + * sorted in ascending order with gaps no larger than max_gap + * between the numbers, a TABLESWITCH instruction is generated, and + * a LOOKUPSWITCH otherwise. The former may be more efficient, but + * needs more space. + * + * Note, that the key array always will be sorted, though we leave + * the original arrays unaltered. + * + * @param match array of match values (case 2: ... case 7: ..., etc.) + * @param targets the instructions to be branched to for each case + * @param target the default target + * @param max_gap maximum gap that may between case branches + */ + public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target, final int max_gap) { + this.match = match.clone(); + this.targets = targets.clone(); + if ((match_length = match.length) < 2) { + instruction = new TABLESWITCH(match, targets, target); + } else { + sort(0, match_length - 1); + if (matchIsOrdered(max_gap)) { + fillup(max_gap, target); + instruction = new TABLESWITCH(this.match, this.targets, target); + } else { + instruction = new LOOKUPSWITCH(this.match, this.targets, target); + } + } } - match = new int[count]; - targets = new InstructionHandle[count]; - System.arraycopy(m_vec, 0, match, 0, count); - System.arraycopy(t_vec, 0, targets, 0, count); - } + public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target) { + this(match, targets, target, 1); + } - /** - * Sort match and targets array with QuickSort. - */ - private final void sort(int l, int r) { - int i = l, j = r; - int h, m = match[(l + r) / 2]; - InstructionHandle h2; - do { - while(match[i] < m) i++; - while(m < match[j]) j--; + private void fillup( final int max_gap, final InstructionHandle target ) { + final int max_size = match_length + match_length * max_gap; + final int[] m_vec = new int[max_size]; + final 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++) { + final int prev = match[i - 1]; + final 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); + } - 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); - } + /** + * Sort match and targets array with QuickSort. + */ + private void sort( final int l, final int r ) { + int i = l; + int j = r; + int h; + final int m = match[(l + r) / 2]; + InstructionHandle h2; + do { + while (match[i] < m) { + i++; + } + while (m < match[j]) { + j--; + } + if (i <= j) { + h = match[i]; + match[i] = match[j]; + match[j] = h; // Swap elements + h2 = targets[i]; + targets[i] = targets[j]; + targets[j] = h2; // Swap instructions, too + i++; + j--; + } + } while (i <= j); + if (l < j) { + sort(l, j); + } + if (i < r) { + sort(i, r); + } + } - /** - * @return match is sorted in ascending order with no gap bigger than max_gap? - */ - private final boolean matchIsOrdered(int max_gap) { - for(int i=1; i < match_length; i++) - if(match[i] - match[i-1] > max_gap) - return false; - return true; - } + /** + * @return match is sorted in ascending order with no gap bigger than max_gap? + */ + private boolean matchIsOrdered( final int max_gap ) { + for (int i = 1; i < match_length; i++) { + if (match[i] - match[i - 1] > max_gap) { + return false; + } + } + return true; + } - public final InstructionList getInstructionList() { - return new InstructionList(instruction); - } - public final Instruction getInstruction() { - return instruction; - } + @Override + public final InstructionList getInstructionList() { + return new InstructionList(instruction); + } + + + public final Instruction getInstruction() { + return instruction; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java index 94d20cba11a..70d6213be88 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,214 +17,338 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions. * - * @author M. Dahm + *

      + * We use our super's target property as the default target. + * + * @version $Id: Select.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see LOOKUPSWITCH * @see TABLESWITCH * @see InstructionList */ -public abstract class Select extends BranchInstruction - implements VariableLengthInstruction, StackProducer -{ - protected int[] match; // matches, i.e., case 1: ... - protected int[] indices; // target offsets - protected InstructionHandle[] targets; // target objects in instruction list - protected int fixed_length; // fixed length defined by subclasses - protected int match_length; // number of cases - protected int padding = 0; // number of pad bytes for alignment +public abstract class Select extends BranchInstruction implements VariableLengthInstruction, + StackConsumer /* @since 6.0 */, StackProducer { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - Select() {} + private int[] match; // matches, i.e., case 1: ... TODO could be package-protected? + private int[] indices; // target offsets TODO could be package-protected? + private InstructionHandle[] targets; // target objects in instruction list TODO could be package-protected? + private int fixed_length; // fixed length defined by subclasses TODO could be package-protected? + private int match_length; // number of cases TODO could be package-protected? + private int padding = 0; // number of pad bytes for alignment TODO could be package-protected? - /** - * (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 - */ - Select(short opcode, int[] match, InstructionHandle[] targets, - InstructionHandle target) { - super(opcode, target); - - this.targets = targets; - for(int i=0; i < targets.length; i++) { - BranchInstruction.notifyTargetChanged(targets[i], this); - } - - this.match = match; - - if((match_length = match.length) != targets.length) - throw new ClassGenException("Match and target array have not the same length"); - - indices = new int[match_length]; - } - - /** - * Since this is a variable length instruction, it may shift the following - * instructions which then need to update their position. - * - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - @Override - protected int updatePosition(int offset, int max_offset) { - position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc. - - short old_length = length; - - /* Alignment on 4-byte-boundary, + 1, because of tag byte. + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. */ - padding = (4 - ((position + 1) % 4)) % 4; - length = (short)(fixed_length + padding); // Update length - - return length - old_length; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump(DataOutputStream out) throws IOException { - out.writeByte(opcode); - - for(int i=0; i < padding; i++) // Padding bytes - out.writeByte(0); - - index = getTargetOffset(); // Write default target offset - out.writeInt(index); - } - - /** - * Read needed data (e.g. index) from file. - */ - @Override - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes - - for(int i=0; i < padding; i++) { - bytes.readByte(); + Select() { } - // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH) - index = bytes.readInt(); - } - - /** - * @return mnemonic for instruction - */ - @Override - public String toString(boolean verbose) { - final StringBuilder buf = new StringBuilder(super.toString(verbose)); - - if(verbose) { - for(int i=0; i < match_length; i++) { - String s = "null"; - - if(targets[i] != null) - s = targets[i].getInstruction().toString(); - - buf.append("(").append(match[i]).append(", ") - .append(s).append(" = {").append(indices[i]).append("})"); - } - } - else - buf.append(" ..."); - - return buf.toString(); - } - - /** - * Set branch target for `i'th case - */ - public final void setTarget(int i, InstructionHandle target) { - notifyTargetChanging(targets[i], this); - targets[i] = target; - notifyTargetChanged(targets[i], this); - } - - /** - * @param old_ih old target - * @param new_ih new target - */ - @Override - public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { - boolean targeted = false; - - if(target == old_ih) { - targeted = true; - setTarget(new_ih); + /** + * (Match, target) pairs for switch. `Match' and `targets' must have the + * same length of course. + * + * @param match array of matching values + * @param targets instruction targets + * @param defaultTarget default instruction target + */ + Select(final short opcode, final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) { + // don't set default target before instuction is built + super(opcode, null); + this.match = match; + this.targets = targets; + // now it's safe to set default target + setTarget(defaultTarget); + for (final InstructionHandle target2 : targets) { + notifyTarget(null, target2, this); + } + if ((match_length = match.length) != targets.length) { + throw new ClassGenException("Match and target array have not the same length: Match length: " + + match.length + " Target length: " + targets.length); + } + indices = new int[match_length]; } - for(int i=0; i < targets.length; i++) { - if(targets[i] == old_ih) { - targeted = true; - setTarget(i, new_ih); - } + /** + * Since this is a variable length instruction, it may shift the following + * instructions which then need to update their position. + * + * Called by InstructionList.setPositions when setting the position for + * every instruction. In the presence of variable length instructions + * `setPositions' performs multiple passes over the instruction list to + * calculate the correct (byte) positions and offsets by calling this + * function. + * + * @param offset additional offset caused by preceding (variable length) + * instructions + * @param max_offset the maximum offset that may be caused by these + * instructions + * @return additional offset caused by possible change of this instruction's + * length + */ + @Override + protected int updatePosition(final int offset, final int max_offset) { + setPosition(getPosition() + offset); // Additional offset caused by preceding SWITCHs, GOTOs, etc. + final short old_length = (short) super.getLength(); + /* Alignment on 4-byte-boundary, + 1, because of tag byte. + */ + padding = (4 - ((getPosition() + 1) % 4)) % 4; + super.setLength((short) (fixed_length + padding)); // Update length + return super.getLength() - old_length; } - if(!targeted) - throw new ClassGenException("Not targeting " + old_ih); - } + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + for (int i = 0; i < padding; i++) { + out.writeByte(0); + } + super.setIndex(getTargetOffset()); // Write default target offset + out.writeInt(super.getIndex()); + } - /** - * @return true, if ih is target of this instruction - */ - @Override - public boolean containsTarget(InstructionHandle ih) { - if(target == ih) - return true; + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes + for (int i = 0; i < padding; i++) { + bytes.readByte(); + } + // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH) + super.setIndex(bytes.readInt()); + } - for(int i=0; i < targets.length; i++) - if(targets[i] == ih) - return true; + /** + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + final StringBuilder buf = new StringBuilder(super.toString(verbose)); + if (verbose) { + for (int i = 0; i < match_length; i++) { + String s = "null"; + if (targets[i] != null) { + s = targets[i].getInstruction().toString(); + } + buf.append("(").append(match[i]).append(", ").append(s).append(" = {").append( + indices[i]).append("})"); + } + } else { + buf.append(" ..."); + } + return buf.toString(); + } - return false; - } + /** + * Set branch target for `i'th case + */ + public void setTarget(final int i, final InstructionHandle target) { // TODO could be package-protected? + notifyTarget(targets[i], target, this); + targets[i] = target; + } - /** - * Inform targets that they're not targeted anymore. - */ - @Override - void dispose() { - super.dispose(); + /** + * @param old_ih old target + * @param new_ih new target + */ + @Override + public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { + boolean targeted = false; + if (super.getTarget() == 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); + } + } - for(int i=0; i < targets.length; i++) - targets[i].removeTargeter(this); - } + /** + * @return true, if ih is target of this instruction + */ + @Override + public boolean containsTarget(final InstructionHandle ih) { + if (super.getTarget() == ih) { + return true; + } + for (final InstructionHandle target2 : targets) { + if (target2 == ih) { + return true; + } + } + return false; + } - /** - * @return array of match indices - */ - public int[] getMatchs() { return match; } + @Override + protected Object clone() throws CloneNotSupportedException { + final Select copy = (Select) super.clone(); + copy.match = match.clone(); + copy.indices = indices.clone(); + copy.targets = targets.clone(); + return copy; + } - /** - * @return array of match target offsets - */ - public int[] getIndices() { return indices; } + /** + * Inform targets that they're not targeted anymore. + */ + @Override + void dispose() { + super.dispose(); + for (final InstructionHandle target2 : targets) { + target2.removeTargeter(this); + } + } - /** - * @return array of match targets - */ - public InstructionHandle[] getTargets() { return targets; } + /** + * @return array of match indices + */ + public int[] getMatchs() { + return match; + } + + /** + * @return array of match target offsets + */ + public int[] getIndices() { + return indices; + } + + /** + * @return array of match targets + */ + public InstructionHandle[] getTargets() { + return targets; + } + + /** + * @return match entry + * @since 6.0 + */ + final int getMatch(final int index) { + return match[index]; + } + + /** + * @return index entry from indices + * @since 6.0 + */ + final int getIndices(final int index) { + return indices[index]; + } + + /** + * @return target entry + * @since 6.0 + */ + final InstructionHandle getTarget(final int index) { + return targets[index]; + } + + /** + * @return the fixed_length + * @since 6.0 + */ + final int getFixed_length() { + return fixed_length; + } + + /** + * @param fixed_length the fixed_length to set + * @since 6.0 + */ + final void setFixed_length(final int fixed_length) { + this.fixed_length = fixed_length; + } + + /** + * @return the match_length + * @since 6.0 + */ + final int getMatch_length() { + return match_length; + } + + /** + * @param match_length the match_length to set + * @since 6.0 + */ + final int setMatch_length(final int match_length) { + this.match_length = match_length; + return match_length; + } + + /** + * + * @param index + * @param value + * @since 6.0 + */ + final void setMatch(final int index, final int value) { + match[index] = value; + } + + /** + * + * @param array + * @since 6.0 + */ + final void setIndices(final int[] array) { + indices = array; + } + + /** + * + * @param array + * @since 6.0 + */ + final void setMatches(final int[] array) { + match = array; + } + + /** + * + * @param array + * @since 6.0 + */ + final void setTargets(final InstructionHandle[] array) { + targets = array; + } + + /** + * + * @return the padding + * @since 6.0 + */ + final int getPadding() { + return padding; + } + + /** + * @since 6.0 + */ + final int setIndices(final int i, final int value) { + indices[i] = value; + return value; // Allow use in nested calls + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java new file mode 100644 index 00000000000..946d962fcf3 --- /dev/null +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java @@ -0,0 +1,273 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.classfile.ConstantDouble; +import com.sun.org.apache.bcel.internal.classfile.ConstantFloat; +import com.sun.org.apache.bcel.internal.classfile.ConstantInteger; +import com.sun.org.apache.bcel.internal.classfile.ConstantLong; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ElementValue; +import com.sun.org.apache.bcel.internal.classfile.SimpleElementValue; + +/** + * @since 6.0 + */ +public class SimpleElementValueGen extends ElementValueGen +{ + // 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 SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) + { + super(type, cpGen); + this.idx = idx; + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) + { + super(type, cpGen); + idx = getConstantPool().addLong(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) + { + super(type, cpGen); + idx = getConstantPool().addDouble(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) + { + super(type, cpGen); + idx = getConstantPool().addFloat(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) + { + super(type, cpGen); + idx = getConstantPool().addInteger(value); + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) + { + super(type, cpGen); + if (value) { + idx = getConstantPool().addInteger(1); + } else { + idx = getConstantPool().addInteger(0); + } + } + + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value) + { + super(type, cpGen); + idx = getConstantPool().addUtf8(value); + } + + /** + * 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 SimpleElementValueGen(final SimpleElementValue value, + final ConstantPoolGen cpool, final 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 " + super.getElementValueType()); + } + } + } + + /** + * Return immutable variant + */ + @Override + public ElementValue getElementValue() + { + return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool()); + } + + public int getIndex() + { + return idx; + } + + public String getValueString() + { + if (super.getElementValueType() != STRING) { + throw new RuntimeException( + "Dont call getValueString() on a non STRING ElementValue"); + } + final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx); + return c.getBytes(); + } + + public int getValueInt() + { + if (super.getElementValueType() != PRIMITIVE_INT) { + throw new RuntimeException( + "Dont call getValueString() on a non STRING ElementValue"); + } + final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); + return c.getBytes(); + } + + // Whatever kind of value it is, return it as a string + @Override + public String stringifyValue() + { + switch (super.getElementValueType()) + { + case PRIMITIVE_INT: + final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(c.getBytes()); + case PRIMITIVE_LONG: + final ConstantLong j = (ConstantLong) getConstantPool().getConstant(idx); + return Long.toString(j.getBytes()); + case PRIMITIVE_DOUBLE: + final ConstantDouble d = (ConstantDouble) getConstantPool().getConstant(idx); + return Double.toString(d.getBytes()); + case PRIMITIVE_FLOAT: + final ConstantFloat f = (ConstantFloat) getConstantPool().getConstant(idx); + return Float.toString(f.getBytes()); + case PRIMITIVE_SHORT: + final ConstantInteger s = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(s.getBytes()); + case PRIMITIVE_BYTE: + final ConstantInteger b = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(b.getBytes()); + case PRIMITIVE_CHAR: + final ConstantInteger ch = (ConstantInteger) getConstantPool().getConstant(idx); + return Integer.toString(ch.getBytes()); + case PRIMITIVE_BOOLEAN: + final ConstantInteger bo = (ConstantInteger) getConstantPool().getConstant(idx); + if (bo.getBytes() == 0) { + return "false"; + } + return "true"; + case STRING: + final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); + return cu8.getBytes(); + default: + throw new RuntimeException( + "SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType()); + } + } + + @Override + public void dump(final DataOutputStream dos) throws IOException + { + dos.writeByte(super.getElementValueType()); // u1 kind of value + switch (super.getElementValueType()) + { + 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 " + super.getElementValueType()); + } + } +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java index 1dd12439cfb..092c3e5e790 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java @@ -21,14 +21,14 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote an instruction that may consume a value from the stack. * - * @author M. Dahm + * @version $Id: StackConsumer.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface StackConsumer { - /** @return how many words are consumed from stack - */ - public int consumeStack(ConstantPoolGen cpg); + + /** @return how many words are consumed from stack + */ + int consumeStack( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java index 82fdd2c89e3..c52fee76c87 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java @@ -21,29 +21,32 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Super class for stack operations like DUP and POP. * - * @author M. Dahm + * @version $Id: StackInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public abstract class StackInstruction extends Instruction { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - StackInstruction() {} - /** - * @param opcode instruction opcode - */ - protected StackInstruction(short opcode) { - super(opcode, (short)1); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + StackInstruction() { + } - /** @return Type.UNKNOWN - */ - public Type getType(ConstantPoolGen cp) { - return Type.UNKNOWN; - } + + /** + * @param opcode instruction opcode + */ + protected StackInstruction(final short opcode) { + super(opcode, (short) 1); + } + + + /** @return Type.UNKNOWN + */ + public Type getType( final ConstantPoolGen cp ) { + return Type.UNKNOWN; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java index 9aa3795c040..4cc8a407051 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java @@ -21,15 +21,15 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denote an instruction that may produce a value on top of the stack * (this excludes DUP_X1, e.g.) * - * @author M. Dahm + * @version $Id: StackProducer.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface StackProducer { - /** @return how many words are produced on stack - */ - public int produceStack(ConstantPoolGen cpg); + + /** @return how many words are produced on stack + */ + int produceStack( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java index 3f27a250cc5..33d871bce79 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java @@ -21,47 +21,48 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an unparameterized instruction to store a value into a local variable, * e.g. ISTORE. * - * @author M. Dahm + * @version $Id: StoreInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ -public abstract class StoreInstruction extends LocalVariableInstruction - implements PopInstruction -{ - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. - */ - StoreInstruction(short canon_tag, short c_tag) { - super(canon_tag, c_tag); - } +public abstract class StoreInstruction extends LocalVariableInstruction implements PopInstruction { - /** - * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ASTORE_0, e.g. - * @param n local variable index (unsigned short) - */ - protected StoreInstruction(short opcode, short c_tag, int n) { - super(opcode, c_tag, n); - } + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + * tag and length are defined in readInstruction and initFromFile, respectively. + */ + StoreInstruction(final short canon_tag, final short c_tag) { + super(canon_tag, c_tag); + } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitStackConsumer(this); - v.visitPopInstruction(this); - v.visitTypedInstruction(this); - v.visitLocalVariableInstruction(this); - v.visitStoreInstruction(this); - } + + /** + * @param opcode Instruction opcode + * @param c_tag Instruction number for compact version, ASTORE_0, e.g. + * @param n local variable index (unsigned short) + */ + protected StoreInstruction(final short opcode, final short c_tag, final int n) { + super(opcode, c_tag, n); + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitStackConsumer(this); + v.visitPopInstruction(this); + v.visitTypedInstruction(this); + v.visitLocalVariableInstruction(this); + v.visitStoreInstruction(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java index 13d91c825c5..a0d994f1e9d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java @@ -21,94 +21,97 @@ package com.sun.org.apache.bcel.internal.generic; -import java.io.*; +import java.io.DataOutputStream; +import java.io.IOException; + import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * TABLESWITCH - Switch within given range of values, i.e., low..high * - * @author M. Dahm + * @version $Id: TABLESWITCH.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see SWITCH */ public class TABLESWITCH extends Select { - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. - */ - TABLESWITCH() {} - /** - * @param match sorted array of match values, match[0] must be low value, - * match[match_length - 1] high value - * @param targets where to branch for matched values - * @param target default branch - */ - public TABLESWITCH(int[] match, InstructionHandle[] targets, - InstructionHandle target) { - super(com.sun.org.apache.bcel.internal.Constants.TABLESWITCH, match, targets, target); - - length = (short)(13 + match_length * 4); /* Alignment remainder assumed - * 0 here, until dump time */ - fixed_length = length; - } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump(DataOutputStream out) throws IOException { - super.dump(out); - - int low = (match_length > 0)? match[0] : 0; - out.writeInt(low); - - int high = (match_length > 0)? match[match_length - 1] : 0; - out.writeInt(high); - - for(int i=0; i < match_length; i++) // jump offsets - out.writeInt(indices[i] = getTargetOffset(targets[i])); - } - - /** - * Read needed data (e.g. index) from file. - */ - protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException - { - super.initFromFile(bytes, wide); - - int low = bytes.readInt(); - int high = bytes.readInt(); - - match_length = high - low + 1; - fixed_length = (short)(13 + match_length * 4); - length = (short)(fixed_length + padding); - - match = new int[match_length]; - indices = new int[match_length]; - targets = new InstructionHandle[match_length]; - - for(int i=low; i <= high; i++) - match[i - low] = i; - - for(int i=0; i < match_length; i++) { - indices[i] = bytes.readInt(); + /** + * Empty constructor needed for the Class.newInstance() statement in + * Instruction.readInstruction(). Not to be used otherwise. + */ + TABLESWITCH() { } - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - public void accept(Visitor v) { - v.visitVariableLengthInstruction(this); - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitTABLESWITCH(this); - } + /** + * @param match sorted array of match values, match[0] must be low value, + * match[match_length - 1] high value + * @param targets where to branch for matched values + * @param defaultTarget default branch + */ + public TABLESWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) { + super(com.sun.org.apache.bcel.internal.Const.TABLESWITCH, match, targets, defaultTarget); + /* Alignment remainder assumed 0 here, until dump time */ + final short _length = (short) (13 + getMatch_length() * 4); + super.setLength(_length); + setFixed_length(_length); + } + + + /** + * Dump instruction as byte code to stream out. + * @param out Output stream + */ + @Override + public void dump( final DataOutputStream out ) throws IOException { + super.dump(out); + final int _match_length = getMatch_length(); + final int low = (_match_length > 0) ? super.getMatch(0) : 0; + out.writeInt(low); + final int high = (_match_length > 0) ? super.getMatch(_match_length - 1) : 0; + out.writeInt(high); + for (int i = 0; i < _match_length; i++) { + out.writeInt(setIndices(i, getTargetOffset(super.getTarget(i)))); + } + } + + + /** + * Read needed data (e.g. index) from file. + */ + @Override + protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + final int low = bytes.readInt(); + final int high = bytes.readInt(); + final int _match_length = high - low + 1; + setMatch_length(_match_length); + final short _fixed_length = (short) (13 + _match_length * 4); + setFixed_length(_fixed_length); + super.setLength((short) (_fixed_length + super.getPadding())); + super.setMatches(new int[_match_length]); + super.setIndices(new int[_match_length]); + super.setTargets(new InstructionHandle[_match_length]); + for (int i = 0; i < _match_length; i++) { + super.setMatch(i, low + i); + super.setIndices(i, bytes.readInt()); + } + } + + + /** + * Call corresponding visitor method(s). The order is: + * Call visitor methods of implemented interfaces first, then + * call methods according to the class hierarchy in descending order, + * i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept( final Visitor v ) { + v.visitVariableLengthInstruction(this); + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitTABLESWITCH(this); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java index 2acd713f3a1..07c9f6c2877 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java @@ -21,47 +21,50 @@ package com.sun.org.apache.bcel.internal.generic; - /** - * Thrown by InstructionList.remove() when one or multiple disposed instruction - * are still being referenced by a InstructionTargeter object. I.e. the + * Thrown by InstructionList.remove() when one or multiple disposed instructions + * are still being referenced by an 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 + *

      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: + * how this may be done:

      * *
        *     ...
        *     try {
      - *      il.delete(start_ih, end_ih);
      + *         il.delete(start_ih, end_ih);
        *     } catch(TargetLostException e) {
      - *       InstructionHandle[] targets = e.getTargets();
      - *       for(int i=0; i < targets.length; i++) {
      - *         InstructionTargeter[] targeters = targets[i].getTargeters();
      - *
      - *         for(int j=0; j < targeters.length; j++)
      - *           targeters[j].updateTarget(targets[i], new_target);
      - *       }
      + *         for (InstructionHandle target : e.getTargets()) {
      + *             for (InstructionTargeter targeter : target.getTargeters()) {
      + *                 targeter.updateTarget(target, new_target);
      + *             }
      + *         }
        *     }
        * 
      * * @see InstructionHandle * @see InstructionList * @see InstructionTargeter - * @author M. Dahm + * @version $Id: TargetLostException.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class TargetLostException extends Exception { - private InstructionHandle[] targets; - TargetLostException(InstructionHandle[] t, String mesg) { - super(mesg); - targets = t; - } + private static final long serialVersionUID = -6857272667645328384L; + private final InstructionHandle[] targets; - /** - * @return list of instructions still being targeted. - */ - public InstructionHandle[] getTargets() { return targets; } + + TargetLostException(final InstructionHandle[] t, final String mesg) { + super(mesg); + targets = t; + } + + + /** + * @return list of instructions still being targeted. + */ + public InstructionHandle[] getTargets() { + return targets; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java index e936ca9b891..b370ca2c177 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,237 +17,374 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.generic; - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.classfile.*; import java.util.ArrayList; +import java.util.List; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.ClassFormatException; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** - * Abstract super class for all possible java types, namely basic types - * such as int, object types like String and array types, e.g. int[] + * Abstract super class for all possible java types, namely basic types such as + * int, object types like String and array types, e.g. int[] * - * @author M. Dahm + * @version $Id: Type.java 1749603 2016-06-21 20:50:19Z ggregory $ */ -public abstract class Type implements java.io.Serializable { - protected byte type; - protected String signature; // signature for the type +public abstract class Type { - /** Predefined constants - */ - public static final BasicType VOID = new BasicType(Constants.T_VOID); - public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); - public static final BasicType INT = new BasicType(Constants.T_INT); - public static final BasicType SHORT = new BasicType(Constants.T_SHORT); - public static final BasicType BYTE = new BasicType(Constants.T_BYTE); - public static final BasicType LONG = new BasicType(Constants.T_LONG); - public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); - public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); - public static final BasicType CHAR = new BasicType(Constants.T_CHAR); - public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); - public static final ObjectType STRING = new ObjectType("java.lang.String"); - public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); - public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); - public static final Type[] NO_ARGS = new Type[0]; - public static final ReferenceType NULL = new ReferenceType(){}; - public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, - ""){}; - - protected Type(byte t, String s) { - type = t; - signature = s; - } - - /** - * @return signature for given type. - */ - public String getSignature() { return signature; } - - /** - * @return type as defined in Constants - */ - public byte getType() { return type; } - - /** - * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise) - */ - public int getSize() { - switch(type) { - case Constants.T_DOUBLE: - case Constants.T_LONG: return 2; - case Constants.T_VOID: return 0; - default: return 1; - } - } - - /** - * @return Type string, e.g. `int[]' - */ - public String toString() { - return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN)))? signature : - Utility.signatureToString(signature, false); - } - - /** - * Convert type to Java method signature, e.g. int[] f(java.lang.String x) - * becomes (Ljava/lang/String;)[I - * - * @param return_type what the method returns - * @param arg_types what are the argument types - * @return method signature for given type(s). - */ - public static String getMethodSignature(Type return_type, Type[] arg_types) { - StringBuffer buf = new StringBuffer("("); - int length = (arg_types == null)? 0 : arg_types.length; - - for(int i=0; i < length; i++) - buf.append(arg_types[i].getSignature()); - - buf.append(')'); - buf.append(return_type.getSignature()); - - return buf.toString(); - } - - private static int consumed_chars=0; // Remember position in string, see getArgumentTypes - - /** - * Convert signature to a Type object. - * @param signature signature string such as Ljava/lang/String; - * @return type object - */ - public static final Type getType(String signature) - throws StringIndexOutOfBoundsException - { - byte type = Utility.typeOfSignature(signature); - - if(type <= Constants.T_VOID) { - consumed_chars = 1; - return BasicType.getType(type); - } else if(type == Constants.T_ARRAY) { - int dim=0; - do { // Count dimensions - dim++; - } while(signature.charAt(dim) == '['); - - // Recurse, but just once, if the signature is ok - Type t = getType(signature.substring(dim)); - - consumed_chars += dim; // update counter - - return new ArrayType(t, dim); - } else { // type == T_REFERENCE - int index = signature.indexOf(';'); // Look for closing `;' - - if(index < 0) - throw new ClassFormatException("Invalid signature: " + signature); - - consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed - - return new ObjectType(signature.substring(1, index).replace('/', '.')); - } - } - - /** - * Convert return value of a method (signature) to a Type object. - * - * @param signature signature string such as (Ljava/lang/String;)V - * @return return type - */ - public static Type getReturnType(String signature) { - try { - // Read return type after `)' - int index = signature.lastIndexOf(')') + 1; - return getType(signature.substring(index)); - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - } - - /** - * Convert arguments of a method (signature) to an array of Type objects. - * @param signature signature string such as (Ljava/lang/String;)V - * @return array of argument types - */ - public static Type[] getArgumentTypes(String signature) { - ArrayList vec = new ArrayList(); - int index; - Type[] types; - - try { // Read all declarations between for `(' and `)' - if(signature.charAt(0) != '(') - throw new ClassFormatException("Invalid method signature: " + signature); - - index = 1; // current string position - - while(signature.charAt(index) != ')') { - vec.add(getType(signature.substring(index))); - index += consumed_chars; // update position - } - } catch(StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid method signature: " + signature); - } - - types = new Type[vec.size()]; - vec.toArray(types); - return types; - } - - /** Convert runtime java.lang.Class to BCEL Type object. - * @param cl Java class - * @return corresponding Type object - */ - public static Type getType(java.lang.Class cl) { - if(cl == null) { - throw new IllegalArgumentException("Class must not be null"); - } - - /* That's an amzingly easy case, because getName() returns - * the signature. That's what we would have liked anyway. + private final byte type; + private String signature; // signature for the type + /** + * Predefined constants */ - 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 final BasicType VOID = new BasicType(Const.T_VOID); + public static final BasicType BOOLEAN = new BasicType(Const.T_BOOLEAN); + public static final BasicType INT = new BasicType(Const.T_INT); + public static final BasicType SHORT = new BasicType(Const.T_SHORT); + public static final BasicType BYTE = new BasicType(Const.T_BYTE); + public static final BasicType LONG = new BasicType(Const.T_LONG); + public static final BasicType DOUBLE = new BasicType(Const.T_DOUBLE); + public static final BasicType FLOAT = new BasicType(Const.T_FLOAT); + public static final BasicType CHAR = new BasicType(Const.T_CHAR); + public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); + public static final ObjectType CLASS = new ObjectType("java.lang.Class"); + public static final ObjectType STRING = new ObjectType("java.lang.String"); + public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); + public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); + public static final Type[] NO_ARGS = new Type[0]; // EMPTY, so immutable + public static final ReferenceType NULL = new ReferenceType() { + }; + public static final Type UNKNOWN = new Type(Const.T_UNKNOWN, "") { + }; - 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()); + protected Type(final byte t, final String s) { + type = t; + signature = s; } - sb.append(")"); - sb.append(getType(meth.getReturnType()).getSignature()); - return sb.toString(); - } + /** + * @return hashcode of Type + */ + @Override + public int hashCode() { + return type ^ signature.hashCode(); + } + + /** + * @return whether the Types are equal + */ + @Override + public boolean equals(final Object o) { + if (o instanceof Type) { + final Type t = (Type) o; + return (type == t.type) && signature.equals(t.signature); + } + return false; + } + + /** + * @return signature for given type. + */ + public String getSignature() { + return signature; + } + + /** + * @return type as defined in Constants + */ + public byte getType() { + return type; + } + + /** + * boolean, short and char variable are considered as int in the stack or + * local variable area. Returns {@link Type#INT} for + * {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise + * returns the given type. + * + * @since 6.0 + */ + public Type normalizeForStackOrLocal() { + if (this == Type.BOOLEAN || this == Type.BYTE || this == Type.SHORT || this == Type.CHAR) { + return Type.INT; + } + return this; + } + + /** + * @return stack size of this type (2 for long and double, 0 for void, 1 + * otherwise) + */ + public int getSize() { + switch (type) { + case Const.T_DOUBLE: + case Const.T_LONG: + return 2; + case Const.T_VOID: + return 0; + default: + return 1; + } + } + + /** + * @return Type string, e.g. `int[]' + */ + @Override + public String toString() { + return ((this.equals(Type.NULL) || (type >= Const.T_UNKNOWN))) ? signature : Utility + .signatureToString(signature, false); + } + + /** + * Convert type to Java method signature, e.g. int[] f(java.lang.String x) + * becomes (Ljava/lang/String;)[I + * + * @param return_type what the method returns + * @param arg_types what are the argument types + * @return method signature for given type(s). + */ + public static String getMethodSignature(final Type return_type, final Type[] arg_types) { + final StringBuilder buf = new StringBuilder("("); + if (arg_types != null) { + for (final Type arg_type : arg_types) { + buf.append(arg_type.getSignature()); + } + } + buf.append(')'); + buf.append(return_type.getSignature()); + return buf.toString(); + } + + private static final ThreadLocal consumed_chars = new ThreadLocal() { + + @Override + protected Integer initialValue() { + return Integer.valueOf(0); + } + };//int consumed_chars=0; // Remember position in string, see getArgumentTypes + + private static int unwrap(final ThreadLocal tl) { + return tl.get().intValue(); + } + + private static void wrap(final ThreadLocal tl, final int value) { + tl.set(Integer.valueOf(value)); + } + + /** + * Convert signature to a Type object. + * + * @param signature signature string such as Ljava/lang/String; + * @return type object + */ + // @since 6.0 no longer final + public static Type getType(final String signature) throws StringIndexOutOfBoundsException { + final byte type = Utility.typeOfSignature(signature); + if (type <= Const.T_VOID) { + //corrected concurrent private static field acess + wrap(consumed_chars, 1); + return BasicType.getType(type); + } else if (type == Const.T_ARRAY) { + int dim = 0; + do { // Count dimensions + dim++; + } while (signature.charAt(dim) == '['); + // Recurse, but just once, if the signature is ok + final Type t = getType(signature.substring(dim)); + //corrected concurrent private static field acess + // consumed_chars += dim; // update counter - is replaced by + final int _temp = unwrap(consumed_chars) + dim; + wrap(consumed_chars, _temp); + return new ArrayType(t, dim); + } else { // type == T_REFERENCE + // Utility.signatureToString understands how to parse + // generic types. + final String parsedSignature = Utility.signatureToString(signature, false); + wrap(consumed_chars, parsedSignature.length() + 2); // "Lblabla;" `L' and `;' are removed + return ObjectType.getInstance(parsedSignature.replace('/', '.')); + } + } + + /** + * Convert return value of a method (signature) to a Type object. + * + * @param signature signature string such as (Ljava/lang/String;)V + * @return return type + */ + public static Type getReturnType(final String signature) { + try { + // Read return type after `)' + final int index = signature.lastIndexOf(')') + 1; + return getType(signature.substring(index)); + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + } + + /** + * Convert arguments of a method (signature) to an array of Type objects. + * + * @param signature signature string such as (Ljava/lang/String;)V + * @return array of argument types + */ + public static Type[] getArgumentTypes(final String signature) { + final List vec = new ArrayList<>(); + int index; + Type[] types; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + vec.add(getType(signature.substring(index))); + //corrected concurrent private static field acess + index += unwrap(consumed_chars); // update position + } + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + types = new Type[vec.size()]; + vec.toArray(types); + return types; + } + + /** + * Convert runtime java.lang.Class to BCEL Type object. + * + * @param cl Java class + * @return corresponding Type object + */ + public static Type getType(final java.lang.Class cl) { + if (cl == null) { + throw new IllegalArgumentException("Class must not be null"); + } + /* That's an amzingly easy case, because getName() returns + * the signature. That's what we would have liked anyway. + */ + if (cl.isArray()) { + return getType(cl.getName()); + } else if (cl.isPrimitive()) { + if (cl == Integer.TYPE) { + return INT; + } else if (cl == Void.TYPE) { + return VOID; + } else if (cl == Double.TYPE) { + return DOUBLE; + } else if (cl == Float.TYPE) { + return FLOAT; + } else if (cl == Boolean.TYPE) { + return BOOLEAN; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Short.TYPE) { + return SHORT; + } else if (cl == Byte.TYPE) { + return BYTE; + } else if (cl == Long.TYPE) { + return LONG; + } else if (cl == Character.TYPE) { + return CHAR; + } else { + throw new IllegalStateException("Ooops, what primitive type is " + cl); + } + } else { // "Real" class + return ObjectType.getInstance(cl.getName()); + } + } + + /** + * Convert runtime java.lang.Class[] to BCEL Type objects. + * + * @param classes an array of runtime class objects + * @return array of corresponding Type objects + */ + public static Type[] getTypes(final java.lang.Class[] classes) { + final Type[] ret = new Type[classes.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = getType(classes[i]); + } + return ret; + } + + public static String getSignature(final java.lang.reflect.Method meth) { + final StringBuilder sb = new StringBuilder("("); + final Class[] params = meth.getParameterTypes(); // avoid clone + for (final Class param : params) { + sb.append(getType(param).getSignature()); + } + sb.append(")"); + sb.append(getType(meth.getReturnType()).getSignature()); + return sb.toString(); + } + + static int size(final int coded) { + return coded & 3; + } + + static int consumed(final int coded) { + return coded >> 2; + } + + static int encode(final int size, final int consumed) { + return consumed << 2 | size; + } + + static int getArgumentTypesSize(final String signature) { + int res = 0; + int index; + try { // Read all declarations between for `(' and `)' + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + index = 1; // current string position + while (signature.charAt(index) != ')') { + final int coded = getTypeSize(signature.substring(index)); + res += size(coded); + index += consumed(coded); + } + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + return res; + } + + static int getTypeSize(final String signature) throws StringIndexOutOfBoundsException { + final byte type = Utility.typeOfSignature(signature); + if (type <= Const.T_VOID) { + return encode(BasicType.getType(type).getSize(), 1); + } else if (type == Const.T_ARRAY) { + int dim = 0; + do { // Count dimensions + dim++; + } while (signature.charAt(dim) == '['); + // Recurse, but just once, if the signature is ok + final int consumed = consumed(getTypeSize(signature.substring(dim))); + return encode(1, dim + consumed); + } else { // type == T_REFERENCE + final int index = signature.indexOf(';'); // Look for closing `;' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + return encode(1, index + 1); + } + } + + static int getReturnTypeSize(final String signature) { + final int index = signature.lastIndexOf(')') + 1; + return Type.size(getTypeSize(signature.substring(index))); + } + + + /* + * Currently only used by the ArrayType constructor. + * The signature has a complicated dependency on other parameter + * so it's tricky to do it in a call to the super ctor. + */ + void setSignature(final String signature) { + this.signature = signature; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java index 6332a4e5747..b16702d2a80 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Get the type associated with an instruction, int for ILOAD, or the type * of the field of a PUTFIELD instruction, e.g.. * - * @author M. Dahm + * @version $Id: TypedInstruction.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface TypedInstruction { - public Type getType(ConstantPoolGen cpg); + + Type getType( ConstantPoolGen cpg ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java index 5c96001f0c2..533626bcf72 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java @@ -21,13 +21,13 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an instruction to perform an unconditional branch, i.e., GOTO, JSR. * - * @author M. Dahm + * @version $Id: UnconditionalBranch.java 1747278 2016-06-07 17:28:43Z britter $ * @see GOTO * @see JSR */ -public interface UnconditionalBranch {} +public interface UnconditionalBranch { +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java index 6395b8d9ec0..c1b2785433f 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java @@ -21,16 +21,16 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Denotes an instruction to be a variable length instruction, such as * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH. * - * @author M. Dahm + * @version $Id: VariableLengthInstruction.java 1747278 2016-06-07 17:28:43Z britter $ * @see GOTO * @see JSR * @see LOOKUPSWITCH * @see TABLESWITCH */ -public interface VariableLengthInstruction {} +public interface VariableLengthInstruction { +} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java index 0a1eb5ee1d5..e4947b02bee 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java @@ -21,194 +21,558 @@ package com.sun.org.apache.bcel.internal.generic; - /** * Interface implementing the Visitor pattern programming style. * I.e., a class that implements this interface can handle all types of * instructions with the properly typed methods just by calling the accept() * method. * - * @author M. Dahm + * @version $Id: Visitor.java 1747278 2016-06-07 17:28:43Z britter $ */ public interface Visitor { - public void visitStackInstruction(StackInstruction obj); - public void visitLocalVariableInstruction(LocalVariableInstruction obj); - public void visitBranchInstruction(BranchInstruction obj); - public void visitLoadClass(LoadClass obj); - public void visitFieldInstruction(FieldInstruction obj); - public void visitIfInstruction(IfInstruction obj); - public void visitConversionInstruction(ConversionInstruction obj); - public void visitPopInstruction(PopInstruction obj); - public void visitStoreInstruction(StoreInstruction obj); - public void visitTypedInstruction(TypedInstruction obj); - public void visitSelect(Select obj); - public void visitJsrInstruction(JsrInstruction obj); - public void visitGotoInstruction(GotoInstruction obj); - public void visitUnconditionalBranch(UnconditionalBranch obj); - public void visitPushInstruction(PushInstruction obj); - public void visitArithmeticInstruction(ArithmeticInstruction obj); - public void visitCPInstruction(CPInstruction obj); - public void visitInvokeInstruction(InvokeInstruction obj); - public void visitArrayInstruction(ArrayInstruction obj); - public void visitAllocationInstruction(AllocationInstruction obj); - public void visitReturnInstruction(ReturnInstruction obj); - public void visitFieldOrMethod(FieldOrMethod obj); - public void visitConstantPushInstruction(ConstantPushInstruction obj); - public void visitExceptionThrower(ExceptionThrower obj); - public void visitLoadInstruction(LoadInstruction obj); - public void visitVariableLengthInstruction(VariableLengthInstruction obj); - public void visitStackProducer(StackProducer obj); - public void visitStackConsumer(StackConsumer obj); - public void visitACONST_NULL(ACONST_NULL obj); - public void visitGETSTATIC(GETSTATIC obj); - public void visitIF_ICMPLT(IF_ICMPLT obj); - public void visitMONITOREXIT(MONITOREXIT obj); - public void visitIFLT(IFLT obj); - public void visitLSTORE(LSTORE obj); - public void visitPOP2(POP2 obj); - public void visitBASTORE(BASTORE obj); - public void visitISTORE(ISTORE obj); - public void visitCHECKCAST(CHECKCAST obj); - public void visitFCMPG(FCMPG obj); - public void visitI2F(I2F obj); - public void visitATHROW(ATHROW obj); - public void visitDCMPL(DCMPL obj); - public void visitARRAYLENGTH(ARRAYLENGTH obj); - public void visitDUP(DUP obj); - public void visitINVOKESTATIC(INVOKESTATIC obj); - public void visitLCONST(LCONST obj); - public void visitDREM(DREM obj); - public void visitIFGE(IFGE obj); - public void visitCALOAD(CALOAD obj); - public void visitLASTORE(LASTORE obj); - public void visitI2D(I2D obj); - public void visitDADD(DADD obj); - public void visitINVOKESPECIAL(INVOKESPECIAL obj); - public void visitIAND(IAND obj); - public void visitPUTFIELD(PUTFIELD obj); - public void visitILOAD(ILOAD obj); - public void visitDLOAD(DLOAD obj); - public void visitDCONST(DCONST obj); - public void visitNEW(NEW obj); - public void visitIFNULL(IFNULL obj); - public void visitLSUB(LSUB obj); - public void visitL2I(L2I obj); - public void visitISHR(ISHR obj); - public void visitTABLESWITCH(TABLESWITCH obj); - public void visitIINC(IINC obj); - public void visitDRETURN(DRETURN obj); - public void visitFSTORE(FSTORE obj); - public void visitDASTORE(DASTORE obj); - public void visitIALOAD(IALOAD obj); - public void visitDDIV(DDIV obj); - public void visitIF_ICMPGE(IF_ICMPGE obj); - public void visitLAND(LAND obj); - public void visitIDIV(IDIV obj); - public void visitLOR(LOR obj); - public void visitCASTORE(CASTORE obj); - public void visitFREM(FREM obj); - public void visitLDC(LDC obj); - public void visitBIPUSH(BIPUSH obj); - public void visitDSTORE(DSTORE obj); - public void visitF2L(F2L obj); - public void visitFMUL(FMUL obj); - public void visitLLOAD(LLOAD obj); - public void visitJSR(JSR obj); - public void visitFSUB(FSUB obj); - public void visitSASTORE(SASTORE obj); - public void visitALOAD(ALOAD obj); - public void visitDUP2_X2(DUP2_X2 obj); - public void visitRETURN(RETURN obj); - public void visitDALOAD(DALOAD obj); - public void visitSIPUSH(SIPUSH obj); - public void visitDSUB(DSUB obj); - public void visitL2F(L2F obj); - public void visitIF_ICMPGT(IF_ICMPGT obj); - public void visitF2D(F2D obj); - public void visitI2L(I2L obj); - public void visitIF_ACMPNE(IF_ACMPNE obj); - public void visitPOP(POP obj); - public void visitI2S(I2S obj); - public void visitIFEQ(IFEQ obj); - public void visitSWAP(SWAP obj); - public void visitIOR(IOR obj); - public void visitIREM(IREM obj); - public void visitIASTORE(IASTORE obj); - public void visitNEWARRAY(NEWARRAY obj); - public void visitINVOKEINTERFACE(INVOKEINTERFACE obj); - public void visitINEG(INEG obj); - public void visitLCMP(LCMP obj); - public void visitJSR_W(JSR_W obj); - public void visitMULTIANEWARRAY(MULTIANEWARRAY obj); - public void visitDUP_X2(DUP_X2 obj); - public void visitSALOAD(SALOAD obj); - public void visitIFNONNULL(IFNONNULL obj); - public void visitDMUL(DMUL obj); - public void visitIFNE(IFNE obj); - public void visitIF_ICMPLE(IF_ICMPLE obj); - public void visitLDC2_W(LDC2_W obj); - public void visitGETFIELD(GETFIELD obj); - public void visitLADD(LADD obj); - public void visitNOP(NOP obj); - public void visitFALOAD(FALOAD obj); - public void visitINSTANCEOF(INSTANCEOF obj); - public void visitIFLE(IFLE obj); - public void visitLXOR(LXOR obj); - public void visitLRETURN(LRETURN obj); - public void visitFCONST(FCONST obj); - public void visitIUSHR(IUSHR obj); - public void visitBALOAD(BALOAD obj); - public void visitDUP2(DUP2 obj); - public void visitIF_ACMPEQ(IF_ACMPEQ obj); - public void visitIMPDEP1(IMPDEP1 obj); - public void visitMONITORENTER(MONITORENTER obj); - public void visitLSHL(LSHL obj); - public void visitDCMPG(DCMPG obj); - public void visitD2L(D2L obj); - public void visitIMPDEP2(IMPDEP2 obj); - public void visitL2D(L2D obj); - public void visitRET(RET obj); - public void visitIFGT(IFGT obj); - public void visitIXOR(IXOR obj); - public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj); - public void visitFASTORE(FASTORE obj); - public void visitIRETURN(IRETURN obj); - public void visitIF_ICMPNE(IF_ICMPNE obj); - public void visitFLOAD(FLOAD obj); - public void visitLDIV(LDIV obj); - public void visitPUTSTATIC(PUTSTATIC obj); - public void visitAALOAD(AALOAD obj); - public void visitD2I(D2I obj); - public void visitIF_ICMPEQ(IF_ICMPEQ obj); - public void visitAASTORE(AASTORE obj); - public void visitARETURN(ARETURN obj); - public void visitDUP2_X1(DUP2_X1 obj); - public void visitFNEG(FNEG obj); - public void visitGOTO_W(GOTO_W obj); - public void visitD2F(D2F obj); - public void visitGOTO(GOTO obj); - public void visitISUB(ISUB obj); - public void visitF2I(F2I obj); - public void visitDNEG(DNEG obj); - public void visitICONST(ICONST obj); - public void visitFDIV(FDIV obj); - public void visitI2B(I2B obj); - public void visitLNEG(LNEG obj); - public void visitLREM(LREM obj); - public void visitIMUL(IMUL obj); - public void visitIADD(IADD obj); - public void visitLSHR(LSHR obj); - public void visitLOOKUPSWITCH(LOOKUPSWITCH obj); - public void visitDUP_X1(DUP_X1 obj); - public void visitFCMPL(FCMPL obj); - public void visitI2C(I2C obj); - public void visitLMUL(LMUL obj); - public void visitLUSHR(LUSHR obj); - public void visitISHL(ISHL obj); - public void visitLALOAD(LALOAD obj); - public void visitASTORE(ASTORE obj); - public void visitANEWARRAY(ANEWARRAY obj); - public void visitFRETURN(FRETURN obj); - public void visitFADD(FADD obj); - public void visitBREAKPOINT(BREAKPOINT obj); + + void visitStackInstruction( StackInstruction obj ); + + + void visitLocalVariableInstruction( LocalVariableInstruction obj ); + + + void visitBranchInstruction( BranchInstruction obj ); + + + void visitLoadClass( LoadClass obj ); + + + void visitFieldInstruction( FieldInstruction obj ); + + + void visitIfInstruction( IfInstruction obj ); + + + void visitConversionInstruction( ConversionInstruction obj ); + + + void visitPopInstruction( PopInstruction obj ); + + + void visitStoreInstruction( StoreInstruction obj ); + + + void visitTypedInstruction( TypedInstruction obj ); + + + void visitSelect( Select obj ); + + + void visitJsrInstruction( JsrInstruction obj ); + + + void visitGotoInstruction( GotoInstruction obj ); + + + void visitUnconditionalBranch( UnconditionalBranch obj ); + + + void visitPushInstruction( PushInstruction obj ); + + + void visitArithmeticInstruction( ArithmeticInstruction obj ); + + + void visitCPInstruction( CPInstruction obj ); + + + void visitInvokeInstruction( InvokeInstruction obj ); + + + void visitArrayInstruction( ArrayInstruction obj ); + + + void visitAllocationInstruction( AllocationInstruction obj ); + + + void visitReturnInstruction( ReturnInstruction obj ); + + + void visitFieldOrMethod( FieldOrMethod obj ); + + + void visitConstantPushInstruction( ConstantPushInstruction obj ); + + + void visitExceptionThrower( ExceptionThrower obj ); + + + void visitLoadInstruction( LoadInstruction obj ); + + + void visitVariableLengthInstruction( VariableLengthInstruction obj ); + + + void visitStackProducer( StackProducer obj ); + + + void visitStackConsumer( StackConsumer obj ); + + + void visitACONST_NULL( ACONST_NULL obj ); + + + void visitGETSTATIC( GETSTATIC obj ); + + + void visitIF_ICMPLT( IF_ICMPLT obj ); + + + void visitMONITOREXIT( MONITOREXIT obj ); + + + void visitIFLT( IFLT obj ); + + + void visitLSTORE( LSTORE obj ); + + + void visitPOP2( POP2 obj ); + + + void visitBASTORE( BASTORE obj ); + + + void visitISTORE( ISTORE obj ); + + + void visitCHECKCAST( CHECKCAST obj ); + + + void visitFCMPG( FCMPG obj ); + + + void visitI2F( I2F obj ); + + + void visitATHROW( ATHROW obj ); + + + void visitDCMPL( DCMPL obj ); + + + void visitARRAYLENGTH( ARRAYLENGTH obj ); + + + void visitDUP( DUP obj ); + + + void visitINVOKESTATIC( INVOKESTATIC obj ); + + + void visitLCONST( LCONST obj ); + + + void visitDREM( DREM obj ); + + + void visitIFGE( IFGE obj ); + + + void visitCALOAD( CALOAD obj ); + + + void visitLASTORE( LASTORE obj ); + + + void visitI2D( I2D obj ); + + + void visitDADD( DADD obj ); + + + void visitINVOKESPECIAL( INVOKESPECIAL obj ); + + + void visitIAND( IAND obj ); + + + void visitPUTFIELD( PUTFIELD obj ); + + + void visitILOAD( ILOAD obj ); + + + void visitDLOAD( DLOAD obj ); + + + void visitDCONST( DCONST obj ); + + + void visitNEW( NEW obj ); + + + void visitIFNULL( IFNULL obj ); + + + void visitLSUB( LSUB obj ); + + + void visitL2I( L2I obj ); + + + void visitISHR( ISHR obj ); + + + void visitTABLESWITCH( TABLESWITCH obj ); + + + void visitIINC( IINC obj ); + + + void visitDRETURN( DRETURN obj ); + + + void visitFSTORE( FSTORE obj ); + + + void visitDASTORE( DASTORE obj ); + + + void visitIALOAD( IALOAD obj ); + + + void visitDDIV( DDIV obj ); + + + void visitIF_ICMPGE( IF_ICMPGE obj ); + + + void visitLAND( LAND obj ); + + + void visitIDIV( IDIV obj ); + + + void visitLOR( LOR obj ); + + + void visitCASTORE( CASTORE obj ); + + + void visitFREM( FREM obj ); + + + void visitLDC( LDC obj ); + + + void visitBIPUSH( BIPUSH obj ); + + + void visitDSTORE( DSTORE obj ); + + + void visitF2L( F2L obj ); + + + void visitFMUL( FMUL obj ); + + + void visitLLOAD( LLOAD obj ); + + + void visitJSR( JSR obj ); + + + void visitFSUB( FSUB obj ); + + + void visitSASTORE( SASTORE obj ); + + + void visitALOAD( ALOAD obj ); + + + void visitDUP2_X2( DUP2_X2 obj ); + + + void visitRETURN( RETURN obj ); + + + void visitDALOAD( DALOAD obj ); + + + void visitSIPUSH( SIPUSH obj ); + + + void visitDSUB( DSUB obj ); + + + void visitL2F( L2F obj ); + + + void visitIF_ICMPGT( IF_ICMPGT obj ); + + + void visitF2D( F2D obj ); + + + void visitI2L( I2L obj ); + + + void visitIF_ACMPNE( IF_ACMPNE obj ); + + + void visitPOP( POP obj ); + + + void visitI2S( I2S obj ); + + + void visitIFEQ( IFEQ obj ); + + + void visitSWAP( SWAP obj ); + + + void visitIOR( IOR obj ); + + + void visitIREM( IREM obj ); + + + void visitIASTORE( IASTORE obj ); + + + void visitNEWARRAY( NEWARRAY obj ); + + + void visitINVOKEINTERFACE( INVOKEINTERFACE obj ); + + + void visitINEG( INEG obj ); + + + void visitLCMP( LCMP obj ); + + + void visitJSR_W( JSR_W obj ); + + + void visitMULTIANEWARRAY( MULTIANEWARRAY obj ); + + + void visitDUP_X2( DUP_X2 obj ); + + + void visitSALOAD( SALOAD obj ); + + + void visitIFNONNULL( IFNONNULL obj ); + + + void visitDMUL( DMUL obj ); + + + void visitIFNE( IFNE obj ); + + + void visitIF_ICMPLE( IF_ICMPLE obj ); + + + void visitLDC2_W( LDC2_W obj ); + + + void visitGETFIELD( GETFIELD obj ); + + + void visitLADD( LADD obj ); + + + void visitNOP( NOP obj ); + + + void visitFALOAD( FALOAD obj ); + + + void visitINSTANCEOF( INSTANCEOF obj ); + + + void visitIFLE( IFLE obj ); + + + void visitLXOR( LXOR obj ); + + + void visitLRETURN( LRETURN obj ); + + + void visitFCONST( FCONST obj ); + + + void visitIUSHR( IUSHR obj ); + + + void visitBALOAD( BALOAD obj ); + + + void visitDUP2( DUP2 obj ); + + + void visitIF_ACMPEQ( IF_ACMPEQ obj ); + + + void visitIMPDEP1( IMPDEP1 obj ); + + + void visitMONITORENTER( MONITORENTER obj ); + + + void visitLSHL( LSHL obj ); + + + void visitDCMPG( DCMPG obj ); + + + void visitD2L( D2L obj ); + + + void visitIMPDEP2( IMPDEP2 obj ); + + + void visitL2D( L2D obj ); + + + void visitRET( RET obj ); + + + void visitIFGT( IFGT obj ); + + + void visitIXOR( IXOR obj ); + + + void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj ); + + + /** + * @since 6.0 + */ + void visitINVOKEDYNAMIC( INVOKEDYNAMIC obj ); + + + void visitFASTORE( FASTORE obj ); + + + void visitIRETURN( IRETURN obj ); + + + void visitIF_ICMPNE( IF_ICMPNE obj ); + + + void visitFLOAD( FLOAD obj ); + + + void visitLDIV( LDIV obj ); + + + void visitPUTSTATIC( PUTSTATIC obj ); + + + void visitAALOAD( AALOAD obj ); + + + void visitD2I( D2I obj ); + + + void visitIF_ICMPEQ( IF_ICMPEQ obj ); + + + void visitAASTORE( AASTORE obj ); + + + void visitARETURN( ARETURN obj ); + + + void visitDUP2_X1( DUP2_X1 obj ); + + + void visitFNEG( FNEG obj ); + + + void visitGOTO_W( GOTO_W obj ); + + + void visitD2F( D2F obj ); + + + void visitGOTO( GOTO obj ); + + + void visitISUB( ISUB obj ); + + + void visitF2I( F2I obj ); + + + void visitDNEG( DNEG obj ); + + + void visitICONST( ICONST obj ); + + + void visitFDIV( FDIV obj ); + + + void visitI2B( I2B obj ); + + + void visitLNEG( LNEG obj ); + + + void visitLREM( LREM obj ); + + + void visitIMUL( IMUL obj ); + + + void visitIADD( IADD obj ); + + + void visitLSHR( LSHR obj ); + + + void visitLOOKUPSWITCH( LOOKUPSWITCH obj ); + + + void visitDUP_X1( DUP_X1 obj ); + + + void visitFCMPL( FCMPL obj ); + + + void visitI2C( I2C obj ); + + + void visitLMUL( LMUL obj ); + + + void visitLUSHR( LUSHR obj ); + + + void visitISHL( ISHL obj ); + + + void visitLALOAD( LALOAD obj ); + + + void visitASTORE( ASTORE obj ); + + + void visitANEWARRAY( ANEWARRAY obj ); + + + void visitFRETURN( FRETURN obj ); + + + void visitFADD( FADD obj ); + + + void visitBREAKPOINT( BREAKPOINT obj ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html index e39189be9d8..d8a276d067b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/package.html @@ -1,14 +1,30 @@ +

      This package contains the "generic" part of the -Byte Code Engineering +Byte Code Engineering Library, i.e., classes to dynamically modify class objects and byte code instructions.

      diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html index 92de99d1fbd..2b6dd18ef9b 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/package.html @@ -1,16 +1,32 @@ +

      This package contains basic classes for the -Byte Code Engineering Library +Byte Code Engineering Library and constants defined by the - + JVM specification.

      diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java index 15417bdd19a..b7246b8f200 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java @@ -21,202 +21,197 @@ package com.sun.org.apache.bcel.internal.util; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.CodeException; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; +import com.sun.org.apache.bcel.internal.classfile.InnerClass; +import com.sun.org.apache.bcel.internal.classfile.InnerClasses; +import com.sun.org.apache.bcel.internal.classfile.LineNumber; +import com.sun.org.apache.bcel.internal.classfile.LineNumberTable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; +import com.sun.org.apache.bcel.internal.classfile.SourceFile; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Convert found attributes into HTML file. * - * @author M. Dahm + * @version $Id: AttributeHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class AttributeHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private PrintWriter file; // file to write to - private int attr_count = 0; - private ConstantHTML constant_html; - private ConstantPool constant_pool; +final class AttributeHTML { - AttributeHTML(String dir, String class_name, ConstantPool constant_pool, - ConstantHTML constant_html) throws IOException - { - this.class_name = class_name; - this.constant_pool = constant_pool; - this.constant_html = constant_html; + private final String class_name; // name of current class + private final PrintWriter file; // file to write to + private int attr_count = 0; + private final ConstantHTML constant_html; + private final ConstantPool constant_pool; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_attributes.html")); - file.println(""); - } - private final String codeLink(int link, int method_number) { - return "" + - link + ""; - } - - final void close() { - file.println("
      "); - file.close(); - } - - final void writeAttribute(Attribute attribute, String anchor) throws IOException { - writeAttribute(attribute, anchor, 0); - } - - final void writeAttribute(Attribute attribute, String anchor, int method_number) throws IOException { - byte tag = attribute.getTag(); - int index; - - if(tag == ATTR_UNKNOWN) // Don't know what to do about this one - return; - - attr_count++; // Increment number of attributes found so far - - if(attr_count % 2 == 0) - file.print(""); - else - file.print(""); - - file.println("

      " + attr_count + " " + ATTRIBUTE_NAMES[tag] + "

      "); - - /* Handle different attributes - */ - switch(tag) { - case ATTR_CODE: - Code c = (Code)attribute; - - // Some directly printable values - file.print("
      • Maximum stack size = " + c.getMaxStack() + - "
      • \n
      • Number of local variables = " + - c.getMaxLocals() + "
      • \n
      • Byte code
      \n"); - - // Get handled exceptions and list them - CodeException[] ce = c.getExceptionTable(); - int len = ce.length; - - if(len > 0) { - file.print("

      Exceptions handled

        "); - - for(int i=0; i < len; i++) { - int catch_type = ce[i].getCatchType(); // Index in constant pool - - file.print("
      • "); - - if(catch_type != 0) - file.print(constant_html.referenceConstant(catch_type)); // Create Link to _cp.html - else - file.print("Any Exception"); - - file.print("
        (Ranging from lines " + codeLink(ce[i].getStartPC(), method_number) + - " to " + codeLink(ce[i].getEndPC(), method_number) + ", handled at line " + - codeLink(ce[i].getHandlerPC(), method_number) + ")
      • "); - } - file.print("
      "); - } - break; - - case ATTR_CONSTANT_VALUE: - index = ((ConstantValue)attribute).getConstantValueIndex(); - - // Reference _cp.html - file.print("\n"); - break; - - case ATTR_SOURCE_FILE: - index = ((SourceFile)attribute).getSourceFileIndex(); - - // Reference _cp.html - file.print("\n"); - break; - - case ATTR_EXCEPTIONS: - // List thrown exceptions - int[] indices = ((ExceptionTable)attribute).getExceptionIndexTable(); - - file.print("\n"); - break; - - case ATTR_LINE_NUMBER_TABLE: - LineNumber[] line_numbers =((LineNumberTable)attribute).getLineNumberTable(); - - // List line number pairs - file.print("

      "); - - for(int i=0; i < line_numbers.length; i++) { - file.print("(" + line_numbers[i].getStartPC() + ", " + line_numbers[i].getLineNumber() + ")"); - - if(i < line_numbers.length - 1) - file.print(", "); // breakable - } - break; - - case ATTR_LOCAL_VARIABLE_TABLE: - LocalVariable[] vars = ((LocalVariableTable)attribute).getLocalVariableTable(); - - // List name, range and type - file.print("

        "); - - for(int i=0; i < vars.length; i++) { - index = vars[i].getSignatureIndex(); - String signature = ((ConstantUtf8)constant_pool.getConstant(index, CONSTANT_Utf8)).getBytes(); - signature = Utility.signatureToString(signature, false); - int start = vars[i].getStartPC(); - int end = (start + vars[i].getLength()); - - file.println("
      • " + Class2HTML.referenceType(signature) + - " " + vars[i].getName() + " in slot %" + vars[i].getIndex() + - "
        Valid from lines " + - "" + - start + " to " + - "" + - end + "
      • "); - } - file.print("
      \n"); - - break; - - case ATTR_INNER_CLASSES: - InnerClass[] classes = ((InnerClasses)attribute).getInnerClasses(); - - // List inner classes - file.print("
        "); - - for(int i=0; i < classes.length; i++) { - String name, access; - - index = classes[i].getInnerNameIndex(); - if(index > 0) - name =((ConstantUtf8)constant_pool.getConstant(index, CONSTANT_Utf8)).getBytes(); - else - name = "<anonymous>"; - - access = Utility.accessToString(classes[i].getInnerAccessFlags()); - - file.print("
      • " + access + " "+ - constant_html.referenceConstant(classes[i].getInnerClassIndex()) + - " in class " + - constant_html.referenceConstant(classes[i].getOuterClassIndex()) + - " named " + name + "
      • \n"); - } - - file.print("
      \n"); - break; - - default: // Such as Unknown attribute or Deprecated - file.print("

      " + attribute.toString()); + AttributeHTML(final String dir, final String class_name, final ConstantPool constant_pool, + final ConstantHTML constant_html) throws IOException { + this.class_name = class_name; + this.constant_pool = constant_pool; + this.constant_html = constant_html; + file = new PrintWriter(new FileOutputStream(dir + class_name + "_attributes.html")); + file.println(""); } - file.println(""); - file.flush(); - } + + private String codeLink( final int link, final int method_number ) { + return "" + link + ""; + } + + + final void close() { + file.println("
      "); + file.close(); + } + + + final void writeAttribute( final Attribute attribute, final String anchor ) { + writeAttribute(attribute, anchor, 0); + } + + + final void writeAttribute( final Attribute attribute, final String anchor, final int method_number ) { + final byte tag = attribute.getTag(); + int index; + if (tag == Const.ATTR_UNKNOWN) { + return; + } + attr_count++; // Increment number of attributes found so far + if (attr_count % 2 == 0) { + file.print(""); + } else { + file.print(""); + } + file.println("

      " + attr_count + " " + Const.getAttributeName(tag) + + "

      "); + /* Handle different attributes + */ + switch (tag) { + case Const.ATTR_CODE: + final Code c = (Code) attribute; + // Some directly printable values + file.print("
      • Maximum stack size = " + c.getMaxStack() + + "
      • \n
      • Number of local variables = " + c.getMaxLocals() + + "
      • \n
      • Byte code
      \n"); + // Get handled exceptions and list them + final CodeException[] ce = c.getExceptionTable(); + final int len = ce.length; + if (len > 0) { + file.print("

      Exceptions handled

        "); + for (final CodeException cex : ce) { + final int catch_type = cex.getCatchType(); // Index in constant pool + file.print("
      • "); + if (catch_type != 0) { + file.print(constant_html.referenceConstant(catch_type)); // Create Link to _cp.html + } else { + file.print("Any Exception"); + } + file.print("
        (Ranging from lines " + + codeLink(cex.getStartPC(), method_number) + " to " + + codeLink(cex.getEndPC(), method_number) + ", handled at line " + + codeLink(cex.getHandlerPC(), method_number) + ")
      • "); + } + file.print("
      "); + } + break; + case Const.ATTR_CONSTANT_VALUE: + index = ((ConstantValue) attribute).getConstantValueIndex(); + // Reference _cp.html + file.print("\n"); + break; + case Const.ATTR_SOURCE_FILE: + index = ((SourceFile) attribute).getSourceFileIndex(); + // Reference _cp.html + file.print("\n"); + break; + case Const.ATTR_EXCEPTIONS: + // List thrown exceptions + final int[] indices = ((ExceptionTable) attribute).getExceptionIndexTable(); + file.print("\n"); + break; + case Const.ATTR_LINE_NUMBER_TABLE: + final LineNumber[] line_numbers = ((LineNumberTable) attribute).getLineNumberTable(); + // List line number pairs + file.print("

      "); + for (int i = 0; i < line_numbers.length; i++) { + file.print("(" + line_numbers[i].getStartPC() + ", " + + line_numbers[i].getLineNumber() + ")"); + if (i < line_numbers.length - 1) { + file.print(", "); // breakable + } + } + break; + case Const.ATTR_LOCAL_VARIABLE_TABLE: + final LocalVariable[] vars = ((LocalVariableTable) attribute).getLocalVariableTable(); + // List name, range and type + file.print("

        "); + for (final LocalVariable var : vars) { + index = var.getSignatureIndex(); + String signature = ((ConstantUtf8) constant_pool.getConstant(index, + Const.CONSTANT_Utf8)).getBytes(); + signature = Utility.signatureToString(signature, false); + final int start = var.getStartPC(); + final int end = start + var.getLength(); + file.println("
      • " + Class2HTML.referenceType(signature) + " " + + var.getName() + " in slot %" + var.getIndex() + + "
        Valid from lines " + "" + + start + " to " + "" + end + "
      • "); + } + file.print("
      \n"); + break; + case Const.ATTR_INNER_CLASSES: + final InnerClass[] classes = ((InnerClasses) attribute).getInnerClasses(); + // List inner classes + file.print("
        "); + for (final InnerClass classe : classes) { + String name; + String access; + index = classe.getInnerNameIndex(); + if (index > 0) { + name = ((ConstantUtf8) constant_pool.getConstant(index, Const.CONSTANT_Utf8)) + .getBytes(); + } else { + name = "<anonymous>"; + } + access = Utility.accessToString(classe.getInnerAccessFlags()); + file.print("
      • " + access + " " + + constant_html.referenceConstant(classe.getInnerClassIndex()) + + " in class " + + constant_html.referenceConstant(classe.getOuterClassIndex()) + + " named " + name + "
      • \n"); + } + file.print("
      \n"); + break; + default: // Such as Unknown attribute or Deprecated + file.print("

      " + attribute); + } + file.println(""); + file.flush(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassVector.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java similarity index 54% rename from jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassVector.java rename to jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java index f95ef244dce..7a2b98bf98e 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassVector.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java @@ -21,26 +21,29 @@ package com.sun.org.apache.bcel.internal.util; -import java.util.ArrayList; -import com.sun.org.apache.bcel.internal.classfile.JavaClass; - /** - * Utility class implementing a (typesafe) collection of JavaClass - * objects. Contains the most important methods of a Vector. + * Used for BCEL comparison strategy * - * @author M. Dahm - * @see ClassQueue -*/ -public class ClassVector implements java.io.Serializable { - protected ArrayList vec = new ArrayList(); + * @version $Id: BCELComparator.java 1747278 2016-06-07 17:28:43Z britter $ + * @since 5.2 + */ +public interface BCELComparator { - public void addElement(JavaClass clazz) { vec.add(clazz); } - public JavaClass elementAt(int index) { return (JavaClass)vec.get(index); } - public void removeElementAt(int index) { vec.remove(index); } + /** + * Compare two objects and return what THIS.equals(THAT) should return + * + * @param THIS + * @param THAT + * @return true if and only if THIS equals THAT + */ + boolean equals( Object THIS, Object THAT ); - public JavaClass[] toArray() { - JavaClass[] classes = new JavaClass[vec.size()]; - vec.toArray(classes); - return classes; - } + + /** + * Return hashcode for THIS.hashCode() + * + * @param THIS + * @return hashcode for THIS.hashCode() + */ + int hashCode( Object THIS ); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java index 084fc7bbd7f..929d2832a34 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java @@ -21,304 +21,331 @@ package com.sun.org.apache.bcel.internal.util; -import com.sun.org.apache.bcel.internal.generic.*; -import com.sun.org.apache.bcel.internal.classfile.Utility; -import com.sun.org.apache.bcel.internal.Constants; import java.io.PrintWriter; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.generic.AllocationInstruction; +import com.sun.org.apache.bcel.internal.generic.ArrayInstruction; +import com.sun.org.apache.bcel.internal.generic.ArrayType; +import com.sun.org.apache.bcel.internal.generic.BranchHandle; +import com.sun.org.apache.bcel.internal.generic.BranchInstruction; +import com.sun.org.apache.bcel.internal.generic.CHECKCAST; +import com.sun.org.apache.bcel.internal.generic.CPInstruction; +import com.sun.org.apache.bcel.internal.generic.CodeExceptionGen; +import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.ConstantPushInstruction; +import com.sun.org.apache.bcel.internal.generic.EmptyVisitor; +import com.sun.org.apache.bcel.internal.generic.FieldInstruction; +import com.sun.org.apache.bcel.internal.generic.IINC; +import com.sun.org.apache.bcel.internal.generic.INSTANCEOF; +import com.sun.org.apache.bcel.internal.generic.Instruction; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; +import com.sun.org.apache.bcel.internal.generic.InvokeInstruction; +import com.sun.org.apache.bcel.internal.generic.LDC; +import com.sun.org.apache.bcel.internal.generic.LDC2_W; +import com.sun.org.apache.bcel.internal.generic.LocalVariableInstruction; +import com.sun.org.apache.bcel.internal.generic.MULTIANEWARRAY; +import com.sun.org.apache.bcel.internal.generic.MethodGen; +import com.sun.org.apache.bcel.internal.generic.NEWARRAY; +import com.sun.org.apache.bcel.internal.generic.ObjectType; +import com.sun.org.apache.bcel.internal.generic.RET; +import com.sun.org.apache.bcel.internal.generic.ReturnInstruction; +import com.sun.org.apache.bcel.internal.generic.Select; +import com.sun.org.apache.bcel.internal.generic.Type; /** * Factory creates il.append() statements, and sets instruction targets. * A helper class for BCELifier. * * @see BCELifier - * @author M. Dahm + * @version $Id: BCELFactory.java 1749603 2016-06-21 20:50:19Z ggregory $ */ class BCELFactory extends EmptyVisitor { - private MethodGen _mg; - private PrintWriter _out; - private ConstantPoolGen _cp; - BCELFactory(MethodGen mg, PrintWriter out) { - _mg = mg; - _cp = mg.getConstantPool(); - _out = out; - } + private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+"."; + private final MethodGen _mg; + private final PrintWriter _out; + private final ConstantPoolGen _cp; - private HashMap branch_map = new HashMap(); // Map - public void start() { - if(!_mg.isAbstract() && !_mg.isNative()) { - for(InstructionHandle ih = _mg.getInstructionList().getStart(); - ih != null; ih = ih.getNext()) { - Instruction i = ih.getInstruction(); + BCELFactory(final MethodGen mg, final PrintWriter out) { + _mg = mg; + _cp = mg.getConstantPool(); + _out = out; + } - if(i instanceof BranchInstruction) { - branch_map.put(i, ih); // memorize container + private final Map branch_map = new HashMap<>(); + + + public void start() { + if (!_mg.isAbstract() && !_mg.isNative()) { + for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih + .getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { + branch_map.put(i, ih); // memorize container + } + if (ih.hasTargeters()) { + if (i instanceof BranchInstruction) { + _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); + } else { + _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); + } + } else { + _out.print(" "); + } + if (!visitInstruction(i)) { + i.accept(this); + } + } + updateBranchTargets(); + updateExceptionHandlers(); } + } - if(ih.hasTargeters()) { - if(i instanceof BranchInstruction) { - _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); - } else { - _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); - } + + private boolean visitInstruction( final Instruction i ) { + final short opcode = i.getOpcode(); + if ((InstructionConst.getInstruction(opcode) != null) + && !(i instanceof ConstantPushInstruction) && !(i instanceof ReturnInstruction)) { // Handled below + _out.println("il.append(InstructionConst." + + i.getName().toUpperCase(Locale.ENGLISH) + ");"); + return true; + } + return false; + } + + + @Override + public void visitLocalVariableInstruction( final LocalVariableInstruction i ) { + final short opcode = i.getOpcode(); + final Type type = i.getType(_cp); + if (opcode == Const.IINC) { + _out.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement() + + "));"); } else { - _out.print(" "); + final String kind = (opcode < Const.ISTORE) ? "Load" : "Store"; + _out.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type) + + ", " + i.getIndex() + "));"); + } + } + + + @Override + public void visitArrayInstruction( final ArrayInstruction i ) { + final short opcode = i.getOpcode(); + final Type type = i.getType(_cp); + final String kind = (opcode < Const.IASTORE) ? "Load" : "Store"; + _out.println("il.append(_factory.createArray" + kind + "(" + BCELifier.printType(type) + + "));"); + } + + + @Override + public void visitFieldInstruction( final FieldInstruction i ) { + final short opcode = i.getOpcode(); + final String class_name = i.getReferenceType(_cp).getSignature(); + final String field_name = i.getFieldName(_cp); + final Type type = i.getFieldType(_cp); + _out.println("il.append(_factory.createFieldAccess(\"" + class_name + "\", \"" + field_name + + "\", " + BCELifier.printType(type) + ", " + CONSTANT_PREFIX + + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); + } + + + @Override + public void visitInvokeInstruction( final InvokeInstruction i ) { + final short opcode = i.getOpcode(); + final String class_name = i.getReferenceType(_cp).getSignature(); + final String method_name = i.getMethodName(_cp); + final Type type = i.getReturnType(_cp); + final Type[] arg_types = i.getArgumentTypes(_cp); + _out.println("il.append(_factory.createInvoke(\"" + class_name + "\", \"" + method_name + + "\", " + BCELifier.printType(type) + ", " + + BCELifier.printArgumentTypes(arg_types) + ", " + CONSTANT_PREFIX + + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); + } + + + @Override + public void visitAllocationInstruction( final AllocationInstruction i ) { + Type type; + if (i instanceof CPInstruction) { + type = ((CPInstruction) i).getType(_cp); + } else { + type = ((NEWARRAY) i).getType(); + } + final short opcode = ((Instruction) i).getOpcode(); + int dim = 1; + switch (opcode) { + case Const.NEW: + _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName() + + "\"));"); + break; + case Const.MULTIANEWARRAY: + dim = ((MULTIANEWARRAY) i).getDimensions(); + //$FALL-THROUGH$ + case Const.ANEWARRAY: + case Const.NEWARRAY: + if (type instanceof ArrayType) { + type = ((ArrayType) type).getBasicType(); + } + _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type) + + ", (short) " + dim + "));"); + break; + default: + throw new RuntimeException("Oops: " + opcode); + } + } + + + private void createConstant( final Object value ) { + String embed = value.toString(); + if (value instanceof String) { + embed = '"' + Utility.convertString(embed) + '"'; + } else if (value instanceof Character) { + embed = "(char)0x" + Integer.toHexString(((Character) value).charValue()); + } else if (value instanceof Float) { + embed += "f"; + } else if (value instanceof Long) { + embed += "L"; + } else if (value instanceof ObjectType) { + final ObjectType ot = (ObjectType) value; + embed = "new ObjectType(\""+ot.getClassName()+"\")"; } - if(!visitInstruction(i)) - i.accept(this); - } - - updateBranchTargets(); - updateExceptionHandlers(); - } - } - - private boolean visitInstruction(Instruction i) { - short opcode = i.getOpcode(); - - if((InstructionConstants.INSTRUCTIONS[opcode] != null) && - !(i instanceof ConstantPushInstruction) && - !(i instanceof ReturnInstruction)) { // Handled below - _out.println("il.append(InstructionConstants." + - i.getName().toUpperCase() + ");"); - return true; + _out.println("il.append(new PUSH(_cp, " + embed + "));"); } - return false; - } - public void visitLocalVariableInstruction(LocalVariableInstruction i) { - short opcode = i.getOpcode(); - Type type = i.getType(_cp); - - if(opcode == Constants.IINC) { - _out.println("il.append(new IINC(" + i.getIndex() + ", " + - ((IINC)i).getIncrement() + "));"); - } else { - String kind = (opcode < Constants.ISTORE)? "Load" : "Store"; - _out.println("il.append(_factory.create" + kind + "(" + - BCELifier.printType(type) + ", " + - i.getIndex() + "));"); - } - } - - public void visitArrayInstruction(ArrayInstruction i) { - short opcode = i.getOpcode(); - Type type = i.getType(_cp); - String kind = (opcode < Constants.IASTORE)? "Load" : "Store"; - - _out.println("il.append(_factory.createArray" + kind + "(" + - BCELifier.printType(type) + "));"); - } - - public void visitFieldInstruction(FieldInstruction i) { - short opcode = i.getOpcode(); - - String class_name = i.getClassName(_cp); - String field_name = i.getFieldName(_cp); - Type type = i.getFieldType(_cp); - - _out.println("il.append(_factory.createFieldAccess(\"" + - class_name + "\", \"" + field_name + "\", " + - BCELifier.printType(type) + ", " + - "Constants." + Constants.OPCODE_NAMES[opcode].toUpperCase() + - "));"); - } - - public void visitInvokeInstruction(InvokeInstruction i) { - short opcode = i.getOpcode(); - String class_name = i.getClassName(_cp); - String method_name = i.getMethodName(_cp); - Type type = i.getReturnType(_cp); - Type[] arg_types = i.getArgumentTypes(_cp); - - _out.println("il.append(_factory.createInvoke(\"" + - class_name + "\", \"" + method_name + "\", " + - BCELifier.printType(type) + ", " + - BCELifier.printArgumentTypes(arg_types) + ", " + - "Constants." + Constants.OPCODE_NAMES[opcode].toUpperCase() + - "));"); - } - - public void visitAllocationInstruction(AllocationInstruction i) { - Type type; - - if(i instanceof CPInstruction) { - type = ((CPInstruction)i).getType(_cp); - } else { - type = ((NEWARRAY)i).getType(); + @Override + public void visitLDC( final LDC i ) { + createConstant(i.getValue(_cp)); } - short opcode = ((Instruction)i).getOpcode(); - int dim = 1; - switch(opcode) { - case Constants.NEW: - _out.println("il.append(_factory.createNew(\"" + - ((ObjectType)type).getClassName() + "\"));"); - break; - - case Constants.MULTIANEWARRAY: - dim = ((MULTIANEWARRAY)i).getDimensions(); - - case Constants.ANEWARRAY: - case Constants.NEWARRAY: - _out.println("il.append(_factory.createNewArray(" + - BCELifier.printType(type) + ", (short) " + dim + "));"); - break; - - default: - throw new RuntimeException("Oops: " + opcode); - } - } - - private void createConstant(Object value) { - String embed = value.toString(); - - if(value instanceof String) - embed = '"' + Utility.convertString(value.toString()) + '"'; - else if(value instanceof Character) - embed = "(char)0x" + Integer.toHexString(((Character)value).charValue()); - - _out.println("il.append(new PUSH(_cp, " + embed + "));"); - } - - public void visitLDC(LDC i) { - createConstant(i.getValue(_cp)); - } - - public void visitLDC2_W(LDC2_W i) { - createConstant(i.getValue(_cp)); - } - - public void visitConstantPushInstruction(ConstantPushInstruction i) { - createConstant(i.getValue()); - } - - public void visitINSTANCEOF(INSTANCEOF i) { - Type type = i.getType(_cp); - - _out.println("il.append(new INSTANCEOF(_cp.addClass(" + - BCELifier.printType(type) + ")));"); - } - - public void visitCHECKCAST(CHECKCAST i) { - Type type = i.getType(_cp); - - _out.println("il.append(_factory.createCheckCast(" + - BCELifier.printType(type) + "));"); - } - - public void visitReturnInstruction(ReturnInstruction i) { - Type type = i.getType(_cp); - - _out.println("il.append(_factory.createReturn(" + - BCELifier.printType(type) + "));"); - } - - // Memorize BranchInstructions that need an update - private ArrayList branches = new ArrayList(); - - public void visitBranchInstruction(BranchInstruction bi) { - BranchHandle bh = (BranchHandle)branch_map.get(bi); - int pos = bh.getPosition(); - String name = bi.getName() + "_" + pos; - - if(bi instanceof Select) { - Select s = (Select)bi; - branches.add(bi); - - StringBuffer args = new StringBuffer("new int[] { "); - int[] matchs = s.getMatchs(); - - for(int i=0; i < matchs.length; i++) { - args.append(matchs[i]); - - if(i < matchs.length - 1) - args.append(", "); - } - - args.append(" }"); - - _out.print(" Select " + name + " = new " + - bi.getName().toUpperCase() + "(" + args + - ", new InstructionHandle[] { "); - - for(int i=0; i < matchs.length; i++) { - _out.print("null"); - - if(i < matchs.length - 1) - _out.print(", "); - } - - _out.println(");"); - } else { - int t_pos = bh.getTarget().getPosition(); - String target; - - if(pos > t_pos) { - target = "ih_" + t_pos; - } else { - branches.add(bi); - target = "null"; - } - - _out.println(" BranchInstruction " + name + - " = _factory.createBranchInstruction(" + - "Constants." + bi.getName().toUpperCase() + ", " + - target + ");"); + @Override + public void visitLDC2_W( final LDC2_W i ) { + createConstant(i.getValue(_cp)); } - if(bh.hasTargeters()) - _out.println(" ih_" + pos + " = il.append(" + name + ");"); - else - _out.println(" il.append(" + name + ");"); - } - public void visitRET(RET i) { - _out.println("il.append(new RET(" + i.getIndex() + ")));"); - } + @Override + public void visitConstantPushInstruction( final ConstantPushInstruction i ) { + createConstant(i.getValue()); + } - private void updateBranchTargets() { - for(Iterator i = branches.iterator(); i.hasNext(); ) { - BranchInstruction bi = (BranchInstruction)i.next(); - BranchHandle bh = (BranchHandle)branch_map.get(bi); - int pos = bh.getPosition(); - String name = bi.getName() + "_" + pos; - int t_pos = bh.getTarget().getPosition(); - _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); + @Override + public void visitINSTANCEOF( final INSTANCEOF i ) { + final Type type = i.getType(_cp); + _out.println("il.append(new INSTANCEOF(_cp.addClass(" + BCELifier.printType(type) + ")));"); + } - if(bi instanceof Select) { - InstructionHandle[] ihs = ((Select)bi).getTargets(); - for(int j = 0; j < ihs.length; j++) { - t_pos = ihs[j].getPosition(); + @Override + public void visitCHECKCAST( final CHECKCAST i ) { + final Type type = i.getType(_cp); + _out.println("il.append(_factory.createCheckCast(" + BCELifier.printType(type) + "));"); + } - _out.println(" " + name + ".setTarget(" + j + - ", ih_" + t_pos + ");"); + + @Override + public void visitReturnInstruction( final ReturnInstruction i ) { + final Type type = i.getType(_cp); + _out.println("il.append(_factory.createReturn(" + BCELifier.printType(type) + "));"); + } + + // Memorize BranchInstructions that need an update + private final List branches = new ArrayList<>(); + + + @Override + public void visitBranchInstruction( final BranchInstruction bi ) { + final BranchHandle bh = (BranchHandle) branch_map.get(bi); + final int pos = bh.getPosition(); + final String name = bi.getName() + "_" + pos; + if (bi instanceof Select) { + final Select s = (Select) bi; + branches.add(bi); + final StringBuilder args = new StringBuilder("new int[] { "); + final int[] matchs = s.getMatchs(); + for (int i = 0; i < matchs.length; i++) { + args.append(matchs[i]); + if (i < matchs.length - 1) { + args.append(", "); + } + } + args.append(" }"); + _out.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH) + + "(" + args + ", new InstructionHandle[] { "); + for (int i = 0; i < matchs.length; i++) { + _out.print("null"); + if (i < matchs.length - 1) { + _out.print(", "); + } + } + _out.println(" }, null);"); + } else { + final int t_pos = bh.getTarget().getPosition(); + String target; + if (pos > t_pos) { + target = "ih_" + t_pos; + } else { + branches.add(bi); + target = "null"; + } + _out.println(" BranchInstruction " + name + " = _factory.createBranchInstruction(" + + CONSTANT_PREFIX + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target + + ");"); + } + if (bh.hasTargeters()) { + _out.println(" ih_" + pos + " = il.append(" + name + ");"); + } else { + _out.println(" il.append(" + name + ");"); } - } } - } - private void updateExceptionHandlers() { - CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); - for(int i=0; i < handlers.length; i++) { - CodeExceptionGen h = handlers[i]; - String type = (h.getCatchType() == null)? - "null" : BCELifier.printType(h.getCatchType()); - - _out.println(" method.addExceptionHandler(" + - "ih_" + h.getStartPC().getPosition() + ", " + - "ih_" + h.getEndPC().getPosition() + ", " + - "ih_" + h.getHandlerPC().getPosition() + ", " + - type + ");"); + @Override + public void visitRET( final RET i ) { + _out.println("il.append(new RET(" + i.getIndex() + ")));"); + } + + + private void updateBranchTargets() { + for (final BranchInstruction bi : branches) { + final BranchHandle bh = (BranchHandle) branch_map.get(bi); + final int pos = bh.getPosition(); + final String name = bi.getName() + "_" + pos; + int t_pos = bh.getTarget().getPosition(); + _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); + if (bi instanceof Select) { + final InstructionHandle[] ihs = ((Select) bi).getTargets(); + for (int j = 0; j < ihs.length; j++) { + t_pos = ihs[j].getPosition(); + _out.println(" " + name + ".setTarget(" + j + ", ih_" + t_pos + ");"); + } + } + } + } + + + private void updateExceptionHandlers() { + final CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); + for (final CodeExceptionGen h : handlers) { + final String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h + .getCatchType()); + _out.println(" method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition() + + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_" + + h.getHandlerPC().getPosition() + ", " + type + ");"); + } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java index de157f0d345..4092e59b263 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java @@ -21,11 +21,23 @@ package com.sun.org.apache.bcel.internal.util; -import com.sun.org.apache.bcel.internal.classfile.*; -import com.sun.org.apache.bcel.internal.generic.*; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.Locale; + +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import com.sun.org.apache.bcel.internal.classfile.ClassParser; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; +import com.sun.org.apache.bcel.internal.generic.ArrayType; +import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.MethodGen; +import com.sun.org.apache.bcel.internal.generic.Type; /** * This class takes a given JavaClass object and converts it to a @@ -34,238 +46,262 @@ import java.io.*; * are done with BCEL. It does not cover all features of BCEL, * but tries to mimic hand-written code as close as possible. * - * @author M. Dahm + * @version $Id: BCELifier.java 1750228 2016-06-25 21:47:44Z ggregory $ */ public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor { - private JavaClass _clazz; - private PrintWriter _out; - private ConstantPoolGen _cp; - /** @param clazz Java class to "decompile" - * @param out where to output Java program - */ - public BCELifier(JavaClass clazz, OutputStream out) { - _clazz = clazz; - _out = new PrintWriter(out); - _cp = new ConstantPoolGen(_clazz.getConstantPool()); - } - - /** Start Java code generation - */ - public void start() { - visitJavaClass(_clazz); - _out.flush(); - } - - public void visitJavaClass(JavaClass clazz) { - String class_name = clazz.getClassName(); - String super_name = clazz.getSuperclassName(); - String package_name = clazz.getPackageName(); - String inter = Utility.printArray(clazz.getInterfaceNames(), - false, true); - if(!"".equals(package_name)) { - class_name = class_name.substring(package_name.length() + 1); - _out.println("package " + package_name + ";\n"); - } - - _out.println("import com.sun.org.apache.bcel.internal.generic.*;"); - _out.println("import com.sun.org.apache.bcel.internal.classfile.*;"); - _out.println("import com.sun.org.apache.bcel.internal.*;"); - _out.println("import java.io.*;\n"); - - _out.println("public class " + class_name + "Creator implements Constants {"); - _out.println(" private InstructionFactory _factory;"); - _out.println(" private ConstantPoolGen _cp;"); - _out.println(" private ClassGen _cg;\n"); - - _out.println(" public " + class_name + "Creator() {"); - _out.println(" _cg = new ClassGen(\"" + - (("".equals(package_name))? class_name : - package_name + "." + class_name) + - "\", \"" + super_name + "\", " + - "\"" + clazz.getSourceFileName() + "\", " + - printFlags(clazz.getAccessFlags(), true) + ", " + - "new String[] { " + inter + " });\n"); - - _out.println(" _cp = _cg.getConstantPool();"); - _out.println(" _factory = new InstructionFactory(_cg, _cp);"); - _out.println(" }\n"); - - printCreate(); - - Field[] fields = clazz.getFields(); - - if(fields.length > 0) { - _out.println(" private void createFields() {"); - _out.println(" FieldGen field;"); - - for(int i=0; i < fields.length; i++) { - fields[i].accept(this); - } - - _out.println(" }\n"); + /** + * Enum corresponding to flag source. + */ + public enum FLAGS { + UNKNOWN, + CLASS, + METHOD, } - Method[] methods = clazz.getMethods(); + // The base package name for imports; assumes Const is at the top level + // N.B we use the class so renames will be detected by the compiler/IDE + private static final String BASE_PACKAGE = Const.class.getPackage().getName(); + private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+"."; - for(int i=0; i < methods.length; i++) { - _out.println(" private void createMethod_" + i + "() {"); + private final JavaClass _clazz; + private final PrintWriter _out; + private final ConstantPoolGen _cp; - methods[i].accept(this); - _out.println(" }\n"); + /** @param clazz Java class to "decompile" + * @param out where to output Java program + */ + public BCELifier(final JavaClass clazz, final OutputStream out) { + _clazz = clazz; + _out = new PrintWriter(out); + _cp = new ConstantPoolGen(_clazz.getConstantPool()); } - printMain(); - _out.println("}"); - } - private void printCreate() { - _out.println(" public void create(OutputStream out) throws IOException {"); - - Field[] fields = _clazz.getFields(); - if(fields.length > 0) { - _out.println(" createFields();"); + /** Start Java code generation + */ + public void start() { + visitJavaClass(_clazz); + _out.flush(); } - Method[] methods = _clazz.getMethods(); - for(int i=0; i < methods.length; i++) { - _out.println(" createMethod_" + i + "();"); + + @Override + public void visitJavaClass( final JavaClass clazz ) { + String class_name = clazz.getClassName(); + final String super_name = clazz.getSuperclassName(); + final String package_name = clazz.getPackageName(); + final String inter = Utility.printArray(clazz.getInterfaceNames(), false, true); + if (!"".equals(package_name)) { + class_name = class_name.substring(package_name.length() + 1); + _out.println("package " + package_name + ";"); + _out.println(); + } + _out.println("import " + BASE_PACKAGE + ".generic.*;"); + _out.println("import " + BASE_PACKAGE + ".classfile.*;"); + _out.println("import " + BASE_PACKAGE + ".*;"); + _out.println("import java.io.*;"); + _out.println(); + _out.println("public class " + class_name + "Creator {"); + _out.println(" private InstructionFactory _factory;"); + _out.println(" private ConstantPoolGen _cp;"); + _out.println(" private ClassGen _cg;"); + _out.println(); + _out.println(" public " + class_name + "Creator() {"); + _out.println(" _cg = new ClassGen(\"" + + (("".equals(package_name)) ? class_name : package_name + "." + class_name) + + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", " + + printFlags(clazz.getAccessFlags(), FLAGS.CLASS) + ", " + + "new String[] { " + inter + " });"); + _out.println(); + _out.println(" _cp = _cg.getConstantPool();"); + _out.println(" _factory = new InstructionFactory(_cg, _cp);"); + _out.println(" }"); + _out.println(); + printCreate(); + final Field[] fields = clazz.getFields(); + if (fields.length > 0) { + _out.println(" private void createFields() {"); + _out.println(" FieldGen field;"); + for (final Field field : fields) { + field.accept(this); + } + _out.println(" }"); + _out.println(); + } + final Method[] methods = clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + _out.println(" private void createMethod_" + i + "() {"); + methods[i].accept(this); + _out.println(" }"); + _out.println(); + } + printMain(); + _out.println("}"); } - _out.println(" _cg.getJavaClass().dump(out);"); - _out.println(" }\n"); - } - - private void printMain() { - String class_name = _clazz.getClassName(); - - _out.println(" public static void _main(String[] args) throws Exception {"); - _out.println(" " + class_name + "Creator creator = new " + - class_name + "Creator();"); - _out.println(" creator.create(new FileOutputStream(\"" + class_name + - ".class\"));"); - _out.println(" }"); - } - - public void visitField(Field field) { - _out.println("\n field = new FieldGen(" + - printFlags(field.getAccessFlags()) + - ", " + printType(field.getSignature()) + ", \"" + - field.getName() + "\", _cp);"); - - ConstantValue cv = field.getConstantValue(); - - if(cv != null) { - String value = cv.toString(); - _out.println(" field.setInitValue(" + value + ")"); + private void printCreate() { + _out.println(" public void create(OutputStream out) throws IOException {"); + final Field[] fields = _clazz.getFields(); + if (fields.length > 0) { + _out.println(" createFields();"); + } + final Method[] methods = _clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + _out.println(" createMethod_" + i + "();"); + } + _out.println(" _cg.getJavaClass().dump(out);"); + _out.println(" }"); + _out.println(); } - _out.println(" _cg.addField(field.getField());"); - } - public void visitMethod(Method method) { - MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); - - Type result_type = mg.getReturnType(); - Type[] arg_types = mg.getArgumentTypes(); - - _out.println(" InstructionList il = new InstructionList();"); - _out.println(" MethodGen method = new MethodGen(" + - printFlags(method.getAccessFlags()) + - ", " + printType(result_type) + - ", " + printArgumentTypes(arg_types) + ", " + - "new String[] { " + - Utility.printArray(mg.getArgumentNames(), false, true) + - " }, \"" + method.getName() + "\", \"" + - _clazz.getClassName() + "\", il, _cp);\n"); - - BCELFactory factory = new BCELFactory(mg, _out); - factory.start(); - - _out.println(" method.setMaxStack();"); - _out.println(" method.setMaxLocals();"); - _out.println(" _cg.addMethod(method.getMethod());"); - _out.println(" il.dispose();"); - } - - static String printFlags(int flags) { - return printFlags(flags, false); - } - - static String printFlags(int flags, boolean for_class) { - if(flags == 0) - return "0"; - - StringBuffer buf = new StringBuffer(); - for(int i=0, pow=1; i <= Constants.MAX_ACC_FLAG; i++) { - if((flags & pow) != 0) { - if((pow == Constants.ACC_SYNCHRONIZED) && for_class) - buf.append("ACC_SUPER | "); - else - buf.append("ACC_" + Constants.ACCESS_NAMES[i].toUpperCase() + " | "); - } - - pow <<= 1; + private void printMain() { + final String class_name = _clazz.getClassName(); + _out.println(" public static void main(String[] args) throws Exception {"); + _out.println(" " + class_name + "Creator creator = new " + class_name + "Creator();"); + _out.println(" creator.create(new FileOutputStream(\"" + class_name + ".class\"));"); + _out.println(" }"); } - String str = buf.toString(); - return str.substring(0, str.length() - 3); - } - static String printArgumentTypes(Type[] arg_types) { - if(arg_types.length == 0) - return "Type.NO_ARGS"; - - StringBuffer args = new StringBuffer(); - - for(int i=0; i < arg_types.length; i++) { - args.append(printType(arg_types[i])); - - if(i < arg_types.length - 1) - args.append(", "); + @Override + public void visitField( final Field field ) { + _out.println(); + _out.println(" field = new FieldGen(" + printFlags(field.getAccessFlags()) + ", " + + printType(field.getSignature()) + ", \"" + field.getName() + "\", _cp);"); + final ConstantValue cv = field.getConstantValue(); + if (cv != null) { + final String value = cv.toString(); + _out.println(" field.setInitValue(" + value + ")"); + } + _out.println(" _cg.addField(field.getField());"); } - return "new Type[] { " + args.toString() + " }"; - } - static String printType(Type type) { - return printType(type.getSignature()); - } - - static String printType(String signature) { - Type type = Type.getType(signature); - byte t = type.getType(); - - if(t <= Constants.T_VOID) { - return "Type." + Constants.TYPE_NAMES[t].toUpperCase(); - } else if(type.toString().equals("java.lang.String")) { - return "Type.STRING"; - } else if(type.toString().equals("java.lang.Object")) { - return "Type.OBJECT"; - } else if(type.toString().equals("java.lang.StringBuffer")) { - return "Type.STRINGBUFFER"; - } else if(type instanceof ArrayType) { - ArrayType at = (ArrayType)type; - - return "new ArrayType(" + printType(at.getBasicType()) + - ", " + at.getDimensions() + ")"; - } else { - return "new ObjectType(\"" + Utility.signatureToString(signature, false) + - "\")"; + @Override + public void visitMethod( final Method method ) { + final MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); + _out.println(" InstructionList il = new InstructionList();"); + _out.println(" MethodGen method = new MethodGen(" + + printFlags(method.getAccessFlags(), FLAGS.METHOD) + ", " + + printType(mg.getReturnType()) + ", " + + printArgumentTypes(mg.getArgumentTypes()) + ", " + + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true) + + " }, \"" + method.getName() + "\", \"" + _clazz.getClassName() + "\", il, _cp);"); + _out.println(); + final BCELFactory factory = new BCELFactory(mg, _out); + factory.start(); + _out.println(" method.setMaxStack();"); + _out.println(" method.setMaxLocals();"); + _out.println(" _cg.addMethod(method.getMethod());"); + _out.println(" il.dispose();"); } - } - /** Default _main method - */ - public static void _main(String[] argv) throws Exception { - JavaClass java_class; - String name = argv[0]; - if((java_class = Repository.lookupClass(name)) == null) - java_class = new ClassParser(name).parse(); // May throw IOException + static String printFlags( final int flags ) { + return printFlags(flags, FLAGS.UNKNOWN); + } - BCELifier bcelifier = new BCELifier(java_class, System.out); - bcelifier.start(); - } + /** + * Return a string with the flag settings + * @param flags the flags field to interpret + * @param location the item type + * @return the formatted string + * @since 6.0 made public + */ + public static String printFlags( final int flags, final FLAGS location ) { + if (flags == 0) { + return "0"; + } + final StringBuilder buf = new StringBuilder(); + for (int i = 0, pow = 1; pow <= Const.MAX_ACC_FLAG; i++) { + if ((flags & pow) != 0) { + if ((pow == Const.ACC_SYNCHRONIZED) && (location == FLAGS.CLASS)) { + buf.append(CONSTANT_PREFIX+"ACC_SUPER | "); + } else if ((pow == Const.ACC_VOLATILE) && (location == FLAGS.METHOD)) { + buf.append(CONSTANT_PREFIX+"ACC_BRIDGE | "); + } else if ((pow == Const.ACC_TRANSIENT) && (location == FLAGS.METHOD)) { + buf.append(CONSTANT_PREFIX+"ACC_VARARGS | "); + } else { + if (i < Const.ACCESS_NAMES_LENGTH) { + buf.append(CONSTANT_PREFIX+"ACC_") + .append(Const.getAccessName(i).toUpperCase(Locale.ENGLISH)) + .append( " | "); + } else { + buf.append(String.format (CONSTANT_PREFIX+"ACC_BIT %x | ", pow)); + } + } + } + pow <<= 1; + } + final String str = buf.toString(); + return str.substring(0, str.length() - 3); + } + + + static String printArgumentTypes( final Type[] arg_types ) { + if (arg_types.length == 0) { + return "Type.NO_ARGS"; + } + final StringBuilder args = new StringBuilder(); + for (int i = 0; i < arg_types.length; i++) { + args.append(printType(arg_types[i])); + if (i < arg_types.length - 1) { + args.append(", "); + } + } + return "new Type[] { " + args.toString() + " }"; + } + + + static String printType( final Type type ) { + return printType(type.getSignature()); + } + + + static String printType( final String signature ) { + final Type type = Type.getType(signature); + final byte t = type.getType(); + if (t <= Const.T_VOID) { + return "Type." + Const.getTypeName(t).toUpperCase(Locale.ENGLISH); + } else if (type.toString().equals("java.lang.String")) { + return "Type.STRING"; + } else if (type.toString().equals("java.lang.Object")) { + return "Type.OBJECT"; + } else if (type.toString().equals("java.lang.StringBuffer")) { + return "Type.STRINGBUFFER"; + } else if (type instanceof ArrayType) { + final ArrayType at = (ArrayType) type; + return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions() + + ")"; + } else { + return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")"; + } + } + + + /** Default main method + */ + public static void _main( final String[] argv ) throws Exception { + if (argv.length != 1) { + System.out.println("Usage: BCELifier classname"); + System.out.println("\tThe class must exist on the classpath"); + return; + } + final JavaClass java_class = getJavaClass(argv[0]); + final BCELifier bcelifier = new BCELifier(java_class, System.out); + bcelifier.start(); + } + + + // Needs to be accessible from unit test code + static JavaClass getJavaClass(final String name) throws ClassNotFoundException, IOException { + JavaClass java_class; + if ((java_class = Repository.lookupClass(name)) == null) { + java_class = new ClassParser(name).parse(); // May throw IOException + } + return java_class; + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java index f1ea3f9c108..9a458bc3dd2 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java @@ -21,29 +21,51 @@ package com.sun.org.apache.bcel.internal.util; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; /** * Utility class that implements a sequence of bytes which can be read * via the `readByte()' method. This is used to implement a wrapper for the * Java byte code stream to gain some more readability. * - * @author M. Dahm + * @version $Id: ByteSequence.java 1747278 2016-06-07 17:28:43Z britter $ */ public final class ByteSequence extends DataInputStream { - private ByteArrayStream byte_stream; - public ByteSequence(byte[] bytes) { - super(new ByteArrayStream(bytes)); - byte_stream = (ByteArrayStream)in; - } + private final ByteArrayStream byteStream; - 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--; } - } + public ByteSequence(final byte[] bytes) { + super(new ByteArrayStream(bytes)); + byteStream = (ByteArrayStream) in; + } + + + public final int getIndex() { + return byteStream.getPosition(); + } + + + final void unreadByte() { + byteStream.unreadByte(); + } + + private static final class ByteArrayStream extends ByteArrayInputStream { + + ByteArrayStream(final byte[] bytes) { + super(bytes); + } + + final int getPosition() { + // pos is protected in ByteArrayInputStream + return pos; + } + + final void unreadByte() { + if (pos > 0) { + pos--; + } + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java index 1ecbb71d632..87cbcf25ba7 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,212 +17,220 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashSet; +import java.util.Set; -import java.io.*; -import java.util.BitSet; -import com.sun.org.apache.bcel.internal.classfile.*; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.ClassParser; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Read class file(s) and convert them into HTML files. * - * Given a JavaClass object "class" that is in package "package" five files - * will be created in the specified directory. + * Given a JavaClass object "class" that is in package "package" five files will + * be created in the specified directory. * *

        - *
      1. "package"."class".html as the main file which defines the frames for - * the following subfiles. - *
      2. "package"."class"_attributes.html contains all (known) attributes found in the file - *
      3. "package"."class"_cp.html contains the constant pool - *
      4. "package"."class"_code.html contains the byte code - *
      5. "package"."class"_methods.html contains references to all methods and fields of the class + *
      6. "package"."class".html as the main file which defines the frames for the + * following subfiles. + *
      7. "package"."class"_attributes.html contains all (known) attributes found + * in the file + *
      8. "package"."class"_cp.html contains the constant pool + *
      9. "package"."class"_code.html contains the byte code + *
      10. "package"."class"_methods.html contains references to all methods and + * fields of the class *
      * - * All subfiles reference each other appropiately, e.g. clicking on a - * method in the Method's frame will jump to the appropiate method in - * the Code frame. + * All subfiles reference each other appropriately, e.g. clicking on a method in + * the Method's frame will jump to the appropriate method in the Code frame. * - * @author M. Dahm -*/ -public class Class2HTML implements Constants -{ - private JavaClass java_class; // current class object - private String dir; + * @version $Id: Class2HTML.java 1749603 2016-06-21 20:50:19Z ggregory $ + */ +public class Class2HTML { - private static String class_package; // name of package, unclean to make it static, but ... - private static String class_name; // name of current class, dito - private static ConstantPool constant_pool; + private final JavaClass java_class; // current class object + private final String dir; + private static String class_package; // name of package, unclean to make it static, but ... + private static String class_name; // name of current class, dito + private static ConstantPool constant_pool; + private static final Set basic_types = new HashSet<>(); - /** - * Write contents of the given JavaClass into HTML files. - * - * @param java_class The class to write - * @param dir The directory to put the files in - */ - public Class2HTML(JavaClass java_class, String dir) throws IOException { - Method[] methods = java_class.getMethods(); - - this.java_class = java_class; - this.dir = dir; - class_name = java_class.getClassName(); // Remember full name - constant_pool = java_class.getConstantPool(); - - // Get package name by tacking off everything after the last `.' - int index = class_name.lastIndexOf('.'); - if(index > -1) - class_package = class_name.substring(0, index); - else - class_package = ""; // default package - - ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods, - constant_pool); - - /* Attributes can't be written in one step, so we just open a file - * which will be written consequently. - */ - AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, constant_html); - - MethodHTML method_html = new MethodHTML(dir, class_name, methods, java_class.getFields(), - constant_html, attribute_html); - // Write main file (with frames, yuk) - writeMainHTML(attribute_html); - new CodeHTML(dir, class_name, methods, constant_pool, constant_html); - attribute_html.close(); - } - - public static void _main(String argv[]) - { - String[] file_name = new String[argv.length]; - int files=0; - ClassParser parser=null; - JavaClass java_class=null; - String zip_file = null; - char sep = SecuritySupport.getSystemProperty("file.separator").toCharArray()[0]; - String dir = "." + sep; // Where to store HTML files - - try { - /* Parse command line arguments. - */ - for(int i=0; i < argv.length; i++) { - if(argv[i].charAt(0) == '-') { // command line switch - if(argv[i].equals("-d")) { // Specify target directory, default '.' - dir = argv[++i]; - - if(!dir.endsWith("" + sep)) - dir = dir + sep; - - new File(dir).mkdirs(); // Create target directory if necessary - } - else if(argv[i].equals("-zip")) - zip_file = argv[++i]; - else - System.out.println("Unknown option " + argv[i]); - } - else // add file name to list */ - file_name[files++] = argv[i]; - } - - if(files == 0) - System.err.println("Class2HTML: No input files specified."); - else { // Loop through files ... - for(int i=0; i < files; i++) { - System.out.print("Processing " + file_name[i] + "..."); - if(zip_file == null) - parser = new ClassParser(file_name[i]); // Create parser object from file - else - parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file - - java_class = parser.parse(); - new Class2HTML(java_class, dir); - System.out.println("Done."); - } - } - } catch(Exception e) { - System.out.println(e); - e.printStackTrace(System.out); + static { + basic_types.add("int"); + basic_types.add("short"); + basic_types.add("boolean"); + basic_types.add("void"); + basic_types.add("char"); + basic_types.add("byte"); + basic_types.add("long"); + basic_types.add("double"); + basic_types.add("float"); } - } - /** - * Utility method that converts a class reference in the constant pool, - * i.e., an index to a string. - */ - static String referenceClass(int index) { - String str = constant_pool.getConstantString(index, CONSTANT_Class); - str = Utility.compactClassName(str); - str = Utility.compactClassName(str, class_package + ".", true); - - return "" + str + ""; - } - - static final String referenceType(String type) { - String short_type = Utility.compactClassName(type); - short_type = Utility.compactClassName(short_type, class_package + ".", true); - - int index = type.indexOf('['); // Type is an array? - if(index > -1) - type = type.substring(0, index); // Tack of the `[' - - // test for basic type - if(type.equals("int") || type.equals("short") || type.equals("boolean") || type.equals("void") || - type.equals("char") || type.equals("byte") || type.equals("long") || type.equals("double") || - type.equals("float")) - return "" + type + ""; - else - return "" + short_type + ""; - } - - static String toHTML(String str) { - StringBuffer buf = new StringBuffer(); - - try { // Filter any characters HTML doesn't like such as < and > in particular - for(int i=0; i < str.length(); i++) { - char ch; - - switch(ch=str.charAt(i)) { - case '<': buf.append("<"); break; - case '>': buf.append(">"); break; - case '\n': buf.append("\\n"); break; - case '\r': buf.append("\\r"); break; - default: buf.append(ch); + /** + * Write contents of the given JavaClass into HTML files. + * + * @param java_class The class to write + * @param dir The directory to put the files in + */ + public Class2HTML(final JavaClass java_class, final String dir) throws IOException { + final Method[] methods = java_class.getMethods(); + this.java_class = java_class; + this.dir = dir; + class_name = java_class.getClassName(); // Remember full name + constant_pool = java_class.getConstantPool(); + // Get package name by tacking off everything after the last `.' + final int index = class_name.lastIndexOf('.'); + if (index > -1) { + class_package = class_name.substring(0, index); + } else { + class_package = ""; // default package } - } - } catch(StringIndexOutOfBoundsException e) {} // Never occurs + final ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods, + constant_pool); + /* Attributes can't be written in one step, so we just open a file + * which will be written consequently. + */ + final AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, + constant_html); + new MethodHTML(dir, class_name, methods, java_class.getFields(), + constant_html, attribute_html); + // Write main file (with frames, yuk) + writeMainHTML(attribute_html); + new CodeHTML(dir, class_name, methods, constant_pool, constant_html); + attribute_html.close(); + } - return buf.toString(); - } + public static void _main(final String[] argv) throws IOException { + final String[] file_name = new String[argv.length]; + int files = 0; + ClassParser parser = null; + JavaClass java_class = null; + String zip_file = null; + final char sep = File.separatorChar; + String dir = "." + sep; // Where to store HTML files + /* Parse command line arguments. + */ + for (int i = 0; i < argv.length; i++) { + if (argv[i].charAt(0) == '-') { // command line switch + if (argv[i].equals("-d")) { // Specify target directory, default '.' + dir = argv[++i]; + if (!dir.endsWith("" + sep)) { + dir = dir + sep; + } + final File store = new File(dir); - private void writeMainHTML(AttributeHTML attribute_html) throws IOException { - PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html")); - Attribute[] attributes = java_class.getAttributes(); + if (!store.isDirectory()) { + final boolean created = store.mkdirs(); // Create target directory if necessary + if (!created) { + if (!store.isDirectory()) { + System.out.println("Tried to create the directory " + dir + " but failed"); + } + } + } + } else if (argv[i].equals("-zip")) { + zip_file = argv[++i]; + } else { + System.out.println("Unknown option " + argv[i]); + } + } else { + file_name[files++] = argv[i]; + } + } + if (files == 0) { + System.err.println("Class2HTML: No input files specified."); + } else { // Loop through files ... + for (int i = 0; i < files; i++) { + System.out.print("Processing " + file_name[i] + "..."); + if (zip_file == null) { + parser = new ClassParser(file_name[i]); // Create parser object from file + } else { + parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file + } + java_class = parser.parse(); + new Class2HTML(java_class, dir); + System.out.println("Done."); + } + } + } - file.println("\n" + "Documentation for " + class_name + "" + - "\n" + - "\n" + - "\n" + + /** + * Utility method that converts a class reference in the constant pool, + * i.e., an index to a string. + */ + static String referenceClass(final int index) { + String str = constant_pool.getConstantString(index, Const.CONSTANT_Class); + str = Utility.compactClassName(str); + str = Utility.compactClassName(str, class_package + ".", true); + return "" + str + + ""; + } - "\n" + - "\n" + - "\n" + + static String referenceType(final String type) { + String short_type = Utility.compactClassName(type); + short_type = Utility.compactClassName(short_type, class_package + ".", true); + final int index = type.indexOf('['); // Type is an array? + String base_type = type; + if (index > -1) { + base_type = type.substring(0, index); // Tack of the `[' + } + // test for basic type + if (basic_types.contains(base_type)) { + return "" + type + ""; + } + return "" + short_type + ""; + } - "\n" + - "\n" + - "\n" + - "" - ); + static String toHTML(final String str) { + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < str.length(); i++) { + char ch; + switch (ch = str.charAt(i)) { + case '<': + buf.append("<"); + break; + case '>': + buf.append(">"); + break; + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + default: + buf.append(ch); + } + } + return buf.toString(); + } - file.close(); - - for(int i=0; i < attributes.length; i++) - attribute_html.writeAttribute(attributes[i], "class" + i); - } + private void writeMainHTML(final AttributeHTML attribute_html) throws IOException { + try (PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html"))) { + file.println("\n" + "Documentation for " + class_name + "" + "\n" + + "\n" + "\n" + + "\n" + "\n" + "\n" + + "\n" + "\n" + + "\n" + ""); + } + final Attribute[] attributes = java_class.getAttributes(); + for (int i = 0; i < attributes.length; i++) { + attribute_html.writeAttribute(attributes[i], "class" + i); + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoader.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoader.java deleted file mode 100644 index 12708ad89f3..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoader.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.util; - - -import java.util.Hashtable; -import java.io.*; -import com.sun.org.apache.bcel.internal.*; -import com.sun.org.apache.bcel.internal.classfile.*; - -/** - *

      Drop in replacement for the standard class loader of the JVM. You can use it - * in conjunction with the JavaWrapper to dynamically modify/create classes - * as they're requested.

      - * - *

      This class loader recognizes special requests in a distinct - * format, i.e., when the name of the requested class contains with - * "$$BCEL$$" it calls the createClass() method with that name - * (everything bevor the $$BCEL$$ is considered to be the package - * name. You can subclass the class loader and override that - * method. "Normal" classes class can be modified by overriding the - * modifyClass() method which is called just before defineClass().

      - * - *

      There may be a number of packages where you have to use the default - * class loader (which may also be faster). You can define the set of packages - * where to use the system class loader in the constructor. The default value contains - * "java.", "sun.", "javax."

      - * - * @author M. Dahm - * @see JavaWrapper - * @see ClassPath - */ -public class ClassLoader extends java.lang.ClassLoader { - private Hashtable classes = new Hashtable(); // Hashtable is synchronized thus thread-safe - private String[] ignored_packages = { - "java.", "javax.", "sun." - }; - private Repository repository = SyntheticRepository.getInstance(); - private java.lang.ClassLoader deferTo = ClassLoader.getSystemClassLoader(); - - public ClassLoader() { - } - - public ClassLoader(java.lang.ClassLoader deferTo) { - this.deferTo = deferTo; - this.repository = new ClassLoaderRepository(deferTo); - } - - /** @param ignored_packages classes contained in these packages will be loaded - * with the system class loader - */ - public ClassLoader(String[] ignored_packages) { - addIgnoredPkgs(ignored_packages); - } - - public ClassLoader(java.lang.ClassLoader deferTo, String [] ignored_packages) { - this.deferTo = deferTo; - this.repository = new ClassLoaderRepository(deferTo); - - addIgnoredPkgs(ignored_packages); - } - - private void addIgnoredPkgs(String[] ignored_packages) { - String[] new_p = new String[ignored_packages.length + this.ignored_packages.length]; - - System.arraycopy(this.ignored_packages, 0, new_p, 0, this.ignored_packages.length); - System.arraycopy(ignored_packages, 0, new_p, this.ignored_packages.length, - ignored_packages.length); - - this.ignored_packages = new_p; - } - - protected Class loadClass(String class_name, boolean resolve) - throws ClassNotFoundException - { - Class cl = null; - - /* First try: lookup hash table. - */ - if((cl=(Class)classes.get(class_name)) == null) { - /* Second try: Load system class using system class loader. You better - * don't mess around with them. - */ - for(int i=0; i < ignored_packages.length; i++) { - if(class_name.startsWith(ignored_packages[i])) { - cl = deferTo.loadClass(class_name); - break; - } - } - - if(cl == null) { - JavaClass clazz = null; - - /* Third try: Special request? - */ - if(class_name.indexOf("$$BCEL$$") >= 0) - clazz = createClass(class_name); - else { // Fourth try: Load classes via repository - if ((clazz = repository.loadClass(class_name)) != null) { - clazz = modifyClass(clazz); - } - else - throw new ClassNotFoundException(class_name); - } - - if(clazz != null) { - byte[] bytes = clazz.getBytes(); - cl = defineClass(class_name, bytes, 0, bytes.length); - } else // Fourth try: Use default class loader - cl = Class.forName(class_name); - } - - if(resolve) - resolveClass(cl); - } - - classes.put(class_name, cl); - - return cl; - } - - /** Override this method if you want to alter a class before it gets actually - * loaded. Does nothing by default. - */ - protected JavaClass modifyClass(JavaClass clazz) { - return clazz; - } - - /** - * Override this method to create you own classes on the fly. The - * name contains the special token $$BCEL$$. Everything before that - * token is consddered to be a package name. You can encode you own - * arguments into the subsequent string. You must regard however not - * to use any "illegal" characters, i.e., characters that may not - * appear in a Java class name too
      - * - * The default implementation interprets the string as a encoded compressed - * Java class, unpacks and decodes it with the Utility.decode() method, and - * parses the resulting byte array and returns the resulting JavaClass object. - * - * @param class_name compressed byte code with "$$BCEL$$" in it - */ - protected JavaClass createClass(String class_name) { - int index = class_name.indexOf("$$BCEL$$"); - String real_name = class_name.substring(index + 8); - - JavaClass clazz = null; - try { - byte[] bytes = Utility.decode(real_name, true); - ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo"); - - clazz = parser.parse(); - } catch(Throwable e) { - e.printStackTrace(); - return null; - } - - // Adapt the class name to the passed value - ConstantPool cp = clazz.getConstantPool(); - - ConstantClass cl = (ConstantClass)cp.getConstant(clazz.getClassNameIndex(), - Constants.CONSTANT_Class); - ConstantUtf8 name = (ConstantUtf8)cp.getConstant(cl.getNameIndex(), - Constants.CONSTANT_Utf8); - name.setBytes(class_name.replace('.', '/')); - - return clazz; - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoaderRepository.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoaderRepository.java deleted file mode 100644 index 80e844216d6..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassLoaderRepository.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.util; - - -import java.io.*; - -import java.util.Map; -import java.util.HashMap; - -import com.sun.org.apache.bcel.internal.classfile.*; - -/** - * The repository maintains information about which classes have - * been loaded. - * - * It loads its data from the ClassLoader implementation - * passed into its constructor. - * - * @see com.sun.org.apache.bcel.internal.Repository - * - * @author M. Dahm - * @author David Dixon-Peugh - */ -public class ClassLoaderRepository - implements Repository -{ - private java.lang.ClassLoader loader; - private HashMap loadedClasses = - new HashMap(); // CLASSNAME X JAVACLASS - - public ClassLoaderRepository( java.lang.ClassLoader loader ) { - this.loader = loader; - } - - /** - * Store a new JavaClass 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 JavaClass. - */ - public JavaClass findClass( String className ) { - if ( loadedClasses.containsKey( className )) { - return (JavaClass) loadedClasses.get( className ); - } else { - return null; - } - } - - /** - * Lookup a JavaClass object from the Class Name provided. - */ - public JavaClass loadClass( String className ) - throws ClassNotFoundException - { - String classFile = className.replace('.', '/'); - - JavaClass RC = findClass( className ); - if (RC != null) { return RC; } - - try { - InputStream is = - loader.getResourceAsStream( classFile + ".class" ); - - if(is == null) { - throw new ClassNotFoundException(className + " not found."); - } - - ClassParser parser = new ClassParser( is, className ); - RC = parser.parse(); - - storeClass( RC ); - - return RC; - } catch (IOException e) { - throw new ClassNotFoundException( e.toString() ); - } - } - - public JavaClass loadClass(Class clazz) throws ClassNotFoundException { - return loadClass(clazz.getName()); - } - - /** Clear all entries from cache. - */ - public void clear() { - loadedClasses.clear(); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java index a4dda645d10..5aa4d430953 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,31 +17,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; import java.util.LinkedList; + import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** - * Utility class implementing a (typesafe) queue of JavaClass - * objects. + * Utility class implementing a (typesafe) queue of JavaClass objects. * - * @author M. Dahm - * @see ClassVector -*/ -public class ClassQueue implements java.io.Serializable { - protected LinkedList vec = new LinkedList(); + * @version $Id: ClassQueue.java 1747278 2016-06-07 17:28:43Z britter $ + */ +public class ClassQueue { - public void enqueue(JavaClass clazz) { vec.addLast(clazz); } + private final LinkedList vec = new LinkedList<>(); - public JavaClass dequeue() { - return (JavaClass)vec.removeFirst(); - } + public void enqueue(final JavaClass clazz) { + vec.addLast(clazz); + } - public boolean empty() { return vec.isEmpty(); } + public JavaClass dequeue() { + return vec.removeFirst(); + } - public String toString() { - return vec.toString(); - } + public boolean empty() { + return vec.isEmpty(); + } + + @Override + public String toString() { + return vec.toString(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java index 27dd9b7ce82..f35a712b663 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java @@ -21,8 +21,10 @@ package com.sun.org.apache.bcel.internal.util; -import java.util.HashMap; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** @@ -30,34 +32,43 @@ import com.sun.org.apache.bcel.internal.classfile.JavaClass; * Since JavaClass has no equals() method, the name of the class is * used for comparison. * - * @author M. Dahm + * @version $Id: ClassSet.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see ClassStack -*/ -public class ClassSet implements java.io.Serializable { - private HashMap _map = new HashMap(); + */ +public class ClassSet { - public boolean add(JavaClass clazz) { - boolean result = false; + private final Map map = new HashMap<>(); - if(!_map.containsKey(clazz.getClassName())) { - result = true; - _map.put(clazz.getClassName(), clazz); + + public boolean add( final JavaClass clazz ) { + boolean result = false; + if (!map.containsKey(clazz.getClassName())) { + result = true; + map.put(clazz.getClassName(), clazz); + } + return result; } - return result; - } - public void remove(JavaClass clazz) { _map.remove(clazz.getClassName()); } - public boolean empty() { return _map.isEmpty(); } + public void remove( final JavaClass clazz ) { + map.remove(clazz.getClassName()); + } - public JavaClass[] toArray() { - Collection values = _map.values(); - JavaClass[] classes = new JavaClass[values.size()]; - values.toArray(classes); - return classes; - } - public String[] getClassNames() { - return (String[])_map.keySet().toArray(new String[_map.keySet().size()]); - } + public boolean empty() { + return map.isEmpty(); + } + + + public JavaClass[] toArray() { + final Collection values = map.values(); + final JavaClass[] classes = new JavaClass[values.size()]; + values.toArray(classes); + return classes; + } + + + public String[] getClassNames() { + return map.keySet().toArray(new String[map.size()]); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java index 52275dda1f1..0ee2767428d 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java @@ -27,14 +27,30 @@ import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** * Utility class implementing a (typesafe) stack of JavaClass objects. * - * @author M. Dahm + * @version $Id: ClassStack.java 1747278 2016-06-07 17:28:43Z britter $ * @see Stack -*/ -public class ClassStack implements java.io.Serializable { - private Stack stack = new Stack(); + */ +public class ClassStack { - public void push(JavaClass clazz) { stack.push(clazz); } - public JavaClass pop() { return (JavaClass)stack.pop(); } - public JavaClass top() { return (JavaClass)stack.peek(); } - public boolean empty() { return stack.empty(); } + private final Stack stack = new Stack<>(); + + + public void push( final JavaClass clazz ) { + stack.push(clazz); + } + + + public JavaClass pop() { + return stack.pop(); + } + + + public JavaClass top() { + return stack.peek(); + } + + + public boolean empty() { + return stack.empty(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java index eb9d4bf65ec..d1e792b1511 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java @@ -21,565 +21,569 @@ package com.sun.org.apache.bcel.internal.util; - -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; import java.util.BitSet; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.CodeException; +import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic; +import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.LocalVariable; +import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; + /** * Convert code into HTML file. * - * @author M. Dahm + * @version $Id: CodeHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class CodeHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private Method[] methods; // Methods to print - private PrintWriter file; // file to write to - private BitSet goto_set; - private ConstantPool constant_pool; - private ConstantHTML constant_html; - private static boolean wide=false; +final class CodeHTML { - CodeHTML(String dir, String class_name, - Method[] methods, ConstantPool constant_pool, - ConstantHTML constant_html) throws IOException - { - this.class_name = class_name; - this.methods = methods; - this.constant_pool = constant_pool; - this.constant_html = constant_html; + private final String class_name; // name of current class +// private Method[] methods; // Methods to print + private final PrintWriter file; // file to write to + private BitSet goto_set; + private final ConstantPool constant_pool; + private final ConstantHTML constant_html; + private static boolean wide = false; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html")); - file.println(""); - for(int i=0; i < methods.length; i++) - writeMethod(methods[i], i); + CodeHTML(final String dir, final String class_name, final Method[] methods, final ConstantPool constant_pool, + final ConstantHTML constant_html) throws IOException { + this.class_name = class_name; +// this.methods = methods; + this.constant_pool = constant_pool; + this.constant_html = constant_html; + file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html")); + file.println(""); + for (int i = 0; i < methods.length; i++) { + writeMethod(methods[i], i); + } + file.println(""); + file.close(); + } - file.println(""); - file.close(); - } - /** - * Disassemble a stream of byte codes and return the - * string representation. - * - * @param stream data input stream - * @return String representation of byte code - */ - private final String codeToHTML(ByteSequence bytes, int method_number) - throws IOException - { - short opcode = (short)bytes.readUnsignedByte(); - StringBuffer buf; - String name, signature; - int default_offset=0, low, high; - int index, class_index, vindex, constant; - int[] jump_table; - int no_pad_bytes=0, offset; - - buf = new StringBuffer("" + OPCODE_NAMES[opcode] + ""); - - /* Special case: Skip (0-3) padding bytes, i.e., the - * following bytes are 4-byte-aligned + /** + * Disassemble a stream of byte codes and return the + * string representation. + * + * @param stream data input stream + * @return String representation of byte code */ - if((opcode == TABLESWITCH) || (opcode == LOOKUPSWITCH)) { - int remainder = bytes.getIndex() % 4; - no_pad_bytes = (remainder == 0)? 0 : 4 - remainder; - - for(int i=0; i < no_pad_bytes; i++) - bytes.readByte(); - - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); - } - - switch(opcode) { - case TABLESWITCH: - low = bytes.readInt(); - high = bytes.readInt(); - - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - - buf.append(""); - - // Print switch indices in first row (and default) - jump_table = new int[high - low + 1]; - for(int i=0; i < jump_table.length; i++) { - jump_table[i] = offset + bytes.readInt(); - - buf.append(""); - } - buf.append("\n"); - - // Print target and default indices in second row - for(int i=0; i < jump_table.length; i++) - buf.append(""); - buf.append("\n
      " + (low + i) + "default
      " + jump_table[i] + "" + default_offset + "
      \n"); - - break; - - /* Lookup switch has variable length arguments. - */ - case LOOKUPSWITCH: - int npairs = bytes.readInt(); - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - jump_table = new int[npairs]; - default_offset += offset; - - buf.append(""); - - // Print switch indices in first row (and default) - for(int i=0; i < npairs; i++) { - int match = bytes.readInt(); - - jump_table[i] = offset + bytes.readInt(); - buf.append(""); - } - buf.append("\n"); - - // Print target and default indices in second row - for(int i=0; i < npairs; i++) - buf.append(""); - buf.append("\n
      " + match + "default
      " + jump_table[i] + "" + default_offset + "
      \n"); - break; - - /* Two address bytes + offset from start of byte stream form the - * jump target. - */ - case GOTO: case IFEQ: case IFGE: case IFGT: - case IFLE: case IFLT: - case IFNE: case IFNONNULL: case IFNULL: 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 JSR: - - index = (int)(bytes.getIndex() + bytes.readShort() - 1); - - buf.append("" + index + ""); - break; - - /* Same for 32-bit wide jumps - */ - case GOTO_W: case JSR_W: - int windex = bytes.getIndex() + bytes.readInt() - 1; - buf.append("" + - windex + ""); - break; - - /* Index byte references local variable (register) - */ - case ALOAD: case ASTORE: case DLOAD: case DSTORE: case FLOAD: - case FSTORE: case ILOAD: case ISTORE: case LLOAD: case LSTORE: - case RET: - if(wide) { - vindex = bytes.readShort(); - wide=false; // Clear flag - } - else - vindex = bytes.readUnsignedByte(); - - buf.append("%" + vindex); - break; - - /* - * Remember wide byte which is used to form a 16-bit address in the - * following instruction. Relies on that the method is called again with - * the following opcode. - */ - case WIDE: - wide = true; - buf.append("(wide)"); - break; - - /* Array of basic type. - */ - case NEWARRAY: - buf.append("" + TYPE_NAMES[bytes.readByte()] + ""); - break; - - /* Access object/class fields. - */ - case GETFIELD: case GETSTATIC: case PUTFIELD: case PUTSTATIC: - index = bytes.readShort(); - ConstantFieldref c1 = (ConstantFieldref)constant_pool.getConstant(index, CONSTANT_Fieldref); - - class_index = c1.getClassIndex(); - name = constant_pool.getConstantString(class_index, CONSTANT_Class); - name = Utility.compactClassName(name, false); - - index = c1.getNameAndTypeIndex(); - String field_name = constant_pool.constantToString(index, CONSTANT_NameAndType); - - if(name.equals(class_name)) { // Local field - buf.append("" + field_name + "\n"); - } - else - buf.append(constant_html.referenceConstant(class_index) + "." + field_name); - - break; - - /* Operands are references to classes in constant pool - */ - case CHECKCAST: case INSTANCEOF: case NEW: - index = bytes.readShort(); - buf.append(constant_html.referenceConstant(index)); - break; - - /* Operands are references to methods in constant pool - */ - case INVOKESPECIAL: case INVOKESTATIC: case INVOKEVIRTUAL: case INVOKEINTERFACE: - int m_index = bytes.readShort(); - String str; - - if(opcode == INVOKEINTERFACE) { // Special treatment needed - int nargs = bytes.readUnsignedByte(); // Redundant - int reserved = bytes.readUnsignedByte(); // Reserved - - ConstantInterfaceMethodref c=(ConstantInterfaceMethodref)constant_pool.getConstant(m_index, CONSTANT_InterfaceMethodref); - - class_index = c.getClassIndex(); - str = constant_pool.constantToString(c); - index = c.getNameAndTypeIndex(); - } - else { - ConstantMethodref c = (ConstantMethodref)constant_pool.getConstant(m_index, CONSTANT_Methodref); - class_index = c.getClassIndex(); - - str = constant_pool.constantToString(c); - index = c.getNameAndTypeIndex(); - } - - name = Class2HTML.referenceClass(class_index); - str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant(index, CONSTANT_NameAndType))); - - // Get signature, i.e., types - ConstantNameAndType c2 = (ConstantNameAndType)constant_pool. - getConstant(index, CONSTANT_NameAndType); - signature = constant_pool.constantToString(c2.getSignatureIndex(), - CONSTANT_Utf8); - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - String type = Utility.methodSignatureReturnType(signature, false); - - buf.append(name + "." + str + "" + "("); - - // List arguments - for(int i=0; i < args.length; i++) { - buf.append(Class2HTML.referenceType(args[i])); - - if(i < args.length - 1) - buf.append(", "); - } - // Attach return type - buf.append("):" + Class2HTML.referenceType(type)); - - break; - - /* Operands are references to items in constant pool - */ - case LDC_W: case LDC2_W: - index = bytes.readShort(); - - buf.append("" + - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool. - getConstant(index).getTag()))+ - ""); - break; - - case LDC: - index = bytes.readUnsignedByte(); - buf.append("" + - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool. - getConstant(index).getTag()))+ - ""); - break; - - /* Array of references. - */ - case ANEWARRAY: - index = bytes.readShort(); - - buf.append(constant_html.referenceConstant(index)); - break; - - /* Multidimensional array of references. - */ - case MULTIANEWARRAY: - index = bytes.readShort(); - int dimensions = bytes.readByte(); - buf.append(constant_html.referenceConstant(index) + ":" + dimensions + "-dimensional"); - break; - - /* Increment local variable. - */ - case IINC: - if(wide) { - vindex = bytes.readShort(); - constant = bytes.readShort(); - wide = false; - } - else { - vindex = bytes.readUnsignedByte(); - constant = bytes.readByte(); - } - buf.append("%" + vindex + " " + constant); - break; - - default: - if(NO_OF_OPERANDS[opcode] > 0) { - for(int i=0; i < TYPE_OF_OPERANDS[opcode].length; i++) { - switch(TYPE_OF_OPERANDS[opcode][i]) { - case T_BYTE: - buf.append(bytes.readUnsignedByte()); - break; - - case T_SHORT: // Either branch or index - buf.append(bytes.readShort()); - break; - - case T_INT: - buf.append(bytes.readInt()); - break; - - default: // Never reached - System.err.println("Unreachable default case reached!"); - System.exit(-1); - } - buf.append(" "); - } - } - } - - buf.append(""); - return buf.toString(); - } - - /** - * Find all target addresses in code, so that they can be marked - * with <A NAME = ...>. Target addresses are kept in an BitSet object. - */ - private final void findGotos(ByteSequence bytes, Method method, Code code) - throws IOException - { - int index; - goto_set = new BitSet(bytes.available()); - int opcode; - - /* First get Code attribute from method and the exceptions handled - * (try .. catch) in this method. We only need the line number here. - */ - - if(code != null) { - CodeException[] ce = code.getExceptionTable(); - int len = ce.length; - - for(int i=0; i < len; i++) { - goto_set.set(ce[i].getStartPC()); - goto_set.set(ce[i].getEndPC()); - goto_set.set(ce[i].getHandlerPC()); - } - - // Look for local variables and their range - Attribute[] attributes = code.getAttributes(); - for(int i=0; i < attributes.length; i++) { - if(attributes[i].getTag() == ATTR_LOCAL_VARIABLE_TABLE) { - LocalVariable[] vars = ((LocalVariableTable)attributes[i]).getLocalVariableTable(); - - for(int j=0; j < vars.length; j++) { - int start = vars[j].getStartPC(); - int end = (int)(start + vars[j].getLength()); - goto_set.set(start); - goto_set.set(end); - } - break; - } - } - } - - // Get target addresses from GOTO, JSR, TABLESWITCH, etc. - for(int i=0; bytes.available() > 0; i++) { - opcode = bytes.readUnsignedByte(); - //System.out.println(OPCODE_NAMES[opcode]); - switch(opcode) { - case TABLESWITCH: case LOOKUPSWITCH: - //bytes.readByte(); // Skip already read byte - - int remainder = bytes.getIndex() % 4; - int no_pad_bytes = (remainder == 0)? 0 : 4 - remainder; - int default_offset, offset; - - for(int j=0; j < no_pad_bytes; j++) - bytes.readByte(); - - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); - - if(opcode == TABLESWITCH) { - int low = bytes.readInt(); - int high = bytes.readInt(); - - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - goto_set.set(default_offset); - - for(int j=0; j < (high - low + 1); j++) { - index = offset + bytes.readInt(); - goto_set.set(index); - } - } - else { // LOOKUPSWITCH - int npairs = bytes.readInt(); - - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - default_offset += offset; - goto_set.set(default_offset); - - for(int j=0; j < npairs; j++) { - int match = bytes.readInt(); - - index = offset + bytes.readInt(); - goto_set.set(index); - } - } - break; - - case GOTO: case IFEQ: case IFGE: case IFGT: - case IFLE: case IFLT: - case IFNE: case IFNONNULL: case IFNULL: 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 JSR: - //bytes.readByte(); // Skip already read byte - index = bytes.getIndex() + bytes.readShort() - 1; - - goto_set.set(index); - break; - - case GOTO_W: case JSR_W: - //bytes.readByte(); // Skip already read byte - index = bytes.getIndex() + bytes.readInt() - 1; - goto_set.set(index); - break; - - default: - bytes.unreadByte(); - codeToHTML(bytes, 0); // Ignore output - } - } - } - - /** - * Write a single method with the byte code associated with it. - */ - private void writeMethod(Method method, int method_number) - throws IOException - { - // Get raw signature - String signature = method.getSignature(); - // Get array of strings containing the argument types - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - // Get return type string - String type = Utility.methodSignatureReturnType(signature, false); - // Get method name - String name = method.getName(); - String html_name = Class2HTML.toHTML(name); - // Get method's access flags - String access = Utility.accessToString(method.getAccessFlags()); - access = Utility.replace(access, " ", " "); - // Get the method's attributes, the Code Attribute in particular - Attribute[] attributes= method.getAttributes(); - - file.print("

      " + access + " " + - "" + Class2HTML.referenceType(type) + - " " + html_name + "("); - - for(int i=0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); - if(i < args.length - 1) - file.print(", "); - } - - file.println(")

      "); - - Code c=null; - byte[] code=null; - - if(attributes.length > 0) { - file.print("

      Attributes

        \n"); - for(int i=0; i < attributes.length; i++) { - byte tag = attributes[i].getTag(); - - if(tag != ATTR_UNKNOWN) - file.print("
      • " + ATTRIBUTE_NAMES[tag] + "
      • \n"); - else - file.print("
      • " + attributes[i] + "
      • "); - - if(tag == ATTR_CODE) { - c = (Code)attributes[i]; - Attribute[] attributes2 = c.getAttributes(); - code = c.getCode(); - - file.print("
          "); - for(int j=0; j < attributes2.length; j++) { - tag = attributes2[j].getTag(); - file.print("
        • " + - ATTRIBUTE_NAMES[tag] + "
        • \n"); - - } - file.print("
        "); - } - } - file.println("
      "); - } - - if(code != null) { // No code, an abstract method, e.g. - //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1)); - - // Print the byte code - ByteSequence stream = new ByteSequence(code); - stream.mark(stream.available()); - findGotos(stream, method, c); - stream.reset(); - - file.println("" + - ""); - - for(int i=0; stream.available() > 0; i++) { - int offset = stream.getIndex(); - String str = codeToHTML(stream, method_number); - String anchor = ""; - - /* Set an anchor mark if this line is targetted by a goto, jsr, etc. - * Defining an anchor for every line is very inefficient! + private String codeToHTML( final ByteSequence bytes, final int method_number ) throws IOException { + final short opcode = (short) bytes.readUnsignedByte(); + String name; + String signature; + int default_offset = 0; + int low; + int high; + int index; + int class_index; + int vindex; + int constant; + int[] jump_table; + int no_pad_bytes = 0; + int offset; + final StringBuilder buf = new StringBuilder(256); // CHECKSTYLE IGNORE MagicNumber + buf.append("").append(Const.getOpcodeName(opcode)).append(""); - } - - // Mark last line, may be targetted from Attributes window - file.println(""); - file.println("
      Byte
      offset
      InstructionArgument"); + /* Special case: Skip (0-3) padding bytes, i.e., the + * following bytes are 4-byte-aligned */ - if(goto_set.get(offset)) - anchor = ""; - - String anchor2; - if(stream.getIndex() == code.length) // last loop - anchor2 = "" + offset + ""; - else - anchor2 = "" + offset; - - file.println("
      " + anchor2 + "" + anchor + str + "
      "); + if ((opcode == Const.TABLESWITCH) || (opcode == Const.LOOKUPSWITCH)) { + final int remainder = bytes.getIndex() % 4; + no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; + for (int i = 0; i < no_pad_bytes; i++) { + bytes.readByte(); + } + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); + } + switch (opcode) { + case Const.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + buf.append(""); + // Print switch indices in first row (and default) + jump_table = new int[high - low + 1]; + for (int i = 0; i < jump_table.length; i++) { + jump_table[i] = offset + bytes.readInt(); + buf.append(""); + } + buf.append("\n"); + // Print target and default indices in second row + for (final int element : jump_table) { + buf.append(""); + } + buf.append("\n
      ").append(low + i).append("default
      ").append(element).append("").append(default_offset).append( + "
      \n"); + break; + /* Lookup switch has variable length arguments. + */ + case Const.LOOKUPSWITCH: + final int npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + jump_table = new int[npairs]; + default_offset += offset; + buf.append(""); + // Print switch indices in first row (and default) + for (int i = 0; i < npairs; i++) { + final int match = bytes.readInt(); + jump_table[i] = offset + bytes.readInt(); + buf.append(""); + } + buf.append("\n"); + // Print target and default indices in second row + for (int i = 0; i < npairs; i++) { + buf.append(""); + } + buf.append("\n
      ").append(match).append("default
      ").append(jump_table[i]).append("").append(default_offset).append( + "
      \n"); + break; + /* Two address bytes + offset from start of byte stream form the + * jump target. + */ + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.JSR: + index = bytes.getIndex() + bytes.readShort() - 1; + buf.append("").append(index).append(""); + break; + /* Same for 32-bit wide jumps + */ + case Const.GOTO_W: + case Const.JSR_W: + final int windex = bytes.getIndex() + bytes.readInt() - 1; + buf.append("").append(windex).append(""); + break; + /* Index byte references local variable (register) + */ + case Const.ALOAD: + case Const.ASTORE: + case Const.DLOAD: + case Const.DSTORE: + case Const.FLOAD: + case Const.FSTORE: + case Const.ILOAD: + case Const.ISTORE: + case Const.LLOAD: + case Const.LSTORE: + case Const.RET: + if (wide) { + vindex = bytes.readShort(); + wide = false; // Clear flag + } else { + vindex = bytes.readUnsignedByte(); + } + buf.append("%").append(vindex); + break; + /* + * Remember wide byte which is used to form a 16-bit address in the + * following instruction. Relies on that the method is called again with + * the following opcode. + */ + case Const.WIDE: + wide = true; + buf.append("(wide)"); + break; + /* Array of basic type. + */ + case Const.NEWARRAY: + buf.append("").append(Const.getTypeName(bytes.readByte())).append( + ""); + break; + /* Access object/class fields. + */ + case Const.GETFIELD: + case Const.GETSTATIC: + case Const.PUTFIELD: + case Const.PUTSTATIC: + index = bytes.readShort(); + final ConstantFieldref c1 = (ConstantFieldref) constant_pool.getConstant(index, + Const.CONSTANT_Fieldref); + class_index = c1.getClassIndex(); + name = constant_pool.getConstantString(class_index, Const.CONSTANT_Class); + name = Utility.compactClassName(name, false); + index = c1.getNameAndTypeIndex(); + final String field_name = constant_pool.constantToString(index, Const.CONSTANT_NameAndType); + if (name.equals(class_name)) { // Local field + buf.append("").append(field_name) + .append("\n"); + } else { + buf.append(constant_html.referenceConstant(class_index)).append(".").append( + field_name); + } + break; + /* Operands are references to classes in constant pool + */ + case Const.CHECKCAST: + case Const.INSTANCEOF: + case Const.NEW: + index = bytes.readShort(); + buf.append(constant_html.referenceConstant(index)); + break; + /* Operands are references to methods in constant pool + */ + case Const.INVOKESPECIAL: + case Const.INVOKESTATIC: + case Const.INVOKEVIRTUAL: + case Const.INVOKEINTERFACE: + case Const.INVOKEDYNAMIC: + final int m_index = bytes.readShort(); + String str; + if (opcode == Const.INVOKEINTERFACE) { // Special treatment needed + bytes.readUnsignedByte(); // Redundant + bytes.readUnsignedByte(); // Reserved +// int nargs = bytes.readUnsignedByte(); // Redundant +// int reserved = bytes.readUnsignedByte(); // Reserved + final ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constant_pool + .getConstant(m_index, Const.CONSTANT_InterfaceMethodref); + class_index = c.getClassIndex(); + index = c.getNameAndTypeIndex(); + name = Class2HTML.referenceClass(class_index); + } else if (opcode == Const.INVOKEDYNAMIC) { // Special treatment needed + bytes.readUnsignedByte(); // Reserved + bytes.readUnsignedByte(); // Reserved + final ConstantInvokeDynamic c = (ConstantInvokeDynamic) constant_pool + .getConstant(m_index, Const.CONSTANT_InvokeDynamic); + index = c.getNameAndTypeIndex(); + name = "#" + c.getBootstrapMethodAttrIndex(); + } else { + // UNDONE: Java8 now allows INVOKESPECIAL and INVOKESTATIC to + // reference EITHER a Methodref OR an InterfaceMethodref. + // Not sure if that affects this code or not. (markro) + final ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(m_index, + Const.CONSTANT_Methodref); + class_index = c.getClassIndex(); + index = c.getNameAndTypeIndex(); + name = Class2HTML.referenceClass(class_index); + } + str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant( + index, Const.CONSTANT_NameAndType))); + // Get signature, i.e., types + final ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant(index, + Const.CONSTANT_NameAndType); + signature = constant_pool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + final String type = Utility.methodSignatureReturnType(signature, false); + buf.append(name).append(".").append(str).append( + "").append("("); + // List arguments + for (int i = 0; i < args.length; i++) { + buf.append(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + buf.append(", "); + } + } + // Attach return type + buf.append("):").append(Class2HTML.referenceType(type)); + break; + /* Operands are references to items in constant pool + */ + case Const.LDC_W: + case Const.LDC2_W: + index = bytes.readShort(); + buf.append("").append( + Class2HTML.toHTML(constant_pool.constantToString(index, + constant_pool.getConstant(index).getTag()))).append(""); + break; + case Const.LDC: + index = bytes.readUnsignedByte(); + buf.append("").append( + Class2HTML.toHTML(constant_pool.constantToString(index, + constant_pool.getConstant(index).getTag()))).append(""); + break; + /* Array of references. + */ + case Const.ANEWARRAY: + index = bytes.readShort(); + buf.append(constant_html.referenceConstant(index)); + break; + /* Multidimensional array of references. + */ + case Const.MULTIANEWARRAY: + index = bytes.readShort(); + final int dimensions = bytes.readByte(); + buf.append(constant_html.referenceConstant(index)).append(":").append(dimensions) + .append("-dimensional"); + break; + /* Increment local variable. + */ + case Const.IINC: + if (wide) { + vindex = bytes.readShort(); + constant = bytes.readShort(); + wide = false; + } else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("%").append(vindex).append(" ").append(constant); + break; + default: + if (Const.getNoOfOperands(opcode) > 0) { + for (int i = 0; i < Const.getOperandTypeCount(opcode); i++) { + switch (Const.getOperandType(opcode, i)) { + case Const.T_BYTE: + buf.append(bytes.readUnsignedByte()); + break; + case Const.T_SHORT: // Either branch or index + buf.append(bytes.readShort()); + break; + case Const.T_INT: + buf.append(bytes.readInt()); + break; + default: // Never reached + throw new IllegalStateException( + "Unreachable default case reached! " + + Const.getOperandType(opcode, i)); + } + buf.append(" "); + } + } + } + buf.append(""); + return buf.toString(); } - } + + /** + * Find all target addresses in code, so that they can be marked + * with <A NAME = ...>. Target addresses are kept in an BitSet object. + */ + private void findGotos( final ByteSequence bytes, final Code code ) throws IOException { + int index; + goto_set = new BitSet(bytes.available()); + int opcode; + /* First get Code attribute from method and the exceptions handled + * (try .. catch) in this method. We only need the line number here. + */ + if (code != null) { + final CodeException[] ce = code.getExceptionTable(); + for (final CodeException cex : ce) { + goto_set.set(cex.getStartPC()); + goto_set.set(cex.getEndPC()); + goto_set.set(cex.getHandlerPC()); + } + // Look for local variables and their range + final Attribute[] attributes = code.getAttributes(); + for (final Attribute attribute : attributes) { + if (attribute.getTag() == Const.ATTR_LOCAL_VARIABLE_TABLE) { + final LocalVariable[] vars = ((LocalVariableTable) attribute) + .getLocalVariableTable(); + for (final LocalVariable var : vars) { + final int start = var.getStartPC(); + final int end = start + var.getLength(); + goto_set.set(start); + goto_set.set(end); + } + break; + } + } + } + // Get target addresses from GOTO, JSR, TABLESWITCH, etc. + for (; bytes.available() > 0;) { + opcode = bytes.readUnsignedByte(); + //System.out.println(getOpcodeName(opcode)); + switch (opcode) { + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: + //bytes.readByte(); // Skip already read byte + final int remainder = bytes.getIndex() % 4; + final int no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; + int default_offset; + int offset; + for (int j = 0; j < no_pad_bytes; j++) { + bytes.readByte(); + } + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); + if (opcode == Const.TABLESWITCH) { + final int low = bytes.readInt(); + final int high = bytes.readInt(); + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + goto_set.set(default_offset); + for (int j = 0; j < (high - low + 1); j++) { + index = offset + bytes.readInt(); + goto_set.set(index); + } + } else { // LOOKUPSWITCH + final int npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + default_offset += offset; + goto_set.set(default_offset); + for (int j = 0; j < npairs; j++) { +// int match = bytes.readInt(); + bytes.readInt(); + index = offset + bytes.readInt(); + goto_set.set(index); + } + } + break; + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.JSR: + //bytes.readByte(); // Skip already read byte + index = bytes.getIndex() + bytes.readShort() - 1; + goto_set.set(index); + break; + case Const.GOTO_W: + case Const.JSR_W: + //bytes.readByte(); // Skip already read byte + index = bytes.getIndex() + bytes.readInt() - 1; + goto_set.set(index); + break; + default: + bytes.unreadByte(); + codeToHTML(bytes, 0); // Ignore output + } + } + } + + + /** + * Write a single method with the byte code associated with it. + */ + private void writeMethod( final Method method, final int method_number ) throws IOException { + // Get raw signature + final String signature = method.getSignature(); + // Get array of strings containing the argument types + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + // Get return type string + final String type = Utility.methodSignatureReturnType(signature, false); + // Get method name + final String name = method.getName(); + final String html_name = Class2HTML.toHTML(name); + // Get method's access flags + String access = Utility.accessToString(method.getAccessFlags()); + access = Utility.replace(access, " ", " "); + // Get the method's attributes, the Code Attribute in particular + final Attribute[] attributes = method.getAttributes(); + file.print("

      " + access + " " + "" + Class2HTML.referenceType(type) + " " + + html_name + "("); + for (int i = 0; i < args.length; i++) { + file.print(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + file.print(", "); + } + } + file.println(")

      "); + Code c = null; + byte[] code = null; + if (attributes.length > 0) { + file.print("

      Attributes

        \n"); + for (int i = 0; i < attributes.length; i++) { + byte tag = attributes[i].getTag(); + if (tag != Const.ATTR_UNKNOWN) { + file.print("
      • " + + Const.getAttributeName(tag) + "
      • \n"); + } else { + file.print("
      • " + attributes[i] + "
      • "); + } + if (tag == Const.ATTR_CODE) { + c = (Code) attributes[i]; + final Attribute[] attributes2 = c.getAttributes(); + code = c.getCode(); + file.print(""); + } + } + file.println("
      "); + } + if (code != null) { // No code, an abstract method, e.g. + //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1)); + // Print the byte code + try (ByteSequence stream = new ByteSequence(code)) { + stream.mark(stream.available()); + findGotos(stream, c); + stream.reset(); + file.println("" + + ""); + for (; stream.available() > 0;) { + final int offset = stream.getIndex(); + final String str = codeToHTML(stream, method_number); + String anchor = ""; + /* + * Set an anchor mark if this line is targetted by a goto, jsr, etc. Defining an anchor for every + * line is very inefficient! + */ + if (goto_set.get(offset)) { + anchor = ""; + } + String anchor2; + if (stream.getIndex() == code.length) { + anchor2 = "" + offset + ""; + } else { + anchor2 = "" + offset; + } + file.println(""); + } + } + // Mark last line, may be targetted from Attributes window + file.println(""); + file.println("
      Byte
      offset
      InstructionArgument
      " + anchor2 + "" + anchor + str + "
      "); + } + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java index ac1d8501783..1f0208437bc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java @@ -21,208 +21,217 @@ package com.sun.org.apache.bcel.internal.util; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.classfile.ConstantClass; +import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; +import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; +import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; +import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.ConstantString; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Convert constant pool into HTML file. * - * @author M. Dahm + * @version $Id: ConstantHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class ConstantHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private String class_package; // name of package - private ConstantPool constant_pool; // reference to constant pool - private PrintWriter file; // file to write to - private String[] constant_ref; // String to return for cp[i] - private Constant[] constants; // The constants in the cp - private Method[] methods; +final class ConstantHTML { - ConstantHTML(String dir, String class_name, String class_package, Method[] methods, - ConstantPool constant_pool) throws IOException - { - this.class_name = class_name; - this.class_package = class_package; - this.constant_pool = constant_pool; - this.methods = methods; - constants = constant_pool.getConstantPool(); - file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); - constant_ref = new String[constants.length]; - constant_ref[0] = "<unknown>"; + private final String class_name; // name of current class + private final String class_package; // name of package + private final ConstantPool constant_pool; // reference to constant pool + private final PrintWriter file; // file to write to + private final String[] constant_ref; // String to return for cp[i] + private final Constant[] constants; // The constants in the cp + private final Method[] methods; - file.println(""); - // Loop through constants, constants[0] is reserved - for(int i=1; i < constants.length; i++) { - if(i % 2 == 0) - file.print("\n"); + ConstantHTML(final String dir, final String class_name, final String class_package, + final Method[] methods, final ConstantPool constant_pool) throws IOException { + this.class_name = class_name; + this.class_package = class_package; + this.constant_pool = constant_pool; + this.methods = methods; + constants = constant_pool.getConstantPool(); + file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); + constant_ref = new String[constants.length]; + constant_ref[0] = "<unknown>"; + file.println("
      "); - else - file.print("
      "); - - if(constants[i] != null) - writeConstant(i); - - file.print("
      "); + // Loop through constants, constants[0] is reserved + for (int i = 1; i < constants.length; i++) { + if (i % 2 == 0) { + file.print("\n"); + } + file.println("
      "); + } else { + file.print("
      "); + } + if (constants[i] != null) { + writeConstant(i); + } + file.print("
      "); + file.close(); } - file.println(""); - file.close(); - } - String referenceConstant(int index) { - return constant_ref[index]; - } - - private void writeConstant(int index) { - byte tag = constants[index].getTag(); - int class_index, name_index; - String ref; - - // The header is always the same - file.println("

      " + index + " " + CONSTANT_NAMES[tag] + "

      "); - - /* For every constant type get the needed parameters and print them appropiately - */ - switch(tag) { - case CONSTANT_InterfaceMethodref: - case CONSTANT_Methodref: - // Get class_index and name_and_type_index, depending on type - if(tag == CONSTANT_Methodref) { - ConstantMethodref c = (ConstantMethodref)constant_pool.getConstant(index, CONSTANT_Methodref); - class_index = c.getClassIndex(); - name_index = c.getNameAndTypeIndex(); - } - else { - ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref)constant_pool.getConstant(index, CONSTANT_InterfaceMethodref); - class_index = c1.getClassIndex(); - name_index = c1.getNameAndTypeIndex(); - } - - // Get method name and its class - String method_name = constant_pool.constantToString(name_index, CONSTANT_NameAndType); - String html_method_name = Class2HTML.toHTML(method_name); - - // Partially compacted class name, i.e., / -> . - String method_class = constant_pool.constantToString(class_index, CONSTANT_Class); - String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(short_method_class, class_package + ".", true); // Remove class package prefix - - // Get method signature - ConstantNameAndType c2 = (ConstantNameAndType)constant_pool.getConstant(name_index, CONSTANT_NameAndType); - String signature = constant_pool.constantToString(c2.getSignatureIndex(), CONSTANT_Utf8); - // Get array of strings containing the argument types - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - - // Get return type string - String type = Utility.methodSignatureReturnType(signature, false); - String ret_type = Class2HTML.referenceType(type); - - StringBuffer buf = new StringBuffer("("); - for(int i=0; i < args.length; i++) { - buf.append(Class2HTML.referenceType(args[i])); - if(i < args.length - 1) - buf.append(", "); - } - buf.append(")"); - - String arg_types = buf.toString(); - - if(method_class.equals(class_name)) // Method is local to class - ref = "" + html_method_name + ""; - else - ref = "" + short_method_class + - "." + html_method_name; - - constant_ref[index] = ret_type + " " + - short_method_class + "." + html_method_name + " " + arg_types; - - file.println("

      " + ret_type + " " + ref + arg_types + " \n

      "); - break; - - case CONSTANT_Fieldref: - // Get class_index and name_and_type_index - ConstantFieldref c3 = (ConstantFieldref)constant_pool.getConstant(index, CONSTANT_Fieldref); - class_index = c3.getClassIndex(); - name_index = c3.getNameAndTypeIndex(); - - // Get method name and its class (compacted) - String field_class = constant_pool.constantToString(class_index, CONSTANT_Class); - String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. - short_field_class = Utility.compactClassName(short_field_class, class_package + ".", true); // Remove class package prefix - - String field_name = constant_pool.constantToString(name_index, CONSTANT_NameAndType); - - if(field_class.equals(class_name)) // Field is local to class - ref = "" + field_name + ""; - else - ref = "" + - short_field_class + "." + field_name + "\n"; - - constant_ref[index] = "" + - short_field_class + "." + field_name + ""; - - file.println("

      " + ref + "
      \n" + "

      "); - break; - - case CONSTANT_Class: - ConstantClass c4 = (ConstantClass)constant_pool.getConstant(index, CONSTANT_Class); - name_index = c4.getNameIndex(); - String class_name2 = constant_pool.constantToString(index, tag); // / -> . - String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. - short_class_name = Utility.compactClassName(short_class_name, class_package + ".", true); // Remove class package prefix - - ref = "" + short_class_name + ""; - constant_ref[index] = "" + short_class_name + ""; - - file.println("

      " + ref + "

      \n"); - break; - - case CONSTANT_String: - ConstantString c5 = (ConstantString)constant_pool.getConstant(index, CONSTANT_String); - name_index = c5.getStringIndex(); - - String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag)); - - file.println("

      " + str + "

      \n"); - break; - - case CONSTANT_NameAndType: - ConstantNameAndType c6 = (ConstantNameAndType)constant_pool.getConstant(index, CONSTANT_NameAndType); - name_index = c6.getNameIndex(); - int signature_index = c6.getSignatureIndex(); - - file.println("

      " + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "

      \n"); - break; - - default: - file.println("

      " + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "\n"); - } // switch - } - - private final int getMethodNumber(String str) { - for(int i=0; i < methods.length; i++) { - String cmp = methods[i].getName() + methods[i].getSignature(); - if(cmp.equals(str)) - return i; + String referenceConstant( final int index ) { + return constant_ref[index]; + } + + + private void writeConstant( final int index ) { + final byte tag = constants[index].getTag(); + int class_index; + int name_index; + String ref; + // The header is always the same + file.println("

      " + index + " " + Const.getConstantName(tag) + + "

      "); + /* For every constant type get the needed parameters and print them appropiately + */ + switch (tag) { + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + // Get class_index and name_and_type_index, depending on type + if (tag == Const.CONSTANT_Methodref) { + final ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(index, + Const.CONSTANT_Methodref); + class_index = c.getClassIndex(); + name_index = c.getNameAndTypeIndex(); + } else { + final ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constant_pool + .getConstant(index, Const.CONSTANT_InterfaceMethodref); + class_index = c1.getClassIndex(); + name_index = c1.getNameAndTypeIndex(); + } + // Get method name and its class + final String method_name = constant_pool.constantToString(name_index, + Const.CONSTANT_NameAndType); + final String html_method_name = Class2HTML.toHTML(method_name); + // Partially compacted class name, i.e., / -> . + final String method_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); + String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. + short_method_class = Utility.compactClassName(short_method_class, class_package + + ".", true); // Remove class package prefix + // Get method signature + final ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant( + name_index, Const.CONSTANT_NameAndType); + final String signature = constant_pool.constantToString(c2.getSignatureIndex(), + Const.CONSTANT_Utf8); + // Get array of strings containing the argument types + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + // Get return type string + final String type = Utility.methodSignatureReturnType(signature, false); + final String ret_type = Class2HTML.referenceType(type); + final StringBuilder buf = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + buf.append(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + buf.append(", "); + } + } + buf.append(")"); + final String arg_types = buf.toString(); + if (method_class.equals(class_name)) { + ref = "" + + html_method_name + ""; + } else { + ref = "" + + short_method_class + "." + html_method_name; + } + constant_ref[index] = ret_type + " " + short_method_class + + "." + html_method_name + " " + arg_types; + file.println("

      " + ret_type + " " + ref + arg_types + + " \n

      "); + break; + case Const.CONSTANT_Fieldref: + // Get class_index and name_and_type_index + final ConstantFieldref c3 = (ConstantFieldref) constant_pool.getConstant(index, + Const.CONSTANT_Fieldref); + class_index = c3.getClassIndex(); + name_index = c3.getNameAndTypeIndex(); + // Get method name and its class (compacted) + final String field_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); + String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. + short_field_class = Utility.compactClassName(short_field_class, + class_package + ".", true); // Remove class package prefix + final String field_name = constant_pool + .constantToString(name_index, Const.CONSTANT_NameAndType); + if (field_class.equals(class_name)) { + ref = "" + field_name + ""; + } else { + ref = "" + short_field_class + + "." + field_name + "\n"; + } + constant_ref[index] = "" + short_field_class + "." + + field_name + ""; + file.println("

      " + ref + "
      \n" + "

      "); + break; + case Const.CONSTANT_Class: + final ConstantClass c4 = (ConstantClass) constant_pool.getConstant(index, Const.CONSTANT_Class); + name_index = c4.getNameIndex(); + final String class_name2 = constant_pool.constantToString(index, tag); // / -> . + String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. + short_class_name = Utility.compactClassName(short_class_name, class_package + ".", + true); // Remove class package prefix + ref = "" + short_class_name + + ""; + constant_ref[index] = "" + short_class_name + ""; + file.println("

      " + ref + "

      \n"); + break; + case Const.CONSTANT_String: + final ConstantString c5 = (ConstantString) constant_pool.getConstant(index, + Const.CONSTANT_String); + name_index = c5.getStringIndex(); + final String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag)); + file.println("

      " + str + "

      \n"); + break; + case Const.CONSTANT_NameAndType: + final ConstantNameAndType c6 = (ConstantNameAndType) constant_pool.getConstant(index, + Const.CONSTANT_NameAndType); + name_index = c6.getNameIndex(); + final int signature_index = c6.getSignatureIndex(); + file.println("

      " + + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + + "

      \n"); + break; + default: + file.println("

      " + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "\n"); + } // switch + } + + + private int getMethodNumber( final String str ) { + for (int i = 0; i < methods.length; i++) { + final String cmp = methods[i].getName() + methods[i].getSignature(); + if (cmp.equals(str)) { + return i; + } + } + return -1; } - return -1; - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java index f755549b902..d9b54fed974 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java @@ -4,399 +4,407 @@ */ package com.sun.org.apache.bcel.internal.util; -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.generic.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.generic.ClassGenException; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; +import com.sun.org.apache.bcel.internal.generic.InstructionList; + /** - * InstructionFinder is a tool to search for given instructions patterns, - * i.e., match sequences of instructions in an instruction list via - * regular expressions. This can be used, e.g., in order to implement - * a peep hole optimizer that looks for code patterns and replaces - * them with faster equivalents. + * InstructionFinder is a tool to search for given instructions patterns, i.e., + * match sequences of instructions in an instruction list via regular + * expressions. This can be used, e.g., in order to implement a peep hole + * optimizer that looks for code patterns and replaces them with faster + * equivalents. * - *

      This class internally uses the - * Regexp package to search for regular expressions. + *

      + * This class internally uses the java.util.regex + * package to search for regular expressions. * * A typical application would look like this: -

      -    InstructionFinder f   = new InstructionFinder(il);
      -    String            pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)";
      -
      -    for(Iterator i = f.search(pat, constraint); i.hasNext(); ) {
      -      InstructionHandle[] match = (InstructionHandle[])i.next();
      -      ...
      -      il.delete(match[1], match[5]);
      -      ...
      -    }
      -
      - * @author M. Dahm - * @see Instruction + * + *
      + *
      + *
      + *   InstructionFinder f   = new InstructionFinder(il);
      + *   String            pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)";
      + *
      + *   for (Iterator i = f.search(pat, constraint); i.hasNext(); ) {
      + *   InstructionHandle[] match = (InstructionHandle[])i.next();
      + *   ...
      + *   il.delete(match[1], match[5]);
      + *   ...
      + *   }
      + *
      + *
      + * 
      + * + * @version $Id: InstructionFinder.java 1749603 2016-06-21 20:50:19Z ggregory $ + * @see com.sun.org.apache.bcel.internal.generic.Instruction * @see InstructionList */ public class InstructionFinder { - private static final int OFFSET = 32767; // char + OFFSET is outside of LATIN-1 - private static final int NO_OPCODES = 256; // Potential number, some are not used - private static final HashMap map = new HashMap(); // Map + private static final int OFFSET = 32767; // char + OFFSET is outside of LATIN-1 + private static final int NO_OPCODES = 256; // Potential number, some are not used + private static final Map map = new HashMap<>(); + private final InstructionList il; + private String il_string; // instruction list as string + private InstructionHandle[] handles; // map instruction - private InstructionList il; - private String il_string; // instruction list as string - private InstructionHandle[] handles; // map instruction list to array - /** - * @param il instruction list to search for given patterns - */ - public InstructionFinder(InstructionList il) { - this.il = il; - reread(); - } - - /** - * Reread the instruction list, e.g., after you've altered the list upon a match. - */ - public final void reread() { - int size = il.getLength(); - char[] buf = new char[size]; // Create a string with length equal to il length - handles = il.getInstructionHandles(); - - // Map opcodes to characters - for(int i=0; i < size; i++) - buf[i] = makeChar(handles[i].getInstruction().getOpcode()); - - il_string = new String(buf); - } - - /** - * Map symbolic instruction names like "getfield" to a single character. - * - * @param pattern instruction pattern in lower case - * @return encoded string for a pattern such as "BranchInstruction". - */ - private static final String mapName(String pattern) { - String result = (String)map.get(pattern); - - if(result != null) - return result; - - for(short i=0; i < NO_OPCODES; i++) - if(pattern.equals(Constants.OPCODE_NAMES[i])) - return "" + makeChar(i); - - throw new RuntimeException("Instruction unknown: " + pattern); - } - - /** - * Replace symbolic names of instructions with the appropiate character and remove - * all white space from string. Meta characters such as +, * are ignored. - * - * @param pattern The pattern to compile - * @return translated regular expression string - */ - private static final String compilePattern(String pattern) { - String lower = pattern.toLowerCase(); - StringBuffer buf = new StringBuffer(); - int size = pattern.length(); - - for(int i=0; i < size; i++) { - char ch = lower.charAt(i); - - if(Character.isLetterOrDigit(ch)) { - StringBuffer name = new StringBuffer(); - - while((Character.isLetterOrDigit(ch) || ch == '_') && i < size) { - name.append(ch); - - if(++i < size) - ch = lower.charAt(i); - else - break; - } - - i--; - - buf.append(mapName(name.toString())); - } else if(!Character.isWhitespace(ch)) - buf.append(ch); - } - - return buf.toString(); - } - - /** - * @return the matched piece of code as an array of instruction (handles) - */ - private InstructionHandle[] getMatch(int matched_from, int match_length) { - InstructionHandle[] match = new InstructionHandle[match_length]; - System.arraycopy(handles, matched_from, match, 0, match_length); - - return match; - } - - /** - * Search for the given pattern in the instruction list. You can search for any valid - * opcode via its symbolic name, e.g. "istore". You can also use a super class or - * an interface name to match a whole set of instructions, e.g. "BranchInstruction" or - * "LoadInstruction". "istore" is also an alias for all "istore_x" instructions. Additional - * aliases are "if" for "ifxx", "if_icmp" for "if_icmpxx", "if_acmp" for "if_acmpxx". - * - * Consecutive instruction names must be separated by white space which will be removed - * during the compilation of the pattern. - * - * For the rest the usual pattern matching rules for regular expressions apply.

      - * Example pattern: - *

      -     search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
      -   * 
      - * - *

      If you alter the instruction list upon a match such that other - * matching areas are affected, you should call reread() to update - * the finder and call search() again, because the matches are cached. - * - * @param pattern the instruction pattern to search for, where case is ignored - * @param from where to start the search in the instruction list - * @param constraint optional CodeConstraint to check the found code pattern for - * user-defined constraints - * @return iterator of matches where e.nextElement() returns an array of instruction handles - * describing the matched area - */ - public final Iterator search(String pattern, InstructionHandle from, - CodeConstraint constraint) - { - String search = compilePattern(pattern); - int start = -1; - - for(int i=0; i < handles.length; i++) { - if(handles[i] == from) { - start = i; // Where to start search from (index) - break; - } - } - - if(start == -1) - throw new ClassGenException("Instruction handle " + from + - " not found in instruction list."); - - Pattern regex = Pattern.compile(search); - List matches = new ArrayList<>(); - Matcher matcher = regex.matcher(il_string); - while(start < il_string.length() && matcher.find(start)) { - int startExpr = matcher.start(); - int endExpr = matcher.end(); - int lenExpr = endExpr - startExpr; - InstructionHandle[] match = getMatch(startExpr, lenExpr); - - if((constraint == null) || constraint.checkCode(match)) - matches.add(match); - start = endExpr; - } - - return matches.iterator(); - } - - /** - * Start search beginning from the start of the given instruction list. - * - * @param pattern the instruction pattern to search for, where case is ignored - * @return iterator of matches where e.nextElement() - * returns an array of instruction handles describing the matched - * area - */ - public final Iterator search(String pattern) { - return search(pattern, il.getStart(), null); - } - - /** - * Start search beginning from `from'. - * - * @param pattern the instruction pattern to search for, where case is ignored - * @param from where to start the search in the instruction list - * @return iterator of matches where e.nextElement() returns an array of instruction handles - * describing the matched area - */ - public final Iterator search(String pattern, InstructionHandle from) { - return search(pattern, from, null); - } - - /** - * Start search beginning from the start of the given instruction list. - * Check found matches with the constraint object. - * - * @param pattern the instruction pattern to search for, case is ignored - * @param constraint constraints to be checked on matching code - * @return instruction handle or `null' if the match failed - */ - public final Iterator search(String pattern, CodeConstraint constraint) { - return search(pattern, il.getStart(), constraint); - } - - /** - * Convert opcode number to char. - */ - private static final char makeChar(short opcode) { - return (char)(opcode + OFFSET); - } - - /** - * @return the inquired instruction list - */ - public final InstructionList getInstructionList() { return il; } - - /** - * Code patterns found may be checked using an additional - * user-defined constraint object whether they really match the needed criterion. - * I.e., check constraints that can not expressed with regular expressions. - * - */ - public interface CodeConstraint { + // list to array /** - * @param match array of instructions matching the requested pattern - * @return true if the matched area is really useful + * @param il + * instruction list to search for given patterns */ - public boolean checkCode(InstructionHandle[] match); - } - - // Initialize pattern map - - static { - map.put("arithmeticinstruction", "(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); - map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial)"); - map.put("arrayinstruction", "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); - map.put("gotoinstruction", "(goto|goto_w)"); - map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); - map.put("localvariableinstruction", "(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); - map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); - map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); - map.put("cpinstruction", "(ldc2_w|invokeinterface|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); - map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); - map.put("branchinstruction", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); - map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)"); - map.put("select", "(tableswitch|lookupswitch)"); - map.put("ifinstruction", "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)"); - map.put("jsrinstruction", "(jsr|jsr_w)"); - map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); - map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); - map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); - map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); - map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); - map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); - map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); - map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); - map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); - map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); - map.put("exceptionthrower", "(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|ldc|invokestatic|daload)"); - map.put("loadclass", "(multianewarray|invokeinterface|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); - map.put("instructiontargeter", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - - // Some aliases - map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); - map.put("if_acmp", "(if_acmpeq|if_acmpne)"); - map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)"); - - // Precompile some aliases first - map.put("iconst", precompile(Constants.ICONST_0, Constants.ICONST_5, Constants.ICONST_M1)); - map.put("lconst", new String(new char[] { '(', makeChar(Constants.LCONST_0), '|', - makeChar(Constants.LCONST_1), ')' })); - map.put("dconst", new String(new char[] { '(', makeChar(Constants.DCONST_0), '|', - makeChar(Constants.DCONST_1), ')' })); - map.put("fconst", new String(new char[] { '(', makeChar(Constants.FCONST_0), '|', - makeChar(Constants.FCONST_1), ')' })); - - map.put("iload", precompile(Constants.ILOAD_0, Constants.ILOAD_3, Constants.ILOAD)); - map.put("dload", precompile(Constants.DLOAD_0, Constants.DLOAD_3, Constants.DLOAD)); - map.put("fload", precompile(Constants.FLOAD_0, Constants.FLOAD_3, Constants.FLOAD)); - map.put("aload", precompile(Constants.ALOAD_0, Constants.ALOAD_3, Constants.ALOAD)); - - map.put("istore", precompile(Constants.ISTORE_0, Constants.ISTORE_3, Constants.ISTORE)); - map.put("dstore", precompile(Constants.DSTORE_0, Constants.DSTORE_3, Constants.DSTORE)); - map.put("fstore", precompile(Constants.FSTORE_0, Constants.FSTORE_3, Constants.FSTORE)); - map.put("astore", precompile(Constants.ASTORE_0, Constants.ASTORE_3, Constants.ASTORE)); - - // Compile strings - - for(Iterator i = map.keySet().iterator(); i.hasNext(); ) { - String key = (String)i.next(); - String value = (String)map.get(key); - - char ch = value.charAt(1); // Omit already precompiled patterns - if(ch < OFFSET) { - map.put(key, compilePattern(value)); // precompile all patterns - } + public InstructionFinder(final InstructionList il) { + this.il = il; + reread(); } - // Add instruction alias to match anything - StringBuffer buf = new StringBuffer("("); - - for(short i=0; i < NO_OPCODES; i++) { - if(Constants.NO_OF_OPERANDS[i] != Constants.UNDEFINED) { // Not an invalid opcode - buf.append(makeChar(i)); - - if(i < NO_OPCODES - 1) - buf.append('|'); - } - } - buf.append(')'); - - map.put("instruction", buf.toString()); - } - - private static String precompile(short from, short to, short extra) { - StringBuffer buf = new StringBuffer("("); - - for(short i=from; i <= to; i++) { - buf.append(makeChar(i)); - buf.append('|'); + /** + * Reread the instruction list, e.g., after you've altered the list upon a + * match. + */ + public final void reread() { + final int size = il.getLength(); + final char[] buf = new char[size]; // Create a string with length equal to il length + handles = il.getInstructionHandles(); + // Map opcodes to characters + for (int i = 0; i < size; i++) { + buf[i] = makeChar(handles[i].getInstruction().getOpcode()); + } + il_string = new String(buf); } - buf.append(makeChar(extra)); - buf.append(")"); - return buf.toString(); - } - /* - * Internal debugging routines. - */ - private static final String pattern2string(String pattern) { - return pattern2string(pattern, true); - } - - private static final String pattern2string(String pattern, boolean make_string) { - StringBuffer buf = new StringBuffer(); - - for(int i=0; i < pattern.length(); i++) { - char ch = pattern.charAt(i); - - if(ch >= OFFSET) { - if(make_string) - buf.append(Constants.OPCODE_NAMES[ch - OFFSET]); - else - buf.append((int)(ch - OFFSET)); - } else - buf.append(ch); + /** + * Map symbolic instruction names like "getfield" to a single character. + * + * @param pattern + * instruction pattern in lower case + * @return encoded string for a pattern such as "BranchInstruction". + */ + private static String mapName( final String pattern ) { + final String result = map.get(pattern); + if (result != null) { + return result; + } + for (short i = 0; i < NO_OPCODES; i++) { + if (pattern.equals(Const.getOpcodeName(i))) { + return "" + makeChar(i); + } + } + throw new RuntimeException("Instruction unknown: " + pattern); } - return buf.toString(); - } + + /** + * Replace symbolic names of instructions with the appropiate character and + * remove all white space from string. Meta characters such as +, * are + * ignored. + * + * @param pattern + * The pattern to compile + * @return translated regular expression string + */ + private static String compilePattern( final String pattern ) { + //Bug: BCEL-77 - Instructions are assumed to be english, to avoid odd Locale issues + final String lower = pattern.toLowerCase(Locale.ENGLISH); + final StringBuilder buf = new StringBuilder(); + final int size = pattern.length(); + for (int i = 0; i < size; i++) { + char ch = lower.charAt(i); + if (Character.isLetterOrDigit(ch)) { + final StringBuilder name = new StringBuilder(); + while ((Character.isLetterOrDigit(ch) || ch == '_') && i < size) { + name.append(ch); + if (++i < size) { + ch = lower.charAt(i); + } else { + break; + } + } + i--; + buf.append(mapName(name.toString())); + } else if (!Character.isWhitespace(ch)) { + buf.append(ch); + } + } + return buf.toString(); + } + + + /** + * @return the matched piece of code as an array of instruction (handles) + */ + private InstructionHandle[] getMatch( final int matched_from, final int match_length ) { + final InstructionHandle[] match = new InstructionHandle[match_length]; + System.arraycopy(handles, matched_from, match, 0, match_length); + return match; + } + + + /** + * Search for the given pattern in the instruction list. You can search for + * any valid opcode via its symbolic name, e.g. "istore". You can also use a + * super class or an interface name to match a whole set of instructions, e.g. + * "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all + * "istore_x" instructions. Additional aliases are "if" for "ifxx", "if_icmp" + * for "if_icmpxx", "if_acmp" for "if_acmpxx". + * + * Consecutive instruction names must be separated by white space which will + * be removed during the compilation of the pattern. + * + * For the rest the usual pattern matching rules for regular expressions + * apply. + *

      + * Example pattern: + * + *

      +     * search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
      +     * 
      + * + *

      + * If you alter the instruction list upon a match such that other matching + * areas are affected, you should call reread() to update the finder and call + * search() again, because the matches are cached. + * + * @param pattern + * the instruction pattern to search for, where case is ignored + * @param from + * where to start the search in the instruction list + * @param constraint + * optional CodeConstraint to check the found code pattern for + * user-defined constraints + * @return iterator of matches where e.nextElement() returns an array of + * instruction handles describing the matched area + */ + public final Iterator search( final String pattern, + final InstructionHandle from, final CodeConstraint constraint ) { + final String search = compilePattern(pattern); + int start = -1; + for (int i = 0; i < handles.length; i++) { + if (handles[i] == from) { + start = i; // Where to start search from (index) + break; + } + } + if (start == -1) { + throw new ClassGenException("Instruction handle " + from + + " not found in instruction list."); + } + final Pattern regex = Pattern.compile(search); + final List matches = new ArrayList<>(); + final Matcher matcher = regex.matcher(il_string); + while (start < il_string.length() && matcher.find(start)) { + final int startExpr = matcher.start(); + final int endExpr = matcher.end(); + final int lenExpr = endExpr - startExpr; + final InstructionHandle[] match = getMatch(startExpr, lenExpr); + if ((constraint == null) || constraint.checkCode(match)) { + matches.add(match); + } + start = endExpr; + } + return matches.iterator(); + } + + + /** + * Start search beginning from the start of the given instruction list. + * + * @param pattern + * the instruction pattern to search for, where case is ignored + * @return iterator of matches where e.nextElement() returns an array of + * instruction handles describing the matched area + */ + public final Iterator search( final String pattern ) { + return search(pattern, il.getStart(), null); + } + + + /** + * Start search beginning from `from'. + * + * @param pattern + * the instruction pattern to search for, where case is ignored + * @param from + * where to start the search in the instruction list + * @return iterator of matches where e.nextElement() returns an array of + * instruction handles describing the matched area + */ + public final Iterator search( final String pattern, + final InstructionHandle from ) { + return search(pattern, from, null); + } + + + /** + * Start search beginning from the start of the given instruction list. Check + * found matches with the constraint object. + * + * @param pattern + * the instruction pattern to search for, case is ignored + * @param constraint + * constraints to be checked on matching code + * @return instruction handle or `null' if the match failed + */ + public final Iterator search( final String pattern, + final CodeConstraint constraint ) { + return search(pattern, il.getStart(), constraint); + } + + + /** + * Convert opcode number to char. + */ + private static char makeChar( final short opcode ) { + return (char) (opcode + OFFSET); + } + + + /** + * @return the inquired instruction list + */ + public final InstructionList getInstructionList() { + return il; + } + + /** + * Code patterns found may be checked using an additional user-defined + * constraint object whether they really match the needed criterion. I.e., + * check constraints that can not expressed with regular expressions. + * + */ + public interface CodeConstraint { + + /** + * @param match + * array of instructions matching the requested pattern + * @return true if the matched area is really useful + */ + boolean checkCode( InstructionHandle[] match ); + } + + // Initialize pattern map + static { + map.put("arithmeticinstruction","(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); + map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial|invokedynamic)"); + map.put("arrayinstruction", "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); + map.put("gotoinstruction", "(goto|goto_w)"); + map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); + map.put("localvariableinstruction","(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); + map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); + map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); + map.put("cpinstruction", "(ldc2_w|invokeinterface|invokedynamic|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); + map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); + map.put("branchinstruction", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); + map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); + map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)"); + map.put("select", "(tableswitch|lookupswitch)"); + map.put("ifinstruction", "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)"); + map.put("jsrinstruction", "(jsr|jsr_w)"); + map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); + map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); + map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); + map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); + map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); + map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); + map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|invokedynamic|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); + map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); + map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|invokedynamic|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); + map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); + map.put("exceptionthrower","(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|invokedynamic|ldc|invokestatic|daload)"); + map.put("loadclass", "(multianewarray|invokeinterface|invokedynamic|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); + map.put("instructiontargeter", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); + // Some aliases + map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); + map.put("if_acmp", "(if_acmpeq|if_acmpne)"); + map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)"); + // Precompile some aliases first + map.put("iconst", precompile(Const.ICONST_0, Const.ICONST_5, Const.ICONST_M1)); + map.put("lconst", new String(new char[] { '(', makeChar(Const.LCONST_0), '|', makeChar(Const.LCONST_1), ')' })); + map.put("dconst", new String(new char[] { '(', makeChar(Const.DCONST_0), '|', makeChar(Const.DCONST_1), ')' })); + map.put("fconst", new String(new char[] { '(', makeChar(Const.FCONST_0), '|', makeChar(Const.FCONST_1), '|', makeChar(Const.FCONST_2), ')' })); + map.put("lload", precompile(Const.LLOAD_0, Const.LLOAD_3, Const.LLOAD)); + map.put("iload", precompile(Const.ILOAD_0, Const.ILOAD_3, Const.ILOAD)); + map.put("dload", precompile(Const.DLOAD_0, Const.DLOAD_3, Const.DLOAD)); + map.put("fload", precompile(Const.FLOAD_0, Const.FLOAD_3, Const.FLOAD)); + map.put("aload", precompile(Const.ALOAD_0, Const.ALOAD_3, Const.ALOAD)); + map.put("lstore", precompile(Const.LSTORE_0, Const.LSTORE_3, Const.LSTORE)); + map.put("istore", precompile(Const.ISTORE_0, Const.ISTORE_3, Const.ISTORE)); + map.put("dstore", precompile(Const.DSTORE_0, Const.DSTORE_3, Const.DSTORE)); + map.put("fstore", precompile(Const.FSTORE_0, Const.FSTORE_3, Const.FSTORE)); + map.put("astore", precompile(Const.ASTORE_0, Const.ASTORE_3, Const.ASTORE)); + // Compile strings + for (final Map.Entry entry : map.entrySet()) { + final String key = entry.getKey(); + final String value = entry.getValue(); + final char ch = value.charAt(1); // Omit already precompiled patterns + if (ch < OFFSET) { + map.put(key, compilePattern(value)); // precompile all patterns + } + } + // Add instruction alias to match anything + final StringBuilder buf = new StringBuilder("("); + for (short i = 0; i < NO_OPCODES; i++) { + if (Const.getNoOfOperands(i) != Const.UNDEFINED) { // Not an invalid opcode + buf.append(makeChar(i)); + if (i < NO_OPCODES - 1) { + buf.append('|'); + } + } + } + buf.append(')'); + map.put("instruction", buf.toString()); + } + + + private static String precompile( final short from, final short to, final short extra ) { + final StringBuilder buf = new StringBuilder("("); + for (short i = from; i <= to; i++) { + buf.append(makeChar(i)); + buf.append('|'); + } + buf.append(makeChar(extra)); + buf.append(")"); + return buf.toString(); + } + + + /* + * Internal debugging routines. + */ +// private static final String pattern2string( String pattern ) { +// return pattern2string(pattern, true); +// } + + +// private static final String pattern2string( String pattern, boolean make_string ) { +// StringBuffer buf = new StringBuffer(); +// for (int i = 0; i < pattern.length(); i++) { +// char ch = pattern.charAt(i); +// if (ch >= OFFSET) { +// if (make_string) { +// buf.append(Constants.getOpcodeName(ch - OFFSET)); +// } else { +// buf.append((ch - OFFSET)); +// } +// } else { +// buf.append(ch); +// } +// } +// return buf.toString(); +// } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java index b2c6725c1e1..d3a368d952a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java @@ -21,146 +21,143 @@ package com.sun.org.apache.bcel.internal.util; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; -import com.sun.org.apache.bcel.internal.classfile.*; -import java.io.*; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Attribute; +import com.sun.org.apache.bcel.internal.classfile.Code; +import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.Method; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Convert methods and fields into HTML file. * - * @author M. Dahm + * @version $Id: MethodHTML.java 1749603 2016-06-21 20:50:19Z ggregory $ * */ -final class MethodHTML implements com.sun.org.apache.bcel.internal.Constants { - private String class_name; // name of current class - private PrintWriter file; // file to write to - private ConstantHTML constant_html; - private AttributeHTML attribute_html; +final class MethodHTML { - MethodHTML(String dir, String class_name, - Method[] methods, Field[] fields, - ConstantHTML constant_html, AttributeHTML attribute_html) throws IOException - { - this.class_name = class_name; - this.attribute_html = attribute_html; - this.constant_html = constant_html; + private final String class_name; // name of current class + private final PrintWriter file; // file to write to + private final ConstantHTML constant_html; + private final AttributeHTML attribute_html; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html")); - file.println(""); - file.println("" + - ""); - for(int i=0; i < fields.length; i++) - writeField(fields[i]); - file.println("
      Access flagsTypeField name
      "); - - file.println("" + - "" + - ""); - for(int i=0; i < methods.length; i++) - writeMethod(methods[i], i); - - file.println("
      Access flagsReturn typeMethod nameArguments
      "); - file.close(); - } - - /** - * Print field of class. - * - * @param field field to print - * @exception java.io.IOException - */ - private void writeField(Field field) throws IOException { - String type = Utility.signatureToString(field.getSignature()); - String name = field.getName(); - String access = Utility.accessToString(field.getAccessFlags()); - Attribute[] attributes; - - access = Utility.replace(access, " ", " "); - - file.print("" + access + "\n" + - Class2HTML.referenceType(type) + "" + - name + ""); - - attributes = field.getAttributes(); - - // Write them to the Attributes.html file with anchor "[]" - for(int i=0; i < attributes.length; i++) - attribute_html.writeAttribute(attributes[i], name + "@" + i); - - for(int i=0; i < attributes.length; i++) { - if(attributes[i].getTag() == ATTR_CONSTANT_VALUE) { // Default value - String str = ((ConstantValue)attributes[i]).toString(); - - // Reference attribute in _attributes.html - file.print("= " + str + "\n"); - break; - } - } - - file.println(""); - } - - private final void writeMethod(Method method, int method_number) throws IOException { - // Get raw signature - String signature = method.getSignature(); - // Get array of strings containing the argument types - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - // Get return type string - String type = Utility.methodSignatureReturnType(signature, false); - // Get method name - String name = method.getName(), html_name; - // Get method's access flags - String access = Utility.accessToString(method.getAccessFlags()); - // Get the method's attributes, the Code Attribute in particular - Attribute[] attributes = method.getAttributes(); - - /* HTML doesn't like names like and spaces are places to break - * lines. Both we don't want... - */ - access = Utility.replace(access, " ", " "); - html_name = Class2HTML.toHTML(name); - - file.print("" + - access + ""); - - file.print("" + Class2HTML.referenceType(type) + "" + - "" + html_name + "\n("); - - for(int i=0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); - if(i < args.length - 1) - file.print(", "); - } - - file.print(")"); - - // Check for thrown exceptions - for(int i=0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i, - method_number); - - byte tag = attributes[i].getTag(); - if(tag == ATTR_EXCEPTIONS) { - file.print("throws"); - int[] exceptions = ((ExceptionTable)attributes[i]).getExceptionIndexTable(); - - for(int j=0; j < exceptions.length; j++) { - file.print(constant_html.referenceConstant(exceptions[j])); - - if(j < exceptions.length - 1) - file.print(", "); + MethodHTML(final String dir, final String class_name, final Method[] methods, final Field[] fields, + final ConstantHTML constant_html, final AttributeHTML attribute_html) throws IOException { + this.class_name = class_name; + this.attribute_html = attribute_html; + this.constant_html = constant_html; + file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html")); + file.println(""); + file.println("" + + ""); + for (final Field field : fields) { + writeField(field); + } + file.println("
      Access flagsTypeField name
      "); + file.println("" + + "" + + ""); + for (int i = 0; i < methods.length; i++) { + writeMethod(methods[i], i); + } + file.println("
      Access flagsReturn typeMethod nameArguments
      "); + file.close(); + } + + + /** + * Print field of class. + * + * @param field field to print + * @throws java.io.IOException + */ + private void writeField( final Field field ) throws IOException { + final String type = Utility.signatureToString(field.getSignature()); + final String name = field.getName(); + String access = Utility.accessToString(field.getAccessFlags()); + Attribute[] attributes; + access = Utility.replace(access, " ", " "); + file.print("" + access + "\n" + + Class2HTML.referenceType(type) + "" + name + + ""); + attributes = field.getAttributes(); + // Write them to the Attributes.html file with anchor "[]" + for (int i = 0; i < attributes.length; i++) { + attribute_html.writeAttribute(attributes[i], name + "@" + i); + } + for (int i = 0; i < attributes.length; i++) { + if (attributes[i].getTag() == Const.ATTR_CONSTANT_VALUE) { // Default value + final String str = ((ConstantValue) attributes[i]).toString(); + // Reference attribute in _attributes.html + file.print("= " + str + "\n"); + break; + } + } + file.println(""); + } + + + private void writeMethod( final Method method, final int method_number ) { + // Get raw signature + final String signature = method.getSignature(); + // Get array of strings containing the argument types + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + // Get return type string + final String type = Utility.methodSignatureReturnType(signature, false); + // Get method name + final String name = method.getName(); + String html_name; + // Get method's access flags + String access = Utility.accessToString(method.getAccessFlags()); + // Get the method's attributes, the Code Attribute in particular + final Attribute[] attributes = method.getAttributes(); + /* HTML doesn't like names like and spaces are places to break + * lines. Both we don't want... + */ + access = Utility.replace(access, " ", " "); + html_name = Class2HTML.toHTML(name); + file.print("" + access + ""); + file.print("" + Class2HTML.referenceType(type) + "" + "" + html_name + + "\n("); + for (int i = 0; i < args.length; i++) { + file.print(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + file.print(", "); + } + } + file.print(")"); + // Check for thrown exceptions + for (int i = 0; i < attributes.length; i++) { + attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i, + method_number); + final byte tag = attributes[i].getTag(); + if (tag == Const.ATTR_EXCEPTIONS) { + file.print("throws"); + final int[] exceptions = ((ExceptionTable) attributes[i]).getExceptionIndexTable(); + for (int j = 0; j < exceptions.length; j++) { + file.print(constant_html.referenceConstant(exceptions[j])); + if (j < exceptions.length - 1) { + file.print(", "); + } + } + file.println(""); + } else if (tag == Const.ATTR_CODE) { + final Attribute[] c_a = ((Code) attributes[i]).getAttributes(); + for (int j = 0; j < c_a.length; j++) { + attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@" + + j, method_number); + } + } } - file.println(""); - } else if(tag == ATTR_CODE) { - Attribute[] c_a = ((Code)attributes[i]).getAttributes(); - - for(int j=0; j < c_a.length; j++) - attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@" + j, - method_number); - } } - } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java index f38198a236b..00d1ed562b5 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,52 +17,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; - import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** - * Abstract definition of a class repository. Instances may be used - * to load classes from different sources and may be used in the + * Abstract definition of a class repository. Instances may be used to load + * classes from different sources and may be used in the * Repository.setRepository method. * * @see com.sun.org.apache.bcel.internal.Repository - * @author M. Dahm - * @author David Dixon-Peugh + * @version $Id: Repository.java 1747278 2016-06-07 17:28:43Z britter $ */ -public interface Repository extends java.io.Serializable { - /** - * Store the provided class under "clazz.getClassName()" - */ - public void storeClass(JavaClass clazz); +public interface Repository { - /** - * Remove class from repository - */ - public void removeClass(JavaClass clazz); + /** + * Store the provided class under "clazz.getClassName()" + */ + void storeClass(JavaClass clazz); - /** - * Find the class with the name provided, if the class - * isn't there, return NULL. - */ - public JavaClass findClass(String className); + /** + * Remove class from repository + */ + void removeClass(JavaClass clazz); - /** - * Find the class with the name provided, if the class - * isn't there, make an attempt to load it. - */ - public JavaClass loadClass(String className) - throws java.lang.ClassNotFoundException; + /** + * Find the class with the name provided, if the class isn't there, return + * NULL. + */ + JavaClass findClass(String className); - /** - * Find the JavaClass instance for the given run-time class object - */ - public JavaClass loadClass(Class clazz) - throws java.lang.ClassNotFoundException; + /** + * Find the class with the name provided, if the class isn't there, make an + * attempt to load it. + */ + JavaClass loadClass(String className) throws java.lang.ClassNotFoundException; - /** Clear all entries from cache. - */ - public void clear(); + /** + * Find the JavaClass instance for the given run-time class object + */ + JavaClass loadClass(Class clazz) throws java.lang.ClassNotFoundException; + + /** + * Clear all entries from cache. + */ + void clear(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SecuritySupport.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SecuritySupport.java deleted file mode 100644 index 3d8447e95b6..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SecuritySupport.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.bcel.internal.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FilenameFilter; -import java.lang.ClassLoader; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ListResourceBundle; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -/** - * This class is duplicated for each subpackage so keep it in sync. It is - * package private and therefore is not exposed as part of any API. - * - * @xerces.internal - */ -public final class SecuritySupport { - - private static final SecuritySupport securitySupport = new SecuritySupport(); - - /** - * Return an instance of this class. - */ - public static SecuritySupport getInstance() { - return securitySupport; - } - - static ClassLoader getContextClassLoader() { - return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { - } - return cl; - } - }); - } - - static ClassLoader getSystemClassLoader() { - return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) { - } - return cl; - } - }); - } - - static ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) { - } - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - public static String getSystemProperty(final String propName) { - return (String) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - static FileInputStream getFileInputStream(final File file) - throws FileNotFoundException { - try { - return (FileInputStream) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws FileNotFoundException { - return new FileInputStream(file); - } - }); - } catch (PrivilegedActionException e) { - throw (FileNotFoundException) e.getException(); - } - } - - /** - * Gets a resource bundle using the specified base name, the default locale, - * and the caller's class loader. - * - * @param bundle the base name of the resource bundle, a fully qualified - * class name - * @return a resource bundle for the given base name and the default locale - */ - public static ListResourceBundle getResourceBundle(String bundle) { - return getResourceBundle(bundle, Locale.getDefault()); - } - - /** - * Gets a resource bundle using the specified base name and locale, and the - * caller's class loader. - * - * @param bundle the base name of the resource bundle, a fully qualified - * class name - * @param locale the locale for which a resource bundle is desired - * @return a resource bundle for the given base name and locale - */ - public static ListResourceBundle getResourceBundle(final String bundle, final Locale locale) { - return AccessController.doPrivileged(new PrivilegedAction() { - public ListResourceBundle run() { - try { - return (ListResourceBundle) ResourceBundle.getBundle(bundle, locale); - } catch (MissingResourceException e) { - try { - return (ListResourceBundle) ResourceBundle.getBundle(bundle, new Locale("en", "US")); - } catch (MissingResourceException e2) { - throw new MissingResourceException( - "Could not load any resource bundle by " + bundle, bundle, ""); - } - } - } - }); - } - - public static String[] getFileList(final File f, final FilenameFilter filter) { - return ((String[]) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return f.list(filter); - } - })); - } - - public static boolean getFileExists(final File f) { - return ((Boolean) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return f.exists() ? Boolean.TRUE : Boolean.FALSE; - } - })).booleanValue(); - } - - static long getLastModified(final File f) { - return ((Long) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return f.lastModified(); - } - })).longValue(); - } - - - /** - * Figure out which ClassLoader to use. - */ - public static ClassLoader findClassLoader() - { - if (System.getSecurityManager()!=null) { - //this will ensure bootclassloader is used - return null; - } else { - return SecuritySupport.class.getClassLoader(); - } - } // findClassLoader():ClassLoader - - private SecuritySupport() { - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java index 42fa078a37c..bde982d7251 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,136 +17,161 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.util; +import java.io.IOException; +import java.io.InputStream; -import java.io.*; - +import com.sun.org.apache.bcel.internal.classfile.ClassParser; +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import java.lang.ref.SoftReference; import java.util.HashMap; - -import com.sun.org.apache.bcel.internal.classfile.*; +import java.util.Map; /** - * This repository is used in situations where a Class is created - * outside the realm of a ClassLoader. Classes are loaded from - * the file systems using the paths specified in the given - * class path. By default, this is the value returned by - * ClassPath.getClassPath(). - *
      - * It is designed to be used as a singleton, however it - * can also be used with custom classpaths. - * -/** - * Abstract definition of a class repository. Instances may be used - * to load classes from different sources and may be used in the - * Repository.setRepository method. + * 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().
      + * This repository uses a factory design, allowing it to maintain a collection + * of different classpaths, and as such It is designed to be used as a singleton + * per classpath. * * @see com.sun.org.apache.bcel.internal.Repository * - * @author M. Dahm - * @author David Dixon-Peugh + * @version $Id: SyntheticRepository.java 1748124 2016-06-13 08:02:16Z ggregory + * $ */ public class SyntheticRepository implements Repository { - private static HashMap _instances = new HashMap(); // CLASSPATH X REPOSITORY - - private HashMap _loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS + // CLASSNAME X JAVACLASS + private final Map> loadedClasses = new HashMap<>(); private SyntheticRepository() { } - public static SyntheticRepository getInstance() { - return new SyntheticRepository(); - } - - /** - * 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 (JavaClass)_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); + public static SyntheticRepository getInstance() { + return new SyntheticRepository(); } - className = className.replace('/', '.'); // Just in case, canonical form - - IOException e = new IOException("Couldn't find: " + className + ".class"); - 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); + /** + * Store a new JavaClass instance into this Repository. + */ + @Override + public void storeClass(final JavaClass clazz) { + loadedClasses.put(clazz.getClassName(), new SoftReference<>(clazz)); + clazz.setRepository(this); } - 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; + /** + * Remove class from repository + */ + @Override + public void removeClass(final JavaClass clazz) { + loadedClasses.remove(clazz.getClassName()); } - 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()); + /** + * Find an already defined (cached) JavaClass object by name. + */ + @Override + public JavaClass findClass(final String className) { + final SoftReference ref = loadedClasses.get(className); + if (ref == null) { + return null; + } + return ref.get(); } - throw new ClassNotFoundException("SyntheticRepository could not load " + - className); - } + /** + * Finds a JavaClass object by name. If it is already in this Repository, the + * Repository version is returned. + * + * @param className the name of the class + * @return the JavaClass object + * @throws ClassNotFoundException if the class is not in the Repository + */ + @Override + public JavaClass loadClass(String className) throws ClassNotFoundException { + if ((className == null) || className.isEmpty()) { + throw new IllegalArgumentException("Invalid class name " + className); + } + className = className.replace('/', '.'); // Just in case, canonical form + final JavaClass clazz = findClass(className); + if (clazz != null) { + return clazz; + } - /** Clear all entries from cache. - */ - public void clear() { - _loadedClasses.clear(); - } + IOException e = new IOException("Couldn't find: " + className + ".class"); + throw new ClassNotFoundException("Exception while looking for class " + + className + ": " + e, e); + } + + /** + * Find the JavaClass object for a runtime Class object. If a class with the + * same name is already in this Repository, the Repository version is + * returned. Otherwise, getResourceAsStream() is called on the Class object + * to find the class's representation. If the representation is found, it is + * added to the Repository. + * + * @see Class + * @param clazz the runtime Class object + * @return JavaClass object for given runtime class + * @throws ClassNotFoundException if the class is not in the Repository, and + * its representation could not be found + */ + @Override + public JavaClass loadClass(final Class clazz) throws ClassNotFoundException { + final String className = clazz.getName(); + final JavaClass repositoryClass = findClass(className); + if (repositoryClass != null) { + return repositoryClass; + } + String name = className; + final int i = name.lastIndexOf('.'); + if (i > 0) { + name = name.substring(i + 1); + } + JavaClass cls = null; + try (InputStream clsStream = clazz.getResourceAsStream(name + ".class")) { + return cls = loadClass(clsStream, className); + } catch (final IOException e) { + return cls; + } + + } + + + private JavaClass loadClass(final InputStream is, final String className) + throws ClassNotFoundException { + try { + if (is != null) { + final ClassParser parser = new ClassParser(is, className); + final JavaClass clazz = parser.parse(); + storeClass(clazz); + return clazz; + } + } catch (final IOException e) { + throw new ClassNotFoundException("Exception while looking for class " + + className + ": " + e, e); + } finally { + if (is != null) { + try { + is.close(); + } catch (final IOException e) { + // ignored + } + } + } + throw new ClassNotFoundException("SyntheticRepository could not load " + + className); + } + + /** + * Clear all entries from cache. + */ + @Override + public void clear() { + loadedClasses.clear(); + } } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html index b14ec463502..e710072cbaa 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/package.html @@ -1,14 +1,30 @@ +

      This package contains utility classes for the -Byte Code Engineering +Byte Code Engineering Library, namely:

      @@ -17,7 +33,7 @@ Library, namely:

    • A converter for class files to HTML
    • A tool to find instructions patterns via regular expressions
    • A class to find classes as defined in the CLASSPATH
    • -
    • A class loader that allows to create clases at run time
    • +
    • A class loader that allows to create classes at run time
    • diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java index 22bc7616a2c..a1489c2c5a8 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,13 +23,68 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.ArithmeticInstruction; +import com.sun.org.apache.bcel.internal.generic.ArrayInstruction; +import com.sun.org.apache.bcel.internal.generic.ConversionInstruction; +import com.sun.org.apache.bcel.internal.generic.Instruction; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; +import com.sun.org.apache.bcel.internal.generic.LocalVariableInstruction; +import com.sun.org.apache.bcel.internal.generic.ReturnInstruction; +import com.sun.org.apache.bcel.internal.generic.StackInstruction; /** * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen */ -public interface Constants extends InstructionConstants { +public interface Constants { + public static final Instruction ACONST_NULL = InstructionConst.ACONST_NULL; + public static final Instruction ATHROW = InstructionConst.ATHROW; + public static final Instruction DCMPG = InstructionConst.DCMPG; + public static final Instruction DCONST_0 = InstructionConst.DCONST_0; + public static final Instruction ICONST_0 = InstructionConst.ICONST_0; + public static final Instruction ICONST_1 = InstructionConst.ICONST_1; + public static final Instruction NOP = InstructionConst.NOP; + + + public static final StackInstruction DUP = InstructionConst.DUP; + public static final StackInstruction DUP2 = InstructionConst.DUP2; + public static final StackInstruction DUP_X1 = InstructionConst.DUP_X1; + public static final StackInstruction DUP_X2 = InstructionConst.DUP_X2; + public static final StackInstruction POP = InstructionConst.POP; + public static final StackInstruction POP2 = InstructionConst.POP2; + public static final StackInstruction SWAP = InstructionConst.SWAP; + + public static final LocalVariableInstruction ALOAD_0 = InstructionConst.ALOAD_0; + public static final LocalVariableInstruction ALOAD_1 = InstructionConst.ALOAD_1; + public static final LocalVariableInstruction ALOAD_2 = InstructionConst.ALOAD_2; + public static final LocalVariableInstruction ILOAD_1 = InstructionConst.ILOAD_1; + public static final LocalVariableInstruction ILOAD_2 = InstructionConst.ILOAD_2; + + public static final ArithmeticInstruction DADD = InstructionConst.DADD; + public static final ArithmeticInstruction IXOR = InstructionConst.IXOR; + + public static final ArrayInstruction AASTORE = InstructionConst.AASTORE; + public static final ArrayInstruction IASTORE = InstructionConst.IASTORE; + + public static final ConversionInstruction D2F = InstructionConst.D2F; + public static final ConversionInstruction D2I = InstructionConst.D2I; + public static final ConversionInstruction D2L = InstructionConst.D2L; + public static final ConversionInstruction F2D = InstructionConst.F2D; + public static final ConversionInstruction I2B = InstructionConst.I2B; + public static final ConversionInstruction I2C = InstructionConst.I2C; + public static final ConversionInstruction I2D = InstructionConst.I2D; + public static final ConversionInstruction I2F = InstructionConst.I2F; + public static final ConversionInstruction I2L = InstructionConst.I2L; + public static final ConversionInstruction I2S = InstructionConst.I2S; + public static final ConversionInstruction L2D = InstructionConst.L2D; + public static final ConversionInstruction L2I = InstructionConst.L2I; + + + public static final ReturnInstruction ARETURN = InstructionConst.ARETURN; + public static final ReturnInstruction IRETURN = InstructionConst.IRETURN; + public static final ReturnInstruction RETURN = InstructionConst.RETURN; + + // Error categories used to report errors to Parser.reportError() @@ -86,17 +141,17 @@ public interface Constants extends InstructionConstants { = "java.lang.String"; public static final int ACC_PUBLIC - = com.sun.org.apache.bcel.internal.Constants.ACC_PUBLIC; + = com.sun.org.apache.bcel.internal.Const.ACC_PUBLIC; public static final int ACC_SUPER - = com.sun.org.apache.bcel.internal.Constants.ACC_SUPER; + = com.sun.org.apache.bcel.internal.Const.ACC_SUPER; public static final int ACC_FINAL - = com.sun.org.apache.bcel.internal.Constants.ACC_FINAL; + = com.sun.org.apache.bcel.internal.Const.ACC_FINAL; public static final int ACC_PRIVATE - = com.sun.org.apache.bcel.internal.Constants.ACC_PRIVATE; + = com.sun.org.apache.bcel.internal.Const.ACC_PRIVATE; public static final int ACC_PROTECTED - = com.sun.org.apache.bcel.internal.Constants.ACC_PROTECTED; + = com.sun.org.apache.bcel.internal.Const.ACC_PROTECTED; public static final int ACC_STATIC - = com.sun.org.apache.bcel.internal.Constants.ACC_STATIC; + = com.sun.org.apache.bcel.internal.Const.ACC_STATIC; public static final String MODULE_SIG = "Ljava/lang/Module;"; diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java index dfaa2f7469b..b55d2a8f982 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,7 +26,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.InvokeInstruction; import com.sun.org.apache.bcel.internal.generic.LDC; @@ -824,7 +824,7 @@ class FunctionCall extends Expression { } il.append(new NEW(cpg.addClass(_className))); - il.append(InstructionConstants.DUP); + il.append(InstructionConst.DUP); for (int i = 0; i < n; i++) { final Expression arg = argument(i); @@ -935,7 +935,7 @@ class FunctionCall extends Expression { ADD_READS, ADD_READS_SIG); il.append(new INVOKEVIRTUAL(index)); - il.append(InstructionConstants.POP); + il.append(InstructionConst.POP); methodGen.markChunkEnd(); } diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java index 25f5a495ff8..bc173a41861 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java @@ -102,7 +102,6 @@ public final class XSLTC { private ArrayList m_characterData; // These define the various methods for outputting the translet - public static final int FILE_OUTPUT = 0; public static final int JAR_OUTPUT = 1; public static final int BYTEARRAY_OUTPUT = 2; public static final int CLASSLOADER_OUTPUT = 3; @@ -116,7 +115,7 @@ public final class XSLTC { private String _className = null; // -o private String _packageName = "die.verwandlung"; // override with -p private File _destDir = null; // -d - private int _outputType = FILE_OUTPUT; // by default + private int _outputType = BYTEARRAY_OUTPUT; // by default private ArrayList _classes; private ArrayList _bcelClasses; @@ -897,8 +896,7 @@ public final class XSLTC { public void dumpClass(JavaClass clazz) { - if (_outputType == FILE_OUTPUT || - _outputType == BYTEARRAY_AND_FILE_OUTPUT) + if (_outputType == BYTEARRAY_AND_FILE_OUTPUT) { File outFile = getOutputFile(clazz.getClassName()); String parentDir = outFile.getParent(); @@ -911,12 +909,6 @@ public final class XSLTC { try { switch (_outputType) { - case FILE_OUTPUT: - clazz.dump( - new BufferedOutputStream( - new FileOutputStream( - getOutputFile(clazz.getClassName())))); - break; case JAR_OUTPUT: _bcelClasses.add(clazz); break; @@ -929,8 +921,7 @@ public final class XSLTC { _classes.add(out); if (_outputType == BYTEARRAY_AND_FILE_OUTPUT) - clazz.dump(new BufferedOutputStream( - new FileOutputStream(getOutputFile(clazz.getClassName())))); + clazz.dump(getOutputFile(clazz.getClassName())); else if (_outputType == BYTEARRAY_AND_JAR_OUTPUT) _bcelClasses.add(clazz); diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java index 79c4aad1996..a750f366672 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/AttributeSetMethodGenerator.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -52,7 +51,7 @@ public final class AttributeSetMethodGenerator extends MethodGenerator { } public AttributeSetMethodGenerator(String methodName, ClassGenerator classGen) { - super(com.sun.org.apache.bcel.internal.Constants.ACC_PRIVATE, + super(com.sun.org.apache.bcel.internal.Const.ACC_PRIVATE, com.sun.org.apache.bcel.internal.generic.Type.VOID, argTypes, argNames, methodName, classGen.getClassName(), diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java index a1f81ed6f0e..68933d14778 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/IntType.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -41,7 +40,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.ISTORE; import com.sun.org.apache.bcel.internal.generic.Instruction; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.NEW; import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants; @@ -247,27 +246,27 @@ public final class IntType extends NumberType { } public Instruction ADD() { - return InstructionConstants.IADD; + return InstructionConst.IADD; } public Instruction SUB() { - return InstructionConstants.ISUB; + return InstructionConst.ISUB; } public Instruction MUL() { - return InstructionConstants.IMUL; + return InstructionConst.IMUL; } public Instruction DIV() { - return InstructionConstants.IDIV; + return InstructionConst.IDIV; } public Instruction REM() { - return InstructionConstants.IREM; + return InstructionConst.IREM; } public Instruction NEG() { - return InstructionConstants.INEG; + return InstructionConst.INEG; } public Instruction LOAD(int slot) { diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java index 929a8dca4d2..28fdd1bfd17 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,7 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler.util; import java.io.DataOutputStream; import java.io.IOException; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; import com.sun.org.apache.bcel.internal.generic.Instruction; import com.sun.org.apache.bcel.internal.generic.Visitor; @@ -43,7 +42,7 @@ abstract class MarkerInstruction extends Instruction { * generated byte code. */ public MarkerInstruction() { - super(Constants.UNDEFINED, (short) 0); + super(Const.UNDEFINED, (short) 0); } /** diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java index 1c101c1b4bb..d6f96c6cedc 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ import java.util.Map; import java.util.Stack; -import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.Field; import com.sun.org.apache.bcel.internal.classfile.Method; import com.sun.org.apache.bcel.internal.generic.ALOAD; @@ -55,7 +55,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.ISTORE; import com.sun.org.apache.bcel.internal.generic.Instruction; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionHandle; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.InstructionTargeter; @@ -87,8 +87,6 @@ public class MethodGenerator extends MethodGen private static final String END_ELEMENT_SIG = START_ELEMENT_SIG; - private InstructionList _mapTypeSub; - private static final int DOM_INDEX = 1; private static final int ITERATOR_INDEX = 2; private static final int HANDLER_INDEX = 3; @@ -1315,8 +1313,8 @@ public class MethodGenerator extends MethodGen // other two are used for references to fields in the CopyLocals object InstructionHandle outlinedMethodCallSetup = oldMethCopyInIL.append(new NEW(cpg.addClass(argTypeName))); - oldMethCopyInIL.append(InstructionConstants.DUP); - oldMethCopyInIL.append(InstructionConstants.DUP); + oldMethCopyInIL.append(InstructionConst.DUP); + oldMethCopyInIL.append(InstructionConst.DUP); oldMethCopyInIL.append( new INVOKESPECIAL(cpg.addMethodref(argTypeName, "", "()V"))); @@ -1332,8 +1330,8 @@ public class MethodGenerator extends MethodGen outlinedMethodName, outlinedMethodGen.getSignature()))); } else { - oldMethCopyOutIL.append(InstructionConstants.THIS); - oldMethCopyOutIL.append(InstructionConstants.SWAP); + oldMethCopyOutIL.append(InstructionConst.THIS); + oldMethCopyOutIL.append(InstructionConst.SWAP); outlinedMethodRef = oldMethCopyOutIL.append( new INVOKEVIRTUAL(cpg.addMethodref( @@ -1479,7 +1477,7 @@ public class MethodGenerator extends MethodGen // CopyLocals prior to invocation of the // outlined method. oldMethCopyInIL.append( - InstructionConstants.DUP); + InstructionConst.DUP); InstructionHandle copyInLoad = oldMethCopyInIL.append( loadLocal(oldLocalVarIndex, varType)); @@ -1498,7 +1496,7 @@ public class MethodGenerator extends MethodGen // CopyLocals to the new local in the outlined // method newMethCopyInIL.append( - InstructionConstants.ALOAD_1); + InstructionConst.ALOAD_1); newMethCopyInIL.append(new GETFIELD(fieldRef)); newMethCopyInIL.append( storeLocal(newLocalVarIndex, varType)); @@ -1510,7 +1508,7 @@ public class MethodGenerator extends MethodGen // variable into a field in CopyLocals // method newMethCopyOutIL.append( - InstructionConstants.ALOAD_1); + InstructionConst.ALOAD_1); newMethCopyOutIL.append( loadLocal(newLocalVarIndex, varType)); newMethCopyOutIL.append(new PUTFIELD(fieldRef)); @@ -1520,7 +1518,7 @@ public class MethodGenerator extends MethodGen // method following invocation of the outlined // method. oldMethCopyOutIL.append( - InstructionConstants.DUP); + InstructionConst.DUP); oldMethCopyOutIL.append(new GETFIELD(fieldRef)); InstructionHandle copyOutStore = oldMethCopyOutIL.append( @@ -1667,7 +1665,7 @@ public class MethodGenerator extends MethodGen } // POP the reference to the CopyLocals object from the stack - oldMethCopyOutIL.append(InstructionConstants.POP); + oldMethCopyOutIL.append(InstructionConst.POP); // Now that the generation of the outlined code is complete, update // the old local variables with new start and end ranges, as required. @@ -1708,7 +1706,7 @@ public class MethodGenerator extends MethodGen // Insert the copying code into the outlined method newIL.insert(newMethCopyInIL); newIL.append(newMethCopyOutIL); - newIL.append(InstructionConstants.RETURN); + newIL.append(InstructionConst.RETURN); // Discard instructions in outlineable chunk from old method try { @@ -1999,8 +1997,8 @@ public class MethodGenerator extends MethodGen switch (inst.getOpcode()) { // Instructions that may have 16-bit or 32-bit branch targets. // The size of the branch offset might increase by two bytes. - case Constants.GOTO: - case Constants.JSR: + case Const.GOTO: + case Const.JSR: maxOffsetChange = maxOffsetChange + 2; break; // Instructions that contain padding for alignment purposes @@ -2008,29 +2006,29 @@ public class MethodGenerator extends MethodGen // accuracy, we should be able to discount any padding already // added to these instructions by InstructionList.setPosition(), // their APIs do not expose that information. - case Constants.TABLESWITCH: - case Constants.LOOKUPSWITCH: + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: maxOffsetChange = maxOffsetChange + 3; break; // Instructions that might be rewritten by this method as a // conditional branch followed by an unconditional branch. // The unconditional branch would require five bytes. - 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: - case Constants.IFEQ: - case Constants.IFGE: - case Constants.IFGT: - case Constants.IFLE: - case Constants.IFLT: - case Constants.IFNE: - case Constants.IFNONNULL: - case Constants.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: maxOffsetChange = maxOffsetChange + 5; break; } @@ -2077,7 +2075,7 @@ public class MethodGenerator extends MethodGen // InstructionList, add a new no-op to act as the target // of the new IF if (nextHandle == null) { - nextHandle = il.append(gotoHandle, NOP); + nextHandle = il.append(gotoHandle, InstructionConst.NOP); } // Make the new IF instruction branch around the GOTO diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java index 4a2e034afc9..19ccd36d2bb 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -33,7 +32,7 @@ import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.Instruction; -import com.sun.org.apache.bcel.internal.generic.InstructionConstants; +import com.sun.org.apache.bcel.internal.generic.InstructionConst; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; import com.sun.org.apache.bcel.internal.generic.NEW; @@ -296,27 +295,27 @@ public final class RealType extends NumberType { } public Instruction ADD() { - return InstructionConstants.DADD; + return InstructionConst.DADD; } public Instruction SUB() { - return InstructionConstants.DSUB; + return InstructionConst.DSUB; } public Instruction MUL() { - return InstructionConstants.DMUL; + return InstructionConst.DMUL; } public Instruction DIV() { - return InstructionConstants.DDIV; + return InstructionConst.DDIV; } public Instruction REM() { - return InstructionConstants.DREM; + return InstructionConst.DREM; } public Instruction NEG() { - return InstructionConstants.DNEG; + return InstructionConst.DNEG; } public Instruction LOAD(int slot) { @@ -332,7 +331,7 @@ public final class RealType extends NumberType { } public Instruction CMP(boolean less) { - return less ? InstructionConstants.DCMPG : InstructionConstants.DCMPL; + return less ? InstructionConst.DCMPG : InstructionConst.DCMPL; } public Instruction DUP() { diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java index cdc4268d47e..8c796a6bcc9 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHMessages.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,9 +20,9 @@ package com.sun.org.apache.xpath.internal.res; -import com.sun.org.apache.bcel.internal.util.SecuritySupport; import com.sun.org.apache.xml.internal.res.XMLMessages; -import java.util.ListResourceBundle; +import java.util.ResourceBundle; +import jdk.xml.internal.SecuritySupport; /** * A utility class for issuing XPath error messages. @@ -35,7 +34,7 @@ public class XPATHMessages extends XMLMessages { /** * The language specific resource object for XPath messages. */ - private static ListResourceBundle XPATHBundle = null; + private static ResourceBundle XPATHBundle = null; /** * The class name of the XPath error message string table. */ @@ -99,7 +98,7 @@ public class XPATHMessages extends XMLMessages { * * @return The formatted message string. */ - public static final String createXPATHMsg(ListResourceBundle fResourceBundle, + private static final String createXPATHMsg(ResourceBundle fResourceBundle, String msgKey, Object args[]) //throws Exception { diff --git a/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java b/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java index b75a612f839..4c27bba6012 100644 --- a/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java +++ b/jaxp/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.text.MessageFormat; import java.util.Locale; +import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; @@ -42,6 +43,8 @@ import java.util.ResourceBundle; * This class contains utility methods for reading resources in the JAXP packages */ public class SecuritySupport { + public final static String NEWLINE = getSystemProperty("line.separator", "\n"); + /** * Cache for properties in java.home/conf/jaxp.properties */ @@ -71,7 +74,7 @@ public class SecuritySupport { } /** - * Reads JAXP system property with privilege + * Reads a system property with privilege * * @param propName the name of the property * @return the value of the property @@ -83,13 +86,51 @@ public class SecuritySupport { } /** - * Reads a system property. + * Reads a system property with privilege + * + * @param propName the name of the property + * @return the value of the property + */ + public static String getSystemProperty(final String propName, String defValue) { + String value = getSystemProperty(propName); + if (value == null) { + return defValue; + } + return value; + } + + /** + * Reads a system property with specified type. * * @param the type of the property value * @param type the type of the property value * @param propName the name of the property * @param defValue the default value - * @return the value of the property, or the default value of no system + * @return the value of the property, or the default value if no system + * property is found + */ + public static T getSystemProperty(Class type, String propName, String defValue) { + String value = getSystemProperty(propName); + if (value == null) { + value = defValue; + } + if (Integer.class.isAssignableFrom(type)) { + return type.cast(Integer.parseInt(value)); + } else if (Boolean.class.isAssignableFrom(type)) { + return type.cast(Boolean.parseBoolean(value)); + } + return type.cast(value); + } + + /** + * Reads JAXP system property in this order: system property, + * $java.home/conf/jaxp.properties if the system property is not specified + * + * @param the type of the property value + * @param type the type of the property value + * @param propName the name of the property + * @param defValue the default value + * @return the value of the property, or the default value if no system * property is found */ public static T getJAXPSystemProperty(Class type, String propName, String defValue) { @@ -136,7 +177,7 @@ public class SecuritySupport { String configFile = getSystemProperty("java.home") + File.separator + "conf" + File.separator + "jaxp.properties"; File f = new File(configFile); - if (getFileExists(f)) { + if (isFileExists(f)) { is = getFileInputStream(f); cacheProps.load(is); } @@ -158,13 +199,28 @@ public class SecuritySupport { return value; } -//------------------- private methods --------------------------- - static boolean getFileExists(final File f) { + /** + * Tests whether the file denoted by this abstract pathname is a directory. + * @param f the file to be tested + * @return true if it is a directory, false otherwise + */ + public static boolean isDirectory(final File f) { return (AccessController.doPrivileged((PrivilegedAction) () - -> f.exists() ? Boolean.TRUE : Boolean.FALSE)); + -> f.isDirectory())); } - static FileInputStream getFileInputStream(final File file) + /** + * Tests whether the file exists. + * + * @param f the file to be tested + * @return true if the file exists, false otherwise + */ + public static boolean isFileExists(final File f) { + return (AccessController.doPrivileged((PrivilegedAction) () + -> f.exists())); + } + + public static FileInputStream getFileInputStream(final File file) throws FileNotFoundException { try { return AccessController.doPrivileged((PrivilegedExceptionAction) () @@ -173,4 +229,34 @@ public class SecuritySupport { throw (FileNotFoundException) e.getException(); } } + + /** + * Gets a resource bundle using the specified base name, the default locale, and the caller's class loader. + * @param bundle the base name of the resource bundle, a fully qualified class name + * @return a resource bundle for the given base name and the default locale + */ + public static ResourceBundle getResourceBundle(String bundle) { + return getResourceBundle(bundle, Locale.getDefault()); + } + + /** + * Gets a resource bundle using the specified base name and locale, and the caller's class loader. + * @param bundle the base name of the resource bundle, a fully qualified class name + * @param locale the locale for which a resource bundle is desired + * @return a resource bundle for the given base name and locale + */ + public static ResourceBundle getResourceBundle(final String bundle, final Locale locale) { + return AccessController.doPrivileged((PrivilegedAction) () -> { + try { + return ResourceBundle.getBundle(bundle, locale); + } catch (MissingResourceException e) { + try { + return ResourceBundle.getBundle(bundle, new Locale("en", "US")); + } catch (MissingResourceException e2) { + throw new MissingResourceException( + "Could not load any resource bundle by " + bundle, bundle, ""); + } + } + }); + } } diff --git a/jaxp/src/java.xml/share/legal/bcel.md b/jaxp/src/java.xml/share/legal/bcel.md index 8c6a3cf0e40..bb434b09d2c 100644 --- a/jaxp/src/java.xml/share/legal/bcel.md +++ b/jaxp/src/java.xml/share/legal/bcel.md @@ -1,12 +1,12 @@ -## Apache Byte Code Engineering Library (BCEL) v5.2 +## Apache Commons Byte Code Engineering Library (BCEL) Version 6.0 -### Apache BCEL Notice +### Apache Commons BCEL Notice
       
           =========================================================================
           ==  NOTICE file corresponding to the section 4 d of                    ==
           ==  the Apache License, Version 2.0,                                   ==
      -    ==  in this case for the Apache Jakarta-BCEL distribution.             ==
      +    ==  in this case for the Apache Commons BCEL distribution.             ==
           =========================================================================
       
          This product includes software developed by
      diff --git a/jdk/.hgtags b/jdk/.hgtags
      index 012f8dd2e2a..c6ed4fccf26 100644
      --- a/jdk/.hgtags
      +++ b/jdk/.hgtags
      @@ -441,3 +441,6 @@ e069834e2c518a7bc2ffadc8c7e3cd7ec69fa8a0 jdk-10+15
       06df1ce4b9b887d05ce6a13f4def3547e434dd1a jdk-9+179
       d93f2fd542b7d7855c2cd49ae15ebcc3d441a83b jdk-10+17
       c4b709bad6c5d29294124de5e74e1e2ac84fcf1f jdk-10+18
      +b561eeca30decc6258b4aca8bb23beffbb6e2f7d jdk-10+19
      +4feab1acec6a9c3620a19ff379a65ab8618d0e2a jdk-9+180
      +bd66ea2fdde3d60a73b5272263a7b8b0ca926a33 jdk-9+181
      diff --git a/jdk/src/java.base/share/classes/java/io/DataInput.java b/jdk/src/java.base/share/classes/java/io/DataInput.java
      index 70f78a6a068..86d8d3eb9fd 100644
      --- a/jdk/src/java.base/share/classes/java/io/DataInput.java
      +++ b/jdk/src/java.base/share/classes/java/io/DataInput.java
      @@ -54,83 +54,90 @@ package java.io;
        * Unicode strings in a format that is a slight modification of UTF-8.
        * (For information regarding the standard UTF-8 format, see section
        * 3.9 Unicode Encoding Forms of The Unicode Standard, Version
      - * 4.0).
      - * Note that in the following table, the most significant bit appears in the
      - * far left-hand column.
      + * 4.0)
        *
      - * 
      - * - * + *
        + *
      • Characters in the range {@code '\u005Cu0001'} to + * {@code '\u005Cu007F'} are represented by a single byte. + *
      • The null character {@code '\u005Cu0000'} and characters + * in the range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are + * represented by a pair of bytes. + *
      • Characters in the range {@code '\u005Cu0800'} + * to {@code '\u005CuFFFF'} are represented by three bytes. + *
      + * + *
      Bit values and bytes
      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * * * - * - * - * - * - * - * - * - * + * + * * * - * - * - * - * - * - * - * - * + * + * * * - * + * + * * * - * - * - * - * - * - * - * - * + * + * * * - * + * + * * * - * + * + * * * *
      Encoding of UTF-8 values
      ValueByteBit Values
      7 6 5 4 3 2 1 0
      - * All characters in the range {@code '\u005Cu0001'} to - * {@code '\u005Cu007F'} are represented by a single byte:
      Bit Values
      Byte 1 + * {@code \u005Cu0001} to {@code \u005Cu007F} 1 0 - * bits 6-0 + * bits 6-0 *
      - * The null character {@code '\u005Cu0000'} and characters - * in the range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are - * represented by a pair of bytes:
      Bit Values
      Byte 1 + * {@code \u005Cu0000},
      + * {@code \u005Cu0080} to {@code \u005Cu07FF}
      1 1 * 1 * 0 - * bits 10-6 + * bits 10-6 *
      Byte 2 2 1 * 0 - * bits 5-0 + * bits 5-0 *
      - * {@code char} values in the range {@code '\u005Cu0800'} - * to {@code '\u005CuFFFF'} are represented by three bytes:
      Bit Values
      Byte 1 + * {@code \u005Cu0800} to {@code \u005CuFFFF} 1 1 * 1 * 1 * 0 - * bits 15-12 + * bits 15-12 *
      Byte 2 2 1 * 0 - * bits 11-6 + * bits 11-6 *
      Byte 3 3 1 * 0 - * bits 5-0 + * bits 5-0 *
      - *
      + * *

      * The differences between this format and the * standard UTF-8 format are the following: diff --git a/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java b/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java index 534e1b2b8de..a45b655f8e7 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputFilter.java @@ -34,6 +34,7 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Function; +import jdk.internal.misc.SharedSecrets; /** * Filter classes, array lengths, and graph metrics during deserialization. @@ -265,6 +266,9 @@ public interface ObjectInputFilter { return null; }); configLog = (configuredFilter != null) ? System.getLogger("java.io.serialization") : null; + + // Setup shared secrets for RegistryImpl to use. + SharedSecrets.setJavaObjectInputFilterAccess(Config::createFilter2); } /** @@ -370,7 +374,20 @@ public interface ObjectInputFilter { */ public static ObjectInputFilter createFilter(String pattern) { Objects.requireNonNull(pattern, "pattern"); - return Global.createFilter(pattern); + return Global.createFilter(pattern, true); + } + + /** + * Returns an ObjectInputFilter from a string of patterns that + * checks only the length for arrays, not the component type. + * + * @param pattern the pattern string to parse; not null + * @return a filter to check a class being deserialized; + * {@code null} if no patterns + */ + static ObjectInputFilter createFilter2(String pattern) { + Objects.requireNonNull(pattern, "pattern"); + return Global.createFilter(pattern, false); } /** @@ -404,20 +421,26 @@ public interface ObjectInputFilter { * Maximum length of any array. */ private long maxArrayLength; + /** + * True to check the component type for arrays. + */ + private final boolean checkComponentType; /** * Returns an ObjectInputFilter from a string of patterns. * * @param pattern the pattern string to parse + * @param checkComponentType true if the filter should check + * the component type of arrays * @return a filter to check a class being deserialized; * {@code null} if no patterns * @throws IllegalArgumentException if the parameter is malformed * if the pattern is missing the name, the long value * is not a number or is negative. */ - static ObjectInputFilter createFilter(String pattern) { + static ObjectInputFilter createFilter(String pattern, boolean checkComponentType) { try { - return new Global(pattern); + return new Global(pattern, checkComponentType); } catch (UnsupportedOperationException uoe) { // no non-empty patterns return null; @@ -428,12 +451,15 @@ public interface ObjectInputFilter { * Construct a new filter from the pattern String. * * @param pattern a pattern string of filters + * @param checkComponentType true if the filter should check + * the component type of arrays * @throws IllegalArgumentException if the pattern is malformed * @throws UnsupportedOperationException if there are no non-empty patterns */ - private Global(String pattern) { + private Global(String pattern, boolean checkComponentType) { boolean hasLimits = false; this.pattern = pattern; + this.checkComponentType = checkComponentType; maxArrayLength = Long.MAX_VALUE; // Default values are unlimited maxDepth = Long.MAX_VALUE; @@ -595,6 +621,10 @@ public interface ObjectInputFilter { // array length is too big return Status.REJECTED; } + if (!checkComponentType) { + // As revised; do not check the component type for arrays + return Status.UNDECIDED; + } do { // Arrays are decided based on the component type clazz = clazz.getComponentType(); diff --git a/jdk/src/java.base/share/classes/java/lang/Character.java b/jdk/src/java.base/share/classes/java/lang/Character.java index fd6682e6196..e2c65b1567f 100644 --- a/jdk/src/java.base/share/classes/java/lang/Character.java +++ b/jdk/src/java.base/share/classes/java/lang/Character.java @@ -9566,18 +9566,23 @@ class Character implements java.io.Serializable, Comparable { * Determines if the specified character is ISO-LATIN-1 white space. * This method returns {@code true} for the following five * characters only: - * + *
      * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * * *
      truechars
      Character + * Code + * Name + *
      {@code '\t'} {@code U+0009}
      {@code '\t'} {@code U+0009}{@code HORIZONTAL TABULATION}
      {@code '\n'} {@code U+000A}
      {@code '\n'} {@code U+000A}{@code NEW LINE}
      {@code '\f'} {@code U+000C}
      {@code '\f'} {@code U+000C}{@code FORM FEED}
      {@code '\r'} {@code U+000D}
      {@code '\r'} {@code U+000D}{@code CARRIAGE RETURN}
      {@code ' '} {@code U+0020}
      {@code ' '} {@code U+0020}{@code SPACE}
      diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 81dd846c26a..54415e990f2 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -728,22 +728,22 @@ public final class Class implements java.io.Serializable, * one or more '{@code [}' characters representing the depth of the array * nesting. The encoding of element type names is as follows: * - *

      + *
      * * - * - * - * + * *
      Element types and encodings
      Element Type Encoding + *
      Element Type Encoding *
      boolean Z - *
      byte B - *
      char C - *
      class or interface - * Lclassname; - *
      double D - *
      float F - *
      int I - *
      long J - *
      short S + *
      boolean Z + *
      byte B + *
      char C + *
      class or interface + * Lclassname; + *
      double D + *
      float F + *
      int I + *
      long J + *
      short S *
      * diff --git a/jdk/src/java.base/share/classes/java/lang/Double.java b/jdk/src/java.base/share/classes/java/lang/Double.java index a7aa0a0f626..52bf32c8153 100644 --- a/jdk/src/java.base/share/classes/java/lang/Double.java +++ b/jdk/src/java.base/share/classes/java/lang/Double.java @@ -255,25 +255,25 @@ public final class Double extends Number implements Comparable { * * * - * + *
      * * - * + * * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * * - * + * * - * + * * - * + * * * *
      Examples
      Floating-point ValueHexadecimal String
      Floating-point ValueHexadecimal String
      {@code 1.0} {@code 0x1.0p0}
      {@code -1.0} {@code -0x1.0p0}
      {@code 2.0} {@code 0x1.0p1}
      {@code 3.0} {@code 0x1.8p1}
      {@code 0.5} {@code 0x1.0p-1}
      {@code 0.25} {@code 0x1.0p-2}
      {@code Double.MAX_VALUE}
      {@code 1.0} {@code 0x1.0p0}
      {@code -1.0} {@code -0x1.0p0}
      {@code 2.0} {@code 0x1.0p1}
      {@code 3.0} {@code 0x1.8p1}
      {@code 0.5} {@code 0x1.0p-1}
      {@code 0.25} {@code 0x1.0p-2}
      {@code Double.MAX_VALUE}{@code 0x1.fffffffffffffp1023}
      {@code Minimum Normal Value}
      {@code Minimum Normal Value}{@code 0x1.0p-1022}
      {@code Maximum Subnormal Value}
      {@code Maximum Subnormal Value}{@code 0x0.fffffffffffffp-1022}
      {@code Double.MIN_VALUE}
      {@code Double.MIN_VALUE}{@code 0x0.0000000000001p-1022}
      diff --git a/jdk/src/java.base/share/classes/java/lang/Float.java b/jdk/src/java.base/share/classes/java/lang/Float.java index 77c1d1671d5..52cb2c09b79 100644 --- a/jdk/src/java.base/share/classes/java/lang/Float.java +++ b/jdk/src/java.base/share/classes/java/lang/Float.java @@ -256,25 +256,25 @@ public final class Float extends Number implements Comparable { * * * - * + *
      * * - * + * * * - * - * - * - * - * - * - * + * + * + * + * + * + * + * * - * + * * - * + * * - * + * * * *
      Examples
      Floating-point ValueHexadecimal String
      Floating-point ValueHexadecimal String
      {@code 1.0} {@code 0x1.0p0}
      {@code -1.0} {@code -0x1.0p0}
      {@code 2.0} {@code 0x1.0p1}
      {@code 3.0} {@code 0x1.8p1}
      {@code 0.5} {@code 0x1.0p-1}
      {@code 0.25} {@code 0x1.0p-2}
      {@code Float.MAX_VALUE}
      {@code 1.0} {@code 0x1.0p0}
      {@code -1.0} {@code -0x1.0p0}
      {@code 2.0} {@code 0x1.0p1}
      {@code 3.0} {@code 0x1.8p1}
      {@code 0.5} {@code 0x1.0p-1}
      {@code 0.25} {@code 0x1.0p-2}
      {@code Float.MAX_VALUE}{@code 0x1.fffffep127}
      {@code Minimum Normal Value}
      {@code Minimum Normal Value}{@code 0x1.0p-126}
      {@code Maximum Subnormal Value}
      {@code Maximum Subnormal Value}{@code 0x0.fffffep-126}
      {@code Float.MIN_VALUE}
      {@code Float.MIN_VALUE}{@code 0x0.000002p-126}
      diff --git a/jdk/src/java.base/share/classes/java/lang/String.java b/jdk/src/java.base/share/classes/java/lang/String.java index 6d06764c1b4..a41a4200b39 100644 --- a/jdk/src/java.base/share/classes/java/lang/String.java +++ b/jdk/src/java.base/share/classes/java/lang/String.java @@ -2208,29 +2208,29 @@ public final class String * Split example showing regex, limit, and result * * - * Regex - * Limit - * Result + * Regex + * Limit + * Result * * * - * : - * 2 + * : + * 2 * {@code { "boo", "and:foo" }} - * : - * 5 + * + * 5 * {@code { "boo", "and", "foo" }} - * : - * -2 + * + * -2 * {@code { "boo", "and", "foo" }} - * o - * 5 + * o + * 5 * {@code { "b", "", ":and:f", "", "" }} - * o - * -2 + * + * -2 * {@code { "b", "", ":and:f", "", "" }} - * o - * 0 + * + * 0 * {@code { "b", "", ":and:f" }} * * @@ -2336,14 +2336,14 @@ public final class String * Split examples showing regex and result * * - * Regex - * Result + * Regex + * Result * * * - * : + * : * {@code { "boo", "and", "foo" }} - * o + * o * {@code { "b", "", ":and:f" }} * * @@ -2460,36 +2460,37 @@ public final class String * Lowercase mapping examples showing language code of locale, upper case, lower case, and description * * - * Language Code of Locale - * Upper Case - * Lower Case - * Description + * Language Code of Locale + * Upper Case + * Lower Case + * Description * * * * * tr (Turkish) - * \u0130 + * \u0130 * \u0069 * capital letter I with dot above -> small letter i * * * tr (Turkish) - * \u0049 + * \u0049 * \u0131 * capital letter I -> small letter dotless i * * * (all) - * French Fries + * French Fries * french fries * lowercased all chars in String * * * (all) - * capiotacapchi + * + * capiotacapchi * capthetacapupsil - * capsigma + * capsigma * iotachi * thetaupsilon * sigma @@ -2546,34 +2547,34 @@ public final class String * Examples of locale-sensitive and 1:M case mappings. Shows Language code of locale, lower case, upper case, and description. * * - * Language Code of Locale - * Lower Case - * Upper Case - * Description + * Language Code of Locale + * Lower Case + * Upper Case + * Description * * * * * tr (Turkish) - * \u0069 + * \u0069 * \u0130 * small letter i -> capital letter I with dot above * * * tr (Turkish) - * \u0131 + * \u0131 * \u0049 * small letter dotless i -> capital letter I * * * (all) - * \u00df + * \u00df * \u0053 \u0053 * small letter sharp s -> two letters: SS * * * (all) - * Fahrvergnügen + * Fahrvergnügen * FAHRVERGNÜGEN * * diff --git a/jdk/src/java.base/share/classes/java/lang/System.java b/jdk/src/java.base/share/classes/java/lang/System.java index 995b2c4e90f..8388dce7562 100644 --- a/jdk/src/java.base/share/classes/java/lang/System.java +++ b/jdk/src/java.base/share/classes/java/lang/System.java @@ -583,7 +583,7 @@ public final class System { * system properties, a set of system properties is first created and * initialized. This set of system properties always includes values * for the following keys: - * + *
      * * * @@ -1049,26 +1049,28 @@ public final class System { * of corresponding severity. *
      The mapping is as follows: *

      - *
      Shows property keys and associated values
      Key
      + *
      * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * *
      System.Logger Severity Level Mapping
      System.Logger Levels{@link Logger.Level#ALL ALL}{@link Logger.Level#TRACE TRACE}{@link Logger.Level#DEBUG DEBUG}{@link Logger.Level#INFO INFO}{@link Logger.Level#WARNING WARNING}{@link Logger.Level#ERROR ERROR}{@link Logger.Level#OFF OFF}
      java.util.logging Levels{@link java.util.logging.Level#ALL ALL}{@link java.util.logging.Level#FINER FINER}{@link java.util.logging.Level#FINE FINE}{@link java.util.logging.Level#INFO INFO}{@link java.util.logging.Level#WARNING WARNING}{@link java.util.logging.Level#SEVERE SEVERE}{@link java.util.logging.Level#OFF OFF}
      System.Logger Levelsjava.util.logging Levels
      {@link Logger.Level#ALL ALL}{@link java.util.logging.Level#ALL ALL}
      {@link Logger.Level#TRACE TRACE}{@link java.util.logging.Level#FINER FINER}
      {@link Logger.Level#DEBUG DEBUG}{@link java.util.logging.Level#FINE FINE}
      {@link Logger.Level#INFO INFO}{@link java.util.logging.Level#INFO INFO}
      {@link Logger.Level#WARNING WARNING}{@link java.util.logging.Level#WARNING WARNING}
      {@link Logger.Level#ERROR ERROR}{@link java.util.logging.Level#SEVERE SEVERE}
      {@link Logger.Level#OFF OFF}{@link java.util.logging.Level#OFF OFF}
      * * @since 9 diff --git a/jdk/src/java.base/share/classes/java/lang/Thread.java b/jdk/src/java.base/share/classes/java/lang/Thread.java index 8ecc90dd964..5d25df81906 100644 --- a/jdk/src/java.base/share/classes/java/lang/Thread.java +++ b/jdk/src/java.base/share/classes/java/lang/Thread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -347,7 +347,7 @@ class Thread implements Runnable { * the calling thread indicates to the runtime that it is busy-waiting. * The runtime may take action to improve the performance of invoking * spin-wait loop constructions. - *

      + * * @apiNote * As an example consider a method in a class that spins in a loop until * some flag is set outside of that method. A call to the {@code onSpinWait} @@ -373,7 +373,7 @@ class Thread implements Runnable { * method was not called at all. However on some architectures the Java * Virtual Machine may issue the processor instructions to address such * code patterns in a more beneficial way. - *

      + * * @since 9 */ @HotSpotIntrinsicCandidate diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java index 95719763b0f..b9bfd64432c 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java @@ -149,24 +149,24 @@ import java.util.Arrays; * capture argument (corresponding to the receiver) must be non-null. * *

      A type Q is considered adaptable to S as follows: - * + *
      * * - * + * * * * - * + * * * * * - * + * * * * * - * + * * * * - * + * * * diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index 6e913a84fd9..1c8eb5a1a9e 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -889,7 +889,7 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray *

      * This method behaves very much like {@link #asSpreader(Class, int)}, but accepts an additional {@code spreadArgPos} * argument to indicate at which position in the parameter list the spreading should take place. - *

      + * * @apiNote Example: *

      {@code
           MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class));
      @@ -1094,7 +1094,7 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
            * This method behaves very much like {@link #asCollector(Class, int)}, but differs in that its {@code
            * collectArgPos} argument indicates at which position in the parameter list arguments should be collected. This
            * index is zero-based.
      -     * 

      + * * @apiNote Examples: *

      {@code
           StringWriter swr = new StringWriter();
      diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      index 45ccb909490..3671ab11833 100644
      --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      @@ -3353,7 +3353,7 @@ assert((int)twice.invokeExact(21) == 42);
            * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
            * 

      The returned method handle is equivalent to * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}. - *

      + * * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as * {@code guardWithTest(pred, target, empty(target.type())}. * @param type the type of the desired method handle @@ -3676,7 +3676,7 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z")); * Given these assumptions, the result of an invocation of {@code dropArgumentsToMatch} will have the parameter type * list {@code S..., P..., M..., A...}, with the {@code P} and {@code A} types inserted as if by * {@link #dropArguments(MethodHandle, int, Class[])}. - *

      + * * @apiNote * Two method handles whose argument lists are "effectively identical" (i.e., identical in a common prefix) may be * mutually converted to a common type by two calls to {@code dropArgumentsToMatch}, as follows: @@ -4169,7 +4169,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); * position in the parameter list at which folding takes place. The argument controlling this, {@code pos}, is a * zero-based index. The aforementioned method {@link #foldArguments(MethodHandle, MethodHandle)} assumes position * 0. - *

      + * * @apiNote Example: *

      {@code
           import static java.lang.invoke.MethodHandles.*;
      @@ -4698,7 +4698,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * Note that the parameter type lists {@code (V...)} and {@code (A...)} have been expanded
            * to their full length, even though individual clause functions may neglect to take them all.
            * As noted above, missing parameters are filled in as if by {@link #dropArgumentsToMatch}.
      -     * 

      + * * @apiNote Example: *

      {@code
            * // iterative implementation of the factorial function as a loop handle
      @@ -4991,7 +4991,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            *   return v;
            * }
            * }
      - *

      + * * @apiNote Example: *

      {@code
            * // implement the zip function for lists as a loop handle
      @@ -5010,7 +5010,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * assertEquals(zipped, (List) loop.invoke(a.iterator(), b.iterator()));
            * }
      * - *

      + * * @apiNote The implementation of this method can be expressed as follows: *

      {@code
            * MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
      @@ -5104,7 +5104,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            *   return v;
            * }
            * }
      - *

      + * * @apiNote Example: *

      {@code
            * // int i = 0; while (i < limit) { ++i; } return i; => limit
      @@ -5116,7 +5116,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * assertEquals(23, loop.invoke(23));
            * }
      * - *

      + * * @apiNote The implementation of this method can be expressed as follows: *

      {@code
            * MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
      @@ -5248,7 +5248,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            *   return v;
            * }
            * }
      - *

      + * * @apiNote Example with a fully conformant body method: *

      {@code
            * // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s;
      @@ -5260,7 +5260,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * MethodHandle loop = MethodHandles.countedLoop(fit13, start, MH_step);
            * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
            * }
      - *

      + * * @apiNote Example with the simplest possible body method type, * and passing the number of iterations to the loop invocation: *

      {@code
      @@ -5273,7 +5273,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * MethodHandle loop = MethodHandles.countedLoop(count, start, MH_step);  // (v, i) -> "na " + v
            * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke(13, "Lambdaman!"));
            * }
      - *

      + * * @apiNote Example that treats the number of iterations, string to append to, and string to append * as loop parameters: *

      {@code
      @@ -5286,7 +5286,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * MethodHandle loop = MethodHandles.countedLoop(count, start, MH_step);  // (v, i, _, pre, _) -> pre + " " + v
            * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke(13, "na", "Lambdaman!"));
            * }
      - *

      + * * @apiNote Example that illustrates the usage of {@link #dropArgumentsToMatch(MethodHandle, int, List, int)} * to enforce a loop type: *

      {@code
      @@ -5301,7 +5301,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * MethodHandle loop = MethodHandles.countedLoop(count, start, body);  // (v, i, pre, _, _) -> pre + " " + v
            * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("na", 13, "Lambdaman!"));
            * }
      - *

      + * * @apiNote The implementation of this method can be expressed as follows: *

      {@code
            * MethodHandle countedLoop(MethodHandle iterations, MethodHandle init, MethodHandle body) {
      @@ -5406,7 +5406,6 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * }
            * }
      * - *

      * @apiNote The implementation of this method can be expressed as follows: *

      {@code
            * MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
      @@ -5607,7 +5606,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            *   return v;
            * }
            * }
      - *

      + * * @apiNote Example: *

      {@code
            * // get an iterator from a list
      @@ -5622,7 +5621,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
            * List reversedList = Arrays.asList("e", "d", "c", "b", "a");
            * assertEquals(reversedList, (List) loop.invoke(list));
            * }
      - *

      + * * @apiNote The implementation of this method can be expressed approximately as follows: *

      {@code
            * MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
      diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java
      index 7e4ce134ec0..e59b5ec9f43 100644
      --- a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java
      +++ b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java
      @@ -165,28 +165,33 @@
        * 

      * Given these rules, here are examples of legal bootstrap method declarations, * given various numbers {@code N} of extra arguments. - * The first rows (marked {@code *}) will work for any number of extra arguments. - *

      adaptable types
      QSLink-time checksInvocation-time checks
      QSLink-time checksInvocation-time checks
      PrimitivePrimitivePrimitivePrimitiveQ can be converted to S via a primitive widening conversionNone
      PrimitiveReferencePrimitiveReferenceS is a supertype of the Wrapper(Q)Cast from Wrapper(Q) to S
      ReferencePrimitiveReferencePrimitivefor parameter types: Q is a primitive wrapper and Primitive(Q) * can be widened to S *
      for return types: If Q is a primitive wrapper, check that @@ -175,7 +175,7 @@ import java.util.Arrays; * for example Number for numeric types
      ReferenceReferenceReferenceReferencefor parameter types: S is a supertype of Q *
      for return types: none
      Cast from Q to S
      + * The first row (marked {@code *}) will work for any number of extra arguments. + *
      * - * - * - * - * - * - * - * - * + * + * + * + * + * + * - * - * - * - * + * + * *
      Static argument types
      NSample bootstrap method
      *CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
      * - * CallSite bootstrap(Object... args)
      * - * CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)
      0 - * CallSite bootstrap(Lookup caller, String name, MethodType type)
      0 - * CallSite bootstrap(Lookup caller, Object... nameAndType)
      1 + *
      NSample bootstrap method
      * + *
        + *
      • CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args) + *
      • CallSite bootstrap(Object... args) + *
      • CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs) + *
      0 + *
        + *
      • CallSite bootstrap(Lookup caller, String name, MethodType type) + *
      • CallSite bootstrap(Lookup caller, Object... nameAndType) + *
      1 * CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)
      2 - * CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
      2 - * CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)
      2CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)
      2 + *
        + *
      • CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args) + *
      • CallSite bootstrap(Lookup caller, String name, MethodType type, String... args) + *
      • CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y) + *
      * The last example assumes that the extra arguments are of type * {@code CONSTANT_String} and {@code CONSTANT_Integer}, respectively. diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java index fd15669931b..c466c82f90c 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/AnnotatedElement.java @@ -108,27 +108,39 @@ import sun.reflect.annotation.AnnotationType; * * * - * - * + * + * + * + * + * + * + * + * * * - * + * + * * - * + * + * * - * + * + * * - * + * + * * - * + * + * * - * + * + * * * *
      Overview of kind of presence detected by different AnnotatedElement methods
      Kind of Presence
      MethodDirectly PresentIndirectly PresentPresentAssociated
      MethodKind of Presence
      Return TypeSignatureDirectly PresentIndirectly PresentPresentAssociated
      {@code T}{@link #getAnnotation(Class) getAnnotation(Class<T>)} - * X
      {@code T}{@link #getAnnotation(Class) getAnnotation(Class<T>)} + * X
      {@code Annotation[]}{@link #getAnnotations getAnnotations()} - * X
      {@code Annotation[]}{@link #getAnnotations getAnnotations()} + * X
      {@code T[]}{@link #getAnnotationsByType(Class) getAnnotationsByType(Class<T>)} - * X
      {@code T[]}{@link #getAnnotationsByType(Class) getAnnotationsByType(Class<T>)} + * X
      {@code T}{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class<T>)} - * X
      {@code T}{@link #getDeclaredAnnotation(Class) getDeclaredAnnotation(Class<T>)} + * X
      {@code Annotation[]}{@link #getDeclaredAnnotations getDeclaredAnnotations()} - * X
      {@code Annotation[]}{@link #getDeclaredAnnotations getDeclaredAnnotations()} + * X
      {@code T[]}{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class<T>)} - * XX
      {@code T[]}{@link #getDeclaredAnnotationsByType(Class) getDeclaredAnnotationsByType(Class<T>)} + * XX
      diff --git a/jdk/src/java.base/share/classes/java/math/BigDecimal.java b/jdk/src/java.base/share/classes/java/math/BigDecimal.java index f4e1f4985d6..cffed200b4e 100644 --- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java +++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java @@ -120,18 +120,18 @@ import java.util.Arrays; * preferred scale for representing a result. The preferred * scale for each operation is listed in the table below. * - * - * + *
      Preferred Scales for Results of Arithmetic Operations - *
      + * * - * + * * * - * - * - * - * - * + * + * + * + * + * * *
      Preferred Scales for Results of Arithmetic Operations + *
      OperationPreferred Scale of Result
      OperationPreferred Scale of Result
      Addmax(addend.scale(), augend.scale())
      Subtractmax(minuend.scale(), subtrahend.scale())
      Multiplymultiplier.scale() + multiplicand.scale()
      Dividedividend.scale() - divisor.scale()
      Square rootradicand.scale()/2
      Addmax(addend.scale(), augend.scale())
      Subtractmax(minuend.scale(), subtrahend.scale())
      Multiplymultiplier.scale() + multiplicand.scale()
      Dividedividend.scale() - divisor.scale()
      Square rootradicand.scale()/2
      * diff --git a/jdk/src/java.base/share/classes/java/math/RoundingMode.java b/jdk/src/java.base/share/classes/java/math/RoundingMode.java index 79ecce36e7f..b4c37f66ed8 100644 --- a/jdk/src/java.base/share/classes/java/math/RoundingMode.java +++ b/jdk/src/java.base/share/classes/java/math/RoundingMode.java @@ -51,13 +51,13 @@ package java.math; * proper {@code MathContext}. A summary table showing the results * of these rounding operations for all rounding modes appears below. * - * + *
      * * - * * - * + * * * * @@ -66,18 +66,18 @@ package java.math; * * * - * + * * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * * *
      Summary of Rounding Operations Under Different Rounding Modes
      Result of rounding input to one digit with the given + *
      Input NumberResult of rounding input to one digit with the given * rounding mode
      Input Number {@code UP}{@code UP}{@code DOWN}{@code CEILING}{@code FLOOR}{@code HALF_EVEN}{@code UNNECESSARY}
      5.5 6 5 6 5 6 5 6 throw {@code ArithmeticException}
      2.5 3 2 3 2 3 2 2 throw {@code ArithmeticException}
      1.6 2 1 2 1 2 2 2 throw {@code ArithmeticException}
      1.1 2 1 2 1 1 1 1 throw {@code ArithmeticException}
      1.0 1 1 1 1 1 1 1 1
      -1.0 -1 -1 -1 -1 -1 -1 -1 -1
      -1.1 -2 -1 -1 -2 -1 -1 -1 throw {@code ArithmeticException}
      -1.6 -2 -1 -1 -2 -2 -2 -2 throw {@code ArithmeticException}
      -2.5 -3 -2 -2 -3 -3 -2 -2 throw {@code ArithmeticException}
      -5.5 -6 -5 -5 -6 -6 -5 -6 throw {@code ArithmeticException}
      5.5 6 5 6 5 6 5 6 throw {@code ArithmeticException}
      2.5 3 2 3 2 3 2 2 throw {@code ArithmeticException}
      1.6 2 1 2 1 2 2 2 throw {@code ArithmeticException}
      1.1 2 1 2 1 1 1 1 throw {@code ArithmeticException}
      1.0 1 1 1 1 1 1 1 1
      -1.0 -1 -1 -1 -1 -1 -1 -1 -1
      -1.1 -2 -1 -1 -2 -1 -1 -1 throw {@code ArithmeticException}
      -1.6 -2 -1 -1 -2 -2 -2 -2 throw {@code ArithmeticException}
      -2.5 -3 -2 -2 -3 -3 -2 -2 throw {@code ArithmeticException}
      -5.5 -6 -5 -5 -6 -6 -5 -6 throw {@code ArithmeticException}
      * @@ -104,23 +104,23 @@ public enum RoundingMode { * value. * *

      Example: - * - * + *
      Rounding mode UP Examples
      + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode UP Examples
      Input NumberInput rounded to one digit
      with {@code UP} rounding + *
      Input NumberInput rounded to one digit
      with {@code UP} rounding *
      5.5 6
      2.5 3
      1.6 2
      1.1 2
      1.0 1
      -1.0 -1
      -1.1 -2
      -1.6 -2
      -2.5 -3
      -5.5 -6
      5.5 6
      2.5 3
      1.6 2
      1.1 2
      1.0 1
      -1.0 -1
      -1.1 -2
      -1.6 -2
      -2.5 -3
      -5.5 -6
      */ @@ -132,23 +132,23 @@ public enum RoundingMode { * rounding mode never increases the magnitude of the calculated value. * *

      Example: - * - * + *
      Rounding mode DOWN Examples
      + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode DOWN Examples
      Input NumberInput rounded to one digit
      with {@code DOWN} rounding + *
      Input NumberInput rounded to one digit
      with {@code DOWN} rounding *
      5.5 5
      2.5 2
      1.6 1
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -1
      -2.5 -2
      -5.5 -5
      5.5 5
      2.5 2
      1.6 1
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -1
      -2.5 -2
      -5.5 -5
      */ @@ -161,23 +161,23 @@ public enum RoundingMode { * that this rounding mode never decreases the calculated value. * *

      Example: - * - * + *
      Rounding mode CEILING Examples
      + * * * * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode CEILING Examples
      Input NumberInput rounded to one digit
      with {@code CEILING} rounding *
      5.5 6
      2.5 3
      1.6 2
      1.1 2
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -1
      -2.5 -2
      -5.5 -5
      5.5 6
      2.5 3
      1.6 2
      1.1 2
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -1
      -2.5 -2
      -5.5 -5
      */ @@ -190,23 +190,23 @@ public enum RoundingMode { * this rounding mode never increases the calculated value. * *

      Example: - * - * + *
      Rounding mode FLOOR Examples
      + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode FLOOR Examples
      Input NumberInput rounded to one digit
      with {@code FLOOR} rounding + *
      Input NumberInput rounded to one digit
      with {@code FLOOR} rounding *
      5.5 5
      2.5 2
      1.6 1
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -2
      -1.6 -2
      -2.5 -3
      -5.5 -6
      5.5 5
      2.5 2
      1.6 1
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -2
      -1.6 -2
      -2.5 -3
      -5.5 -6
      */ @@ -221,23 +221,23 @@ public enum RoundingMode { * mode commonly taught at school. * *

      Example: - * - * + *
      Rounding mode HALF_UP Examples
      + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode HALF_UP Examples
      Input NumberInput rounded to one digit
      with {@code HALF_UP} rounding + *
      Input NumberInput rounded to one digit
      with {@code HALF_UP} rounding *
      5.5 6
      2.5 3
      1.6 2
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -2
      -2.5 -3
      -5.5 -6
      5.5 6
      2.5 3
      1.6 2
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -2
      -2.5 -3
      -5.5 -6
      */ @@ -251,23 +251,23 @@ public enum RoundingMode { * {@code RoundingMode.DOWN}. * *

      Example: - * - * + *
      Rounding mode HALF_DOWN Examples
      + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode HALF_DOWN Examples
      Input NumberInput rounded to one digit
      with {@code HALF_DOWN} rounding + *
      Input NumberInput rounded to one digit
      with {@code HALF_DOWN} rounding *
      5.5 5
      2.5 2
      1.6 2
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -2
      -2.5 -2
      -5.5 -5
      5.5 5
      2.5 2
      1.6 2
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -2
      -2.5 -2
      -5.5 -5
      */ @@ -288,23 +288,23 @@ public enum RoundingMode { * arithmetic in Java. * *

      Example: - * - * + *
      Rounding mode HALF_EVEN Examples
      + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode HALF_EVEN Examples
      Input NumberInput rounded to one digit
      with {@code HALF_EVEN} rounding + *
      Input NumberInput rounded to one digit
      with {@code HALF_EVEN} rounding *
      5.5 6
      2.5 2
      1.6 2
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -2
      -2.5 -2
      -5.5 -6
      5.5 6
      2.5 2
      1.6 2
      1.1 1
      1.0 1
      -1.0 -1
      -1.1 -1
      -1.6 -2
      -2.5 -2
      -5.5 -6
      */ @@ -316,23 +316,23 @@ public enum RoundingMode { * specified on an operation that yields an inexact result, an * {@code ArithmeticException} is thrown. *

      Example: - * - * + *
      Rounding mode UNNECESSARY Examples
      + * * - * - * + * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + * * *
      Rounding mode UNNECESSARY Examples
      Input NumberInput rounded to one digit
      with {@code UNNECESSARY} rounding + *
      Input NumberInput rounded to one digit
      with {@code UNNECESSARY} rounding *
      5.5 throw {@code ArithmeticException}
      2.5 throw {@code ArithmeticException}
      1.6 throw {@code ArithmeticException}
      1.1 throw {@code ArithmeticException}
      1.0 1
      -1.0 -1
      -1.1 throw {@code ArithmeticException}
      -1.6 throw {@code ArithmeticException}
      -2.5 throw {@code ArithmeticException}
      -5.5 throw {@code ArithmeticException}
      5.5 throw {@code ArithmeticException}
      2.5 throw {@code ArithmeticException}
      1.6 throw {@code ArithmeticException}
      1.1 throw {@code ArithmeticException}
      1.0 1
      -1.0 -1
      -1.1 throw {@code ArithmeticException}
      -1.6 throw {@code ArithmeticException}
      -2.5 throw {@code ArithmeticException}
      -5.5 throw {@code ArithmeticException}
      */ diff --git a/jdk/src/java.base/share/classes/java/net/InetAddress.java b/jdk/src/java.base/share/classes/java/net/InetAddress.java index 95b38875d9c..d4815f486df 100644 --- a/jdk/src/java.base/share/classes/java/net/InetAddress.java +++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java @@ -72,10 +72,13 @@ import sun.net.util.IPAddressUtil; * *

      Address types

      * - *
      + *
      * + * + * + * * - * + * * - * + * * * - *
      Description of unicast and multicast address types
      Address TypeDescription
      unicast
      unicastAn identifier for a single interface. A packet sent to * a unicast address is delivered to the interface identified by * that address. @@ -94,12 +97,12 @@ import sun.net.util.IPAddressUtil; * IP address loops around and becomes IP input on the local * host. This address is often used when testing a * client.
      multicast
      multicastAn identifier for a set of interfaces (typically belonging * to different nodes). A packet sent to a multicast address is * delivered to all interfaces identified by that address.
      + * * *

      IP address scope

      * @@ -163,8 +166,7 @@ import sun.net.util.IPAddressUtil; *

      Two Java security properties control the TTL values used for * positive and negative host name resolution caching: * - *

      - *
      + *
      *
      networkaddress.cache.ttl
      *
      Indicates the caching policy for successful name lookups from * the name service. The value is specified as an integer to indicate @@ -183,7 +185,6 @@ import sun.net.util.IPAddressUtil; * A value of -1 indicates "cache forever". *
      *
      - *
      * * @author Chris Warth * @see java.net.InetAddress#getByAddress(byte[]) diff --git a/jdk/src/java.base/share/classes/java/net/URI.java b/jdk/src/java.base/share/classes/java/net/URI.java index eab652cbbf5..5199a3dd2bb 100644 --- a/jdk/src/java.base/share/classes/java/net/URI.java +++ b/jdk/src/java.base/share/classes/java/net/URI.java @@ -132,23 +132,23 @@ import java.lang.NullPointerException; // for javadoc * *

      All told, then, a URI instance has the following nine components: * - *

      + *
      * * - * + * * - * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * + * * - *
      Describes the components of a URI:scheme,scheme-specific-part,authority,user-info,host,port,path,query,fragment
      ComponentType
      ComponentType
      scheme{@code String}
      scheme-specific-part    {@code String}
      authority{@code String}
      user-info{@code String}
      host{@code String}
      port{@code int}
      path{@code String}
      query{@code String}
      fragment{@code String}
      scheme{@code String}
      scheme-specific-part{@code String}
      authority{@code String}
      user-info{@code String}
      host{@code String}
      port{@code int}
      path{@code String}
      query{@code String}
      fragment{@code String}
      + * * * In a given instance any particular component is either undefined or * defined with a distinct value. Undefined string components are @@ -253,32 +253,35 @@ import java.lang.NullPointerException; // for javadoc * which are taken from that specification, are used below to describe these * constraints: * - *
      + *
      * - * - * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * * - *
      Describes categories alpha,digit,alphanum,unreserved,punct,reserved,escaped,and other
      alpha
      CategoryDescription
      alphaThe US-ASCII alphabetic characters, * {@code 'A'} through {@code 'Z'} * and {@code 'a'} through {@code 'z'}
      digit
      digitThe US-ASCII decimal digit characters, * {@code '0'} through {@code '9'}
      alphanum
      alphanumAll alpha and digit characters
      unreserved    
      unreservedAll alphanum characters together with those in the string * {@code "_-!.~'()*"}
      punct
      punctThe characters in the string {@code ",;:$&+="}
      reserved
      reservedAll punct characters together with those in the string * {@code "?/[]@"}
      escaped
      escapedEscaped octets, that is, triplets consisting of the percent * character ({@code '%'}) followed by two hexadecimal digits * ({@code '0'}-{@code '9'}, {@code 'A'}-{@code 'F'}, and * {@code 'a'}-{@code 'f'})
      other
      otherThe Unicode characters that are not in the US-ASCII character set, * are not control characters (according to the {@link * java.lang.Character#isISOControl(char) Character.isISOControl} @@ -287,7 +290,7 @@ import java.lang.NullPointerException; // for javadoc * method)  (Deviation from RFC 2396, which is * limited to US-ASCII)
      + * * *

      The set of all legal URI characters consists of * the unreserved, reserved, escaped, and other diff --git a/jdk/src/java.base/share/classes/java/net/URLConnection.java b/jdk/src/java.base/share/classes/java/net/URLConnection.java index e54a0b1a126..a5c30df3d4b 100644 --- a/jdk/src/java.base/share/classes/java/net/URLConnection.java +++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java @@ -51,31 +51,16 @@ import sun.security.action.GetPropertyAction; * The abstract class {@code URLConnection} is the superclass * of all classes that represent a communications link between the * application and a URL. Instances of this class can be used both to - * read from and to write to the resource referenced by the URL. In - * general, creating a connection to a URL is a multistep process: - * - *

      - * - * - * - * - * - * - * - * - * - *
      Describes the process of creating a connection to a URL: openConnection() and connect() over time.
      {@code openConnection()}{@code connect()}
      Manipulate parameters that affect the connection to the remote - * resource.Interact with the resource; query header fields and - * contents.
      - * ----------------------------> - *
      time
      + * read from and to write to the resource referenced by the URL. * + *

      + * In general, creating a connection to a URL is a multistep process: *

        *
      1. The connection object is created by invoking the - * {@code openConnection} method on a URL. + * {@link URL#openConnection() openConnection} method on a URL. *
      2. The setup parameters and general request properties are manipulated. *
      3. The actual connection to the remote object is made, using the - * {@code connect} method. + * {@link #connect() connect} method. *
      4. The remote object becomes available. The header fields and the contents * of the remote object can be accessed. *
      diff --git a/jdk/src/java.base/share/classes/java/net/URLPermission.java b/jdk/src/java.base/share/classes/java/net/URLPermission.java index 43a8bd43066..31441749659 100644 --- a/jdk/src/java.base/share/classes/java/net/URLPermission.java +++ b/jdk/src/java.base/share/classes/java/net/URLPermission.java @@ -72,22 +72,22 @@ import java.security.Permission; * separated by '/' characters. path may also be empty. The path is specified * in a similar way to the path in {@link java.io.FilePermission}. There are * three different ways as the following examples show: - * + *
      * * - * + * * - * - * + * + * * * - * + * * * - * + * * + *
      URL Examples
      Example urlDescription
      Example urlDescription
      http://www.oracle.com/a/b/c.html
      http://www.oracle.com/a/b/c.htmlA url which identifies a specific (single) resource
      http://www.oracle.com/a/b/*
      http://www.oracle.com/a/b/*The '*' character refers to all resources in the same "directory" - in * other words all resources with the same number of path components, and * which only differ in the final path component, represented by the '*'. *
      http://www.oracle.com/a/b/-
      http://www.oracle.com/a/b/-The '-' character refers to all resources recursively below the * preceding path (eg. http://www.oracle.com/a/b/c/d/e.html matches this * example). @@ -114,11 +114,12 @@ import java.security.Permission; * methods and permitted request headers of the permission (respectively). The two lists * are separated by a colon ':' character and elements of each list are comma separated. * Some examples are: - *
      - *         "POST,GET,DELETE"
      - *         "GET:X-Foo-Request,X-Bar-Request"
      - *         "POST,GET:Header1,Header2"
      - * 
      + *
        + *
      • "POST,GET,DELETE" + *
      • "GET:X-Foo-Request,X-Bar-Request" + *
      • "POST,GET:Header1,Header2" + *
      + *

      * The first example specifies the methods: POST, GET and DELETE, but no request headers. * The second example specifies one request method and two headers. The third * example specifies two request methods, and two headers. @@ -253,16 +254,16 @@ public final class URLPermission extends Permission { * * * - * + * * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * * *
      Examples of Path Matching
      this's pathp's pathmatch
      this's pathp's pathmatch
      /a/b/a/byes
      /a/b/*/a/b/cyes
      /a/b/*/a/b/c/dno
      /a/b/-/a/b/c/dyes
      /a/b/-/a/b/c/d/eyes
      /a/b/-/a/b/c/*yes
      /a/b/*/a/b/c/-no
      /a/b/a/byes
      /a/b/*/a/b/cyes
      /a/b/c/dno
      /a/b/c/-no
      /a/b/-/a/b/c/dyes
      /a/b/c/d/eyes
      /a/b/c/*yes
      */ diff --git a/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html b/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html index 003749ba7f2..acf653ebaed 100644 --- a/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html +++ b/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html @@ -23,7 +23,7 @@ or visit www.oracle.com if you need additional information or have any questions. --> - + Networking Properties @@ -35,7 +35,7 @@ alter the mechanisms and behavior of the various classes of the java.net package. Some are checked only once at startup of the VM, and therefore are best set using the -D option of the java command, while others have a more dynamic nature and can also be changed using -the System.setProperty() API. +the System.setProperty() API. The purpose of this document is to list and detail all of these properties.

      If there is no special note, a property value is checked every time it is used.

      diff --git a/jdk/src/java.base/share/classes/java/nio/channels/package-info.java b/jdk/src/java.base/share/classes/java/nio/channels/package-info.java index d29ae67590f..0dc410ddd76 100644 --- a/jdk/src/java.base/share/classes/java/nio/channels/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/channels/package-info.java @@ -30,46 +30,50 @@ * * * - *
      + *
      * - * - * - * + * + * + * + * + * + * * - * + * * - * - * - * + * + * + * * - * - * - * - * - * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - *
      Lists channels and their descriptions
      ChannelsDescription
      {@link java.nio.channels.Channel}
      ChannelsDescription
      {@link java.nio.channels.Channel}A nexus for I/O operations
      - *   {@link java.nio.channels.ReadableByteChannel}
      + * {@link java.nio.channels.ReadableByteChannel}Can read into a buffer
      - *     {@link java.nio.channels.ScatteringByteChannel}  Can read into a sequence of buffers
      - *   {@link java.nio.channels.WritableByteChannel}
      + * {@link java.nio.channels.ScatteringByteChannel}Can read into a sequence of buffers
      + * {@link java.nio.channels.WritableByteChannel}Can write from a buffer
      - *     {@link java.nio.channels.GatheringByteChannel}Can write from a sequence of buffers
      - *   {@link java.nio.channels.ByteChannel}Can read/write to/from a buffer
      - *     {@link java.nio.channels.SeekableByteChannel}
      + * {@link java.nio.channels.GatheringByteChannel}Can write from a sequence of buffers
      + * {@link java.nio.channels.ByteChannel}Can read/write to/from a buffer
      + * {@link java.nio.channels.SeekableByteChannel}A {@code ByteChannel} connected to an entity that contains a variable-length * sequence of bytes
      - *   {@link java.nio.channels.AsynchronousChannel}
      + * {@link java.nio.channels.AsynchronousChannel}Supports asynchronous I/O operations.
      - *     {@link java.nio.channels.AsynchronousByteChannel}
      + * {@link java.nio.channels.AsynchronousByteChannel}Can read and write bytes asynchronously
      - *   {@link java.nio.channels.NetworkChannel}
      + * {@link java.nio.channels.NetworkChannel}A channel to a network socket
      - *     {@link java.nio.channels.MulticastChannel}
      + * {@link java.nio.channels.MulticastChannel}Can join Internet Protocol (IP) multicast groups
      {@link java.nio.channels.Channels}
      {@link java.nio.channels.Channels}Utility methods for channel/stream interoperation
      + *
      * *

      A channel represents an open connection to an entity such as a * hardware device, a file, a network socket, or a program component that is @@ -122,21 +126,25 @@ * be constructed that uses a given charset to encode characters into bytes and * write them to a given writable byte channel. * - *

      + *
      * - * - * - * + * + * + * + * + * + * * - * + * * - * - * - *
      * Lists file channels and their descriptions
      File channelsDescription
      - * {@link java.nio.channels.FileChannel}
      File channelsDescription
      + * {@link java.nio.channels.FileChannel}Reads, writes, maps, and manipulates files
      - * {@link java.nio.channels.FileLock}
      + * {@link java.nio.channels.FileLock}A lock on a (region of a) file
      - * {@link java.nio.MappedByteBuffer}  A direct byte buffer mapped to a region of a file
      + * + * {@link java.nio.MappedByteBuffer} + * A direct byte buffer mapped to a region of a file + * + * * *

      The {@link java.nio.channels.FileChannel} class supports the usual * operations of reading bytes from, and writing bytes to, a channel connected to @@ -156,36 +164,40 @@ * class. * * - *

      + *
      * - * - * - * + * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * - * - * - * - *
      * Lists multiplexed, non-blocking channels and their descriptions
      Multiplexed, non-blocking I/ODescription
      {@link java.nio.channels.SelectableChannel}
      Multiplexed, non-blocking I/ODescription
      {@link java.nio.channels.SelectableChannel}A channel that can be multiplexed
      - *   {@link java.nio.channels.DatagramChannel}
      + * {@link java.nio.channels.DatagramChannel}A channel to a datagram-oriented socket
      - *   {@link java.nio.channels.Pipe.SinkChannel}
      + * {@link java.nio.channels.Pipe.SinkChannel}The write end of a pipe
      - *   {@link java.nio.channels.Pipe.SourceChannel}
      + * {@link java.nio.channels.Pipe.SourceChannel}The read end of a pipe
      - *   {@link java.nio.channels.ServerSocketChannel}  
      + * {@link java.nio.channels.ServerSocketChannel}A channel to a stream-oriented listening socket
      - *   {@link java.nio.channels.SocketChannel}
      + * {@link java.nio.channels.SocketChannel}A channel for a stream-oriented connecting socket
      {@link java.nio.channels.Selector}
      {@link java.nio.channels.Selector}A multiplexor of selectable channels
      {@link java.nio.channels.SelectionKey}A token representing the registration
      of a channel - * with a selector
      {@link java.nio.channels.Pipe}Two channels that form a unidirectional pipe
      + * {@link java.nio.channels.SelectionKey} + * A token representing the registration of a channel + * with a selector + * {@link java.nio.channels.Pipe} + * Two channels that form a unidirectional pipe + * + * * *

      Multiplexed, non-blocking I/O, which is much more scalable than * thread-oriented, blocking I/O, is provided by selectors, selectable @@ -251,27 +263,31 @@ * * * - *

      + *
      * - * - * + * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - *
      * Lists asynchronous channels and their descriptions
      - * Asynchronous I/ODescription
      - * {@link java.nio.channels.AsynchronousFileChannel}
      Asynchronous I/ODescription
      + * {@link java.nio.channels.AsynchronousFileChannel}An asynchronous channel for reading, writing, and manipulating a file
      - * {@link java.nio.channels.AsynchronousSocketChannel}
      + * {@link java.nio.channels.AsynchronousSocketChannel}An asynchronous channel to a stream-oriented connecting socket
      - * {@link java.nio.channels.AsynchronousServerSocketChannel}  
      + * {@link java.nio.channels.AsynchronousServerSocketChannel}An asynchronous channel to a stream-oriented listening socket
      - * {@link java.nio.channels.CompletionHandler}
      + * {@link java.nio.channels.CompletionHandler}A handler for consuming the result of an asynchronous operation
      - * {@link java.nio.channels.AsynchronousChannelGroup}
      + * {@link java.nio.channels.AsynchronousChannelGroup}A grouping of asynchronous channels for the purpose of resource sharing
      + * + * * *

      {@link java.nio.channels.AsynchronousChannel Asynchronous channels} are a * special type of channel capable of asynchronous I/O operations. Asynchronous diff --git a/jdk/src/java.base/share/classes/java/nio/charset/package-info.java b/jdk/src/java.base/share/classes/java/nio/charset/package-info.java index 80141dc8b6a..046606a57db 100644 --- a/jdk/src/java.base/share/classes/java/nio/charset/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/charset/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,22 +27,25 @@ * Defines charsets, decoders, and encoders, for translating between * bytes and Unicode characters. * - *

      + *
      * - * - * - * - * + * + * + * + * + * + * + * * - * + * * - * + * * - * - * - * - *
      Summary of charsets, decoders, and encoders in this package
      Class nameDescriptiPath - *
      {@link java.nio.charset.Charset}A named mapping between characters
      and bytes
      {@link java.nio.charset.CharsetDecoder}
      Class nameDescription + *
      {@link java.nio.charset.Charset}A named mapping between characters and bytes
      {@link java.nio.charset.CharsetDecoder}Decodes bytes into characters
      {@link java.nio.charset.CharsetEncoder}
      {@link java.nio.charset.CharsetEncoder}Encodes characters into bytes
      {@link java.nio.charset.CoderResult}
      {@link java.nio.charset.CoderResult}Describes coder results
      {@link java.nio.charset.CodingErrorAction}Describes actions to take when
      coding errors are detected
      + * {@link java.nio.charset.CodingErrorAction} + * Describes actions to take when coding errors are detected + * + * * *

      A charset is named mapping between sequences of * sixteen-bit Unicode characters and sequences of bytes, in the sense diff --git a/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java b/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java index 0fd5be4fcf0..27bca11922e 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java +++ b/jdk/src/java.base/share/classes/java/nio/file/FileSystem.java @@ -314,45 +314,49 @@ public abstract class FileSystem * representation of the path is matched using a limited pattern language * that resembles regular expressions but with a simpler syntax. For example: * - *

      - * + *
      * + * + * + * + * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * - * * * - * * * - * * * *
      Pattern Language
      Example + * Description + *
      {@code *.java}{@code *.java}Matches a path that represents a file name ending in {@code .java}
      {@code *.*}{@code *.*}Matches file names containing a dot
      {@code *.{java,class}}{@code *.{java,class}}Matches file names ending with {@code .java} or {@code .class}
      {@code foo.?}{@code foo.?}Matches file names starting with {@code foo.} and a single * character extension
      /home/*/* + * /home/*/* * Matches /home/gus/data on UNIX platforms
      /home/** + * /home/** * Matches /home/gus and * /home/gus/data on UNIX platforms
      C:\\* + * C:\\* * Matches C:\foo and C:\bar on the Windows * platform (note that the backslash is escaped; as a string literal in the * Java Language the pattern would be "C:\\\\*")
      - *
      * *

      The following rules are used to interpret glob patterns: * diff --git a/jdk/src/java.base/share/classes/java/nio/file/Files.java b/jdk/src/java.base/share/classes/java/nio/file/Files.java index 09bce16a844..f5dbba9c358 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/Files.java +++ b/jdk/src/java.base/share/classes/java/nio/file/Files.java @@ -1923,30 +1923,33 @@ public final class Files { *

      The following examples demonstrate possible values for the {@code * attributes} parameter: * - *

      - * + *
      * + * + * + * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * * *
      Possible values
      Example + * Description + *
      {@code "*"} {@code "*"} Read all {@link BasicFileAttributes basic-file-attributes}.
      {@code "size,lastModifiedTime,lastAccessTime"} {@code "size,lastModifiedTime,lastAccessTime"} Reads the file size, last modified time, and last access time * attributes.
      {@code "posix:*"} {@code "posix:*"} Read all {@link PosixFileAttributes POSIX-file-attributes}.
      {@code "posix:permissions,owner,size"} {@code "posix:permissions,owner,size"} Reads the POSIX file permissions, owner, and file size.
      - *
      * *

      The {@code options} array may be used to indicate how symbolic links * are handled for the case that the file is a symbolic link. By default, diff --git a/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java b/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java index 11f5d6e2720..911d38a9bea 100644 --- a/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,43 +26,47 @@ /** * Interfaces and classes providing access to file and file system attributes. * - *

      + *
      * - * - * - * + * + * + * + * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - *
      Attribute views
      Attribute viewsDescription
      {@link java.nio.file.attribute.AttributeView}
      Attribute viewsDescription
      {@link java.nio.file.attribute.AttributeView}Can read or update non-opaque values associated with objects in a file system
      - *   {@link java.nio.file.attribute.FileAttributeView}
      + * {@link java.nio.file.attribute.FileAttributeView}Can read or update file attributes
      - *      - * {@link java.nio.file.attribute.BasicFileAttributeView}  
      + * + * {@link java.nio.file.attribute.BasicFileAttributeView}Can read or update a basic set of file attributes
      - *        - * {@link java.nio.file.attribute.PosixFileAttributeView}  
      + * + * {@link java.nio.file.attribute.PosixFileAttributeView}Can read or update POSIX defined file attributes
      - *        - * {@link java.nio.file.attribute.DosFileAttributeView}  
      + * + * {@link java.nio.file.attribute.DosFileAttributeView}Can read or update FAT file attributes
      - *      - * {@link java.nio.file.attribute.FileOwnerAttributeView}  
      + * + * {@link java.nio.file.attribute.FileOwnerAttributeView}Can read or update the owner of a file
      - *       - * {@link java.nio.file.attribute.AclFileAttributeView}  
      + * + * {@link java.nio.file.attribute.AclFileAttributeView}Can read or update Access Control Lists
      - *      - * {@link java.nio.file.attribute.UserDefinedFileAttributeView}  
      + * + * {@link java.nio.file.attribute.UserDefinedFileAttributeView}Can read or update user-defined file attributes
      - *   {@link java.nio.file.attribute.FileStoreAttributeView}
      + * {@link java.nio.file.attribute.FileStoreAttributeView}Can read or update file system attributes
      + * + * * *

      An attribute view provides a read-only or updatable view of the non-opaque * values, or metadata, associated with objects in a file system. diff --git a/jdk/src/java.base/share/classes/java/nio/package-info.java b/jdk/src/java.base/share/classes/java/nio/package-info.java index 9fa17c945e0..c743a058fc7 100644 --- a/jdk/src/java.base/share/classes/java/nio/package-info.java +++ b/jdk/src/java.base/share/classes/java/nio/package-info.java @@ -48,7 +48,7 @@ *

    • Selectors and selection keys, which * together with
      selectable channels define a multiplexed, - * non-blocking
      I/O
       facility.

    • + * non-blocking
      I/O facility.

      * * * @@ -62,33 +62,44 @@ * * * - *
      + *
      * - * - * - * + * + * + * + * + * + * * - * - * - * + * clear, flip, rewind, and mark/reset + * + * + * * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
      Description of the various buffers
      BuffersDescription
      {@link java.nio.Buffer}
      BuffersDescription
      {@link java.nio.Buffer}Position, limit, and capacity; - *
      clear, flip, rewind, and mark/reset
        {@link java.nio.ByteBuffer}Get/put, compact, views; allocate, wrap
      - *     {@link java.nio.MappedByteBuffer}  
      + * {@link java.nio.ByteBuffer}Get/put, compact, views; allocate, wrap
      + * {@link java.nio.MappedByteBuffer}A byte buffer mapped to a file
        {@link java.nio.CharBuffer}Get/put, compact; allocate, wrap
        {@link java.nio.DoubleBuffer}    ' '
        {@link java.nio.FloatBuffer}    ' '
        {@link java.nio.IntBuffer}    ' '
        {@link java.nio.LongBuffer}    ' '
        {@link java.nio.ShortBuffer}    ' '
      {@link java.nio.ByteOrder}Typesafe enumeration for byte orders
      + * + * {@link java.nio.CharBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.DoubleBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.FloatBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.IntBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.LongBuffer} + * Get/put, compact; allocate, wrap + * + * {@link java.nio.ShortBuffer} + * Get/put, compact; allocate, wrap + * {@link java.nio.ByteOrder} + * Typesafe enumeration for byte orders + * + * * *

      A buffer is a container for a fixed amount of data of a * specific primitive type. In addition to its content a buffer has a diff --git a/jdk/src/java.base/share/classes/java/security/DrbgParameters.java b/jdk/src/java.base/share/classes/java/security/DrbgParameters.java index 05723baa916..4dba498faf1 100644 --- a/jdk/src/java.base/share/classes/java/security/DrbgParameters.java +++ b/jdk/src/java.base/share/classes/java/security/DrbgParameters.java @@ -263,18 +263,18 @@ public class DrbgParameters { * Capability effective = ((DrbgParametes.Initiate) s.getParameters()) * .getCapability();

      * - * + *
      * * * - * - * + * + * * * - * - * - * - * + * + * + * + * * *
      requested and effective capabilities
      Requested ValuePossible Effective ValuesRequested ValuePossible Effective Values
      NONENONE, RESEED_ONLY, PR_AND_RESEED
      RESEED_ONLYRESEED_ONLY, PR_AND_RESEED
      PR_AND_RESEEDPR_AND_RESEED
      NONENONE, RESEED_ONLY, PR_AND_RESEED
      RESEED_ONLYRESEED_ONLY, PR_AND_RESEED
      PR_AND_RESEEDPR_AND_RESEED
      *

      diff --git a/jdk/src/java.base/share/classes/java/security/Provider.java b/jdk/src/java.base/share/classes/java/security/Provider.java index cf20bfec3ac..83ce4ff9aa2 100644 --- a/jdk/src/java.base/share/classes/java/security/Provider.java +++ b/jdk/src/java.base/share/classes/java/security/Provider.java @@ -61,19 +61,19 @@ import java.util.function.Function; * security framework. Services of this type cannot be added, removed, * or modified by applications. * The following attributes are automatically placed in each Provider object: - * + *
      * * - * + * * - * - * + * + * * - * + * * - * + * * - * + * * * *
      Attributes Automatically Placed in a Provider Object
      NameValue
      NameValue
      {@code Provider.id name}
      {@code Provider.id name}{@code String.valueOf(provider.getName())}
      {@code Provider.id version}
      {@code Provider.id version}{@code String.valueOf(provider.getVersionStr())}
      {@code Provider.id info}
      {@code Provider.id info}{@code String.valueOf(provider.getInfo())}
      {@code Provider.id className}
      {@code Provider.id className}{@code provider.getClass().getName()}
      diff --git a/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java b/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java index b7533a2c697..b8aa25fb9ca 100644 --- a/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java +++ b/jdk/src/java.base/share/classes/java/security/cert/X509Extension.java @@ -153,33 +153,33 @@ public interface X509Extension { * by periods. * *

      For example:
      - * + *
      * * * - * - * + * + * * - * - * + * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * - * + * * * *
      Examples of OIDs and extension names
      OID (Object Identifier)Extension Name
      OID (Object Identifier)Extension Name
      2.5.29.14
      2.5.29.14SubjectKeyIdentifier
      2.5.29.15
      2.5.29.15KeyUsage
      2.5.29.16
      2.5.29.16PrivateKeyUsage
      2.5.29.17
      2.5.29.17SubjectAlternativeName
      2.5.29.18
      2.5.29.18IssuerAlternativeName
      2.5.29.19
      2.5.29.19BasicConstraints
      2.5.29.30
      2.5.29.30NameConstraints
      2.5.29.33
      2.5.29.33PolicyMappings
      2.5.29.35
      2.5.29.35AuthorityKeyIdentifier
      2.5.29.36
      2.5.29.36PolicyConstraints
      diff --git a/jdk/src/java.base/share/classes/java/text/MessageFormat.java b/jdk/src/java.base/share/classes/java/text/MessageFormat.java index b80eb054f51..dfed999a5df 100644 --- a/jdk/src/java.base/share/classes/java/text/MessageFormat.java +++ b/jdk/src/java.base/share/classes/java/text/MessageFormat.java @@ -150,73 +150,73 @@ import java.util.Locale; * Shows how FormatType and FormatStyle values map to Format instances * * - * FormatType - * FormatStyle - * Subformat Created + * FormatType + * FormatStyle + * Subformat Created * * * - * (none) - * (none) - * null + * (none) + * (none) + * {@code null} * - * number - * (none) - * {@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())} + * {@code number} + * (none) + * {@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())} * - * integer - * {@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())} + * {@code integer} + * {@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())} * - * currency - * {@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())} + * {@code currency} + * {@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())} * - * percent - * {@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())} + * {@code percent} + * {@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())} * - * SubformatPattern - * {@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))} + * SubformatPattern + * {@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))} * - * date - * (none) - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code date} + * (none) + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * short - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} + * {@code short} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} * - * medium - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code medium} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * long - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} + * {@code long} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} * - * full - * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} + * {@code full} + * {@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} * - * SubformatPattern - * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} + * SubformatPattern + * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} * - * time - * (none) - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code time} + * (none) + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * short - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} + * {@code short} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())} * - * medium - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} + * {@code medium} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())} * - * long - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} + * {@code long} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())} * - * full - * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} + * {@code full} + * {@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())} * - * SubformatPattern - * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} + * SubformatPattern + * {@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())} * - * choice - * SubformatPattern - * {@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)} + * {@code choice} + * SubformatPattern + * {@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)} * * * @@ -776,44 +776,40 @@ public class MessageFormat extends Format { * Examples of subformat,argument,and formatted text * * - * Subformat - * Argument - * Formatted Text + * Subformat + * Argument + * Formatted Text * * * - * any - * unavailable + * any + * unavailable * "{" + argumentIndex + "}" * - * any - * null + * null * "null" * - * instanceof ChoiceFormat - * any + * instanceof ChoiceFormat + * any * subformat.format(argument).indexOf('{') >= 0 ?
      * (new MessageFormat(subformat.format(argument), getLocale())).format(argument) : * subformat.format(argument)
      * - * != null - * any + * != null + * any * subformat.format(argument) * - * null - * instanceof Number + * null + * instanceof Number * NumberFormat.getInstance(getLocale()).format(argument) * - * null - * instanceof Date + * instanceof Date * DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()).format(argument) * - * null - * instanceof String + * instanceof String * argument * - * null - * any + * any * argument.toString() * * diff --git a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java index 0ec1b591bc2..bc702a44d07 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java @@ -103,19 +103,19 @@ import sun.util.logging.PlatformLogger; * *

      * CLDR and LDML identify variants: - * + *
      * * * - * - * - * - * + * + * + * + * * * * * - * + * * * * @@ -148,38 +148,38 @@ import sun.util.logging.PlatformLogger; *

      * The Hijrah property resource is a set of properties that describe the calendar. * The syntax is defined by {@code java.util.Properties#load(Reader)}. - *

      Variants of Hijrah Calendars
      Chronology IDCalendar TypeLocale extension, see {@link java.util.Locale}DescriptionChronology IDCalendar TypeLocale extension, see {@link java.util.Locale}Description
      Hijrah-umalquraHijrah-umalquraislamic-umalquraca-islamic-umalquraIslamic - Umm Al-Qura calendar of Saudi Arabia
      + *
      * * * - * - * - * + * + * + * * * * * - * + * * * * * - * + * * * * * - * + * * * * * - * + * * * * * - * + * * *
      Configuration of Hijrah Calendar
      Property Name Property value Description Property NameProperty valueDescription
      ididChronology Id, for example, "Hijrah-umalqura"The Id of the calendar in common usage
      typetypeCalendar type, for example, "islamic-umalqura"LDML defines the calendar types
      versionversionVersion, for example: "1.8.0_1"The version of the Hijrah variant data
      iso-startiso-startISO start date, formatted as {@code yyyy-MM-dd}, for example: "1900-04-30"The ISO date of the first day of the minimum Hijrah year.
      yyyy - a numeric 4 digit year, for example "1434"yyyy - a numeric 4 digit year, for example "1434"The value is a sequence of 12 month lengths, * for example: "29 30 29 30 29 30 30 30 29 30 29 29"The lengths of the 12 months of the year separated by whitespace. diff --git a/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java b/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java index 702fabdf920..887d76f72b6 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/IsoEra.java @@ -70,27 +70,27 @@ import java.time.DateTimeException; * A definition has therefore been created with two eras - 'Current era' (CE) for * years on or after 0001-01-01 (ISO), and 'Before current era' (BCE) for years before that. * - * + *
      * * * - * - * - * + * + * + * * * * * - * + * * * - * + * * * - * + * * * - * + * * * *
      ISO years and eras
      year-of-eraeraproleptic-yearyear-of-eraeraproleptic-year
      2CE22CE2
      1CE11CE1
      1BCE01BCE0
      2BCE-12BCE-1
      diff --git a/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java b/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java index edac0ec02e7..9c227884994 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/MinguoEra.java @@ -71,28 +71,28 @@ import java.time.DateTimeException; * All previous years, zero or earlier in the proleptic count or one and greater * in the year-of-era count, are part of the 'Before Republic of China' era. * - * + *
      * * * - * - * - * - * + * + * + * + * * * * * - * + * * * - * + * * * - * + * * * - * + * * * *
      Minguo years and eras
      year-of-eraeraproleptic-yearISO proleptic-yearyear-of-eraeraproleptic-yearISO proleptic-year
      2ROC219132ROC21913
      1ROC119121ROC11912
      1BEFORE_ROC019111BEFORE_ROC01911
      2BEFORE_ROC-119102BEFORE_ROC-11910
      diff --git a/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java b/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java index 53cb5d870be..46c0f112bd5 100644 --- a/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java +++ b/jdk/src/java.base/share/classes/java/time/chrono/ThaiBuddhistEra.java @@ -71,28 +71,28 @@ import java.time.DateTimeException; * All previous years, zero or earlier in the proleptic count or one and greater * in the year-of-era count, are part of the 'Before Buddhist' era. * - * + *
      * * * - * - * - * - * + * + * + * + * * * * * - * + * * * - * + * * * - * + * * * - * + * * * *
      Buddhist years and eras
      year-of-eraeraproleptic-yearISO proleptic-yearyear-of-eraeraproleptic-yearISO proleptic-year
      2BE2-5422BE2-542
      1BE1-5431BE1-543
      1BEFORE_BE0-5441BEFORE_BE0-544
      2BEFORE_BE-1-5452BEFORE_BE-1-545
      diff --git a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java index 7315a9a3544..79d2f061508 100644 --- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java +++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java @@ -150,13 +150,13 @@ import java.util.Set; * implementation of {@code java.text.Format}. * *

      Predefined Formatters

      - * + *
      * * * - * - * - * + * + * + * * * * @@ -276,56 +276,60 @@ import java.util.Set; *

      * All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The * following pattern letters are defined: - *

      - *  Symbol  Meaning                     Presentation      Examples
      - *  ------  -------                     ------------      -------
      - *   G       era                         text              AD; Anno Domini; A
      - *   u       year                        year              2004; 04
      - *   y       year-of-era                 year              2004; 04
      - *   D       day-of-year                 number            189
      - *   M/L     month-of-year               number/text       7; 07; Jul; July; J
      - *   d       day-of-month                number            10
      - *   g       modified-julian-day         number            2451334
      + * 
      Predefined Formatters
      FormatterDescriptionExampleFormatterDescriptionExample
      + * + * + * + * + * + * + * + * + * + * + * + * * - * Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter - * Y week-based-year year 1996; 96 - * w week-of-week-based-year number 27 - * W week-of-month number 4 - * E day-of-week text Tue; Tuesday; T - * e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T - * F day-of-week-in-month number 3 + * + * + * + * + * + * + * * - * a am-pm-of-day text PM - * h clock-hour-of-am-pm (1-12) number 12 - * K hour-of-am-pm (0-11) number 0 - * k clock-hour-of-day (1-24) number 24 + * + * + * + * * - * H hour-of-day (0-23) number 0 - * m minute-of-hour number 30 - * s second-of-minute number 55 - * S fraction-of-second fraction 978 - * A milli-of-day number 1234 - * n nano-of-second number 987654321 - * N nano-of-day number 1234000000 + * + * + * + * + * + * + * * - * V time-zone ID zone-id America/Los_Angeles; Z; -08:30 - * v generic time-zone name zone-name Pacific Time; PT - * z time-zone name zone-name Pacific Standard Time; PST - * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00 - * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15 - * x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15 - * Z zone-offset offset-Z +0000; -0800; -08:00 + * + * + * + * + * + * + * * - * p pad next pad modifier 1 + * * - * ' escape for text delimiter - * '' single quote literal ' - * [ optional section start - * ] optional section end - * # reserved for future use - * { reserved for future use - * } reserved for future use - * + * + * + * + * + * + * + * + * + *
      Pattern Letters and Symbols
      Symbol Meaning Presentation Examples
      G era text AD; Anno Domini; A
      u year year 2004; 04
      y year-of-era year 2004; 04
      D day-of-year number 189
      M/L month-of-year number/text 7; 07; Jul; July; J
      d day-of-month number 10
      g modified-julian-day number 2451334
      Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
      Y week-based-year year 1996; 96
      w week-of-week-based-year number 27
      W week-of-month number 4
      E day-of-week text Tue; Tuesday; T
      e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
      F day-of-week-in-month number 3
      a am-pm-of-day text PM
      h clock-hour-of-am-pm (1-12) number 12
      K hour-of-am-pm (0-11) number 0
      k clock-hour-of-day (1-24) number 24
      H hour-of-day (0-23) number 0
      m minute-of-hour number 30
      s second-of-minute number 55
      S fraction-of-second fraction 978
      A milli-of-day number 1234
      n nano-of-second number 987654321
      N nano-of-day number 1234000000
      V time-zone ID zone-id America/Los_Angeles; Z; -08:30
      v generic time-zone name zone-name Pacific Time; PT
      z time-zone name zone-name Pacific Standard Time; PST
      O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00
      X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15
      x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15
      Z zone-offset offset-Z +0000; -0800; -08:00
      p pad next pad modifier 1
      ' escape for text delimiter
      '' single quote literal '
      [ optional section start
      ] optional section end
      # reserved for future use
      { reserved for future use
      } reserved for future use
      *

      * The count of pattern letters determines the format. *

      diff --git a/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java b/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java index 9740a9defc0..0b910830126 100644 --- a/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java +++ b/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java @@ -136,18 +136,18 @@ import sun.util.locale.provider.LocaleResources; *

      * For example: * - * + *
      * * - * + * * * - * - * - * - * - * - * + * + * + * + * + * + * * *
      Examples of Week based Years
      DateDay-of-weekField values
      DateDay-of-weekField values
      2008-12-28SundayWeek 52 of week-based-year 2008
      2008-12-29MondayWeek 1 of week-based-year 2009
      2008-12-31WednesdayWeek 1 of week-based-year 2009
      2009-01-01ThursdayWeek 1 of week-based-year 2009
      2009-01-04SundayWeek 1 of week-based-year 2009
      2009-01-05MondayWeek 2 of week-based-year 2009
      2008-12-28SundayWeek 52 of week-based-year 2008
      2008-12-29MondayWeek 1 of week-based-year 2009
      2008-12-31WednesdayWeek 1 of week-based-year 2009
      2009-01-01ThursdayWeek 1 of week-based-year 2009
      2009-01-04SundayWeek 1 of week-based-year 2009
      2009-01-05MondayWeek 2 of week-based-year 2009
      * diff --git a/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java b/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java index 2f13368d28f..60478772d9f 100644 --- a/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java +++ b/jdk/src/java.base/share/classes/java/time/temporal/WeekFields.java @@ -130,17 +130,17 @@ import sun.util.locale.provider.LocaleResources; * * * - * - * + * + * * * - * + * * - * + * * - * + * * - * + * * * *
      Examples of WeekFields
      DateDay-of-weekFirst day: Monday
      Minimal days: 4
      First day: Monday
      Minimal days: 5
      DateDay-of-weekFirst day: Monday
      Minimal days: 4
      First day: Monday
      Minimal days: 5
      2008-12-31Wednesday
      2008-12-31WednesdayWeek 5 of December 2008Week 5 of December 2008
      2009-01-01Thursday
      2009-01-01ThursdayWeek 1 of January 2009Week 0 of January 2009
      2009-01-04Sunday
      2009-01-04SundayWeek 1 of January 2009Week 0 of January 2009
      2009-01-05Monday
      2009-01-05MondayWeek 2 of January 2009Week 1 of January 2009
      @@ -164,17 +164,17 @@ import sun.util.locale.provider.LocaleResources; * * * - * - * + * + * * * - * + * * - * + * * - * + * * - * + * * * *
      Examples of WeekFields for week-based-year
      DateDay-of-weekFirst day: Monday
      Minimal days: 4
      First day: Monday
      Minimal days: 5
      DateDay-of-weekFirst day: Monday
      Minimal days: 4
      First day: Monday
      Minimal days: 5
      2008-12-31Wednesday
      2008-12-31WednesdayWeek 1 of 2009Week 53 of 2008
      2009-01-01Thursday
      2009-01-01ThursdayWeek 1 of 2009Week 53 of 2008
      2009-01-04Sunday
      2009-01-04SundayWeek 1 of 2009Week 53 of 2008
      2009-01-05Monday
      2009-01-05MondayWeek 2 of 2009Week 1 of 2009
      diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 8149d0877dd..82e4b987781 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -35,8 +35,7 @@ package java.util.concurrent; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.VarHandle; +import java.lang.reflect.Field; import java.util.AbstractSet; import java.util.Collection; import java.util.Collections; @@ -506,19 +505,21 @@ public class ConcurrentSkipListSet : ((ConcurrentSkipListMap.SubMap)m).new SubMapKeyIterator(); } - // Support for resetting map in clone + /** Initializes map field; for use in clone. */ private void setMap(ConcurrentNavigableMap map) { - MAP.setVolatile(this, map); - } - - // VarHandle mechanics - private static final VarHandle MAP; - static { + Field mapField = java.security.AccessController.doPrivileged( + (java.security.PrivilegedAction) () -> { + try { + Field f = ConcurrentSkipListSet.class + .getDeclaredField("m"); + f.setAccessible(true); + return f; + } catch (ReflectiveOperationException e) { + throw new Error(e); + }}); try { - MethodHandles.Lookup l = MethodHandles.lookup(); - MAP = l.findVarHandle(ConcurrentSkipListSet.class, "m", - ConcurrentNavigableMap.class); - } catch (ReflectiveOperationException e) { + mapField.set(this, map); + } catch (IllegalAccessException e) { throw new Error(e); } } diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java b/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java index 65e994350ce..1aefaea43b0 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/Flow.java @@ -85,9 +85,9 @@ package java.util.concurrent; * this.executor = executor; * } * public synchronized void request(long n) { - * if (n != 0 && !completed) { + * if (!completed) { * completed = true; - * if (n < 0) { + * if (n <= 0) { * IllegalArgumentException ex = new IllegalArgumentException(); * executor.execute(() -> subscriber.onError(ex)); * } else { diff --git a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java index 1b3b866b25c..21221005f52 100644 --- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java @@ -576,7 +576,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { private static final RuntimePermission shutdownPerm = new RuntimePermission("modifyThread"); - /* The context to be used when executing the finalizer, or null. */ + /** The context to be used when executing the finalizer, or null. */ private final AccessControlContext acc; /** @@ -1314,9 +1314,9 @@ public class ThreadPoolExecutor extends AbstractExecutorService { throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); - this.acc = System.getSecurityManager() == null ? - null : - AccessController.getContext(); + this.acc = (System.getSecurityManager() == null) + ? null + : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java index 8c682a813b6..e618ef18a78 100644 --- a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java @@ -81,13 +81,24 @@ class ZipUtils { * Converts DOS time to Java time (number of milliseconds since epoch). */ public static long dosToJavaTime(long dtime) { - LocalDateTime ldt = LocalDateTime.of( - (int) (((dtime >> 25) & 0x7f) + 1980), - (int) ((dtime >> 21) & 0x0f), - (int) ((dtime >> 16) & 0x1f), - (int) ((dtime >> 11) & 0x1f), - (int) ((dtime >> 5) & 0x3f), - (int) ((dtime << 1) & 0x3e)); + int year; + int month; + int day; + int hour = (int) ((dtime >> 11) & 0x1f); + int minute = (int) ((dtime >> 5) & 0x3f); + int second = (int) ((dtime << 1) & 0x3e); + if ((dtime >> 16) == 0) { + // Interpret the 0 DOS date as 1979-11-30 for compatibility with + // other implementations. + year = 1979; + month = 11; + day = 30; + } else { + year = (int) (((dtime >> 25) & 0x7f) + 1980); + month = (int) ((dtime >> 21) & 0x0f); + day = (int) ((dtime >> 16) & 0x1f); + } + LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second); return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond( ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS); } diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java index b765128cd85..3eec4282ba6 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java @@ -1292,7 +1292,7 @@ public abstract class SSLEngine { * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 , the * Application-Layer Protocol Negotiation (ALPN), can negotiate * application-level values between peers. - *

      + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. @@ -1317,7 +1317,7 @@ public abstract class SSLEngine { * Like {@link #getHandshakeSession()}, * a connection may be in the middle of a handshake. The * application protocol may or may not yet be available. - *

      + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java index 19b05f9de8a..1c3c947035e 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java @@ -646,7 +646,7 @@ public class SSLParameters { * requested by the peer, the underlying protocol will determine what * action to take. (For example, ALPN will send a * {@code "no_application_protocol"} alert and terminate the connection.) - *

      + * * @implSpec * This method will make a copy of the {@code protocols} array. * diff --git a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java index 6f8e20d9538..ccaea95b167 100644 --- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java +++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java @@ -702,7 +702,7 @@ public abstract class SSLSocket extends Socket * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 , the * Application-Layer Protocol Negotiation (ALPN), can negotiate * application-level values between peers. - *

      + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. @@ -727,7 +727,7 @@ public abstract class SSLSocket extends Socket * Like {@link #getHandshakeSession()}, * a connection may be in the middle of a handshake. The * application protocol may or may not yet be available. - *

      + * * @implSpec * The implementation in this class throws * {@code UnsupportedOperationException} and performs no other action. diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputFilterAccess.java b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputFilterAccess.java new file mode 100644 index 00000000000..5edb4c778e4 --- /dev/null +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputFilterAccess.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.misc; + +import java.io.ObjectInputFilter; + +/** + * Access to the alternative ObjectInputFilter.Config.createFilter2 for RMI. + */ +public interface JavaObjectInputFilterAccess { + /** + * Creates a filter from the pattern. + */ + ObjectInputFilter createFilter2(String pattern); +} diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java index cd54d422c21..0f60833ec78 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java @@ -25,6 +25,7 @@ package jdk.internal.misc; +import java.io.ObjectInputFilter; import java.lang.module.ModuleDescriptor; import java.util.ResourceBundle; import java.util.jar.JarFile; @@ -70,6 +71,7 @@ public class SharedSecrets { private static JavaAWTFontAccess javaAWTFontAccess; private static JavaBeansAccess javaBeansAccess; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; + private static JavaObjectInputFilterAccess javaObjectInputFilterAccess; private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess; public static JavaUtilJarAccess javaUtilJarAccess() { @@ -315,6 +317,17 @@ public class SharedSecrets { javaObjectInputStreamAccess = access; } + public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() { + if (javaObjectInputFilterAccess == null) { + unsafe.ensureClassInitialized(ObjectInputFilter.Config.class); + } + return javaObjectInputFilterAccess; + } + + public static void setJavaObjectInputFilterAccess(JavaObjectInputFilterAccess access) { + javaObjectInputFilterAccess = access; + } + public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) { javaIORandomAccessFileAccess = jirafa; } diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java index ec5e59c07fc..dac650b1451 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -3071,8 +3071,14 @@ public final class Main { private String withWeak(PublicKey key) { if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - return String.format(rb.getString("key.bit"), - KeyUtil.getKeySize(key), key.getAlgorithm()); + int kLen = KeyUtil.getKeySize(key); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), + kLen, key.getAlgorithm()); + } else { + return String.format( + rb.getString("unknown.size.1"), key.getAlgorithm()); + } } else { return String.format(rb.getString("key.bit.weak"), KeyUtil.getKeySize(key), key.getAlgorithm()); diff --git a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java index a78eb6bc3e6..9bdd95cbda0 100644 --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java @@ -462,6 +462,7 @@ public class Resources extends java.util.ListResourceBundle { {"with.weak", "%s (weak)"}, {"key.bit", "%d-bit %s key"}, {"key.bit.weak", "%d-bit %s key (weak)"}, + {"unknown.size.1", "unknown size %s key"}, {".PATTERN.printX509Cert.with.weak", "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8}\nVersion: {9}"}, {"PKCS.10.with.weak", diff --git a/jdk/src/java.base/share/conf/security/java.security b/jdk/src/java.base/share/conf/security/java.security index 5ddf6198819..2ea7c3616d3 100644 --- a/jdk/src/java.base/share/conf/security/java.security +++ b/jdk/src/java.base/share/conf/security/java.security @@ -951,12 +951,36 @@ jdk.xml.dsig.secureValidationPolicy=\ # # The filter pattern uses the same format as jdk.serialFilter. # This filter can override the builtin filter if additional types need to be -# allowed or rejected from the RMI Registry. +# allowed or rejected from the RMI Registry or to decrease limits but not +# to increase limits. +# If the limits (maxdepth, maxrefs, or maxbytes) are exceeded, the object is rejected. +# +# Each non-array type is allowed or rejected if it matches one of the patterns, +# evaluated from left to right, and is otherwise allowed. Arrays of any +# component type, including subarrays and arrays of primitives, are allowed. +# +# Array construction of any component type, including subarrays and arrays of +# primitives, are allowed unless the length is greater than the maxarray limit. +# The filter is applied to each array element. # # Note: This property is currently used by the JDK Reference implementation. # It is not guaranteed to be examined and used by other implementations. # -#sun.rmi.registry.registryFilter=pattern;pattern +# The built-in filter allows subclasses of allowed classes and +# can approximately be represented as the pattern: +# +#sun.rmi.registry.registryFilter=\ +# maxarray=1000000;\ +# maxdepth=20;\ +# java.lang.String;\ +# java.lang.Number;\ +# java.lang.reflect.Proxy;\ +# java.rmi.Remote;\ +# sun.rmi.server.UnicastRef;\ +# sun.rmi.server.RMIClientSocketFactory;\ +# sun.rmi.server.RMIServerSocketFactory;\ +# java.rmi.activation.ActivationID;\ +# java.rmi.server.UID # # RMI Distributed Garbage Collector (DGC) Serial Filter # diff --git a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java index 74bda0a928f..31c5e74c624 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -1887,13 +1887,17 @@ public class LogManager { * The registered {@linkplain #addConfigurationListener configuration * listeners} will be invoked after the configuration is successfully updated. *

      - * + *
      Updating configuration properties
      + * + * * - * - * + * + * * + * + * * - * + * * * - * + * * * * - * + * * * * - * + * * * * - * + * * * + * *
      Updating configuration properties
      PropertyResulting BehaviorPropertyResulting Behavior
      {@code .level}{@code .level} *
        *
      • If the resulting configuration defines a level for a logger and @@ -1914,7 +1918,7 @@ public class LogManager { *
      *
      {@code .useParentHandlers}{@code .useParentHandlers} *
        *
      • If either the resulting or the old value for the useParentHandlers @@ -1928,7 +1932,7 @@ public class LogManager { *
      {@code .handlers}{@code .handlers} *
        *
      • If the resulting configuration defines a list of handlers for a @@ -1952,7 +1956,7 @@ public class LogManager { *
      {@code .*}{@code .*} *
        *
      • Properties configured/changed on handler classes will only affect @@ -1964,7 +1968,7 @@ public class LogManager { *
      {@code config} and any other property{@code config} and any other property *
        *
      • The resulting value for these property will be stored in the @@ -1974,6 +1978,7 @@ public class LogManager { *
      *
      *

      * Example mapper functions: diff --git a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java index dea269302d2..6a1d4b5bc30 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1497,7 +1497,7 @@ public class Logger { * The {@code msg} string is localized using the given resource bundle. * If the resource bundle is {@code null}, then the {@code msg} string is not * localized. - *

      + * * @param level One of the message level identifiers, e.g., {@code SEVERE} * @param bundle Resource bundle to localize {@code msg}; * can be {@code null}. @@ -1614,7 +1614,7 @@ public class Logger { * processed specially by output {@code Formatter} objects and is not treated * as a formatting parameter to the {@code LogRecord} {@code message} * property. - *

      + * * @param level One of the message level identifiers, e.g., {@code SEVERE} * @param bundle Resource bundle to localize {@code msg}; * can be {@code null}. diff --git a/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java b/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java index fe81640654b..2324940502e 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/SimpleFormatter.java @@ -41,7 +41,7 @@ import jdk.internal.logger.SurrogateLogger; * The {@code SimpleFormatter} is initialized with the * format string * specified in the {@code java.util.logging.SimpleFormatter.format} - * property to {@linkplain #format format} the log messages. + * property to {@linkplain #format(LogRecord) format} the log messages. * This property can be defined * in the {@linkplain LogManager#getProperty logging properties} * configuration file diff --git a/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java b/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java index af012faeb78..f6f486f80a5 100644 --- a/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java @@ -28,7 +28,6 @@ package sun.rmi.registry; import java.io.ObjectInputFilter; import java.nio.file.Path; import java.nio.file.Paths; -import java.rmi.server.LogStream; import java.security.PrivilegedAction; import java.security.Security; import java.util.ArrayList; @@ -58,6 +57,7 @@ import java.security.Permissions; import java.security.ProtectionDomain; import java.text.MessageFormat; +import jdk.internal.misc.SharedSecrets; import sun.rmi.runtime.Log; import sun.rmi.server.UnicastRef; import sun.rmi.server.UnicastServerRef; @@ -109,7 +109,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer private static final int REGISTRY_MAX_DEPTH = 20; /** Registry maximum array size in remote invocations. **/ - private static final int REGISTRY_MAX_ARRAY_SIZE = 10000; + private static final int REGISTRY_MAX_ARRAY_SIZE = 1_000_000; /** * The registryFilter created from the value of the {@code "sun.rmi.registry.registryFilter"} @@ -130,7 +130,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer props = Security.getProperty(REGISTRY_FILTER_PROPNAME); } if (props != null) { - filter = ObjectInputFilter.Config.createFilter(props); + filter = SharedSecrets.getJavaObjectInputFilterAccess().createFilter2(props); Log regLog = Log.getLog("sun.rmi.registry", "registry", -1); if (regLog.isLoggable(Log.BRIEF)) { regLog.log(Log.BRIEF, "registryFilter = " + filter); @@ -451,17 +451,10 @@ public class RegistryImpl extends java.rmi.server.RemoteServer Class clazz = filterInfo.serialClass(); if (clazz != null) { if (clazz.isArray()) { - if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) { - return ObjectInputFilter.Status.REJECTED; - } - do { - // Arrays are allowed depending on the component type - clazz = clazz.getComponentType(); - } while (clazz.isArray()); - } - if (clazz.isPrimitive()) { - // Arrays of primitives are allowed - return ObjectInputFilter.Status.ALLOWED; + // Arrays are REJECTED only if they exceed the limit + return (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) + ? ObjectInputFilter.Status.REJECTED + : ObjectInputFilter.Status.UNDECIDED; } if (String.class == clazz || java.lang.Number.class.isAssignableFrom(clazz) diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java new file mode 100644 index 00000000000..07223e61f25 --- /dev/null +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AbstractAsyncSSLConnection.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.http; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.util.concurrent.CompletableFuture; +import javax.net.ssl.SSLEngine; +import jdk.incubator.http.internal.common.ExceptionallyCloseable; + + +/** + * Asynchronous version of SSLConnection. + * + * There are two concrete implementations of this class: AsyncSSLConnection + * and AsyncSSLTunnelConnection. + * This abstraction is useful when downgrading from HTTP/2 to HTTP/1.1 over + * an SSL connection. See ExchangeImpl::get in the case where an ALPNException + * is thrown. + * + * Note: An AsyncSSLConnection wraps a PlainHttpConnection, while an + * AsyncSSLTunnelConnection wraps a PlainTunnelingConnection. + * If both these wrapped classes where made to inherit from a + * common abstraction then it might be possible to merge + * AsyncSSLConnection and AsyncSSLTunnelConnection back into + * a single class - and simply use different factory methods to + * create different wrappees, but this is left up for further cleanup. + * + */ +abstract class AbstractAsyncSSLConnection extends HttpConnection + implements AsyncConnection, ExceptionallyCloseable { + + + AbstractAsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client) { + super(addr, client); + } + + abstract SSLEngine getEngine(); + abstract AsyncSSLDelegate sslDelegate(); + abstract HttpConnection plainConnection(); + abstract HttpConnection downgrade(); + + @Override + final boolean isSecure() { + return true; + } + + // Blocking read functions not used here + @Override + protected final ByteBuffer readImpl() throws IOException { + throw new UnsupportedOperationException("Not supported."); + } + + // whenReceivedResponse only used in HTTP/1.1 (Http1Exchange) + // AbstractAsyncSSLConnection is only used with HTTP/2 + @Override + final CompletableFuture whenReceivingResponse() { + throw new UnsupportedOperationException("Not supported."); + } + +} diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java index b1e6063951f..f6c095526ee 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLConnection.java @@ -35,14 +35,12 @@ import java.util.function.Supplier; import javax.net.ssl.SSLEngine; import jdk.incubator.http.internal.common.ByteBufferReference; -import jdk.incubator.http.internal.common.ExceptionallyCloseable; import jdk.incubator.http.internal.common.Utils; /** * Asynchronous version of SSLConnection. */ -class AsyncSSLConnection extends HttpConnection - implements AsyncConnection, ExceptionallyCloseable { +class AsyncSSLConnection extends AbstractAsyncSSLConnection { final AsyncSSLDelegate sslDelegate; final PlainHttpConnection plainConnection; @@ -61,15 +59,14 @@ class AsyncSSLConnection extends HttpConnection plainConnection.configureMode(mode); } - private CompletableFuture configureModeAsync(Void ignore) { - CompletableFuture cf = new CompletableFuture<>(); - try { - configureMode(Mode.ASYNC); - cf.complete(null); - } catch (Throwable t) { - cf.completeExceptionally(t); - } - return cf; + @Override + PlainHttpConnection plainConnection() { + return plainConnection; + } + + @Override + AsyncSSLDelegate sslDelegate() { + return sslDelegate; } @Override @@ -91,11 +88,6 @@ class AsyncSSLConnection extends HttpConnection return plainConnection.connected() && sslDelegate.connected(); } - @Override - boolean isSecure() { - return true; - } - @Override boolean isProxied() { return false; @@ -172,6 +164,7 @@ class AsyncSSLConnection extends HttpConnection plainConnection.channel().shutdownOutput(); } + @Override SSLEngine getEngine() { return sslDelegate.getEngine(); } @@ -184,18 +177,6 @@ class AsyncSSLConnection extends HttpConnection plainConnection.setAsyncCallbacks(sslDelegate::asyncReceive, errorReceiver, sslDelegate::getNetBuffer); } - // Blocking read functions not used here - - @Override - protected ByteBuffer readImpl() throws IOException { - throw new UnsupportedOperationException("Not supported."); - } - - @Override - CompletableFuture whenReceivingResponse() { - throw new UnsupportedOperationException("Not supported."); - } - @Override public void startReading() { plainConnection.startReading(); @@ -206,4 +187,9 @@ class AsyncSSLConnection extends HttpConnection public void stopAsyncReading() { plainConnection.stopAsyncReading(); } + + @Override + SSLConnection downgrade() { + return new SSLConnection(this); + } } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java new file mode 100644 index 00000000000..7afb87f5191 --- /dev/null +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLTunnelConnection.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.incubator.http; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Supplier; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import jdk.incubator.http.internal.common.ByteBufferReference; +import jdk.incubator.http.internal.common.Utils; + +/** + * An SSL tunnel built on a Plain (CONNECT) TCP tunnel. + */ +class AsyncSSLTunnelConnection extends AbstractAsyncSSLConnection { + + final PlainTunnelingConnection plainConnection; + final AsyncSSLDelegate sslDelegate; + final String serverName; + + @Override + public void connect() throws IOException, InterruptedException { + plainConnection.connect(); + configureMode(Mode.ASYNC); + startReading(); + sslDelegate.connect(); + } + + @Override + boolean connected() { + return plainConnection.connected() && sslDelegate.connected(); + } + + @Override + public CompletableFuture connectAsync() { + throw new InternalError(); + } + + AsyncSSLTunnelConnection(InetSocketAddress addr, + HttpClientImpl client, + String[] alpn, + InetSocketAddress proxy) + { + super(addr, client); + this.serverName = Utils.getServerName(addr); + this.plainConnection = new PlainTunnelingConnection(addr, proxy, client); + this.sslDelegate = new AsyncSSLDelegate(plainConnection, client, alpn, serverName); + } + + @Override + synchronized void configureMode(Mode mode) throws IOException { + super.configureMode(mode); + plainConnection.configureMode(mode); + } + + @Override + SSLParameters sslParameters() { + return sslDelegate.getSSLParameters(); + } + + @Override + public String toString() { + return "AsyncSSLTunnelConnection: " + super.toString(); + } + + @Override + PlainTunnelingConnection plainConnection() { + return plainConnection; + } + + @Override + AsyncSSLDelegate sslDelegate() { + return sslDelegate; + } + + @Override + ConnectionPool.CacheKey cacheKey() { + return ConnectionPool.cacheKey(address, plainConnection.proxyAddr); + } + + @Override + long write(ByteBuffer[] buffers, int start, int number) throws IOException { + //debugPrint("Send", buffers, start, number); + ByteBuffer[] bufs = Utils.reduce(buffers, start, number); + long n = Utils.remaining(bufs); + sslDelegate.writeAsync(ByteBufferReference.toReferences(bufs)); + sslDelegate.flushAsync(); + return n; + } + + @Override + long write(ByteBuffer buffer) throws IOException { + //debugPrint("Send", buffer); + long n = buffer.remaining(); + sslDelegate.writeAsync(ByteBufferReference.toReferences(buffer)); + sslDelegate.flushAsync(); + return n; + } + + @Override + public void writeAsync(ByteBufferReference[] buffers) throws IOException { + sslDelegate.writeAsync(buffers); + } + + @Override + public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { + sslDelegate.writeAsyncUnordered(buffers); + } + + @Override + public void flushAsync() throws IOException { + sslDelegate.flushAsync(); + } + + @Override + public void close() { + Utils.close(sslDelegate, plainConnection.channel()); + } + + @Override + void shutdownInput() throws IOException { + plainConnection.channel().shutdownInput(); + } + + @Override + void shutdownOutput() throws IOException { + plainConnection.channel().shutdownOutput(); + } + + @Override + SocketChannel channel() { + return plainConnection.channel(); + } + + @Override + boolean isProxied() { + return true; + } + + @Override + public void setAsyncCallbacks(Consumer asyncReceiver, + Consumer errorReceiver, + Supplier readBufferSupplier) { + sslDelegate.setAsyncCallbacks(asyncReceiver, errorReceiver, readBufferSupplier); + plainConnection.setAsyncCallbacks(sslDelegate::asyncReceive, errorReceiver, sslDelegate::getNetBuffer); + } + + @Override + public void startReading() { + plainConnection.startReading(); + sslDelegate.startReading(); + } + + @Override + public void stopAsyncReading() { + plainConnection.stopAsyncReading(); + } + + @Override + public void enableCallback() { + sslDelegate.enableCallback(); + } + + @Override + public void closeExceptionally(Throwable cause) throws IOException { + Utils.close(cause, sslDelegate, plainConnection.channel()); + } + + @Override + SSLEngine getEngine() { + return sslDelegate.getEngine(); + } + + @Override + SSLTunnelConnection downgrade() { + return new SSLTunnelConnection(this); + } +} diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java index 27b6c1964f4..3d41179d903 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ExchangeImpl.java @@ -82,9 +82,9 @@ abstract class ExchangeImpl { c = c2.getConnectionFor(request); } catch (Http2Connection.ALPNException e) { // failed to negotiate "h2" - AsyncSSLConnection as = e.getConnection(); + AbstractAsyncSSLConnection as = e.getConnection(); as.stopAsyncReading(); - SSLConnection sslc = new SSLConnection(as); + HttpConnection sslc = as.downgrade(); ExchangeImpl ex = new Http1Exchange<>(exchange, sslc); return ex; } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java index 275325f8b29..8e42022c286 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/Http2Connection.java @@ -211,12 +211,13 @@ class Http2Connection { this.hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE)); this.windowUpdater = new ConnectionWindowUpdateSender(this, client.getReceiveBufferSize()); } - /** - * Case 1) Create from upgraded HTTP/1.1 connection. - * Is ready to use. Will not be SSL. exchange is the Exchange - * that initiated the connection, whose response will be delivered - * on a Stream. - */ + + /** + * Case 1) Create from upgraded HTTP/1.1 connection. + * Is ready to use. Will not be SSL. exchange is the Exchange + * that initiated the connection, whose response will be delivered + * on a Stream. + */ Http2Connection(HttpConnection connection, Http2ClientImpl client2, Exchange exchange, @@ -280,7 +281,7 @@ class Http2Connection { * Throws an IOException if h2 was not negotiated */ private void checkSSLConfig() throws IOException { - AsyncSSLConnection aconn = (AsyncSSLConnection)connection; + AbstractAsyncSSLConnection aconn = (AbstractAsyncSSLConnection)connection; SSLEngine engine = aconn.getEngine(); String alpn = engine.getApplicationProtocol(); if (alpn == null || !alpn.equals("h2")) { @@ -906,14 +907,14 @@ class Http2Connection { */ static final class ALPNException extends IOException { private static final long serialVersionUID = 23138275393635783L; - final AsyncSSLConnection connection; + final AbstractAsyncSSLConnection connection; - ALPNException(String msg, AsyncSSLConnection connection) { + ALPNException(String msg, AbstractAsyncSSLConnection connection) { super(msg); this.connection = connection; } - AsyncSSLConnection getConnection() { + AbstractAsyncSSLConnection getConnection() { return connection; } } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java index 96bd67f969e..d81d3950374 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpConnection.java @@ -34,7 +34,6 @@ import java.nio.channels.SocketChannel; import java.util.concurrent.CompletableFuture; import jdk.incubator.http.internal.common.ByteBufferReference; -import jdk.incubator.http.internal.common.Utils; /** * Wraps socket channel layer and takes care of SSL also. @@ -136,7 +135,11 @@ abstract class HttpConnection implements Closeable { String[] alpn, boolean isHttp2, HttpClientImpl client) { if (proxy != null) { - return new SSLTunnelConnection(addr, client, proxy); + if (!isHttp2) { + return new SSLTunnelConnection(addr, client, proxy); + } else { + return new AsyncSSLTunnelConnection(addr, client, alpn, proxy); + } } else if (!isHttp2) { return new SSLConnection(addr, client, alpn); } else { @@ -154,6 +157,12 @@ abstract class HttpConnection implements Closeable { { HttpConnection c = null; InetSocketAddress proxy = request.proxy(client); + if (proxy != null && proxy.isUnresolved()) { + // The default proxy selector may select a proxy whose + // address is unresolved. We must resolve the address + // before using it to connect. + proxy = new InetSocketAddress(proxy.getHostString(), proxy.getPort()); + } boolean secure = request.secure(); ConnectionPool pool = client.connectionPool(); String[] alpn = null; diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java index d133df1e250..c167c53f2b3 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/PlainTunnelingConnection.java @@ -34,12 +34,15 @@ import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Supplier; /** * A plain text socket tunnel through a proxy. Uses "CONNECT" but does not - * encrypt. Used by WebSocket. Subclassed in SSLTunnelConnection for encryption. + * encrypt. Used by WebSocket, as well as HTTP over SSL + Proxy. + * Wrapped in SSLTunnelConnection or AsyncSSLTunnelConnection for encryption. */ -class PlainTunnelingConnection extends HttpConnection { +class PlainTunnelingConnection extends HttpConnection implements AsyncConnection { final PlainHttpConnection delegate; protected final InetSocketAddress proxyAddr; @@ -116,17 +119,17 @@ class PlainTunnelingConnection extends HttpConnection { } @Override - void writeAsync(ByteBufferReference[] buffers) throws IOException { + public void writeAsync(ByteBufferReference[] buffers) throws IOException { delegate.writeAsync(buffers); } @Override - void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { + public void writeAsyncUnordered(ByteBufferReference[] buffers) throws IOException { delegate.writeAsyncUnordered(buffers); } @Override - void flushAsync() throws IOException { + public void flushAsync() throws IOException { delegate.flushAsync(); } @@ -165,4 +168,32 @@ class PlainTunnelingConnection extends HttpConnection { boolean isProxied() { return true; } + + @Override + public void setAsyncCallbacks(Consumer asyncReceiver, + Consumer errorReceiver, + Supplier readBufferSupplier) { + delegate.setAsyncCallbacks(asyncReceiver, errorReceiver, readBufferSupplier); + } + + @Override + public void startReading() { + delegate.startReading(); + } + + @Override + public void stopAsyncReading() { + delegate.stopAsyncReading(); + } + + @Override + public void enableCallback() { + delegate.enableCallback(); + } + + @Override + synchronized void configureMode(Mode mode) throws IOException { + super.configureMode(mode); + delegate.configureMode(mode); + } } diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java index 790d98b7fa0..9eb6a37e250 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLConnection.java @@ -77,8 +77,8 @@ class SSLConnection extends HttpConnection { */ SSLConnection(AsyncSSLConnection c) { super(c.address, c.client); - this.delegate = c.plainConnection; - AsyncSSLDelegate adel = c.sslDelegate; + this.delegate = c.plainConnection(); + AsyncSSLDelegate adel = c.sslDelegate(); this.sslDelegate = new SSLDelegate(adel.engine, delegate.channel(), client, adel.serverName); this.alpn = adel.alpn; this.serverName = adel.serverName; diff --git a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java index fcd71728b5b..d5cade109b7 100644 --- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java +++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLTunnelConnection.java @@ -85,6 +85,19 @@ class SSLTunnelConnection extends HttpConnection { delegate = new PlainTunnelingConnection(addr, proxy, client); } + /** + * Create an SSLTunnelConnection from an existing connected AsyncSSLTunnelConnection. + * Used when downgrading from HTTP/2 to HTTP/1.1 + */ + SSLTunnelConnection(AsyncSSLTunnelConnection c) { + super(c.address, c.client); + this.delegate = c.plainConnection(); + AsyncSSLDelegate adel = c.sslDelegate(); + this.sslDelegate = new SSLDelegate(adel.engine, delegate.channel(), client, adel.serverName); + this.serverName = adel.serverName; + connected = c.connected(); + } + @Override SSLParameters sslParameters() { return sslDelegate.getSSLParameters(); diff --git a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index cb86682f7da..12d4e1ba380 100644 --- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -1088,8 +1088,12 @@ public class Main { private String withWeak(PublicKey key) { if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - return String.format( - rb.getString("key.bit"), KeyUtil.getKeySize(key)); + int kLen = KeyUtil.getKeySize(key); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), kLen); + } else { + return rb.getString("unknown.size"); + } } else { seeWeak = true; return String.format( diff --git a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index 26e0553ebb2..ebdd79d792e 100644 --- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -164,6 +164,7 @@ public class Resources extends java.util.ListResourceBundle { {"with.weak", "%s (weak)"}, {"key.bit", "%d-bit key"}, {"key.bit.weak", "%d-bit key (weak)"}, + {"unknown.size", "unknown size"}, {"jarsigner.", "jarsigner: "}, {"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.", diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java index 5351594c952..422a7cbfce8 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java @@ -28,7 +28,6 @@ package com.sun.jdi; /** * Thrown to indicate that the requested module is invalid * or became invalid after the module was unloaded. - *

      * * @since 9 */ diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java index 8f9b4da9980..2c80497d3f1 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/JDIPermission.java @@ -40,17 +40,20 @@ package com.sun.jdi; * permission allows, and discusses the risks of granting code the * permission. * - * + *
      * + * * - * - * - * + * + * + * * + * * + * * - * + * * @@ -59,6 +62,7 @@ package com.sun.jdi; * misbehave. * * + * * *
      Table shows permission target name, what the * permission allows, and associated risks
      Permission Target NameWhat the Permission AllowsRisks of Allowing this PermissionPermission Target NameWhat the Permission AllowsRisks of Allowing this Permission
      virtualMachineManagervirtualMachineManagerAbility to inspect and modify the JDI objects in the * {@code VirtualMachineManager} *
      * diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java index 50ad02747e8..0eb7eae3e0e 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Type.java @@ -43,79 +43,86 @@ package com.sun.jdi; * {@link ArrayType#componentType()} * *

      - * The following table illustrates which subinterfaces of Type + * The following tables illustrate which subinterfaces of Type * are used to mirror types in the target VM -- - * - * - * - * - * - * - * + *
      Maps each type declared in target to a mirrored - * instance of a subinterface of PrimitiveType or ReferenceType"
      Subinterfaces of {@link PrimitiveType}
      Type declared in target asIs mirrored as an instance of
      + * + * * - * - * + * + * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * + * + * * - * - * - * - * - * - * - * - * + * + * * - * - * - * + * + * + * + *
      Subinterfaces of {@link PrimitiveType}
      boolean {@link BooleanType}Type declared in target asIs mirrored as an instance of
      byte{@link ByteType}boolean {@link BooleanType}
      char{@link CharType}byte{@link ByteType}
      double{@link DoubleType}char{@link CharType}
      float{@link FloatType}double{@link DoubleType}
      int{@link IntegerType}float{@link FloatType}
      long{@link LongType}int{@link IntegerType}
      short{@link ShortType}long{@link LongType}
      void{@link VoidType}
      Subinterfaces of {@link ReferenceType}
      Type declared in target asFor exampleIs mirrored as an instance ofshort{@link ShortType}
      a classDate{@link ClassType}void{@link VoidType}
      + * + * + * + * * - * - * - * + * + * + * + * + * * - * - * - * + * + * + * * - * - * - * + * + * + * + * + * + * + * + * + * + * * - * - * - * + * * - * - * - * + * + * *
      Subinterfaces of {@link ReferenceType}
      an interfaceRunnable{@link InterfaceType}Type declared in target asFor exampleIs mirrored as an instance of
      an array {@link ArrayType}a classDate{@link ClassType}
      an arrayint[]{@link ArrayType} whose + * an interfaceRunnable{@link InterfaceType}
      an array(any){@link ArrayType}
      int[]{@link ArrayType} whose * {@link ArrayType#componentType() componentType()} is * {@link IntegerType}
      an arrayDate[]{@link ArrayType} whose + * + * Date[]{@link ArrayType} whose * {@link ArrayType#componentType() componentType()} is * {@link ClassType}
      an arrayRunnable[]{@link ArrayType} whose + * + * Runnable[]{@link ArrayType} whose * {@link ArrayType#componentType() componentType()} is * {@link InterfaceType}
      * * @see PrimitiveType Subinterface PrimitiveType diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java index 99568fe60bc..42afbc2bfdf 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/Value.java @@ -33,7 +33,7 @@ import com.sun.jdi.event.ModificationWatchpointEvent; * value hierarchy encompassing primitive values and object values. *

      * Some examples of where values may be accessed: - *

      + *
      layout
      * *
      {@link ObjectReference#getValue(Field) * ObjectReference.getValue(Field)} @@ -52,117 +52,130 @@ import com.sun.jdi.event.ModificationWatchpointEvent; * - returned with an event *
      *

      - * The following table illustrates which subinterfaces of Value + * The following tables illustrate which subinterfaces of Value * are used to mirror values in the target VM -- - * - * - * - * - * - * - * - * - * + *
      Maps each kind of value to a mirrored - * instance of a subinterface of Value
      Subinterfaces of {@link PrimitiveValue}
      Kind of valueFor example -
      expression in target
      Is mirrored as an
      instance of
      {@link Type} of value
      {@link #type() Value.type()}
      + * + * * - * - * - * - * + * + * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * + * + *
      Subinterfaces of {@link PrimitiveValue}
      a boolean {@code true} {@link BooleanValue} {@link BooleanType}Kind of valueFor example -
      expression in target
      Is mirrored as an
      instance of
      {@link Type} of value
      {@link #type() Value.type()}
      a byte {@code (byte)4} {@link ByteValue} {@link ByteType}a boolean{@code true}{@link BooleanValue}{@link BooleanType}
      a char {@code 'a'} {@link CharValue} {@link CharType}a byte{@code (byte)4}{@link ByteValue}{@link ByteType}
      a double {@code 3.1415926} {@link DoubleValue} {@link DoubleType}a char{@code 'a'}{@link CharValue}{@link CharType}
      a float {@code 2.5f} {@link FloatValue} {@link FloatType}a double{@code 3.1415926}{@link DoubleValue}{@link DoubleType}
      an int {@code 22} {@link IntegerValue} {@link IntegerType}a float{@code 2.5f}{@link FloatValue}{@link FloatType}
      a long {@code 1024L} {@link LongValue} {@link LongType}an int{@code 22}{@link IntegerValue}{@link IntegerType}
      a short {@code (short)12} {@link ShortValue} {@link ShortType}a long{@code 1024L}{@link LongValue}{@link LongType}
      a void {@link VoidValue} {@link VoidType}
      Subinterfaces of {@link ObjectReference}
      Kind of valueFor example -
      expression in target
      Is mirrored as an
      instance of
      {@link Type} of value
      {@link #type() Value.type()}
      a short{@code (short)12}{@link ShortValue}{@link ShortType}
      a class instance {@code this} {@link ObjectReference} {@link ClassType}a void{@link VoidValue}{@link VoidType}
      + * + * + * + * * - * - * - * - * + * + * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * * - * - * - * - * - * - * - * - * - * - * - * + * + * + * + * * - * - * - * - * + * + * + * + * + * + * + * + * + * + * + *
      Subinterfaces of {@link ObjectReference}
      an array {@code new int[5]} {@link ArrayReference} {@link ArrayType}Kind of valueFor example -
      expression in target
      Is mirrored as an
      instance of
      {@link Type} of value
      {@link #type() Value.type()}
      a string {@code "hello"} {@link StringReference} {@link ClassType}a class instance{@code this}{@link ObjectReference}{@link ClassType}
      a thread {@code Thread.currentThread()} {@link ThreadReference} {@link ClassType}an array{@code new int[5]}{@link ArrayReference}{@link ArrayType}
      a thread group {@code Thread.currentThread()}
        {@code .getThreadGroup()}
      {@link ThreadGroupReference} {@link ClassType}a string{@code "hello"}{@link StringReference}{@link ClassType}
      a {@code java.lang.Class}
      instance
      {@code this.getClass()} {@link ClassObjectReference} {@link ClassType}a thread{@code Thread.currentThread()}{@link ThreadReference}{@link ClassType}
      a class loader {@code this.getClass()}
        {@code .getClassLoader()}
      {@link ClassLoaderReference} {@link ClassType}
      Other
      Kind of valueFor example -
      expression in target
      Is mirrored as{@link Type} of valuea thread group{@code Thread.currentThread()}
        {@code .getThreadGroup()}
      {@link ThreadGroupReference}{@link ClassType}
      null {@code null} {@code null} n/aa {@code java.lang.Class}
      instance
      {@code this.getClass()}{@link ClassObjectReference}{@link ClassType}
      a class loader{@code this.getClass()}
        {@code .getClassLoader()}
      {@link ClassLoaderReference}{@link ClassType}
      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * *
      Other values
      Kind of valueFor example -
      expression in target
      Is mirrored as{@link Type} of value
      null{@code null}{@code null}n/a
      * * @author Robert Field diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java index ae3c5ffd016..2431f6c02ed 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java @@ -59,13 +59,16 @@ import com.sun.jdi.event.VMStartEvent; * Some {@link Connector} implementations may require slightly * different handling than presented below. * - * + *
      * + * * - * - * + * + * + * + * * - * + * * * * * - * + * * * * - * + * * * * - * + * *
      Four scenarios for connecting a debugger to a virtual machine"
      ScenarioDescriptionScenarioDescription
      Debugger launches target VM (simplest, most-common scenario)Debugger launches target VM (simplest, most-common scenario)Debugger calls the {@link LaunchingConnector#launch(java.util.Map)} * method of the default connector, obtained with {@link #defaultConnector}. The @@ -86,7 +89,7 @@ import com.sun.jdi.event.VMStartEvent; *
      Debugger attaches to previously-running VMDebugger attaches to previously-running VM *
        *
      • @@ -113,7 +116,7 @@ import com.sun.jdi.event.VMStartEvent; *
      Target VM attaches to previously-running debuggerTarget VM attaches to previously-running debugger *
        *
      • @@ -146,7 +149,7 @@ import com.sun.jdi.event.VMStartEvent; *
      Target VM launches debugger (sometimes called "Just-In-Time" debugging)Target VM launches debugger (sometimes called "Just-In-Time" debugging) *
        *
      • diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html index 75bb46c1c32..8c7d4f95398 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html +++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html @@ -1,34 +1,42 @@ - + JDI Type Signatures + +
        - - + + + +
        JDI Type Signatures
        Type Signature -Java Type -
        Zboolean -
        Bbyte -
        Cchar -
        Sshort -
        Iint -
        Jlong -
        Ffloat -
        Ddouble -
        L fully-qualified-class +
        JDI Type Signatures
        Type Signature +Java Type +
        Zboolean +
        Bbyte +
        Cchar +
        Sshort +
        Iint +
        Jlong +
        Ffloat +
        Ddouble +
        L fully-qualified-class ; fully-qualified-class -
        [ type +
        [ type type[] -
        +
        ( arg-types ) ret-type method type (including constructors) +

        For example, the Java method: diff --git a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java index b87a63d87cb..3c45090dbe2 100644 --- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java @@ -106,13 +106,24 @@ class ZipUtils { * Converts DOS time to Java time (number of milliseconds since epoch). */ public static long dosToJavaTime(long dtime) { - LocalDateTime ldt = LocalDateTime.of( - (int) (((dtime >> 25) & 0x7f) + 1980), - (int) ((dtime >> 21) & 0x0f), - (int) ((dtime >> 16) & 0x1f), - (int) ((dtime >> 11) & 0x1f), - (int) ((dtime >> 5) & 0x3f), - (int) ((dtime << 1) & 0x3e)); + int year; + int month; + int day; + int hour = (int) ((dtime >> 11) & 0x1f); + int minute = (int) ((dtime >> 5) & 0x3f); + int second = (int) ((dtime << 1) & 0x3e); + if ((dtime >> 16) == 0) { + // Interpret the 0 DOS date as 1979-11-30 for compatibility with + // other implementations. + year = 1979; + month = 11; + day = 30; + } else { + year = (int) (((dtime >> 25) & 0x7f) + 1980); + month = (int) ((dtime >> 21) & 0x0f); + day = (int) ((dtime >> 16) & 0x1f); + } + LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second); return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond( ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS); } diff --git a/jdk/test/TEST.ROOT b/jdk/test/TEST.ROOT index 41cb9e82c8d..ccf4c295d14 100644 --- a/jdk/test/TEST.ROOT +++ b/jdk/test/TEST.ROOT @@ -10,9 +10,11 @@ # randomness tests. # # A "headful" test requires a graphical environment to meaningfully -# run. Tests that are not headful are "headless." +# run. Tests that are not headful are "headless". +# A test flagged with key "printer" requires a printer to succeed, else +# throws a PrinterException or the like. -keys=2d dnd i18n intermittent randomness headful +keys=2d dnd headful i18n intermittent printer randomness # Tests that must run in othervm mode othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces javax/xml/jaxp/testng/validation java/lang/ProcessHandle diff --git a/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java b/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java index b5257e60957..9f87d7c5572 100644 --- a/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java +++ b/jdk/test/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,9 @@ * questions. */ -/* +/** * @test + * @key headful * @bug 8007267 * @summary [macosx] com.apple.eawt.Application.setDefaultMenuBar is not working * @requires (os.family == "mac") diff --git a/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java b/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java index 26071d4bb7b..9971967bbb6 100644 --- a/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java +++ b/jdk/test/com/apple/laf/ScreenMenu/ScreenMenuMemoryLeakTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -20,13 +20,16 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -/* + +/** * @test + * @key headful * @bug 8158325 * @summary Memory leak in com.apple.laf.ScreenMenu: removed JMenuItems are still referenced * @requires (os.family == "mac") * @run main/timeout=300/othervm -Xmx16m ScreenMenuMemoryLeakTest */ + import java.awt.EventQueue; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; diff --git a/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java b/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java index fd23b478ca0..09e7e08dd8f 100644 --- a/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java +++ b/jdk/test/java/awt/Choice/ChoiceHiDpi/ChoiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,8 +21,9 @@ * questions. */ -/* +/** * @test + * @key headful * @bug 8144594 * @summary HiDPI: awt.Choice looks improperly (Win 8) * @run main ChoiceTest diff --git a/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java b/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java index 5769f88938f..4b86476e7a0 100644 --- a/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java +++ b/jdk/test/java/awt/Desktop/DesktopGtkLoadTest/DesktopGtkLoadTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,9 @@ * questions. */ -/* @test +/** + * @test + * @key headful * @bug 8157827 * @summary AWT_Desktop/Automated/Exceptions/BasicTest loads incorrect GTK * version when jdk.gtk.version=3 diff --git a/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java b/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java index 3053d793043..4db2d52e4ea 100644 --- a/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java +++ b/jdk/test/java/awt/Dialog/CloseDialog/CloseDialogTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,11 +30,13 @@ import java.util.concurrent.atomic.AtomicReference; /** * @test + * @key headful * @bug 8043705 * @summary Can't exit color chooser dialog when running as an applet * @modules java.desktop/sun.awt * @run main CloseDialogTest */ + public class CloseDialogTest { private static volatile Frame frame; diff --git a/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java b/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java index 80c0dbb2f6c..7d32c5dd3d3 100644 --- a/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java +++ b/jdk/test/java/awt/Dialog/NestedDialogs/Modal/NestedModalDialogTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,17 +21,19 @@ * questions. */ - /* - @test 8155740 - @summary See : Events: actionPerformed() method not - called when it is button is clicked (system load related) - @summary com.apple.junit.java.awt.Frame - @library ../../../regtesthelpers - @build VisibilityValidator - @build Util - @build Waypoint - @run main NestedModalDialogTest +/** + * @test 8155740 + * @key headful + * @summary See : Events: actionPerformed() method not + * called when it is button is clicked (system load related) + * @summary com.apple.junit.java.awt.Frame + * @library ../../../regtesthelpers + * @build VisibilityValidator + * @build Util + * @build Waypoint + * @run main NestedModalDialogTest */ + ////////////////////////////////////////////////////////////////////////////// // NestedModalDialogTest.java // The test launches a parent frame. From this parent frame it launches a modal diff --git a/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java b/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java index 853ff02e615..d41079d1f79 100644 --- a/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java +++ b/jdk/test/java/awt/Dialog/NestedDialogs/Modeless/NestedModelessDialogTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,17 +21,19 @@ * questions. */ - /* - @test 8155740 - @summary See : Events: actionPerformed() method not - called when it is button is clicked (system load related) - @summary com.apple.junit.java.awt.Frame - @library ../../../regtesthelpers - @build VisibilityValidator - @build Util - @build Waypoint - @run main NestedModelessDialogTest +/** + * @test 8155740 + * @key headful + * @summary See : Events: actionPerformed() method not + * called when it is button is clicked (system load related) + * @summary com.apple.junit.java.awt.Frame + * @library ../../../regtesthelpers + * @build VisibilityValidator + * @build Util + * @build Waypoint + * @run main NestedModelessDialogTest -Xlog:exception */ + ///////////////////////////////////////////////////////////////////////////// // NestedModelessDialogTest.java // The test launches a parent frame. From this parent frame it launches a modal diff --git a/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java b/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java index 082681bd69b..daf9d29fbb4 100644 --- a/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java +++ b/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,24 +21,20 @@ * questions. */ -/* - @test - @bug 4980592 8171363 - @summary switching user in XP causes an NPE in - sun.awt.windows.WWindowPeer.displayChanged - @requires (os.family == "windows") - @modules java.desktop/java.awt.peer - @modules java.desktop/sun.awt.windows:open - @modules java.desktop/sun.awt - @author son@sparc.spb.su: area=embedded - @run main DisplayChangedTest - */ /** - * DisplayChangedTest.java - * - * summary: switching user in XP causes an NPE in - * sun.awt.windows.WWindowPeer.displayChanged + * @test + * @key headful + * @bug 4980592 8171363 + * @summary switching user in XP causes an NPE in + * sun.awt.windows.WWindowPeer.displayChanged + * @requires (os.family == "windows") + * @modules java.desktop/java.awt.peer + * @modules java.desktop/sun.awt.windows:open + * @modules java.desktop/sun.awt + * @author son@sparc.spb.su: area=embedded + * @run main DisplayChangedTest */ + import java.awt.Frame; import java.awt.Dialog; import java.awt.TextArea; diff --git a/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java b/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java index 5249dca3b14..e7fb0b8c6a0 100644 --- a/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java +++ b/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,22 +21,19 @@ * questions. */ -/* - @test - @bug 6345003 8171363 - @summary grab problems with EmbeddedFrame - @requires (os.family == "windows") - @modules java.desktop/java.awt.peer - @modules java.desktop/sun.awt - @modules java.desktop/sun.awt.windows:open - @author Oleg.Semenov@sun.com area=EmbeddedFrame - @run main EmbeddedFrameGrabTest - */ /** - * EmbeddedFrameGrabTest.java - * - * summary: grab problems with EmbeddedFrame + * @test + * @key headful + * @bug 6345003 8171363 + * @summary grab problems with EmbeddedFrame + * @requires (os.family == "windows") + * @modules java.desktop/java.awt.peer + * @modules java.desktop/sun.awt + * @modules java.desktop/sun.awt.windows:open + * @author Oleg.Semenov@sun.com area=EmbeddedFrame + * @run main EmbeddedFrameGrabTest */ + import java.awt.Frame; import java.awt.peer.FramePeer; import javax.swing.JComboBox; diff --git a/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html b/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html index 8f5e722fb68..1a1808de681 100644 --- a/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html +++ b/jdk/test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.html @@ -1,5 +1,5 @@