1 /*
2  * Copyright (c) 2001, 2018, 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 
24 package nsk.share.jdwp;
25 
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Hashtable;
29 
30 import nsk.share.Failure;
31 
32 /**
33  * This class contains JDWP constants, types and parameters.
34  */
35 public class JDWP {
36 
37     public static class Error {
38 
39         public static final int NONE                            = 0;
40         public static final int INVALID_THREAD                  = 10;
41         public static final int INVALID_THREAD_GROUP            = 11;
42         public static final int INVALID_PRIORITY                = 12;
43         public static final int THREAD_NOT_SUSPENDED            = 13;
44         public static final int THREAD_SUSPENDED                = 14;
45         public static final int INVALID_OBJECT                  = 20;
46         public static final int INVALID_CLASS                   = 21;
47         public static final int CLASS_NOT_PREPARED              = 22;
48         public static final int INVALID_METHODID                = 23;
49         public static final int INVALID_LOCATION                = 24;
50         public static final int INVALID_FIELDID                 = 25;
51         public static final int INVALID_FRAMEID                 = 30;
52         public static final int NO_MORE_FRAMES                  = 31;
53         public static final int OPAQUE_FRAME                    = 32;
54         public static final int NOT_CURRENT_FRAME               = 33;
55         public static final int TYPE_MISMATCH                   = 34;
56         public static final int INVALID_SLOT                    = 35;
57         public static final int DUPLICATE                       = 40;
58         public static final int NOT_FOUND                       = 41;
59         public static final int INVALID_MONITOR                 = 50;
60         public static final int NOT_MONITOR_OWNER               = 51;
61         public static final int INTERRUPT                       = 52;
62         public static final int INVALID_CLASS_FORMAT            = 60;
63         public static final int CIRCULAR_CLASS_DEFINITION       = 61;
64         public static final int FAILS_VERIFICATION              = 62;
65         public static final int ADD_METHOD_NOT_IMPLEMENTED      = 63;
66         public static final int SCHEMA_CHANGE_NOT_IMPLEMENTED   = 64;
67         public static final int INVALID_TYPESTATE               = 65;
68         public static final int HIERARCHY_CHANGE_NOT_IMPLEMENTED= 66;
69         public static final int DELETE_METHOD_NOT_IMPLEMENTED   = 67;
70         public static final int UNSUPPORTED_VERSION             = 68;
71         public static final int NAMES_DONT_MATCH                = 69;
72         public static final int CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED  = 70;
73         public static final int METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 71;
74         public static final int NOT_IMPLEMENTED                 = 99;
75         public static final int NULL_POINTER                    = 100;
76         public static final int ABSENT_INFORMATION              = 101;
77         public static final int INVALID_EVENT_TYPE              = 102;
78         public static final int ILLEGAL_ARGUMENT                = 103;
79         public static final int OUT_OF_MEMORY                   = 110;
80         public static final int ACCESS_DENIED                   = 111;
81         public static final int VM_DEATH                        = 112;
82         public static final int INTERNAL                        = 113;
83         public static final int UNATTACHED_THREAD               = 115;
84         public static final int INVALID_TAG                     = 500;
85         public static final int ALREADY_INVOKING                = 502;
86         public static final int INVALID_INDEX                   = 503;
87         public static final int INVALID_LENGTH                  = 504;
88         public static final int INVALID_STRING                  = 506;
89         public static final int INVALID_CLASS_LOADER            = 507;
90         public static final int INVALID_ARRAY                   = 508;
91         public static final int TRANSPORT_LOAD                  = 509;
92         public static final int TRANSPORT_INIT                  = 510;
93         public static final int NATIVE_METHOD                   = 511;
94         public static final int INVALID_COUNT                   = 512;
95 
96     }
97 
98     public static class Flag {
99 
100         public static final byte NONE           = (byte)0;
101         public static final byte REPLY_PACKET   = (byte)0x80;
102         public static final byte EVENT_PACKET   = NONE;
103 
104     }
105 
106     public static class EventKind {
107 
108         public static final byte VM_INIT         = (byte)90;
109         public static final byte VM_START        = VM_INIT;
110         public static final byte VM_DISCONNECTED = (byte)100;
111         public static final byte VM_DEATH        = (byte)99;
112 
113         public static final byte THREAD_START    = (byte)6;
114         public static final byte THREAD_END      = (byte)7;
115         public static final byte THREAD_DEATH    = THREAD_END;
116 
117         public static final byte CLASS_PREPARE   = (byte)8;
118         public static final byte CLASS_LOAD      = (byte)10;
119         public static final byte CLASS_UNLOAD    = (byte)9;
120 
121         public static final byte METHOD_ENTRY    = (byte)40;
122         public static final byte METHOD_EXIT     = (byte)41;
123 
124         public static final byte FIELD_ACCESS    = (byte)20;
125         public static final byte FIELD_MODIFICATION = (byte)21;
126 
127         public static final byte EXCEPTION       = (byte)4;
128         public static final byte EXCEPTION_CATCH = (byte)30;
129 
130         public static final byte FRAME_POP       = (byte)3;
131 
132         public static final byte BREAKPOINT      = (byte)2;
133 
134         public static final byte SINGLE_STEP     = (byte)1;
135 
136         public static final byte USER_DEFINED    = (byte)5;
137 
138     }
139 
140     public static class EventModifierKind {
141 
142         public static final byte COUNT          = (byte)1;
143         public static final byte CONDITIONAL    = (byte)2;
144         public static final byte THREAD_ONLY    = (byte)3;
145         public static final byte CLASS_ONLY     = (byte)4;
146         public static final byte CLASS_MATCH    = (byte)5;
147         public static final byte CLASS_EXCLUDE  = (byte)6;
148         public static final byte LOCATION_ONLY  = (byte)7;
149         public static final byte EXCEPTION_ONLY = (byte)8;
150         public static final byte FIELD_ONLY     = (byte)9;
151         public static final byte STEP           = (byte)10;
152         public static final byte INSTANCE_ONLY  = (byte)11;
153     };
154 
155     public static class ThreadStatus {
156 
157         public static final int ZOMBIE          = 0;
158         public static final int RUNNING         = 1;
159         public static final int SLEEPING        = 2;
160         public static final int MONITOR         = 3;
161         public static final int WAIT            = 4;
162 
163     }
164 
165     public static class SuspendStatus {
166 
167         public static final int SUSPEND_STATUS_SUSPENDED = 0x1;
168 
169     }
170 
171     public static class ClassStatus {
172 
173         public static final int PREPARED        = 2;
174         public static final int VERIFIED        = 1;
175         public static final int INITIALIZED     = 4;
176         public static final int ERROR           = 8;
177 
178     }
179 
180     public static class TypeTag {
181 
182         public static final byte CLASS           = (byte)1;
183         public static final byte INTERFACE       = (byte)2;
184         public static final byte ARRAY           = (byte)3;
185 
186     }
187 
188     public static class Tag {
189 
190         public static final byte ARRAY           = (byte)91;
191         public static final byte BYTE            = (byte)66;
192         public static final byte CHAR            = (byte)67;
193         public static final byte OBJECT          = (byte)76;
194         public static final byte FLOAT           = (byte)70;
195         public static final byte DOUBLE          = (byte)68;
196         public static final byte INT             = (byte)73;
197         public static final byte LONG            = (byte)74;
198         public static final byte SHORT           = (byte)83;
199         public static final byte VOID            = (byte)86;
200         public static final byte BOOLEAN         = (byte)90;
201         public static final byte STRING          = (byte)115;
202         public static final byte THREAD          = (byte)116;
203         public static final byte THREAD_GROUP    = (byte)103;
204         public static final byte CLASS_LOADER    = (byte)108;
205         public static final byte CLASS_OBJECT    = (byte)99;
206 
207     }
208 
209     public static class StepDepth {
210 
211         public static final int INTO            = 0;
212         public static final int OVER            = 1;
213         public static final int OUT             = 2;
214 
215     }
216 
217     public static class StepSize {
218 
219         public static final int MIN             = 0;
220         public static final int LINE            = 1;
221 
222     }
223 
224     public static class SuspendPolicy {
225 
226         public static final byte NONE            = (byte)0;
227         public static final byte EVENT_THREAD    = (byte)1;
228         public static final byte ALL             = (byte)2;
229 
230     }
231 
232     public static class InvokeOptions {
233 
234         public static final int INVOKE_SINGLE_THREADED     = 0x01;
235         public static final int INVOKE_NONVIRTUAL          = 0x02;
236 
237     }
238 
239     public static class TypeSize {
240 
241         // VM independent type sizes
242 
243         public static final int BYTE              = 1;
244         public static final int BOOLEAN           = 1;
245         public static final int CHAR              = 2;
246         public static final int SHORT             = 2;
247         public static final int FLOAT             = 4;
248         public static final int INT               = 4;
249         public static final int LONG              = 8;
250         public static final int DOUBLE            = 8;
251 
252         public static final int TAG               = 1;
253         public static final int LOCATION_INDEX    = 8;
254 
255         // basic VM specific type sizes
256 
257         public static int OBJECT_ID         = 8;
258         public static int METHOD_ID         = 4;
259         public static int FIELD_ID          = 4;
260         public static int FRAME_ID          = 4;
261 
262         // derivative VM specific type sizes
263 
264         public static int TAGGED_OBJECT_ID  = TAG + OBJECT_ID;
265 
266         public static int THREAD_ID         = OBJECT_ID;
267         public static int THREAD_GROUP_ID   = OBJECT_ID;
268         public static int STRING_ID         = OBJECT_ID;
269         public static int CLASS_LOADER_ID   = OBJECT_ID;
270         public static int CLASS_OBJECT_ID   = OBJECT_ID;
271         public static int REFERENCE_TYPE_ID = OBJECT_ID;
272 
273         public static int CLASS_ID          = REFERENCE_TYPE_ID;
274         public static int INTERFACE_ID      = REFERENCE_TYPE_ID;
275         public static int ARRAY_ID          = REFERENCE_TYPE_ID;
276 
277         public static int LOCATION          = TAG + CLASS_ID + METHOD_ID + LOCATION_INDEX;
278 
279         /**
280          * Calculate type sizes based on VM dependent basic type sizes.
281          */
CalculateSizes()282         public static void CalculateSizes() {
283 
284             TAGGED_OBJECT_ID  = TAG + OBJECT_ID;
285 
286             THREAD_ID         = OBJECT_ID;
287             THREAD_GROUP_ID   = OBJECT_ID;
288             STRING_ID         = OBJECT_ID;
289             CLASS_LOADER_ID   = OBJECT_ID;
290             CLASS_OBJECT_ID   = OBJECT_ID;
291             REFERENCE_TYPE_ID = OBJECT_ID;
292 
293             CLASS_ID          = REFERENCE_TYPE_ID;
294             INTERFACE_ID      = REFERENCE_TYPE_ID;
295             ARRAY_ID          = REFERENCE_TYPE_ID;
296 
297             LOCATION          = TAG + CLASS_ID + METHOD_ID + LOCATION_INDEX;
298         }
299 
300     }
301 
302     public static class ModifierFlag {
303 
304         public static final int PUBLIC                = 0x0001;
305         public static final int PRIVATE               = 0x0002;
306         public static final int PROTECTED             = 0x0004;
307         public static final int STATIC                = 0x0008;
308         public static final int FINAL                 = 0x0010;
309         public static final int SUPER                 = 0x0020;
310         public static final int VOLATILE              = 0x0040;
311         public static final int TRANSIENT             = 0x0080;
312         public static final int SYNCHRONIZED          = 0x0020;
313         public static final int NATIVE                = 0x0100;
314         public static final int INTERFACE             = 0x0200;
315         public static final int ABSTRACT              = 0x0400;
316         public static final int SYNTHETIC             = 0xF0000000;
317 
318         public static final int CLASS_MASK            = PUBLIC | FINAL | SUPER | INTERFACE | ABSTRACT;
319         public static final int FIELD_MASK            = PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT;
320         public static final int METHOD_MASK           = PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | SYNCHRONIZED | NATIVE | ABSTRACT;
321 
322     }
323 
324     public static class CommandSet {
325 
326         public static final byte VirtualMachine        = (byte)0x01;
327         public static final byte ReferenceType         = (byte)0x02;
328         public static final byte ClassType             = (byte)0x03;
329         public static final byte ArrayType             = (byte)0x04;
330         public static final byte InterfaceType         = (byte)0x05;
331         public static final byte Method                = (byte)0x06;
332         public static final byte Field                 = (byte)0x08;
333         public static final byte ObjectReference       = (byte)0x09;
334         public static final byte StringReference       = (byte)0x0A;
335         public static final byte ThreadReference       = (byte)0x0B;
336         public static final byte ThreadGroupReference  = (byte)0x0C;
337         public static final byte ArrayReferemce        = (byte)0x0D;
338         public static final byte ClassLoaderReference  = (byte)0x0E;
339         public static final byte EventRequest          = (byte)0x0F;
340         public static final byte StackFrame            = (byte)0x10;
341         public static final byte ClassObjectReference  = (byte)0x11;
342         public static final byte Event                 = (byte)0x40;
343 
344     }
345 
346     // command names, used only for debug output
347     public static HashMap<Integer, String> commandNames = new HashMap<Integer, String>();
348 
349     static
350     {
commandNames.put(Command.ObjectReference.ReferringObjects, R)351         commandNames.put(Command.ObjectReference.ReferringObjects, "ObjectReference.ReferringObjects");
commandNames.put(Command.ReferenceType.Instances, R)352         commandNames.put(Command.ReferenceType.Instances, "ReferenceType.Instances");
commandNames.put(Command.ReferenceType.ClassFileVersion, R)353         commandNames.put(Command.ReferenceType.ClassFileVersion, "ReferenceType.ClassFileVersion");
commandNames.put(Command.ReferenceType.ConstantPool, R)354         commandNames.put(Command.ReferenceType.ConstantPool, "ReferenceType.ConstantPool");
commandNames.put(Command.ThreadReference.OwnedMonitorsStackDepthInfo, R)355         commandNames.put(Command.ThreadReference.OwnedMonitorsStackDepthInfo, "ThreadReference.OwnedMonitorsStackDepthInfo");
commandNames.put(Command.ThreadReference.ForceEarlyReturn, R)356         commandNames.put(Command.ThreadReference.ForceEarlyReturn, "ThreadReference.ForceEarlyReturn");
commandNames.put(Command.VirtualMachine.InstanceCounts, R)357         commandNames.put(Command.VirtualMachine.InstanceCounts, "VirtualMachine.InstanceCounts");
358     }
359 
360     public static class Command {
361 
362         public static class VirtualMachine {
363 
364             public static final int Version             = 0x0101;
365             public static final int ClassesBySignature  = 0x0102;
366             public static final int AllClasses          = 0x0103;
367             public static final int AllThreads          = 0x0104;
368             public static final int TopLevelThreadGroups  = 0x0105;
369             public static final int Dispose             = 0x0106;
370             public static final int IDSizes             = 0x0107;
371             public static final int Suspend             = 0x0108;
372             public static final int Resume              = 0x0109;
373             public static final int Exit                = 0x010A;
374             public static final int CreateString        = 0x010B;
375             public static final int Capabilities        = 0x010C;
376             public static final int ClassPaths          = 0x010D;
377             public static final int DisposeObjects      = 0x010E;
378             public static final int HoldEvents          = 0x010F;
379             public static final int ReleaseEvents       = 0x0110;
380 
381             // since JDK-1.4
382             public static final int CapabilitiesNew     = 0x0111;
383             public static final int RedefineClasses     = 0x0112;
384             public static final int SetDefaultStratum   = 0x0113;
385 
386             // since JDK-1.5
387             public static final int AllClassesWithGeneric = 0x0114;
388 
389             // since JDK-1.6
390             public static final int InstanceCounts      = 0x0115;
391         }
392 
393         public static class ReferenceType {
394 
395             public static final int Signature           = 0x0201;
396             public static final int ClassLoader         = 0x0202;
397             public static final int Modifiers           = 0x0203;
398             public static final int Fields              = 0x0204;
399             public static final int Methods             = 0x0205;
400             public static final int GetValues           = 0x0206;
401             public static final int SourceFile          = 0x0207;
402             public static final int NestedTypes         = 0x0208;
403             public static final int Status              = 0x0209;
404             public static final int Interfaces          = 0x020A;
405             public static final int ClassObject         = 0x020B;
406 
407             // since JDK-1.4
408             public static final int SourceDebugExtension = 0x020C;
409 
410             // since JDK-1.5
411             public static final int SignatureWithGeneric = 0x020D;
412             public static final int FieldsWithGeneric = 0x020E;
413             public static final int MethodsWithGeneric = 0x020F;
414 
415             // since JDK-1.6
416             public static final int Instances = 0x0210;
417             public static final int ClassFileVersion = 0x0211;
418             public static final int ConstantPool = 0x0212;
419         }
420 
421         public static class ClassType {
422 
423             public static final int Superclass          = 0x0301;
424             public static final int SetValues           = 0x0302;
425             public static final int InvokeMethod        = 0x0303;
426             public static final int NewInstance         = 0x0304;
427 
428         }
429 
430         public static class ArrayType {
431 
432             public static final int NewInstance         = 0x0401;
433 
434         }
435 
436         public static class InterfaceType {
437 
438         }
439 
440         public static class Method {
441 
442             public static final int LineTable           = 0x0601;
443             public static final int VariableTable       = 0x0602;
444             public static final int Bytecodes           = 0x0603;
445 
446             // since JDK-1.4
447             public static final int IsObsolete          = 0x0604;
448 
449             // since JDK-1.5
450             public static final int VariableTableWithGeneric = 0x0605;
451 
452         }
453 
454         public static class Field {
455 
456         }
457 
458         public static class ObjectReference {
459 
460             public static final int ReferenceType       = 0x0901;
461             public static final int GetValues           = 0x0902;
462             public static final int SetValues           = 0x0903;
463             public static final int MonitorInfo         = 0x0905;
464             public static final int InvokeMethod        = 0x0906;
465             public static final int DisableCollection   = 0x0907;
466             public static final int EnableCollection    = 0x0908;
467             public static final int IsCollected         = 0x0909;
468 
469             // since JDK-1.6
470             public static final int ReferringObjects         = 0x090A;
471         }
472 
473         public static class StringReference {
474 
475             public static final int Value               = 0x0A01;
476 
477         }
478 
479         public static class ThreadReference {
480 
481             public static final int Name                = 0x0B01;
482             public static final int Suspend             = 0x0B02;
483             public static final int Resume              = 0x0B03;
484             public static final int Status              = 0x0B04;
485             public static final int ThreadGroup         = 0x0B05;
486             public static final int Frames              = 0x0B06;
487             public static final int FrameCount          = 0x0B07;
488             public static final int OwnedMonitors       = 0x0B08;
489             public static final int CurrentContendedMonitor = 0x0B09;
490             public static final int Stop                = 0x0B0A;
491             public static final int Interrupt           = 0x0B0B;
492             public static final int SuspendCount        = 0x0B0C;
493             public static final int PopTopFrame         = 0x0B0D;
494 
495             // since JDK-1.6
496             public static final int OwnedMonitorsStackDepthInfo = 0x0B0D;
497             public static final int ForceEarlyReturn = 0x0B0E;
498         }
499 
500         public static class ThreadGroupReference {
501 
502             public static final int Name                = 0x0C01;
503             public static final int Parent              = 0x0C02;
504             public static final int Children            = 0x0C03;
505 
506         }
507 
508         public static class ArrayReference {
509 
510             public static final int Length              = 0x0D01;
511             public static final int GetValues           = 0x0D02;
512             public static final int SetValues           = 0x0D03;
513 
514         }
515 
516         public static class ClassLoaderReference {
517 
518             public static final int VisibleClasses      = 0x0E01;
519 
520         }
521 
522         public static class EventRequest {
523 
524             public static final int Set                 = 0x0F01;
525             public static final int Clear               = 0x0F02;
526             public static final int ClearAllBreakpoints = 0x0F03;
527 
528         }
529 
530         public static class StackFrame {
531 
532             public static final int GetValues           = 0x1001;
533             public static final int SetValues           = 0x1002;
534             public static final int ThisObject          = 0x1003;
535 
536             // since JDK-1.4
537             public static final int PopFrames           = 0x1004;
538 
539         }
540 
541         public static class ClassObjectReference {
542 
543             public static final int ReflectedType       = 0x1101;
544 
545         }
546 
547         public static class Event {
548 
549             public static final int Composite           = 0x4064;
550 
551         }
552 
553     } // end of class Command
554 
555     public static class Capability {
556 
557         // common capabilities
558         public static final int CAN_WATCH_FIELD_MODIFICATION        = 0;
559         public static final int CAN_WATCH_FIELD_ACCESS              = 1;
560         public static final int CAN_GET_BYTECODES                   = 2;
561         public static final int CAN_GET_SYNTHETIC_ATTRIBUTE         = 3;
562         public static final int CAN_GET_OWNED_MONITOR_INFO          = 4;
563         public static final int CAN_GET_CURRENT_CONTENDED_MONITOR   = 5;
564         public static final int CAN_GET_MONITOR_INFO                = 6;
565 
566         // new capabilities (since JDWP version 1.4)
567         public static final int CAN_REDEFINE_CLASSES                = 7;
568         public static final int CAN_ADD_METHODR_INFO                = 8;
569         public static final int CAN_UNRESTRICTEDLY_REDEFINE_CLASSES = 9;
570         public static final int CAN_POP_FRAMES                      = 10;
571         public static final int CAN_USE_INSTANCE_FILTER             = 11;
572         public static final int CAN_GET_SOURCE_DEBUG_EXTENSION      = 12;
573         public static final int CAN_REQUEST_VMDEATH_EVENT           = 13;
574         public static final int CAN_SET_DEFAULT_STRATUM             = 14;
575     }
576 
577     public static class Location extends ByteBuffer {
578 
579         public static int TAG_OFFSET = 0;
580         public static int CLASS_ID_OFFSET = TAG_OFFSET + JDWP.TypeSize.TAG;
581         public static int METHOD_ID_OFFSET = CLASS_ID_OFFSET + JDWP.TypeSize.CLASS_ID;
582         public static int INDEX_OFFSET = METHOD_ID_OFFSET + JDWP.TypeSize.METHOD_ID;
583 
calculateOffsets()584         private static void calculateOffsets() {
585             CLASS_ID_OFFSET = TAG_OFFSET + JDWP.TypeSize.TAG;
586             METHOD_ID_OFFSET = CLASS_ID_OFFSET + JDWP.TypeSize.CLASS_ID;
587             INDEX_OFFSET = METHOD_ID_OFFSET + JDWP.TypeSize.METHOD_ID;
588         }
589 
Location(byte typeTag, long classID, long methodID, long index)590         public Location(byte typeTag, long classID, long methodID, long index) {
591             this();
592             // 1 byte type tag
593             putTag(typeTag);
594             // classID
595             putClassID(classID);
596             // methodID
597             putMethodID(methodID);
598             // 8 bytes index
599             putIndex(index);
600         }
601 
Location()602         public Location() {
603             super(JDWP.TypeSize.LOCATION, 0);
604             addBytes((byte)0, TypeSize.LOCATION);
605 
606             // calculate offsets for VM-dependent type sizes
607             calculateOffsets();
608         }
609 
getTag()610         public final byte getTag() {
611             try {
612                 return getByte(TAG_OFFSET);
613             } catch (BoundException e) {
614                 throw new Failure("Unable to get tag from location:\n\t" + e);
615             }
616         }
617 
getClassID()618         public final long getClassID() {
619             try {
620                 return getID(CLASS_ID_OFFSET, JDWP.TypeSize.CLASS_ID);
621             } catch (BoundException e) {
622                 throw new Failure("Unable to get classID from location:\n\t" + e);
623             }
624         }
625 
getMethodID()626         public final long getMethodID() {
627             try {
628                 return getID(METHOD_ID_OFFSET, JDWP.TypeSize.METHOD_ID);
629             } catch (BoundException e) {
630                 throw new Failure("Unable to get methodID from location:\n\t" + e);
631             }
632         }
633 
getIndex()634         public final long getIndex() {
635             try {
636                 return getID(INDEX_OFFSET, JDWP.TypeSize.LOCATION_INDEX);
637             } catch (BoundException e) {
638                 throw new Failure("Unable to get code index from location:\n\t" + e);
639             }
640         }
641 
putTag(byte tag)642         public final void putTag(byte tag) {
643             try {
644                 putByte(TAG_OFFSET, tag);
645             } catch (BoundException e) {
646                 throw new Failure("Unable to put tag into location:\n\t" + e);
647             }
648         }
649 
putClassID(long classID)650         public final void putClassID(long classID) {
651             try {
652                 putID(CLASS_ID_OFFSET, classID, JDWP.TypeSize.CLASS_ID);
653             } catch (BoundException e) {
654                 throw new Failure("Unable to put classID into location:\n\t" + e);
655             }
656         }
657 
putMethodID(long methodID)658         public final void putMethodID(long methodID) {
659             try {
660                 putID(METHOD_ID_OFFSET, methodID, JDWP.TypeSize.METHOD_ID);
661             } catch (BoundException e) {
662                 throw new Failure("Unable to put methodID into location:\n\t" + e);
663             }
664         }
665 
putIndex(long index)666         public final void putIndex(long index) {
667             try {
668                 putID(INDEX_OFFSET, index, JDWP.TypeSize.LOCATION_INDEX);
669             } catch (BoundException e) {
670                 throw new Failure("Unable to put code index into location:\n\t" + e);
671             }
672         }
673 
toString()674         public String toString() {
675             return "Location("
676             + "tag=" + getTag() + ", "
677             + "classID=" + getClassID() + ", "
678             + "methodID=" + getMethodID() + ", "
679             + "index=" + getIndex()
680             + ")";
681         }
682 
683     } // end of class Location
684 
685     public static class UntaggedValue {
686 
687         public Object value = null;
688 
UntaggedValue()689         public UntaggedValue() {
690         }
691 
UntaggedValue(Object value)692         public UntaggedValue(Object value) {
693             this.value = value;
694         }
695 
getValue()696         public Object getValue() {
697             return value;
698         }
699 
length(byte tag)700         public int length(byte tag) {
701             int valueSize = 0;
702             try {
703                 switch (tag) {
704                     case JDWP.Tag.BYTE: {
705                         valueSize = JDWP.TypeSize.BYTE;
706                     } break;
707                     case JDWP.Tag.CHAR: {
708                         valueSize = JDWP.TypeSize.CHAR;
709                     } break;
710                     case JDWP.Tag.FLOAT: {
711                         valueSize = JDWP.TypeSize.FLOAT;
712                     } break;
713                     case JDWP.Tag.DOUBLE: {
714                         valueSize = JDWP.TypeSize.DOUBLE;
715                     } break;
716                     case JDWP.Tag.INT: {
717                         valueSize = JDWP.TypeSize.INT;
718                     } break;
719                     case JDWP.Tag.SHORT: {
720                         valueSize = JDWP.TypeSize.SHORT;
721                     } break;
722                     case JDWP.Tag.BOOLEAN: {
723                         valueSize = JDWP.TypeSize.BYTE;
724                     } break;
725                     case JDWP.Tag.LONG: {
726                         valueSize = JDWP.TypeSize.LONG;
727                     } break;
728                     case JDWP.Tag.VOID: {
729                         valueSize = 0;
730                     } break;
731                     case JDWP.Tag.ARRAY:
732                     case JDWP.Tag.OBJECT:
733                     case JDWP.Tag.STRING:
734                     case JDWP.Tag.THREAD:
735                     case JDWP.Tag.THREAD_GROUP:
736                     case JDWP.Tag.CLASS_LOADER:
737                     case JDWP.Tag.CLASS_OBJECT: {
738                         valueSize = JDWP.TypeSize.OBJECT_ID;
739                     } break;
740                     default: {
741                         throw new Failure("Unknown tag found while putting value into packet: " + tag);
742                     }
743                 }
744             } catch (ClassCastException e) {
745                 throw new Failure("Wrong tag " + tag + " found while putting value to packet: " + value);
746             }
747             return JDWP.TypeSize.TAG + valueSize;
748         }
749 
addValueTo(Packet packet, byte tag)750         public void addValueTo(Packet packet, byte tag) {
751             if (value == null) {
752                 throw new Failure("Unable to put null value into packet: " + this);
753             }
754             try {
755                 switch (tag) {
756                     case JDWP.Tag.BYTE: {
757                         byte castedValue = ((Byte)value).byteValue();
758                         packet.addByte(castedValue);
759                     } break;
760                     case JDWP.Tag.CHAR: {
761                         char castedValue = ((Character)value).charValue();
762                         packet.addChar(castedValue);
763                     } break;
764                     case JDWP.Tag.FLOAT: {
765                         float castedValue = ((Float)value).floatValue();
766                         packet.addFloat(castedValue);
767                     } break;
768                     case JDWP.Tag.DOUBLE: {
769                         double castedValue = ((Double)value).doubleValue();
770                         packet.addDouble(castedValue);
771                     } break;
772                     case JDWP.Tag.INT: {
773                         int castedValue = ((Integer)value).intValue();
774                         packet.addInt(castedValue);
775                     } break;
776                     case JDWP.Tag.SHORT: {
777                         short castedValue = ((Short)value).shortValue();
778                         packet.addShort(castedValue);
779                     } break;
780                     case JDWP.Tag.BOOLEAN: {
781                         boolean castedValue = ((Boolean)value).booleanValue();
782                         packet.addByte((byte)(castedValue? 1 : 0));
783                     } break;
784                     case JDWP.Tag.LONG: {
785                         long castedValue = ((Long)value).longValue();
786                         packet.addLong(castedValue);
787                     } break;
788                     case JDWP.Tag.VOID: {
789                     } break;
790                     case JDWP.Tag.ARRAY:
791                     case JDWP.Tag.OBJECT:
792                     case JDWP.Tag.STRING:
793                     case JDWP.Tag.THREAD:
794                     case JDWP.Tag.THREAD_GROUP:
795                     case JDWP.Tag.CLASS_LOADER:
796                     case JDWP.Tag.CLASS_OBJECT: {
797                         long castedValue = ((Long)value).longValue();
798                         packet.addObjectID(castedValue);
799                     } break;
800                     default: {
801                         throw new Failure("Unknown tag found while putting value into packet: " + tag);
802                     }
803                 }
804             } catch (ClassCastException e) {
805                 throw new Failure("Wrong tag " + tag + " found while putting value to packet: " + value);
806             }
807         }
808 
getValueFrom(Packet packet, byte tag)809         public void getValueFrom(Packet packet, byte tag) throws BoundException {
810             switch (tag) {
811                 case JDWP.Tag.BYTE: {
812                     byte castedValue = packet.getByte();
813                     value = new Byte(castedValue);
814                 } break;
815                 case JDWP.Tag.CHAR: {
816                     char castedValue = packet.getChar();
817                     value = new Character(castedValue);
818                 } break;
819                 case JDWP.Tag.FLOAT: {
820                     float castedValue = packet.getFloat();
821                     value = new Float(castedValue);
822                 } break;
823                 case JDWP.Tag.DOUBLE: {
824                     double castedValue = packet.getDouble();
825                     value = new Double(castedValue);
826                 } break;
827                 case JDWP.Tag.INT: {
828                     int castedValue = packet.getInt();
829                     value = new Integer(castedValue);
830                 } break;
831                 case JDWP.Tag.SHORT: {
832                     short castedValue = packet.getShort();
833                     value = new Short(castedValue);
834                 } break;
835                 case JDWP.Tag.BOOLEAN: {
836                     byte castedValue = packet.getByte();
837                     value = new Boolean(castedValue != 0);
838                 } break;
839                 case JDWP.Tag.LONG: {
840                     long castedValue = packet.getLong();
841                     value = new Long(castedValue);
842                 } break;
843                 case JDWP.Tag.VOID: {
844                     value = new Long(0);
845                 } break;
846                 case JDWP.Tag.ARRAY:
847                 case JDWP.Tag.OBJECT:
848                 case JDWP.Tag.STRING:
849                 case JDWP.Tag.THREAD:
850                 case JDWP.Tag.THREAD_GROUP:
851                 case JDWP.Tag.CLASS_LOADER:
852                 case JDWP.Tag.CLASS_OBJECT: {
853                     long castedValue = packet.getObjectID();
854                     value = new Long(castedValue);
855                 } break;
856                 default: {
857                     throw new Failure("Unknown tag found while reading value from packet: " + tag);
858                 }
859             }
860         }
861 
toString(byte tag)862         public String toString(byte tag) {
863             if (value == null) {
864                 return "null";
865             }
866             String type = null;
867             try {
868                 switch (tag) {
869                     case JDWP.Tag.BYTE: {
870                         type = "BYTE";
871                     } break;
872                     case JDWP.Tag.CHAR: {
873                         type = "CHAR";
874                     } break;
875                     case JDWP.Tag.FLOAT: {
876                         type = "FLOAT";
877                     } break;
878                     case JDWP.Tag.DOUBLE: {
879                         type = "DOUBLE";
880                     } break;
881                     case JDWP.Tag.INT: {
882                         type = "INT";
883                     } break;
884                     case JDWP.Tag.SHORT: {
885                         type = "SHORT";
886                     } break;
887                     case JDWP.Tag.BOOLEAN: {
888                         type = "BOOLEAN";
889                     } break;
890                     case JDWP.Tag.LONG: {
891                         type = "LONG";
892                     } break;
893                     case JDWP.Tag.VOID: {
894                         type = "VOID";
895                     } break;
896                     case JDWP.Tag.ARRAY: {
897                         type = "ARRAY_ID";
898                     } break;
899                     case JDWP.Tag.OBJECT: {
900                         type = "OBJECT_ID";
901                     } break;
902                     case JDWP.Tag.STRING: {
903                         type = "STRING_ID";
904                     } break;
905                     case JDWP.Tag.THREAD: {
906                         type = "THREAD_ID";
907                     } break;
908                     case JDWP.Tag.THREAD_GROUP: {
909                         type = "THREAD_GROUP_ID";
910                     } break;
911                     case JDWP.Tag.CLASS_LOADER: {
912                         type = "CLASS_LOADER_ID";
913                     } break;
914                     case JDWP.Tag.CLASS_OBJECT: {
915                         type = "CLASS_OBJECT_ID";
916                     } break;
917                     default: {
918                         throw new Failure("Unknown tag found while converting value into string: " + tag);
919                     }
920                 }
921                 return "(" + type + ")" + value;
922             } catch (ClassCastException e) {
923                 throw new Failure("Wrong tag " + tag + " found while putting value to packet: " + value);
924             }
925         }
926 
927     } // end of class Value
928 
929     public static class Value extends UntaggedValue {
930 
931         public static final int TAG_OFFSET = 0;
932         public static final int VALUE_OFFSET = TAG_OFFSET + TypeSize.TAG;
933 
934         public byte tag = 0;
935 
Value()936         public Value() {
937         }
938 
Value(byte tag, Object value)939         public Value(byte tag, Object value) {
940             super(value);
941             this.tag = tag;
942         }
943 
getTag()944         public byte getTag() {
945             return tag;
946         }
947 
length()948         public int length() {
949             return super.length(tag);
950         }
951 
addValueTo(Packet packet)952         public void addValueTo(Packet packet) {
953             if (value == null) {
954                 throw new Failure("Unable to put null value into packet: " + this);
955             }
956             packet.addByte(tag);
957             super.addValueTo(packet, tag);
958         }
959 
getValueFrom(Packet packet)960         public void getValueFrom(Packet packet) throws BoundException {
961             tag = packet.getByte();
962             super.getValueFrom(packet, tag);
963         }
964 
toString()965         public String toString() {
966             return super.toString(tag);
967         }
968 
969     } // end of class Value
970 
971 } // end of class JDWP
972