This commit is contained in:
J. Duke 2017-08-24 16:36:46 +02:00
commit 28960fc50e
616 changed files with 41281 additions and 25215 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
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 &quot;class
* initialization method&quot; or &quot;interface initialization
* method&quot;. This is &quot;&lt;clinit&gt;&quot;.
*/
public final static String STATIC_INITIALIZER_NAME = "<clinit>";
/** The name of every constructor method in a class, also called
* &quot;instance initialization method&quot;. This is &quot;&lt;init&gt;&quot;.
*/
public final static String CONSTRUCTOR_NAME = "<init>";
/** The names of the interfaces implemented by arrays */
public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"};
/**
* Limitations of the Java Virtual Machine.
* See The Java Virtual Machine Specification, Second Edition, page 152, chapter 4.10.
*/
public static final int MAX_CP_ENTRIES = 65535;
public static final int MAX_CODE_SIZE = 65536; //bytes
/** Java VM opcodes.
*/
public static final short NOP = 0;
public static final short ACONST_NULL = 1;
public static final short ICONST_M1 = 2;
public static final short ICONST_0 = 3;
public static final short ICONST_1 = 4;
public static final short ICONST_2 = 5;
public static final short ICONST_3 = 6;
public static final short ICONST_4 = 7;
public static final short ICONST_5 = 8;
public static final short LCONST_0 = 9;
public static final short LCONST_1 = 10;
public static final short FCONST_0 = 11;
public static final short FCONST_1 = 12;
public static final short FCONST_2 = 13;
public static final short DCONST_0 = 14;
public static final short DCONST_1 = 15;
public static final short BIPUSH = 16;
public static final short SIPUSH = 17;
public static final short LDC = 18;
public static final short LDC_W = 19;
public static final short LDC2_W = 20;
public static final short ILOAD = 21;
public static final short LLOAD = 22;
public static final short FLOAD = 23;
public static final short DLOAD = 24;
public static final short ALOAD = 25;
public static final short ILOAD_0 = 26;
public static final short ILOAD_1 = 27;
public static final short ILOAD_2 = 28;
public static final short ILOAD_3 = 29;
public static final short LLOAD_0 = 30;
public static final short LLOAD_1 = 31;
public static final short LLOAD_2 = 32;
public static final short LLOAD_3 = 33;
public static final short FLOAD_0 = 34;
public static final short FLOAD_1 = 35;
public static final short FLOAD_2 = 36;
public static final short FLOAD_3 = 37;
public static final short DLOAD_0 = 38;
public static final short DLOAD_1 = 39;
public static final short DLOAD_2 = 40;
public static final short DLOAD_3 = 41;
public static final short ALOAD_0 = 42;
public static final short ALOAD_1 = 43;
public static final short ALOAD_2 = 44;
public static final short ALOAD_3 = 45;
public static final short IALOAD = 46;
public static final short LALOAD = 47;
public static final short FALOAD = 48;
public static final short DALOAD = 49;
public static final short AALOAD = 50;
public static final short BALOAD = 51;
public static final short CALOAD = 52;
public static final short SALOAD = 53;
public static final short ISTORE = 54;
public static final short LSTORE = 55;
public static final short FSTORE = 56;
public static final short DSTORE = 57;
public static final short ASTORE = 58;
public static final short ISTORE_0 = 59;
public static final short ISTORE_1 = 60;
public static final short ISTORE_2 = 61;
public static final short ISTORE_3 = 62;
public static final short LSTORE_0 = 63;
public static final short LSTORE_1 = 64;
public static final short LSTORE_2 = 65;
public static final short LSTORE_3 = 66;
public static final short FSTORE_0 = 67;
public static final short FSTORE_1 = 68;
public static final short FSTORE_2 = 69;
public static final short FSTORE_3 = 70;
public static final short DSTORE_0 = 71;
public static final short DSTORE_1 = 72;
public static final short DSTORE_2 = 73;
public static final short DSTORE_3 = 74;
public static final short ASTORE_0 = 75;
public static final short ASTORE_1 = 76;
public static final short ASTORE_2 = 77;
public static final short ASTORE_3 = 78;
public static final short IASTORE = 79;
public static final short LASTORE = 80;
public static final short FASTORE = 81;
public static final short DASTORE = 82;
public static final short AASTORE = 83;
public static final short BASTORE = 84;
public static final short CASTORE = 85;
public static final short SASTORE = 86;
public static final short POP = 87;
public static final short POP2 = 88;
public static final short DUP = 89;
public static final short DUP_X1 = 90;
public static final short DUP_X2 = 91;
public static final short DUP2 = 92;
public static final short DUP2_X1 = 93;
public static final short DUP2_X2 = 94;
public static final short SWAP = 95;
public static final short IADD = 96;
public static final short LADD = 97;
public static final short FADD = 98;
public static final short DADD = 99;
public static final short ISUB = 100;
public static final short LSUB = 101;
public static final short FSUB = 102;
public static final short DSUB = 103;
public static final short IMUL = 104;
public static final short LMUL = 105;
public static final short FMUL = 106;
public static final short DMUL = 107;
public static final short IDIV = 108;
public static final short LDIV = 109;
public static final short FDIV = 110;
public static final short DDIV = 111;
public static final short IREM = 112;
public static final short LREM = 113;
public static final short FREM = 114;
public static final short DREM = 115;
public static final short INEG = 116;
public static final short LNEG = 117;
public static final short FNEG = 118;
public static final short DNEG = 119;
public static final short ISHL = 120;
public static final short LSHL = 121;
public static final short ISHR = 122;
public static final short LSHR = 123;
public static final short IUSHR = 124;
public static final short LUSHR = 125;
public static final short IAND = 126;
public static final short LAND = 127;
public static final short IOR = 128;
public static final short LOR = 129;
public static final short IXOR = 130;
public static final short LXOR = 131;
public static final short IINC = 132;
public static final short I2L = 133;
public static final short I2F = 134;
public static final short I2D = 135;
public static final short L2I = 136;
public static final short L2F = 137;
public static final short L2D = 138;
public static final short F2I = 139;
public static final short F2L = 140;
public static final short F2D = 141;
public static final short D2I = 142;
public static final short D2L = 143;
public static final short D2F = 144;
public static final short I2B = 145;
public static final short INT2BYTE = 145; // Old notion
public static final short I2C = 146;
public static final short INT2CHAR = 146; // Old notion
public static final short I2S = 147;
public static final short INT2SHORT = 147; // Old notion
public static final short LCMP = 148;
public static final short FCMPL = 149;
public static final short FCMPG = 150;
public static final short DCMPL = 151;
public static final short DCMPG = 152;
public static final short IFEQ = 153;
public static final short IFNE = 154;
public static final short IFLT = 155;
public static final short IFGE = 156;
public static final short IFGT = 157;
public static final short IFLE = 158;
public static final short IF_ICMPEQ = 159;
public static final short IF_ICMPNE = 160;
public static final short IF_ICMPLT = 161;
public static final short IF_ICMPGE = 162;
public static final short IF_ICMPGT = 163;
public static final short IF_ICMPLE = 164;
public static final short IF_ACMPEQ = 165;
public static final short IF_ACMPNE = 166;
public static final short GOTO = 167;
public static final short JSR = 168;
public static final short RET = 169;
public static final short TABLESWITCH = 170;
public static final short LOOKUPSWITCH = 171;
public static final short IRETURN = 172;
public static final short LRETURN = 173;
public static final short FRETURN = 174;
public static final short DRETURN = 175;
public static final short ARETURN = 176;
public static final short RETURN = 177;
public static final short GETSTATIC = 178;
public static final short PUTSTATIC = 179;
public static final short GETFIELD = 180;
public static final short PUTFIELD = 181;
public static final short INVOKEVIRTUAL = 182;
public static final short INVOKESPECIAL = 183;
public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0
public static final short INVOKESTATIC = 184;
public static final short INVOKEINTERFACE = 185;
public static final short 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 = "<illegal opcode>";
public static final String ILLEGAL_TYPE = "<illegal type>";
public static final byte T_BOOLEAN = 4;
public static final byte T_CHAR = 5;
public static final byte T_FLOAT = 6;
public static final byte T_DOUBLE = 7;
public static final byte T_BYTE = 8;
public static final byte T_SHORT = 9;
public static final byte T_INT = 10;
public static final byte T_LONG = 11;
public static final byte T_VOID = 12; // Non-standard
public static final byte T_ARRAY = 13;
public static final byte T_OBJECT = 14;
public static final byte T_REFERENCE = 14; // Deprecated
public static final byte T_UNKNOWN = 15;
public static final byte T_ADDRESS = 16;
/** The primitive type names corresponding to the T_XX constants,
* e.g., TYPE_NAMES[T_INT] = "int"
*/
public static final String[] TYPE_NAMES = {
ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE,
"boolean", "char", "float", "double", "byte", "short", "int", "long",
"void", "array", "object", "unknown" // Non-standard
};
/** The primitive class names corresponding to the T_XX constants,
* e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer"
*/
public static final String[] CLASS_TYPE_NAMES = {
ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE,
"java.lang.Boolean", "java.lang.Character", "java.lang.Float",
"java.lang.Double", "java.lang.Byte", "java.lang.Short",
"java.lang.Integer", "java.lang.Long", "java.lang.Void",
ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE
};
/** The signature characters corresponding to primitive types,
* e.g., SHORT_TYPE_NAMES[T_INT] = "I"
*/
public static final String[] SHORT_TYPE_NAMES = {
ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE,
"Z", "C", "F", "D", "B", "S", "I", "J",
"V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE
};
/**
* 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"
};
}

View File

@ -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 = Throwable.class;
/** Super class of any run-time exception
*/
public static final Class<RuntimeException> RUNTIME_EXCEPTION = RuntimeException.class;
/** Super class of any linking exception (aka Linkage Error)
*/
public static final Class<LinkageError> LINKING_EXCEPTION = LinkageError.class;
/** Linking Exceptions
*/
public static final Class<ClassCircularityError> CLASS_CIRCULARITY_ERROR = ClassCircularityError.class;
public static final Class<ClassFormatError> CLASS_FORMAT_ERROR = ClassFormatError.class;
public static final Class<ExceptionInInitializerError> EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class;
public static final Class<IncompatibleClassChangeError> INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class;
public static final Class<AbstractMethodError> ABSTRACT_METHOD_ERROR = AbstractMethodError.class;
public static final Class<IllegalAccessError> ILLEGAL_ACCESS_ERROR = IllegalAccessError.class;
public static final Class<InstantiationError> INSTANTIATION_ERROR = InstantiationError.class;
public static final Class<NoSuchFieldError> NO_SUCH_FIELD_ERROR = NoSuchFieldError.class;
public static final Class<NoSuchMethodError> NO_SUCH_METHOD_ERROR = NoSuchMethodError.class;
public static final Class<NoClassDefFoundError> NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class;
public static final Class<UnsatisfiedLinkError> UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class;
public static final Class<VerifyError> VERIFY_ERROR = VerifyError.class;
/* UnsupportedClassVersionError is new in JDK 1.2 */
// public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class;
/** Run-Time Exceptions
*/
public static final Class<NullPointerException> NULL_POINTER_EXCEPTION = NullPointerException.class;
public static final Class<ArrayIndexOutOfBoundsException> ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION
= ArrayIndexOutOfBoundsException.class;
public static final Class<ArithmeticException> ARITHMETIC_EXCEPTION = ArithmeticException.class;
public static final Class<NegativeArraySizeException> NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class;
public static final Class<ClassCastException> CLASS_CAST_EXCEPTION = ClassCastException.class;
public static final Class<IllegalMonitorStateException> ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class;
/**
* Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual
* Machine Specification
*/
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);
}
}
}

