mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-27 02:30:06 +00:00
Merge
This commit is contained in:
commit
28960fc50e
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
@ -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 "class
|
||||
* initialization method" or "interface initialization
|
||||
* method". This is "<clinit>".
|
||||
*/
|
||||
public final static String STATIC_INITIALIZER_NAME = "<clinit>";
|
||||
|
||||
/** The name of every constructor method in a class, also called
|
||||
* "instance initialization method". This is "<init>".
|
||||
*/
|
||||
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"
|
||||
};
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -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
|
||||
};
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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()]);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 );
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 );
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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") + "\")";
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<Ljava/lang/String>;' Coded for performance -
|
||||
* searches for the attribute only when requested - only searches for it
|
||||
* once.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
public final String getGenericSignature() {
|
||||
if (!searchedForSignatureAttribute) {
|
||||
boolean found = false;
|
||||
for (int i = 0; !found && i < attributes.length; i++) {
|
||||
if (attributes[i] instanceof Signature) {
|
||||
signatureAttributeString = ((Signature) attributes[i])
|
||||
.getSignature();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
searchedForSignatureAttribute = true;
|
||||
}
|
||||
return signatureAttributeString;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 );
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()]);
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 );
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -21,34 +21,35 @@
|
||||
|
||||
package com.sun.org.apache.bcel.internal.generic;
|
||||
|
||||
|
||||
/**
|
||||
* AALOAD - Load reference from array
|
||||
* <PRE>Stack: ..., arrayref, index -> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,34 +21,35 @@
|
||||
|
||||
package com.sun.org.apache.bcel.internal.generic;
|
||||
|
||||
|
||||
/**
|
||||
* AASTORE - Store into reference array
|
||||
* <PRE>Stack: ..., arrayref, index, value -> ...</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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,41 +21,43 @@
|
||||
|
||||
package com.sun.org.apache.bcel.internal.generic;
|
||||
|
||||
|
||||
/**
|
||||
* ACONST_NULL - Push null reference
|
||||
* <PRE>Stack: ... -> ..., 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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: ... -> ..., 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 -> ..., 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,35 +21,36 @@
|
||||
|
||||
package com.sun.org.apache.bcel.internal.generic;
|
||||
|
||||
|
||||
/**
|
||||
* ARETURN - Return reference from method
|
||||
* <PRE>Stack: ..., objectref -> <empty></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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 -> ..., 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 -> ... </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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 -> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user