1 /*
  2  * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 package org.openjdk.asmtools.jasm;
 24 
 25 import java.io.PrintWriter;
 26 import java.util.HashMap;
 27 
 28 /**
 29  *
 30  * Tables
 31  *
 32  * The classes in Tables are following a Singleton Pattern. These classes are Enums, and
 33  * they are contained in private hash maps (lookup tables and reverse lookup tables).
 34  * These hash maps all have public accessors, which clients use to look-up enums.
 35  *
 36  * Tokens in this table carry no external state, and are typically treated as constants.
 37  * They do not need to be reset.
 38  *
 39  */
 40 public class Tables {
 41 
 42     public static final int JAVA_MAGIC = 0xCAFEBABE;
 43     /**
 44      * Lookup-tables for various types.
 45      */
 46     private static HashMap<String, AttrTag> NameToAttrTag = new HashMap<>(9);
 47     private static HashMap<Integer, AttrTag> AttrTags = new HashMap<>(9);
 48 
 49     private static HashMap<String, SubTag> NameToSubTag = new HashMap<>(9);
 50     private static HashMap<Integer, SubTag> SubTags = new HashMap<>(9);
 51 
 52     private static HashMap<String, BasicType> NameToBasicType = new HashMap<>(10);
 53     private static HashMap<Integer, BasicType> BasicTypes = new HashMap<>(10);
 54 
 55     private static HashMap<String, AnnotElemType> NameToAnnotElemType = new HashMap<>(10);
 56     private static HashMap<Character, AnnotElemType> AnnotElemTypes = new HashMap<>(10);
 57 
 58     private static HashMap<String, StackMapType> KeyToStackMapType = new HashMap<>(10);
 59     private static HashMap<String, StackMapType> NameToStackMapType = new HashMap<>(10);
 60     private static HashMap<Integer, StackMapType> StackMapTypes = new HashMap<>(10);
 61 
 62     private static HashMap<String, StackMapFrameType> NameToStackMapFrameType = new HashMap<>(10);
 63     private static HashMap<Integer, StackMapFrameType> StackMapFrameTypes = new HashMap<>(10);
 64 
 65     private static HashMap<String, ConstType> NameToConstantType = new HashMap<>(ConstType.maxTag);
 66     private static HashMap<Integer, ConstType> ConstantTypes = new HashMap<>(ConstType.maxTag);
 67 
 68     static {
 69         // register all of the tokens
 70         for (ConstType ct : ConstType.values()) {
 71             registerConstantType(ct);
 72         }
 73 
 74         /* Type codes for SubTags */
 75         for (AttrTag at : AttrTag.values()) {
 76             registerAttrtag(at);
 77         }
 78 
 79         /* Type codes for SubTags */
 80         for (SubTag st : SubTag.values()) {
 81             registerSubtag(st);
 82         }
 83 
 84         /* Type codes for BasicTypes */
 85         for (BasicType bt : BasicType.values()) {
 86             registerBasicType(bt);
 87         }
 88 
 89         /* Type codes for BasicTypes */
 90         for (AnnotElemType aet : AnnotElemType.values()) {
 91             registerAnnotElemType(aet);
 92         }
 93 
 94         /* Type codes for StackMapTypes */
 95         for (StackMapType smt : StackMapType.values()) {
 96             registerStackMapType(smt);
 97         }
 98 
 99         /* Type codes for StackMapFrame attribute */
100         for (StackMapFrameType smft : StackMapFrameType.values()) {
101             registerStackMapFrameType(smft);
102         }
103 
104     }
105 
106     /**
107      * ConstType
108      *
109      * A (typed) tag (constant) representing the type of Constant in the Constant Pool.
110      */
111     static public enum ConstType {
112         CONSTANT_ZERO                       (-3, "CONSTANT_ZERO", ""),
113         CONSTANT_UTF8                       (1, "CONSTANT_UTF8", "Asciz"),
114         CONSTANT_UNICODE                    (2, "CONSTANT_UNICODE", ""),
115         CONSTANT_INTEGER                    (3, "CONSTANT_INTEGER", "int"),
116         CONSTANT_FLOAT                      (4, "CONSTANT_FLOAT", "float"),
117         CONSTANT_LONG                       (5, "CONSTANT_LONG", "long"),
118         CONSTANT_DOUBLE                     (6, "CONSTANT_DOUBLE", "double"),
119         CONSTANT_CLASS                      (7, "CONSTANT_CLASS", "class"),
120         CONSTANT_STRING                     (8, "CONSTANT_STRING", "String"),
121         CONSTANT_FIELD                      (9, "CONSTANT_FIELD", "Field"),
122         CONSTANT_METHOD                     (10, "CONSTANT_METHOD", "Method"),
123         CONSTANT_INTERFACEMETHOD            (11, "CONSTANT_INTERFACEMETHOD", "InterfaceMethod"),
124         CONSTANT_NAMEANDTYPE                (12, "CONSTANT_NAMEANDTYPE", "NameAndType"),
125         // Constant 13 reserved
126         // Constant 14 reserved
127         CONSTANT_METHODHANDLE               (15, "CONSTANT_METHODHANDLE", "MethodHandle"),
128         CONSTANT_METHODTYPE                 (16, "CONSTANT_METHODTYPE", "MethodType"),
129         CONSTANT_DYNAMIC                    (17, "CONSTANT_DYNAMIC", "Dynamic"),
130         CONSTANT_INVOKEDYNAMIC              (18, "CONSTANT_INVOKEDYNAMIC", "InvokeDynamic"),
131         CONSTANT_MODULE                     (19, "CONSTANT_MODULE",        "Module"),
132         CONSTANT_PACKAGE                    (20, "CONSTANT_PACKAGE",       "Package");
133 
134         static final public int maxTag = 20;
135 
136         private final int value;
137         private final String parseKey;
138         private final String printval;
139 
140         ConstType(int val, String print, String parse) {
141             value = val;
142             parseKey = parse;
143             printval = print;
144         }
145 
146         public int value() {
147             return value;
148         }
149 
150         public String parseKey() {
151             return parseKey;
152         }
153 
154         public String printval() {
155             return printval;
156         }
157 
158         public void print(PrintWriter out) {
159             out.print(parseKey);
160         }
161 
162         @Override
163         public String toString() {
164             return "<" + printval + "> [" + Integer.toString(value) + "]";
165         }
166     };
167 
168     static public ConstType tag(int i) {
169         return ConstantTypes.get(i);
170     }
171 
172     static public ConstType tag(String parsekey) {
173         return NameToConstantType.get(parsekey);
174     }
175 
176     private static void registerConstantType(ConstType tt) {
177         NameToConstantType.put(tt.parseKey, tt);
178         ConstantTypes.put(tt.value, tt);
179     }
180 
181     /**
182      * Attribute descriptor enums
183      */
184     static public enum AttrTag {
185 
186         // Constant for ME Spec (StackMap does not appear in SE VM Spec)
187         ATT_Unrecognized                            (0, "ATT_Unrecognized", ""),
188         ATT_StackMap                                (1, "ATT_StackMap", "StackMap"),
189         // Numbers corespond to VM spec (chapter 4.7.X)
190         ATT_ConstantValue                           (2, "ATT_ConstantValue", "ConstantValue"),
191         ATT_Code                                    (3, "ATT_Code", "Code"),
192         ATT_StackMapTable                           (4, "ATT_StackMapTable", "StackMapTable"),
193         ATT_Exceptions                              (5, "ATT_Exceptions", "Exceptions"),
194         ATT_InnerClasses                            (6, "ATT_InnerClasses", "InnerClasses"),
195         ATT_EnclosingMethod                         (7, "ATT_EnclosingMethod", "EnclosingMethod"),
196         ATT_Synthetic                               (8, "ATT_Synthetic", "Synthetic"),
197         ATT_Signature                               (9, "ATT_Signature", "Signature"),
198         ATT_SourceFile                              (10, "ATT_SourceFile", "SourceFile"),
199         ATT_SourceDebugExtension                    (11, "ATT_SourceDebugExtension", "SourceDebugExtension"),
200         ATT_LineNumberTable                         (12, "ATT_LineNumberTable", "LineNumberTable"),
201         ATT_LocalVariableTable                      (13, "ATT_LocalVariableTable", "LocalVariableTable"),
202         ATT_LocalVariableTypeTable                  (14, "ATT_LocalVariableTypeTable", "LocalVariableTypeTable"),
203         ATT_Deprecated                              (15, "ATT_Deprecated", "Deprecated"),
204         ATT_RuntimeVisibleAnnotations               (16, "ATT_RuntimeVisibleAnnotations", "RuntimeVisibleAnnotations"),
205         ATT_RuntimeInvisibleAnnotations             (17, "ATT_RuntimeInvisibleAnnotations", "RuntimeInvisibleAnnotations"),
206         ATT_RuntimeVisibleParameterAnnotations      (18, "ATT_RuntimeVisibleParameterAnnotations", "RuntimeVisibleParameterAnnotations"),
207         ATT_RuntimeInvisibleParameterAnnotations    (19, "ATT_RuntimeInvisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations"),
208         ATT_AnnotationDefault                       (20, "ATT_AnnotationDefault", "AnnotationDefault"),
209         ATT_BootstrapMethods                        (21, "ATT_BootstrapMethods", "BootstrapMethods"),
210         ATT_RuntimeVisibleTypeAnnotations           (22, "ATT_RuntimeVisibleTypeAnnotations", "RuntimeVisibleTypeAnnotations"),
211         ATT_RuntimeInvisibleTypeAnnotations         (23, "ATT_RuntimeInvisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations"),
212         ATT_MethodParameters                        (24, "ATT_MethodParameters", "MethodParameters"),
213         ATT_Module                                  (25, "ATT_Module",  "Module"),
214         ATT_Version                                 (26, "ATT_Version", "Version"),
215         ATT_TargetPlatform                          (27, "ATT_TargetPlatform", "TargetPlatform"),
216         ATT_MainClass                               (28, "ATT_MainClass", "MainClass"),
217         ATT_ModulePackages                          (29, "ATT_ModulePackages", "ModulePackages"),
218         ATT_ModuleMainClass                         (30, "ATT_ModuleMainClass", "ModuleMainClass"),
219         ATT_ModuleTarget                            (31, "ATT_ModuleTarget", "ModuleTarget"),
220         // JEP 181: class file 55.0
221         ATT_NestHost                                (32, "ATT_NestHost", "NestHost"),
222         ATT_NestMembers                             (33, "ATT_NestMembers", "NestMembers"),
223         //  JEP 359 Record(Preview): class file 58.65535
224         //  Record_attribute {
225         //    u2 attribute_name_index;
226         //    u4 attribute_length;
227         //    u2 components_count;
228         //    component_info components[components_count];
229         // }
230         ATT_Record                                  (34, "ATT_Record", "Record"),
231         // JEP 360 (Sealed types): class file 59.65535
232         // PermittedSubclasses_attribute {
233         //    u2 attribute_name_index;
234         //    u4 attribute_length;
235         //    u2 number_of_classes;
236         //    u2 classes[number_of_classes];
237         // }
238         ATT_PermittedSubclasses                     (35, "ATT_PermittedSubclasses", "PermittedSubclasses"),
239         ATT_Preload                                 (36, "ATT_Preload", "Preload");
240 
241         private final Integer value;
242         private final String printval;
243         private final String parsekey;
244 
245         AttrTag(Integer val, String print, String parse) {
246             value = val;
247             printval = print;
248             parsekey = parse;
249         }
250 
251         public String printval() {
252             return printval;
253         }
254 
255         public String parsekey() {
256             return parsekey;
257         }
258     }
259 
260     private static void registerAttrtag(AttrTag tg) {
261         NameToAttrTag.put(tg.parsekey, tg);
262         AttrTags.put(tg.value, tg);
263     }
264 
265     public static AttrTag attrtag(int val) {
266         AttrTag tg = AttrTags.get(val);
267         if (tg == null) {
268             tg = AttrTag.ATT_Unrecognized;
269         }
270         return tg;
271     }
272 
273     public static AttrTag attrtag(String idValue) {
274         AttrTag tg = NameToAttrTag.get(idValue);
275         if (tg == null) {
276             tg = AttrTag.ATT_Unrecognized;
277         }
278         return tg;
279     }
280 
281     public static String attrtagName(int subtag) {
282         AttrTag tg = AttrTags.get(subtag);
283         return tg.parsekey;
284     }
285 
286     public static int attrtagValue(String idValue) {
287         AttrTag tg = attrtag(idValue);
288         return tg.value;
289     }
290 
291 
292     /*-------------------------------------------------------- */
293     /**
294      * SubTag enums
295      */
296     static public enum SubTag {
297         REF_GETFIELD            (1, "REF_getField"),
298         REF_GETSTATIC           (2, "REF_getStatic"),
299         REF_PUTFIELD            (3, "REF_putField"),
300         REF_PUTSTATIC           (4, "REF_putStatic"),
301         REF_INVOKEVIRTUAL       (5, "REF_invokeVirtual"),
302         REF_INVOKESTATIC        (6, "REF_invokeStatic"),
303         REF_INVOKESPECIAL       (7, "REF_invokeSpecial"),
304         REF_NEWINVOKESPECIAL    (8, "REF_newInvokeSpecial"),
305         REF_INVOKEINTERFACE     (9, "REF_invokeInterface");
306 
307         private final Integer value;
308         private final String printval;
309 
310         SubTag(Integer val, String print) {
311             value = val;
312             printval = print;
313         }
314 
315         public String printval() {
316             return printval;
317         }
318 
319         public Integer value() {
320             return value;
321         }
322     }
323 
324     private static void registerSubtag(SubTag tg) {
325         NameToSubTag.put(tg.printval, tg);
326         SubTags.put(tg.value, tg);
327     }
328 
329     public static SubTag subtag(String subtag) {
330         return NameToSubTag.get(subtag);
331     }
332 
333     public static SubTag subtag(int subtag) {
334         return SubTags.get(subtag);
335     }
336 
337     public static String subtagName(int subtag) {
338         String retval = null;
339         SubTag tg = SubTags.get(subtag);
340         if (tg != null) {
341             retval = tg.printval;
342         }
343         return retval;
344     }
345 
346     public static int subtagValue(String idValue) {
347         int retval = 0;
348         SubTag tg = NameToSubTag.get(idValue);
349         if (tg != null) {
350             retval = tg.value;
351         }
352         return retval;
353     }
354 
355     /*-------------------------------------------------------- */
356     /**
357      * BasicType enums
358      */
359     static public enum BasicType {
360         T_INT       (0x0000000a, "int"),
361         T_LONG      (0x0000000b, "long"),
362         T_FLOAT     (0x00000006, "float"),
363         T_DOUBLE    (0x00000007, "double"),
364         T_CLASS     (0x00000002, "class"),
365         T_BOOLEAN   (0x00000004, "boolean"),
366         T_CHAR      (0x00000005, "char"),
367         T_BYTE      (0x00000008, "byte"),
368         T_SHORT     (0x00000009, "short");
369 
370         private final Integer value;
371         private final String printval;
372 
373         BasicType(Integer val, String print) {
374             value = val;
375             printval = print;
376         }
377 
378         public String printval() {
379             return printval;
380         }
381     }
382 
383     private static void registerBasicType(BasicType typ) {
384         NameToBasicType.put(typ.printval, typ);
385         BasicTypes.put(typ.value, typ);
386     }
387 
388     public static BasicType basictype(String idValue) {
389         return NameToBasicType.get(idValue);
390     }
391 
392     public static BasicType basictype(int subtag) {
393         return BasicTypes.get(subtag);
394     }
395 
396     public static String basictypeName(int subtag) {
397         String retval = null;
398         BasicType tg = BasicTypes.get(subtag);
399         if (tg != null) {
400             retval = tg.printval;
401         }
402         return retval;
403     }
404 
405     public static int basictypeValue(String idValue) {
406         int retval = -1;
407         BasicType tg = NameToBasicType.get(idValue);
408         if (tg != null) {
409             retval = tg.value;
410         }
411         return retval;
412     }
413 
414     /*-------------------------------------------------------- */
415     /**
416      * AnnotElemType enums
417      */
418     static public enum AnnotElemType {
419 
420         AE_BYTE         ('B', "byte"),
421         AE_CHAR         ('C', "char"),
422         AE_SHORT        ('S', "short"),
423         AE_INT          ('I', "int"),
424         AE_LONG         ('J', "long"),
425         AE_FLOAT        ('F', "float"),
426         AE_DOUBLE       ('D', "double"),
427         AE_BOOLEAN      ('Z', "boolean"),
428         AE_STRING       ('s', "string"),
429         AE_ENUM         ('e', "enum"),
430         AE_CLASS        ('c', "class"),
431         AE_ANNOTATION   ('@', "annotation"),
432         AE_ARRAY        ('[', "array"),
433         AE_UNKNOWN      ((char)0, "unknown");
434 
435         private char value;
436         private final String printval;
437 
438         AnnotElemType(char val, String print) {
439             value = val;
440             printval = print;
441         }
442 
443         public char val() {
444             return value;
445         }
446 
447         public String printval() {
448             return printval;
449         }
450     }
451 
452     private static void registerAnnotElemType(AnnotElemType typ) {
453         NameToAnnotElemType.put(typ.printval, typ);
454         AnnotElemTypes.put(typ.value, typ);
455     }
456 
457     public static AnnotElemType annotElemType(String idValue) {
458         return NameToAnnotElemType.get(idValue);
459     }
460 
461     public static AnnotElemType annotElemType(char subtag) {
462         AnnotElemType type = AnnotElemTypes.get(subtag);
463         if ( type == null ) {
464             type = AnnotElemType.AE_UNKNOWN;
465         }
466         return type;
467     }
468 
469     public static String annotElemTypeName(char subtag) {
470         String retval = null;
471         AnnotElemType tg = AnnotElemTypes.get(subtag);
472         if (tg != null) {
473             retval = tg.printval;
474         }
475         return retval;
476     }
477 
478     public static char annotElemTypeVal(String idValue) {
479         char retval = 0;
480         AnnotElemType tg = NameToAnnotElemType.get(idValue);
481         if (tg != null) {
482             retval = tg.value;
483         }
484         return retval;
485     }
486 
487 
488     /*-------------------------------------------------------- */
489     /**
490      * MapTypes table. These constants are used in stackmap pseudo-instructions only.
491      */
492     static public enum StackMapType {
493         /* Type codes for StackMap attribute */
494         ITEM_Bogus      (0,     "bogus",    "B"),           // an unknown or uninitialized value
495         ITEM_Integer    (1,     "int",      "I"),           // a 32-bit integer
496         ITEM_Float      (2,     "float",    "F"),           // not used
497         ITEM_Double     (3,     "double",   "D"),           // not used
498         ITEM_Long       (4,     "long",     "L"),           // a 64-bit integer
499         ITEM_Null       (5,     "null",     "N"),           // the type of null
500         ITEM_InitObject (6,     "this",     "IO"),          // "this" in constructor
501         ITEM_Object     (7,     "CP",       "O"),           // followed by 2-byte index of class name
502         ITEM_NewObject  (8,     "at",       "NO"),          // followed by 2-byte ref to "new"
503         ITEM_UNKNOWN    (null,  "UNKNOWN",  "UNKNOWN");     // placeholder for wrong types
504 
505         private Integer value;
506         private final String printval;
507         private final String parsekey;
508 
509         StackMapType(Integer val, String print, String parse) {
510             value = val;
511             printval = print;
512             parsekey = parse;
513         }
514 
515         public String parsekey() {
516             return parsekey;
517         }
518 
519         public String printval() {
520             return printval;
521         }
522 
523         public Integer value() {
524             return value;
525         }
526     }
527 
528     private static void registerStackMapType(StackMapType typ) {
529         KeyToStackMapType.put(typ.parsekey, typ);
530         NameToStackMapType.put(typ.printval, typ);
531         StackMapTypes.put(typ.value, typ);
532     }
533 
534     public static StackMapType stackMapType(int subtag, PrintWriter out) {
535         StackMapType type = StackMapTypes.get(subtag);
536         if (type == null || type == StackMapType.ITEM_UNKNOWN) {
537             if (out != null)
538                 out.println("// Unknown StackMap type " + subtag);
539             type = StackMapType.ITEM_UNKNOWN;
540             type.value = subtag;
541         }
542         return type;
543     }
544 
545     public static StackMapType stackMapType(String subtag) {
546         return NameToStackMapType.get(subtag);
547     }
548 
549     public static StackMapType stackMapTypeKey(String subtag) {
550         return KeyToStackMapType.get(subtag);
551     }
552 
553     public static String stackMapTypeName(int subtag) {
554         String retval = null;
555         StackMapType tg = StackMapTypes.get(subtag);
556         if (tg != null) {
557             retval = tg.printval;
558         }
559         return retval;
560     }
561 
562     public static int stackMapTypeValue(String idValue) {
563         int retval = 0;
564         StackMapType tg = NameToStackMapType.get(idValue);
565         if (tg != null) {
566             retval = tg.value;
567         }
568         return retval;
569     }
570 
571 
572     /*-------------------------------------------------------- */
573     /**
574      * StackMap-FrameType table. These constants are used in stackmap pseudo-instructions
575      * only.
576      */
577     static public enum StackMapFrameType {
578         /* Type codes for StackMapFrame attribute */
579         SAME_FRAME                              (0, "same"),
580         SAME_LOCALS_1_STACK_ITEM_FRAME          (64, "stack1"),
581         SAME_LOCALS_1_STACK_ITEM_EXTENDED_FRAME (247, "stack1_ex"),
582         CHOP_1_FRAME                            (250, "chop1"),
583         CHOP_2_FRAME                            (249, "chop2"),
584         CHOP_3_FRAME                            (248, "chop3"),
585         SAME_FRAME_EX                           (251, "same_ex"),
586         APPEND_FRAME                            (252, "append"),
587         FULL_FRAME                              (255, "full");
588 
589         private final Integer value;
590         private final String parsekey;
591 
592         StackMapFrameType(Integer val, String print) {
593             value = val;
594             parsekey = print;
595         }
596 
597         public String parsekey() {
598             return parsekey;
599         }
600 
601         public Integer value() {
602             return value;
603         }
604     }
605 
606     private static void registerStackMapFrameType(StackMapFrameType typ) {
607         NameToStackMapFrameType.put(typ.parsekey, typ);
608         StackMapFrameTypes.put(typ.value, typ);
609     }
610 
611     public static StackMapFrameType stackMapFrameTypeVal(int subtag) {
612         return StackMapFrameTypes.get(subtag);
613     }
614 
615     public static String stackMapFrameTypeName(int subtag) {
616         String retval = null;
617         StackMapFrameType tg = StackMapFrameTypes.get(subtag);
618         if (tg != null) {
619             retval = tg.parsekey;
620         }
621         return retval;
622     }
623 
624     public static StackMapFrameType stackMapFrameType(int subtag) {
625         StackMapFrameType frametype;
626         if (subtag < StackMapFrameType.SAME_LOCALS_1_STACK_ITEM_FRAME.value()) {
627             // type is same_frame;
628             frametype = StackMapFrameType.SAME_FRAME;
629         } else if (subtag >= StackMapFrameType.SAME_LOCALS_1_STACK_ITEM_FRAME.value()
630                 && subtag <= 127) {
631             // type is same_locals_1_stack_item_frame
632             frametype = StackMapFrameType.SAME_LOCALS_1_STACK_ITEM_FRAME;
633 
634         } else if (subtag >= StackMapFrameType.APPEND_FRAME.value()
635                 && subtag < StackMapFrameType.FULL_FRAME.value()) {
636             // type is append_frame
637             frametype = StackMapFrameType.APPEND_FRAME;
638         } else {
639             frametype = StackMapFrameTypes.get(subtag);
640         }
641         return frametype;
642     }
643 
644     public static int stackMapFrameTypeValue(String idValue) {
645         int retval = 0;
646         StackMapFrameType tg = NameToStackMapFrameType.get(idValue);
647         if (tg != null) {
648             retval = tg.value;
649         }
650         return retval;
651     }
652 
653     /**
654      * CF_Context enums
655      */
656     public enum CF_Context {
657 
658         CTX_CLASS       (0, "class"),
659         CTX_FIELD       (1, "field"),
660         CTX_METHOD      (2, "method"),
661         CTX_INNERCLASS  (3, "inner-class"),
662         CTX_MODULE      (4, "module") ;
663 
664         private final int value;
665         private final String printval;
666 
667         CF_Context(int val, String print) {
668             value = val;
669             printval = print;
670         }
671 
672         boolean isOneOf(CF_Context... items) {
673             for(CF_Context item : items) {
674                 if(item.value == value) {
675                     return true;
676                 }
677             }
678             return false;
679         }
680 
681         public int val() {
682             return value;
683         }
684 
685         public String printval() {
686             return printval;
687         }
688     }
689 }