View File

@ -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 <A HREF="http://www.inf.fu-berlin.de/~ehaase">E. Haase</A>
*/
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
};
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <em>Code</em>
* @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 <em>Code</em>
* @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);
}
}

View File

@ -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;
}
}

View File

@ -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<ElementValuePair> 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<AnnotationEntry> 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()]);
}
}

View File

@ -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 <em>Code</em>
* @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 <em>Code</em>
* @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);
}
}
}

View File

@ -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;
}
}

View File

@ -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 <em>Attribute</em> objects. Currently the
* <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>,
* <em>Exceptiontable</em>, <em>LineNumberTable</em>,
* <em>LocalVariableTable</em>, <em>InnerClasses</em> and
* <em>Synthetic</em> attributes are supported. The
* <em>Unknown</em> attribute stands for non-standard-attributes.
* <em>Synthetic</em> attributes are supported. The <em>Unknown</em>
* attribute stands for non-standard-attributes.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @see ConstantValue
* @see SourceFile
* @see Code
* @see Unknown
* @see ExceptionTable
* @see LineNumberTable
* @see LocalVariableTable
* @see InnerClasses
* @see Synthetic
* @see Deprecated
* @see Signature
*/
public abstract class Attribute implements Cloneable, Node, Serializable {
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<String, Object> 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);
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 );
}

