2014-12-18 21:56:02 +00:00
|
|
|
/*
|
2017-10-06 22:15:23 +00:00
|
|
|
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
2014-12-18 21:56:02 +00:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
package org.openjdk.asmtools.jasm;
|
|
|
|
|
2017-10-06 22:15:23 +00:00
|
|
|
import java.io.IOException;
|
2014-12-18 21:56:02 +00:00
|
|
|
import java.io.PrintWriter;
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Tables
|
|
|
|
*
|
|
|
|
* The classes in Tables are following a Singleton Pattern. These classes are Enums, and
|
|
|
|
* they are contained in private hash maps (lookup tables and reverse lookup tables).
|
|
|
|
* These hash maps all have public accessors, which clients use to look-up enums.
|
|
|
|
*
|
|
|
|
* Tokens in this table carry no external state, and are typically treated as constants.
|
|
|
|
* They do not need to be reset.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public class Tables {
|
|
|
|
|
|
|
|
public static final int JAVA_MAGIC = 0xCAFEBABE;
|
|
|
|
/**
|
|
|
|
* Lookup-tables for various types.
|
|
|
|
*/
|
|
|
|
private static HashMap<String, AttrTag> NameToAttrTag = new HashMap<>(9);
|
|
|
|
private static HashMap<Integer, AttrTag> AttrTags = new HashMap<>(9);
|
|
|
|
|
|
|
|
private static HashMap<String, SubTag> NameToSubTag = new HashMap<>(9);
|
|
|
|
private static HashMap<Integer, SubTag> SubTags = new HashMap<>(9);
|
|
|
|
|
|
|
|
private static HashMap<String, BasicType> NameToBasicType = new HashMap<>(10);
|
|
|
|
private static HashMap<Integer, BasicType> BasicTypes = new HashMap<>(10);
|
|
|
|
|
|
|
|
private static HashMap<String, AnnotElemType> NameToAnnotElemType = new HashMap<>(10);
|
|
|
|
private static HashMap<Character, AnnotElemType> AnnotElemTypes = new HashMap<>(10);
|
|
|
|
|
|
|
|
private static HashMap<String, StackMapType> KeyToStackMapType = new HashMap<>(10);
|
|
|
|
private static HashMap<String, StackMapType> NameToStackMapType = new HashMap<>(10);
|
|
|
|
private static HashMap<Integer, StackMapType> StackMapTypes = new HashMap<>(10);
|
|
|
|
|
|
|
|
private static HashMap<String, StackMapFrameType> NameToStackMapFrameType = new HashMap<>(10);
|
|
|
|
private static HashMap<Integer, StackMapFrameType> StackMapFrameTypes = new HashMap<>(10);
|
|
|
|
|
|
|
|
private static HashMap<String, ConstType> NameToConstantType = new HashMap<>(ConstType.maxTag);
|
|
|
|
private static HashMap<Integer, ConstType> ConstantTypes = new HashMap<>(ConstType.maxTag);
|
|
|
|
|
|
|
|
static {
|
|
|
|
// register all of the tokens
|
|
|
|
for (ConstType ct : ConstType.values()) {
|
|
|
|
registerConstantType(ct);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Type codes for SubTags */
|
|
|
|
for (AttrTag at : AttrTag.values()) {
|
|
|
|
registerAttrtag(at);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Type codes for SubTags */
|
|
|
|
for (SubTag st : SubTag.values()) {
|
|
|
|
registerSubtag(st);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Type codes for BasicTypes */
|
|
|
|
for (BasicType bt : BasicType.values()) {
|
|
|
|
registerBasicType(bt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Type codes for BasicTypes */
|
|
|
|
for (AnnotElemType aet : AnnotElemType.values()) {
|
|
|
|
registerAnnotElemType(aet);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Type codes for StackMapTypes */
|
|
|
|
for (StackMapType smt : StackMapType.values()) {
|
|
|
|
registerStackMapType(smt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Type codes for StackMapFrame attribute */
|
|
|
|
for (StackMapFrameType smft : StackMapFrameType.values()) {
|
|
|
|
registerStackMapFrameType(smft);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ConstType
|
|
|
|
*
|
|
|
|
* A (typed) tag (constant) representing the type of Constant in the Constant Pool.
|
|
|
|
*/
|
|
|
|
static public enum ConstType {
|
|
|
|
CONSTANT_ZERO (-3, "CONSTANT_ZERO", ""),
|
|
|
|
CONSTANT_UTF8 (1, "CONSTANT_UTF8", "Asciz"),
|
|
|
|
CONSTANT_UNICODE (2, "CONSTANT_UNICODE", ""),
|
|
|
|
CONSTANT_INTEGER (3, "CONSTANT_INTEGER", "int"),
|
|
|
|
CONSTANT_FLOAT (4, "CONSTANT_FLOAT", "float"),
|
|
|
|
CONSTANT_LONG (5, "CONSTANT_LONG", "long"),
|
|
|
|
CONSTANT_DOUBLE (6, "CONSTANT_DOUBLE", "double"),
|
|
|
|
CONSTANT_CLASS (7, "CONSTANT_CLASS", "class"),
|
|
|
|
CONSTANT_STRING (8, "CONSTANT_STRING", "String"),
|
|
|
|
CONSTANT_FIELD (9, "CONSTANT_FIELD", "Field"),
|
|
|
|
CONSTANT_METHOD (10, "CONSTANT_METHOD", "Method"),
|
|
|
|
CONSTANT_INTERFACEMETHOD (11, "CONSTANT_INTERFACEMETHOD", "InterfaceMethod"),
|
|
|
|
CONSTANT_NAMEANDTYPE (12, "CONSTANT_NAMEANDTYPE", "NameAndType"),
|
|
|
|
// Constant 13 reserved
|
|
|
|
// Constant 14 reserved
|
|
|
|
CONSTANT_METHODHANDLE (15, "CONSTANT_METHODHANDLE", "MethodHandle"),
|
|
|
|
CONSTANT_METHODTYPE (16, "CONSTANT_METHODTYPE", "MethodType"),
|
2017-10-06 22:15:23 +00:00
|
|
|
// Constant 17 reserved
|
|
|
|
CONSTANT_INVOKEDYNAMIC (18, "CONSTANT_INVOKEDYNAMIC", "InvokeDynamic"),
|
|
|
|
CONSTANT_MODULE (19, "CONSTANT_MODULE", "Module"),
|
|
|
|
CONSTANT_PACKAGE (20, "CONSTANT_PACKAGE", "Package");
|
2014-12-18 21:56:02 +00:00
|
|
|
|
2017-10-06 22:15:23 +00:00
|
|
|
static final public int maxTag = 20;
|
2014-12-18 21:56:02 +00:00
|
|
|
|
|
|
|
private final int value;
|
|
|
|
private final String parseKey;
|
|
|
|
private final String printval;
|
|
|
|
|
|
|
|
ConstType(int val, String print, String parse) {
|
|
|
|
value = val;
|
|
|
|
parseKey = parse;
|
|
|
|
printval = print;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int value() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String parseKey() {
|
|
|
|
return parseKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String printval() {
|
|
|
|
return printval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void print(PrintWriter out) {
|
|
|
|
out.print(parseKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "<" + printval + "> [" + Integer.toString(value) + "]";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static public ConstType tag(int i) {
|
|
|
|
return ConstantTypes.get(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
static public ConstType tag(String parsekey) {
|
|
|
|
return NameToConstantType.get(parsekey);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerConstantType(ConstType tt) {
|
|
|
|
NameToConstantType.put(tt.parseKey, tt);
|
|
|
|
ConstantTypes.put(tt.value, tt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Attribute descriptor enums
|
|
|
|
*/
|
|
|
|
static public enum AttrTag {
|
|
|
|
|
|
|
|
// Constant for ME Spec (StackMap does not appear in SE VM Spec)
|
|
|
|
ATT_Unrecognized (0, "ATT_Unrecognized", ""),
|
|
|
|
ATT_StackMap (1, "ATT_StackMap", "StackMap"),
|
|
|
|
// Numbers corespond to VM spec (chapter 4.7.X)
|
|
|
|
ATT_ConstantValue (2, "ATT_ConstantValue", "ConstantValue"),
|
|
|
|
ATT_Code (3, "ATT_Code", "Code"),
|
|
|
|
ATT_StackMapTable (4, "ATT_StackMapTable", "StackMapTable"),
|
|
|
|
ATT_Exceptions (5, "ATT_Exceptions", "Exceptions"),
|
|
|
|
ATT_InnerClasses (6, "ATT_InnerClasses", "InnerClasses"),
|
|
|
|
ATT_EnclosingMethod (7, "ATT_EnclosingMethod", "EnclosingMethod"),
|
|
|
|
ATT_Synthetic (8, "ATT_Synthetic", "Synthetic"),
|
|
|
|
ATT_Signature (9, "ATT_Signature", "Signature"),
|
|
|
|
ATT_SourceFile (10, "ATT_SourceFile", "SourceFile"),
|
|
|
|
ATT_SourceDebugExtension (11, "ATT_SourceDebugExtension", "SourceDebugExtension"),
|
|
|
|
ATT_LineNumberTable (12, "ATT_LineNumberTable", "LineNumberTable"),
|
|
|
|
ATT_LocalVariableTable (13, "ATT_LocalVariableTable", "LocalVariableTable"),
|
|
|
|
ATT_LocalVariableTypeTable (14, "ATT_LocalVariableTypeTable", "LocalVariableTypeTable"),
|
|
|
|
ATT_Deprecated (15, "ATT_Deprecated", "Deprecated"),
|
|
|
|
ATT_RuntimeVisibleAnnotations (16, "ATT_RuntimeVisibleAnnotations", "RuntimeVisibleAnnotations"),
|
|
|
|
ATT_RuntimeInvisibleAnnotations (17, "ATT_RuntimeInvisibleAnnotations", "RuntimeInvisibleAnnotations"),
|
|
|
|
ATT_RuntimeVisibleParameterAnnotations (18, "ATT_RuntimeVisibleParameterAnnotations", "RuntimeVisibleParameterAnnotations"),
|
|
|
|
ATT_RuntimeInvisibleParameterAnnotations (19, "ATT_RuntimeInvisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations"),
|
|
|
|
ATT_AnnotationDefault (20, "ATT_AnnotationDefault", "AnnotationDefault"),
|
|
|
|
ATT_BootstrapMethods (21, "ATT_BootstrapMethods", "BootstrapMethods"),
|
|
|
|
ATT_RuntimeVisibleTypeAnnotations (22, "ATT_RuntimeVisibleTypeAnnotations", "RuntimeVisibleTypeAnnotations"),
|
|
|
|
ATT_RuntimeInvisibleTypeAnnotations (23, "ATT_RuntimeInvisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations"),
|
2016-03-02 21:00:55 +00:00
|
|
|
ATT_MethodParameters (24, "ATT_MethodParameters", "MethodParameters"),
|
2017-10-06 22:15:23 +00:00
|
|
|
ATT_Module (25, "ATT_Module", "Module"),
|
|
|
|
ATT_Version (26, "ATT_Version", "Version"),
|
|
|
|
ATT_TargetPlatform (27, "ATT_TargetPlatform", "TargetPlatform"),
|
|
|
|
ATT_MainClass (28, "ATT_MainClass", "MainClass"),
|
|
|
|
ATT_ModulePackages (29, "ATT_ModulePackages", "ModulePackages"),
|
|
|
|
ATT_ModuleMainClass (30, "ATT_ModuleMainClass", "ModuleMainClass"),
|
|
|
|
ATT_ModuleTarget (31, "ATT_ModuleTarget", "ModuleTarget");
|
2014-12-18 21:56:02 +00:00
|
|
|
|
|
|
|
private final Integer value;
|
|
|
|
private final String printval;
|
|
|
|
private final String parsekey;
|
|
|
|
|
|
|
|
AttrTag(Integer val, String print, String parse) {
|
|
|
|
value = val;
|
|
|
|
printval = print;
|
|
|
|
parsekey = parse;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String printval() {
|
|
|
|
return printval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String parsekey() {
|
|
|
|
return parsekey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerAttrtag(AttrTag tg) {
|
|
|
|
NameToAttrTag.put(tg.parsekey, tg);
|
|
|
|
AttrTags.put(tg.value, tg);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static AttrTag attrtag(int val) {
|
|
|
|
AttrTag tg = AttrTags.get(val);
|
|
|
|
if (tg == null) {
|
|
|
|
tg = AttrTag.ATT_Unrecognized;
|
|
|
|
}
|
|
|
|
return tg;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static AttrTag attrtag(String idValue) {
|
|
|
|
AttrTag tg = NameToAttrTag.get(idValue);
|
|
|
|
if (tg == null) {
|
|
|
|
tg = AttrTag.ATT_Unrecognized;
|
|
|
|
}
|
|
|
|
return tg;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String attrtagName(int subtag) {
|
|
|
|
AttrTag tg = AttrTags.get(subtag);
|
|
|
|
return tg.parsekey;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int attrtagValue(String idValue) {
|
|
|
|
AttrTag tg = attrtag(idValue);
|
|
|
|
return tg.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* SubTag enums
|
|
|
|
*/
|
|
|
|
static public enum SubTag {
|
|
|
|
REF_GETFIELD (1, "REF_getField"),
|
|
|
|
REF_GETSTATIC (2, "REF_getStatic"),
|
|
|
|
REF_PUTFIELD (3, "REF_putField"),
|
|
|
|
REF_PUTSTATIC (4, "REF_putStatic"),
|
|
|
|
REF_INVOKEVIRTUAL (5, "REF_invokeVirtual"),
|
|
|
|
REF_INVOKESTATIC (6, "REF_invokeStatic"),
|
|
|
|
REF_INVOKESPECIAL (7, "REF_invokeSpecial"),
|
|
|
|
REF_NEWINVOKESPECIAL (8, "REF_newInvokeSpecial"),
|
|
|
|
REF_INVOKEINTERFACE (9, "REF_invokeInterface");
|
|
|
|
|
|
|
|
private final Integer value;
|
|
|
|
private final String printval;
|
|
|
|
|
|
|
|
SubTag(Integer val, String print) {
|
|
|
|
value = val;
|
|
|
|
printval = print;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String printval() {
|
|
|
|
return printval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Integer value() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerSubtag(SubTag tg) {
|
|
|
|
NameToSubTag.put(tg.printval, tg);
|
|
|
|
SubTags.put(tg.value, tg);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static SubTag subtag(String subtag) {
|
|
|
|
return NameToSubTag.get(subtag);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static SubTag subtag(int subtag) {
|
|
|
|
return SubTags.get(subtag);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String subtagName(int subtag) {
|
|
|
|
String retval = null;
|
|
|
|
SubTag tg = SubTags.get(subtag);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.printval;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int subtagValue(String idValue) {
|
|
|
|
int retval = 0;
|
|
|
|
SubTag tg = NameToSubTag.get(idValue);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.value;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* BasicType enums
|
|
|
|
*/
|
|
|
|
static public enum BasicType {
|
|
|
|
T_INT (0x0000000a, "int"),
|
|
|
|
T_LONG (0x0000000b, "long"),
|
|
|
|
T_FLOAT (0x00000006, "float"),
|
|
|
|
T_DOUBLE (0x00000007, "double"),
|
|
|
|
T_CLASS (0x00000002, "class"),
|
|
|
|
T_BOOLEAN (0x00000004, "boolean"),
|
|
|
|
T_CHAR (0x00000005, "char"),
|
|
|
|
T_BYTE (0x00000008, "byte"),
|
|
|
|
T_SHORT (0x00000009, "short");
|
|
|
|
|
|
|
|
private final Integer value;
|
|
|
|
private final String printval;
|
|
|
|
|
|
|
|
BasicType(Integer val, String print) {
|
|
|
|
value = val;
|
|
|
|
printval = print;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String printval() {
|
|
|
|
return printval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerBasicType(BasicType typ) {
|
|
|
|
NameToBasicType.put(typ.printval, typ);
|
|
|
|
BasicTypes.put(typ.value, typ);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static BasicType basictype(String idValue) {
|
|
|
|
return NameToBasicType.get(idValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static BasicType basictype(int subtag) {
|
|
|
|
return BasicTypes.get(subtag);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String basictypeName(int subtag) {
|
|
|
|
String retval = null;
|
|
|
|
BasicType tg = BasicTypes.get(subtag);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.printval;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int basictypeValue(String idValue) {
|
|
|
|
int retval = -1;
|
|
|
|
BasicType tg = NameToBasicType.get(idValue);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.value;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* AnnotElemType enums
|
|
|
|
*/
|
|
|
|
static public enum AnnotElemType {
|
|
|
|
|
2017-10-06 22:15:23 +00:00
|
|
|
AE_BYTE ('B', "byte"),
|
|
|
|
AE_CHAR ('C', "char"),
|
|
|
|
AE_SHORT ('S', "short"),
|
|
|
|
AE_INT ('I', "int"),
|
|
|
|
AE_LONG ('J', "long"),
|
|
|
|
AE_FLOAT ('F', "float"),
|
|
|
|
AE_DOUBLE ('D', "double"),
|
|
|
|
AE_BOOLEAN ('Z', "boolean"),
|
|
|
|
AE_STRING ('s', "string"),
|
|
|
|
AE_ENUM ('e', "enum"),
|
|
|
|
AE_CLASS ('c', "class"),
|
2014-12-18 21:56:02 +00:00
|
|
|
AE_ANNOTATION ('@', "annotation"),
|
2017-10-06 22:15:23 +00:00
|
|
|
AE_ARRAY ('[', "array"),
|
|
|
|
AE_UNKNOWN ((char)0, "unknown");
|
2014-12-18 21:56:02 +00:00
|
|
|
|
2017-10-06 22:15:23 +00:00
|
|
|
private char value;
|
2014-12-18 21:56:02 +00:00
|
|
|
private final String printval;
|
|
|
|
|
|
|
|
AnnotElemType(char val, String print) {
|
|
|
|
value = val;
|
|
|
|
printval = print;
|
|
|
|
}
|
|
|
|
|
|
|
|
public char val() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String printval() {
|
|
|
|
return printval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerAnnotElemType(AnnotElemType typ) {
|
|
|
|
NameToAnnotElemType.put(typ.printval, typ);
|
|
|
|
AnnotElemTypes.put(typ.value, typ);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static AnnotElemType annotElemType(String idValue) {
|
|
|
|
return NameToAnnotElemType.get(idValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static AnnotElemType annotElemType(char subtag) {
|
2017-10-06 22:15:23 +00:00
|
|
|
AnnotElemType type = AnnotElemTypes.get(subtag);
|
|
|
|
if ( type == null ) {
|
|
|
|
type = AnnotElemType.AE_UNKNOWN;
|
|
|
|
}
|
|
|
|
return type;
|
2014-12-18 21:56:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static String annotElemTypeName(char subtag) {
|
|
|
|
String retval = null;
|
|
|
|
AnnotElemType tg = AnnotElemTypes.get(subtag);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.printval;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static char annotElemTypeVal(String idValue) {
|
|
|
|
char retval = 0;
|
|
|
|
AnnotElemType tg = NameToAnnotElemType.get(idValue);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.value;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* MapTypes table. These constants are used in stackmap pseudo-instructions only.
|
|
|
|
*/
|
|
|
|
static public enum StackMapType {
|
|
|
|
/* Type codes for StackMap attribute */
|
2017-10-06 22:15:23 +00:00
|
|
|
ITEM_Bogus (0, "bogus", "B"), // an unknown or uninitialized value
|
|
|
|
ITEM_Integer (1, "int", "I"), // a 32-bit integer
|
|
|
|
ITEM_Float (2, "float", "F"), // not used
|
|
|
|
ITEM_Double (3, "double", "D"), // not used
|
|
|
|
ITEM_Long (4, "long", "L"), // a 64-bit integer
|
|
|
|
ITEM_Null (5, "null", "N"), // the type of null
|
|
|
|
ITEM_InitObject (6, "this", "IO"), // "this" in constructor
|
|
|
|
ITEM_Object (7, "CP", "O"), // followed by 2-byte index of class name
|
|
|
|
ITEM_NewObject (8, "at", "NO"), // followed by 2-byte ref to "new"
|
|
|
|
ITEM_UNKNOWN (null, "UNKNOWN", "UNKNOWN"); // placeholder for wrong types
|
|
|
|
|
|
|
|
private Integer value;
|
2014-12-18 21:56:02 +00:00
|
|
|
private final String printval;
|
|
|
|
private final String parsekey;
|
|
|
|
|
|
|
|
StackMapType(Integer val, String print, String parse) {
|
|
|
|
value = val;
|
|
|
|
printval = print;
|
|
|
|
parsekey = parse;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String parsekey() {
|
|
|
|
return parsekey;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String printval() {
|
|
|
|
return printval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Integer value() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerStackMapType(StackMapType typ) {
|
|
|
|
KeyToStackMapType.put(typ.parsekey, typ);
|
|
|
|
NameToStackMapType.put(typ.printval, typ);
|
|
|
|
StackMapTypes.put(typ.value, typ);
|
|
|
|
}
|
|
|
|
|
2017-10-06 22:15:23 +00:00
|
|
|
public static StackMapType stackMapType(int subtag, PrintWriter out) {
|
|
|
|
StackMapType type = StackMapTypes.get(subtag);
|
|
|
|
if (type == null || type == StackMapType.ITEM_UNKNOWN) {
|
|
|
|
if (out != null)
|
|
|
|
out.println("// Unknown StackMap type " + subtag);
|
|
|
|
type = StackMapType.ITEM_UNKNOWN;
|
|
|
|
type.value = subtag;
|
|
|
|
}
|
|
|
|
return type;
|
2014-12-18 21:56:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static StackMapType stackMapType(String subtag) {
|
|
|
|
return NameToStackMapType.get(subtag);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static StackMapType stackMapTypeKey(String subtag) {
|
|
|
|
return KeyToStackMapType.get(subtag);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String stackMapTypeName(int subtag) {
|
|
|
|
String retval = null;
|
|
|
|
StackMapType tg = StackMapTypes.get(subtag);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.printval;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int stackMapTypeValue(String idValue) {
|
|
|
|
int retval = 0;
|
|
|
|
StackMapType tg = NameToStackMapType.get(idValue);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.value;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* StackMap-FrameType table. These constants are used in stackmap pseudo-instructions
|
|
|
|
* only.
|
|
|
|
*/
|
|
|
|
static public enum StackMapFrameType {
|
|
|
|
/* Type codes for StackMapFrame attribute */
|
|
|
|
SAME_FRAME (0, "same"),
|
|
|
|
SAME_LOCALS_1_STACK_ITEM_FRAME (64, "stack1"),
|
|
|
|
SAME_LOCALS_1_STACK_ITEM_EXTENDED_FRAME (247, "stack1_ex"),
|
|
|
|
CHOP_1_FRAME (250, "chop1"),
|
|
|
|
CHOP_2_FRAME (249, "chop2"),
|
|
|
|
CHOP_3_FRAME (248, "chop3"),
|
|
|
|
SAME_FRAME_EX (251, "same_ex"),
|
|
|
|
APPEND_FRAME (252, "append"),
|
|
|
|
FULL_FRAME (255, "full");
|
|
|
|
|
|
|
|
private final Integer value;
|
|
|
|
private final String parsekey;
|
|
|
|
|
|
|
|
StackMapFrameType(Integer val, String print) {
|
|
|
|
value = val;
|
|
|
|
parsekey = print;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String parsekey() {
|
|
|
|
return parsekey;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Integer value() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerStackMapFrameType(StackMapFrameType typ) {
|
|
|
|
NameToStackMapFrameType.put(typ.parsekey, typ);
|
|
|
|
StackMapFrameTypes.put(typ.value, typ);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static StackMapFrameType stackMapFrameTypeVal(int subtag) {
|
|
|
|
return StackMapFrameTypes.get(subtag);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String stackMapFrameTypeName(int subtag) {
|
|
|
|
String retval = null;
|
|
|
|
StackMapFrameType tg = StackMapFrameTypes.get(subtag);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.parsekey;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static StackMapFrameType stackMapFrameType(int subtag) {
|
|
|
|
StackMapFrameType frametype;
|
|
|
|
if (subtag < StackMapFrameType.SAME_LOCALS_1_STACK_ITEM_FRAME.value()) {
|
|
|
|
// type is same_frame;
|
|
|
|
frametype = StackMapFrameType.SAME_FRAME;
|
|
|
|
} else if (subtag >= StackMapFrameType.SAME_LOCALS_1_STACK_ITEM_FRAME.value()
|
|
|
|
&& subtag <= 127) {
|
|
|
|
// type is same_locals_1_stack_item_frame
|
|
|
|
frametype = StackMapFrameType.SAME_LOCALS_1_STACK_ITEM_FRAME;
|
|
|
|
|
|
|
|
} else if (subtag >= StackMapFrameType.APPEND_FRAME.value()
|
|
|
|
&& subtag < StackMapFrameType.FULL_FRAME.value()) {
|
|
|
|
// type is append_frame
|
|
|
|
frametype = StackMapFrameType.APPEND_FRAME;
|
|
|
|
} else {
|
|
|
|
frametype = StackMapFrameTypes.get(subtag);
|
|
|
|
}
|
|
|
|
return frametype;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int stackMapFrameTypeValue(String idValue) {
|
|
|
|
int retval = 0;
|
|
|
|
StackMapFrameType tg = NameToStackMapFrameType.get(idValue);
|
|
|
|
if (tg != null) {
|
|
|
|
retval = tg.value;
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* CF_Context enums
|
|
|
|
*/
|
|
|
|
static public enum CF_Context {
|
|
|
|
|
|
|
|
CTX_CLASS (0, "class"),
|
|
|
|
CTX_FIELD (1, "field"),
|
|
|
|
CTX_METHOD (2, "method"),
|
2017-10-06 22:15:23 +00:00
|
|
|
CTX_INNERCLASS (3, "inner-class"),
|
|
|
|
CTX_MODULE (4, "module") ;
|
2014-12-18 21:56:02 +00:00
|
|
|
|
|
|
|
private final int value;
|
|
|
|
private final String printval;
|
|
|
|
|
|
|
|
CF_Context(int val, String print) {
|
|
|
|
value = val;
|
|
|
|
printval = print;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int val() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String printval() {
|
|
|
|
return printval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void registerAnnotElemType(CF_Context ctx) {
|
|
|
|
// NameToAnnotElemType.put(typ.printval, typ);
|
2017-10-06 22:15:23 +00:00
|
|
|
// AnnotElemTypes.put(typ.value, typ);
|
2014-12-18 21:56:02 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
public static CF_Context annotElemType(String idValue) {
|
|
|
|
return NameToAnnotElemType.get(idValue);
|
|
|
|
}
|
|
|
|
public static CF_Context annotElemType(int subtag) {
|
|
|
|
return AnnotElemTypes.get(subtag);
|
|
|
|
}
|
2017-10-06 22:15:23 +00:00
|
|
|
*/
|
2014-12-18 21:56:02 +00:00
|
|
|
}
|