View File

@ -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 <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23">
* The class File Format : The BootstrapMethods Attribute</a>
* @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_<type>_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_<type>_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_<type>_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;
}
}

View File

@ -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 <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23">
* The class File Format : The BootstrapMethods Attribute</a>
* @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();
}
}

View File

@ -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);
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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 <A
@ -34,262 +39,274 @@ import java.util.zip.*;
* the caller.
*
* The structure and the names comply, except for a few conveniences,
* exactly with the <A href="ftp://java.sun.com/docs/specs/vmspec.ps">
* exactly with the <A href="http://docs.oracle.com/javase/specs/">
* JVM specification 1.0</a>. See this paper for
* further details about the structure of a bytecode file.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 <em>ClassFormatException</em> is raised, if the file is not a valid
* .class file. (This does not include verification of the byte code as it
* is performed by the java interpreter).
*
* @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 <em>ClassFormatException</em> is raised, if the file is not a valid
* .class file. (This does not include verification of the byte code as it
* is performed by the java interpreter).
*
* @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();
}
}

View File

@ -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 <em>LocalVariableTable</em> which
* contains information about the local variables.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 <em>Code</em>
* @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 <em>Code</em>
* @param length Content length in bytes
* @param max_stack Maximum size of stack
* @param max_locals Number of local variables
* @param code Actual byte code
* @param exception_table Table of handled exceptions
* @param attributes Attributes of code: LineNumber or LocalVariable
* @param constant_pool Array of constants
*/
public Code(int name_index, int length,
int max_stack, int max_locals,
byte[] code,
CodeException[] exception_table,
Attribute[] attributes,
ConstantPool constant_pool)
{
super(Constants.ATTR_CODE, name_index, length, constant_pool);
this.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 <em>Code</em>
* @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 <em>Code</em>
* @param length Content length in bytes
* @param max_stack Maximum size of stack
* @param max_locals Number of local variables
* @param code Actual byte code
* @param exception_table Table of handled exceptions
* @param attributes Attributes of code: LineNumber or LocalVariable
* @param constant_pool Array of constants
*/
public Code(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;
}
}

View File

@ -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 <em>Code</em>
* attribute and is used only there. It contains a range in which a
* particular exception handler is active.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 = "<Any exception>(0)";
else
str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false) +
(verbose? "(" + catch_type + ")" : "");
return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str;
}
/**
* @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 = "<Any exception>(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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 + ")";
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class
* This class is derived from the abstract {@link Constant}
* and represents a reference to a (external) class.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 + ")";
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class
* This class is derived from the abstract {@link Constant}
* and represents a reference to a Double object.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class
* This class is derived from the abstract {@link Constant}
* and represents a reference to a float object.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class
* This class is derived from the abstract {@link Constant}
* and represents a reference to an int object.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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 <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10">
* The CONSTANT_InvokeDynamic_info Structure in The Java Virtual Machine Specification</a>
* @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");
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class
* This class is derived from the abstract {@link Constant}
* and represents a reference to a long object.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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 + ")";
}
}

View File

@ -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 + ")";
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> 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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 + ")";
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 );
}

View File

@ -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 <a href="../generic/ConstantPoolGen.html">
* ConstantPoolGen</a>.
* @version $Id: ConstantPool.java 1749603 2016-06-21 20:50:19Z ggregory $
* @see Constant
* @see com.sun.org.apache.bcel.internal.generic.ConstantPoolGen
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
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;
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class
* This class is derived from the abstract {@link Constant}
* and represents a reference to a String object.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <A HREF="com.sun.org.apache.bcel.internal.classfile.Constant.html">Constant</A> class
* This class is derived from the abstract {@link Constant}
* and represents a reference to a Utf8 encoded string.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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<String, ConstantUtf8> CACHE =
new LinkedHashMap<String, ConstantUtf8>(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<String, ConstantUtf8> 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") + "\")";
}
}

View File

@ -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 <em>Attribute</em> and represents a constant
* value, i.e., a default value for initializing a class field.
* This class is instantiated by the <em>Attribute.readAttribute()</em> method.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <em>Attribute</em> and denotes that this is a
* deprecated method.
* It is instantiated from the <em>Attribute.readAttribute()</em> method.
* deprecated method. It is instantiated from the
* <em>Attribute.readAttribute()</em> method.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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<Object> 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();
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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) {
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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 <em>Exceptions</em> (which is inconsistent
* with the other classes).
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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&lt;Ljava/lang/String&gt;;' 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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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 = "<not a member>";
if(inner_name_index != 0)
inner_name = ((ConstantUtf8)constant_pool.
getConstant(inner_name_index, Constants.CONSTANT_Utf8)).getBytes();
else
inner_name = "<anonymous>";
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;
}
}

View File

@ -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 <em>Attribute</em> and denotes that this class
@ -31,118 +33,129 @@ import java.io.*;
* to the source file of this class.
* It is instantiated from the <em>Attribute.readAttribute()</em> method.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <em>Code</em> 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 <em>Code</em> attribute. It contains pairs of PCs
* and line numbers.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <em>Code</em> attribute.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24">
* The class File Format : The MethodParameters Attribute</a>
* @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;
}
}

View File

@ -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 <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24">
* The class File Format : The MethodParameters Attribute</a>
* @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);
}
}
}

View File

@ -21,12 +21,12 @@
package com.sun.org.apache.bcel.internal.classfile;
/**
* Denote class to have an accept method();
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @version $Id: Node.java 1747278 2016-06-07 17:28:43Z britter $
*/
public interface Node {
public void accept(Visitor obj);
void accept( Visitor obj );
}

View File

@ -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 <em>Attribute</em> and represents a reference
* to a <a href="http://www.inf.fu-berlin.de/~bokowski/pmgjava/index.html">PMG</a>
* attribute.
* to a PMG attribute.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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();
}
}

View File

@ -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<ParameterAnnotationEntry> 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()]);
}
}

View File

@ -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 <em>Code</em>
* @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 <em>Code</em>
* @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();
}
}

View File

@ -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 <em>Code</em>
* @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);
}
}

View File

@ -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 <em>Code</em>
* @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);
}
}

View File

@ -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 <em>Code</em>
* @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);
}
}

View File

@ -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 <em>Code</em>
* @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);
}
}

View File

@ -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 <em>Attribute</em> and represents a reference
* to a <href="http://wwwipd.ira.uka.de/~pizza/gj/">GJ</a> attribute.
* to a GJ attribute.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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();
}
}

View File

@ -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);
}
}
}

View File

@ -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 <em>Attribute</em> 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 <em>Attribute.readAttribute()</em> method.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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();
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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=<unknown>";
}
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;
}
}

View File

@ -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 <em>Attribute</em> and declares this class as
@ -34,110 +36,125 @@ import java.io.*;
* is intended to be instantiated from the
* <em>Attribute.readAttribute()</em> method.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -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
* <em>Attribute.readAttribute()</em> method. Applications that need to
* read in application-specific attributes should create an <a
* href="./AttributeReader.html">AttributeReader</a> implementation and
* attach it via <a
* href="./Attribute.html#addAttributeReader(java.lang.String,
* com.sun.org.apache.bcel.internal.classfile.AttributeReader)">Attribute.addAttributeReader</a>.
* {@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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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<String, Unknown> 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;
}
}

View File

@ -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 );
}

View File

@ -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
* <A HREF="http://www.inf.fu-berlin.de/~bokowski">Boris Bokowski</A>.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}

View File

@ -1,8 +1,24 @@
<!--
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.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<!--
$Id: package.html,v 1.1.2.1 2005/07/31 23:46:33 jeffsuttor Exp $
$Id: package.html 919342 2010-03-05 09:12:23Z markt $
-->
</head>
<body bgcolor="white">

View File

@ -21,34 +21,35 @@
package com.sun.org.apache.bcel.internal.generic;
/**
* AALOAD - Load reference from array
* <PRE>Stack: ..., arrayref, index -&gt; value</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -21,34 +21,35 @@
package com.sun.org.apache.bcel.internal.generic;
/**
* AASTORE - Store into reference array
* <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -21,41 +21,43 @@
package com.sun.org.apache.bcel.internal.generic;
/**
* ACONST_NULL - Push null reference
* <PRE>Stack: ... -&gt; ..., null</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <PRE>Stack: ... -&gt; ..., objectref</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <PRE>Stack: ..., count -&gt; ..., arrayref</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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;
}
}

View File

@ -21,35 +21,36 @@
package com.sun.org.apache.bcel.internal.generic;
/**
* ARETURN - Return reference from method
* <PRE>Stack: ..., objectref -&gt; &lt;empty&gt;</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <PRE>Stack: ..., arrayref -&gt; ..., length</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -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
* <PRE>Stack ..., objectref -&gt; ... </PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -21,39 +21,46 @@
package com.sun.org.apache.bcel.internal.generic;
import com.sun.org.apache.bcel.internal.ExceptionConst;
/**
* ATHROW - Throw exception
* <PRE>Stack: ..., objectref -&gt; objectref</PRE>
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}

View File

@ -21,10 +21,10 @@
package com.sun.org.apache.bcel.internal.generic;
/**
* Denote family of instructions that allocates space in the heap.
*
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @version $Id: AllocationInstruction.java 1747278 2016-06-07 17:28:43Z britter $
*/
public interface AllocationInstruction {}
public interface AllocationInstruction {
}

View File

@ -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;
}
}

View File

@ -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<ElementValuePairGen> 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<ElementValuePairGen> copyValues(final ElementValuePair[] in, final ConstantPoolGen cpool,
final boolean copyPoolEntries) {
final List<ElementValuePairGen> 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<ElementValuePairGen> 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<ElementValuePairGen> 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<Attribute> 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<AnnotationEntryGen>[] /*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<Attribute> 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;
}
}

View File

@ -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 <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @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);
}
}
}
}

View File

@ -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<ElementValueGen> 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<ElementValueGen> getElementValues()
{
return evalues;
}
public int getElementValuesSize()
{
return evalues.size();
}
public void addElement(final ElementValueGen gen)
{
evalues.add(gen);
}
}

Some files were not shown because too many files have changed in this diff Show More